diff options
author | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2009-06-23 11:25:24 +0000 |
---|---|---|
committer | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2009-06-23 11:25:24 +0000 |
commit | 41787e147279ff0695e9d759487266a60b80867b (patch) | |
tree | 8f28566c8fd7106c80d2536d2df540dbb4499cc5 /src/pluto/packet.c | |
parent | c3e7f611ea8273c6b3909cb006ade4903a74aad0 (diff) | |
download | vyos-strongswan-41787e147279ff0695e9d759487266a60b80867b.tar.gz vyos-strongswan-41787e147279ff0695e9d759487266a60b80867b.zip |
[svn-upgrade] Integrating new upstream version, strongswan (4.3.2)
Diffstat (limited to 'src/pluto/packet.c')
-rw-r--r-- | src/pluto/packet.c | 1286 |
1 files changed, 642 insertions, 644 deletions
diff --git a/src/pluto/packet.c b/src/pluto/packet.c index e8a3a1e11..01967efed 100644 --- a/src/pluto/packet.c +++ b/src/pluto/packet.c @@ -11,8 +11,6 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. - * - * RCSID $Id: packet.c 3252 2007-10-06 21:24:50Z andreas $ */ #include <stdio.h> @@ -27,7 +25,7 @@ #include "defs.h" #include "log.h" #include "packet.h" -#include "whack.h" /* for RC_LOG_SERIOUS */ +#include "whack.h" /* for RC_LOG_SERIOUS */ /* ISAKMP Header: for all messages * layout from RFC 2408 "ISAKMP" section 3.1 @@ -49,15 +47,15 @@ */ static field_desc isa_fields[] = { - { ft_raw, COOKIE_SIZE, "initiator cookie", NULL }, - { ft_raw, COOKIE_SIZE, "responder cookie", NULL }, - { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, - { ft_enum, 8/BITS_PER_BYTE, "ISAKMP version", &version_names }, - { ft_enum, 8/BITS_PER_BYTE, "exchange type", &exchange_names }, - { ft_set, 8/BITS_PER_BYTE, "flags", flag_bit_names }, - { ft_raw, 32/BITS_PER_BYTE, "message ID", NULL }, - { ft_len, 32/BITS_PER_BYTE, "length", NULL }, - { ft_end, 0, NULL, NULL } + { ft_raw, COOKIE_SIZE, "initiator cookie", NULL }, + { ft_raw, COOKIE_SIZE, "responder cookie", NULL }, + { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, + { ft_enum, 8/BITS_PER_BYTE, "ISAKMP version", &version_names }, + { ft_enum, 8/BITS_PER_BYTE, "exchange type", &exchange_names }, + { ft_set, 8/BITS_PER_BYTE, "flags", flag_bit_names }, + { ft_raw, 32/BITS_PER_BYTE, "message ID", NULL }, + { ft_len, 32/BITS_PER_BYTE, "length", NULL }, + { ft_end, 0, NULL, NULL } }; struct_desc isakmp_hdr_desc = { "ISAKMP Message", isa_fields, sizeof(struct isakmp_hdr) }; @@ -74,10 +72,10 @@ struct_desc isakmp_hdr_desc = { "ISAKMP Message", isa_fields, sizeof(struct isak */ static field_desc isag_fields[] = { - { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, - { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, - { ft_len, 16/BITS_PER_BYTE, "length", NULL }, - { ft_end, 0, NULL, NULL } + { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, + { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, + { ft_len, 16/BITS_PER_BYTE, "length", NULL }, + { ft_end, 0, NULL, NULL } }; struct_desc isakmp_generic_desc = { "ISAKMP Generic Payload", isag_fields, sizeof(struct isakmp_generic) }; @@ -100,36 +98,36 @@ struct_desc isakmp_generic_desc = { "ISAKMP Generic Payload", isag_fields, sizeo /* Oakley Attributes */ static field_desc isaat_fields_oakley[] = { - { ft_af_enum, 16/BITS_PER_BYTE, "af+type", &oakley_attr_names }, - { ft_lv, 16/BITS_PER_BYTE, "length/value", NULL }, - { ft_end, 0, NULL, NULL } + { ft_af_enum, 16/BITS_PER_BYTE, "af+type", &oakley_attr_names }, + { ft_lv, 16/BITS_PER_BYTE, "length/value", NULL }, + { ft_end, 0, NULL, NULL } }; struct_desc isakmp_oakley_attribute_desc = { - "ISAKMP Oakley attribute", - isaat_fields_oakley, sizeof(struct isakmp_attribute) }; + "ISAKMP Oakley attribute", + isaat_fields_oakley, sizeof(struct isakmp_attribute) }; /* IPsec DOI Attributes */ static field_desc isaat_fields_ipsec[] = { - { ft_af_enum, 16/BITS_PER_BYTE, "af+type", &ipsec_attr_names }, - { ft_lv, 16/BITS_PER_BYTE, "length/value", NULL }, - { ft_end, 0, NULL, NULL } + { ft_af_enum, 16/BITS_PER_BYTE, "af+type", &ipsec_attr_names }, + { ft_lv, 16/BITS_PER_BYTE, "length/value", NULL }, + { ft_end, 0, NULL, NULL } }; struct_desc isakmp_ipsec_attribute_desc = { - "ISAKMP IPsec DOI attribute", - isaat_fields_ipsec, sizeof(struct isakmp_attribute) }; + "ISAKMP IPsec DOI attribute", + isaat_fields_ipsec, sizeof(struct isakmp_attribute) }; /* Mode Config Attributes */ static field_desc isaat_fields_modecfg[] = { - { ft_af_loose_enum, 16/BITS_PER_BYTE, "ModeCfg attr type", &modecfg_attr_names }, - { ft_lv, 16/BITS_PER_BYTE, "length/value", NULL }, - { ft_end, 0, NULL, NULL } + { ft_af_loose_enum, 16/BITS_PER_BYTE, "ModeCfg attr type", &modecfg_attr_names }, + { ft_lv, 16/BITS_PER_BYTE, "length/value", NULL }, + { ft_end, 0, NULL, NULL } }; struct_desc isakmp_modecfg_attribute_desc = { - "ISAKMP ModeCfg attribute", - isaat_fields_modecfg, sizeof(struct isakmp_attribute) }; + "ISAKMP ModeCfg attribute", + isaat_fields_modecfg, sizeof(struct isakmp_attribute) }; /* ISAKMP Security Association Payload * layout from RFC 2408 "ISAKMP" section 3.4 @@ -148,18 +146,18 @@ struct_desc isakmp_modecfg_attribute_desc = { * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ static field_desc isasa_fields[] = { - { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, - { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, - { ft_len, 16/BITS_PER_BYTE, "length", NULL }, - { ft_enum, 32/BITS_PER_BYTE, "DOI", &doi_names }, - { ft_end, 0, NULL, NULL } + { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, + { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, + { ft_len, 16/BITS_PER_BYTE, "length", NULL }, + { ft_enum, 32/BITS_PER_BYTE, "DOI", &doi_names }, + { ft_end, 0, NULL, NULL } }; struct_desc isakmp_sa_desc = { "ISAKMP Security Association Payload", isasa_fields, sizeof(struct isakmp_sa) }; static field_desc ipsec_sit_field[] = { - { ft_set, 32/BITS_PER_BYTE, "IPsec DOI SIT", &sit_bit_names }, - { ft_end, 0, NULL, NULL } + { ft_set, 32/BITS_PER_BYTE, "IPsec DOI SIT", &sit_bit_names }, + { ft_end, 0, NULL, NULL } }; struct_desc ipsec_sit_desc = { "IPsec DOI SIT", ipsec_sit_field, sizeof(u_int32_t) }; @@ -179,14 +177,14 @@ struct_desc ipsec_sit_desc = { "IPsec DOI SIT", ipsec_sit_field, sizeof(u_int32_ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ static field_desc isap_fields[] = { - { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, - { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, - { ft_len, 16/BITS_PER_BYTE, "length", NULL }, - { ft_nat, 8/BITS_PER_BYTE, "proposal number", NULL }, - { ft_enum, 8/BITS_PER_BYTE, "protocol ID", &protocol_names }, - { ft_nat, 8/BITS_PER_BYTE, "SPI size", NULL }, - { ft_nat, 8/BITS_PER_BYTE, "number of transforms", NULL }, - { ft_end, 0, NULL, NULL } + { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, + { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, + { ft_len, 16/BITS_PER_BYTE, "length", NULL }, + { ft_nat, 8/BITS_PER_BYTE, "proposal number", NULL }, + { ft_enum, 8/BITS_PER_BYTE, "protocol ID", &protocol_names }, + { ft_nat, 8/BITS_PER_BYTE, "SPI size", NULL }, + { ft_nat, 8/BITS_PER_BYTE, "number of transforms", NULL }, + { ft_end, 0, NULL, NULL } }; struct_desc isakmp_proposal_desc = { "ISAKMP Proposal Payload", isap_fields, sizeof(struct isakmp_proposal) }; @@ -210,63 +208,63 @@ struct_desc isakmp_proposal_desc = { "ISAKMP Proposal Payload", isap_fields, siz /* PROTO_ISAKMP */ static field_desc isat_fields_isakmp[] = { - { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, - { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, - { ft_len, 16/BITS_PER_BYTE, "length", NULL }, - { ft_nat, 8/BITS_PER_BYTE, "transform number", NULL }, - { ft_enum, 8/BITS_PER_BYTE, "transform ID", &isakmp_transformid_names }, - { ft_mbz, 16/BITS_PER_BYTE, NULL, NULL }, - { ft_end, 0, NULL, NULL } + { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, + { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, + { ft_len, 16/BITS_PER_BYTE, "length", NULL }, + { ft_nat, 8/BITS_PER_BYTE, "transform number", NULL }, + { ft_enum, 8/BITS_PER_BYTE, "transform ID", &isakmp_transformid_names }, + { ft_mbz, 16/BITS_PER_BYTE, NULL, NULL }, + { ft_end, 0, NULL, NULL } }; struct_desc isakmp_isakmp_transform_desc = { - "ISAKMP Transform Payload (ISAKMP)", - isat_fields_isakmp, sizeof(struct isakmp_transform) }; + "ISAKMP Transform Payload (ISAKMP)", + isat_fields_isakmp, sizeof(struct isakmp_transform) }; /* PROTO_IPSEC_AH */ static field_desc isat_fields_ah[] = { - { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, - { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, - { ft_len, 16/BITS_PER_BYTE, "length", NULL }, - { ft_nat, 8/BITS_PER_BYTE, "transform number", NULL }, - { ft_enum, 8/BITS_PER_BYTE, "transform ID", &ah_transformid_names }, - { ft_mbz, 16/BITS_PER_BYTE, NULL, NULL }, - { ft_end, 0, NULL, NULL } + { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, + { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, + { ft_len, 16/BITS_PER_BYTE, "length", NULL }, + { ft_nat, 8/BITS_PER_BYTE, "transform number", NULL }, + { ft_enum, 8/BITS_PER_BYTE, "transform ID", &ah_transformid_names }, + { ft_mbz, 16/BITS_PER_BYTE, NULL, NULL }, + { ft_end, 0, NULL, NULL } }; struct_desc isakmp_ah_transform_desc = { - "ISAKMP Transform Payload (AH)", - isat_fields_ah, sizeof(struct isakmp_transform) }; + "ISAKMP Transform Payload (AH)", + isat_fields_ah, sizeof(struct isakmp_transform) }; /* PROTO_IPSEC_ESP */ static field_desc isat_fields_esp[] = { - { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, - { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, - { ft_len, 16/BITS_PER_BYTE, "length", NULL }, - { ft_nat, 8/BITS_PER_BYTE, "transform number", NULL }, - { ft_enum, 8/BITS_PER_BYTE, "transform ID", &esp_transformid_names }, - { ft_mbz, 16/BITS_PER_BYTE, NULL, NULL }, - { ft_end, 0, NULL, NULL } + { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, + { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, + { ft_len, 16/BITS_PER_BYTE, "length", NULL }, + { ft_nat, 8/BITS_PER_BYTE, "transform number", NULL }, + { ft_enum, 8/BITS_PER_BYTE, "transform ID", &esp_transformid_names }, + { ft_mbz, 16/BITS_PER_BYTE, NULL, NULL }, + { ft_end, 0, NULL, NULL } }; struct_desc isakmp_esp_transform_desc = { - "ISAKMP Transform Payload (ESP)", - isat_fields_esp, sizeof(struct isakmp_transform) }; + "ISAKMP Transform Payload (ESP)", + isat_fields_esp, sizeof(struct isakmp_transform) }; /* PROTO_IPCOMP */ static field_desc isat_fields_ipcomp[] = { - { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, - { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, - { ft_len, 16/BITS_PER_BYTE, "length", NULL }, - { ft_nat, 8/BITS_PER_BYTE, "transform number", NULL }, - { ft_enum, 8/BITS_PER_BYTE, "transform ID", &ipcomp_transformid_names }, - { ft_mbz, 16/BITS_PER_BYTE, NULL, NULL }, - { ft_end, 0, NULL, NULL } + { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, + { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, + { ft_len, 16/BITS_PER_BYTE, "length", NULL }, + { ft_nat, 8/BITS_PER_BYTE, "transform number", NULL }, + { ft_enum, 8/BITS_PER_BYTE, "transform ID", &ipcomp_transformid_names }, + { ft_mbz, 16/BITS_PER_BYTE, NULL, NULL }, + { ft_end, 0, NULL, NULL } }; struct_desc isakmp_ipcomp_transform_desc = { - "ISAKMP Transform Payload (COMP)", - isat_fields_ipcomp, sizeof(struct isakmp_transform) }; + "ISAKMP Transform Payload (COMP)", + isat_fields_ipcomp, sizeof(struct isakmp_transform) }; /* ISAKMP Key Exchange Payload: no fixed fields beyond the generic ones. @@ -303,13 +301,13 @@ struct_desc isakmp_keyex_desc = { "ISAKMP Key Exchange Payload", isag_fields, si * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ static field_desc isaid_fields[] = { - { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, - { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, - { ft_len, 16/BITS_PER_BYTE, "length", NULL }, - { ft_enum, 8/BITS_PER_BYTE, "ID type", &ident_names }, /* ??? depends on DOI? */ - { ft_nat, 8/BITS_PER_BYTE, "DOI specific A", NULL }, /* ??? depends on DOI? */ - { ft_nat, 16/BITS_PER_BYTE, "DOI specific B", NULL }, /* ??? depends on DOI? */ - { ft_end, 0, NULL, NULL } + { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, + { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, + { ft_len, 16/BITS_PER_BYTE, "length", NULL }, + { ft_enum, 8/BITS_PER_BYTE, "ID type", &ident_names }, /* ??? depends on DOI? */ + { ft_nat, 8/BITS_PER_BYTE, "DOI specific A", NULL }, /* ??? depends on DOI? */ + { ft_nat, 16/BITS_PER_BYTE, "DOI specific B", NULL }, /* ??? depends on DOI? */ + { ft_end, 0, NULL, NULL } }; struct_desc isakmp_identification_desc = { "ISAKMP Identification Payload", isaid_fields, sizeof(struct isakmp_id) }; @@ -330,13 +328,13 @@ struct_desc isakmp_identification_desc = { "ISAKMP Identification Payload", isai * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ static field_desc isaiid_fields[] = { - { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, - { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, - { ft_len, 16/BITS_PER_BYTE, "length", NULL }, - { ft_enum, 8/BITS_PER_BYTE, "ID type", &ident_names }, - { ft_nat, 8/BITS_PER_BYTE, "Protocol ID", NULL }, /* ??? UDP/TCP or 0? */ - { ft_nat, 16/BITS_PER_BYTE, "port", NULL }, - { ft_end, 0, NULL, NULL } + { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, + { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, + { ft_len, 16/BITS_PER_BYTE, "length", NULL }, + { ft_enum, 8/BITS_PER_BYTE, "ID type", &ident_names }, + { ft_nat, 8/BITS_PER_BYTE, "Protocol ID", NULL }, /* ??? UDP/TCP or 0? */ + { ft_nat, 16/BITS_PER_BYTE, "port", NULL }, + { ft_end, 0, NULL, NULL } }; struct_desc isakmp_ipsec_identification_desc = { "ISAKMP Identification Payload (IPsec DOI)", isaiid_fields, sizeof(struct isakmp_ipsec_id) }; @@ -357,11 +355,11 @@ struct_desc isakmp_ipsec_identification_desc = { "ISAKMP Identification Payload * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ static field_desc isacert_fields[] = { - { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, - { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, - { ft_len, 16/BITS_PER_BYTE, "length", NULL }, - { ft_enum, 8/BITS_PER_BYTE, "cert encoding", &cert_type_names }, - { ft_end, 0, NULL, NULL } + { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, + { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, + { ft_len, 16/BITS_PER_BYTE, "length", NULL }, + { ft_enum, 8/BITS_PER_BYTE, "cert encoding", &cert_type_names }, + { ft_end, 0, NULL, NULL } }; /* Note: the size field of isakmp_ipsec_certificate_desc cannot be @@ -385,11 +383,11 @@ static field_desc isacert_fields[] = { * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ static field_desc isacr_fields[] = { - { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, - { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, - { ft_len, 16/BITS_PER_BYTE, "length", NULL }, - { ft_enum, 8/BITS_PER_BYTE, "cert type", &cert_type_names }, - { ft_end, 0, NULL, NULL } + { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, + { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, + { ft_len, 16/BITS_PER_BYTE, "length", NULL }, + { ft_enum, 8/BITS_PER_BYTE, "cert type", &cert_type_names }, + { ft_end, 0, NULL, NULL } }; /* Note: the size field of isakmp_ipsec_cert_req_desc cannot be @@ -469,14 +467,14 @@ struct_desc isakmp_nonce_desc = { "ISAKMP Nonce Payload", isag_fields, sizeof(st * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ static field_desc isan_fields[] = { - { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, - { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, - { ft_len, 16/BITS_PER_BYTE, "length", NULL }, - { ft_enum, 32/BITS_PER_BYTE, "DOI", &doi_names }, - { ft_nat, 8/BITS_PER_BYTE, "protocol ID", NULL }, /* ??? really enum: ISAKMP, IPSEC, ESP, ... */ - { ft_nat, 8/BITS_PER_BYTE, "SPI size", NULL }, - { ft_enum, 16/BITS_PER_BYTE, "Notify Message Type", ¬ification_names }, - { ft_end, 0, NULL, NULL } + { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, + { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, + { ft_len, 16/BITS_PER_BYTE, "length", NULL }, + { ft_enum, 32/BITS_PER_BYTE, "DOI", &doi_names }, + { ft_nat, 8/BITS_PER_BYTE, "protocol ID", NULL }, /* ??? really enum: ISAKMP, IPSEC, ESP, ... */ + { ft_nat, 8/BITS_PER_BYTE, "SPI size", NULL }, + { ft_enum, 16/BITS_PER_BYTE, "Notify Message Type", ¬ification_names }, + { ft_end, 0, NULL, NULL } }; struct_desc isakmp_notification_desc = { "ISAKMP Notification Payload", isan_fields, sizeof(struct isakmp_notification) }; @@ -500,14 +498,14 @@ struct_desc isakmp_notification_desc = { "ISAKMP Notification Payload", isan_fie * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ static field_desc isad_fields[] = { - { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, - { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, - { ft_len, 16/BITS_PER_BYTE, "length", NULL }, - { ft_enum, 32/BITS_PER_BYTE, "DOI", &doi_names }, - { ft_nat, 8/BITS_PER_BYTE, "protocol ID", NULL }, /* ??? really enum: ISAKMP, IPSEC */ - { ft_nat, 8/BITS_PER_BYTE, "SPI size", NULL }, - { ft_nat, 16/BITS_PER_BYTE, "number of SPIs", NULL }, - { ft_end, 0, NULL, NULL } + { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, + { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, + { ft_len, 16/BITS_PER_BYTE, "length", NULL }, + { ft_enum, 32/BITS_PER_BYTE, "DOI", &doi_names }, + { ft_nat, 8/BITS_PER_BYTE, "protocol ID", NULL }, /* ??? really enum: ISAKMP, IPSEC */ + { ft_nat, 8/BITS_PER_BYTE, "SPI size", NULL }, + { ft_nat, 16/BITS_PER_BYTE, "number of SPIs", NULL }, + { ft_end, 0, NULL, NULL } }; struct_desc isakmp_delete_desc = { "ISAKMP Delete Payload", isad_fields, sizeof(struct isakmp_delete) }; @@ -532,26 +530,26 @@ struct_desc isakmp_vendor_id_desc = { "ISAKMP Vendor ID Payload", isag_fields, s /* * From draft-dukes-ike-mode-cfg 3.2. Attribute Payload - 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ! Next Payload ! RESERVED ! Payload Length ! - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ! Type ! RESERVED ! Identifier ! - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ! ! - ~ Attributes ~ - ! ! - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Next Payload ! RESERVED ! Payload Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Type ! RESERVED ! Identifier ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! ! + ~ Attributes ~ + ! ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ static field_desc isaattr_fields[] = { - { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, - { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, - { ft_len, 16/BITS_PER_BYTE, "length", NULL }, - { ft_enum, 8/BITS_PER_BYTE, "Attr Msg Type", &attr_msg_type_names }, - { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, - { ft_nat, 16/BITS_PER_BYTE, "Identifier", NULL }, - { ft_end, 0, NULL, NULL } + { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, + { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, + { ft_len, 16/BITS_PER_BYTE, "length", NULL }, + { ft_enum, 8/BITS_PER_BYTE, "Attr Msg Type", &attr_msg_type_names }, + { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, + { ft_nat, 16/BITS_PER_BYTE, "Identifier", NULL }, + { ft_end, 0, NULL, NULL } }; struct_desc isakmp_attr_desc = { "ISAKMP Mode Attribute", isaattr_fields, sizeof(struct isakmp_mode_attr) }; @@ -581,12 +579,12 @@ struct_desc isakmp_nat_d = { "ISAKMP NAT-D Payload", isag_fields, sizeof(struct * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ static field_desc isanat_oa_fields[] = { - { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, - { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, - { ft_len, 16/BITS_PER_BYTE, "length", NULL }, - { ft_enum, 8/BITS_PER_BYTE, "ID type", &ident_names }, - { ft_mbz, 24/BITS_PER_BYTE, NULL, NULL }, - { ft_end, 0, NULL, NULL } + { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names }, + { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL }, + { ft_len, 16/BITS_PER_BYTE, "length", NULL }, + { ft_enum, 8/BITS_PER_BYTE, "ID type", &ident_names }, + { ft_mbz, 24/BITS_PER_BYTE, NULL, NULL }, + { ft_end, 0, NULL, NULL } }; struct_desc isakmp_nat_oa = { "ISAKMP NAT-OA Payload", isanat_oa_fields, sizeof(struct isakmp_nat_oa) }; @@ -600,40 +598,40 @@ struct_desc isakmp_nat_oa = { "ISAKMP NAT-OA Payload", isanat_oa_fields, sizeof( * We make all these entries NULL */ struct_desc *const payload_descs[ISAKMP_NEXT_ROOF] = { - NULL, /* 0 ISAKMP_NEXT_NONE (No other payload following) */ - &isakmp_sa_desc, /* 1 ISAKMP_NEXT_SA (Security Association) */ - NULL, /* 2 ISAKMP_NEXT_P (Proposal) */ - NULL, /* 3 ISAKMP_NEXT_T (Transform) */ - &isakmp_keyex_desc, /* 4 ISAKMP_NEXT_KE (Key Exchange) */ - NULL, /* 5 ISAKMP_NEXT_ID (Identification) */ - &isakmp_ipsec_certificate_desc, /* 6 ISAKMP_NEXT_CERT (Certificate) */ - &isakmp_ipsec_cert_req_desc, /* 7 ISAKMP_NEXT_CR (Certificate Request) */ - &isakmp_hash_desc, /* 8 ISAKMP_NEXT_HASH (Hash) */ - &isakmp_signature_desc, /* 9 ISAKMP_NEXT_SIG (Signature) */ - &isakmp_nonce_desc, /* 10 ISAKMP_NEXT_NONCE (Nonce) */ - &isakmp_notification_desc, /* 11 ISAKMP_NEXT_N (Notification) */ - &isakmp_delete_desc, /* 12 ISAKMP_NEXT_D (Delete) */ - &isakmp_vendor_id_desc, /* 13 ISAKMP_NEXT_VID (Vendor ID) */ - &isakmp_attr_desc, /* 14 ISAKMP_NEXT_ATTR (Mode Config) */ - NULL, /* 15 */ - NULL, /* 16 */ - NULL, /* 17 */ - NULL, /* 18 */ - NULL, /* 19 */ - &isakmp_nat_d, /* 20=130 ISAKMP_NEXT_NATD (NAT-D) */ - &isakmp_nat_oa, /* 20=131 ISAKMP_NEXT_NATOA (NAT-OA) */ + NULL, /* 0 ISAKMP_NEXT_NONE (No other payload following) */ + &isakmp_sa_desc, /* 1 ISAKMP_NEXT_SA (Security Association) */ + NULL, /* 2 ISAKMP_NEXT_P (Proposal) */ + NULL, /* 3 ISAKMP_NEXT_T (Transform) */ + &isakmp_keyex_desc, /* 4 ISAKMP_NEXT_KE (Key Exchange) */ + NULL, /* 5 ISAKMP_NEXT_ID (Identification) */ + &isakmp_ipsec_certificate_desc, /* 6 ISAKMP_NEXT_CERT (Certificate) */ + &isakmp_ipsec_cert_req_desc, /* 7 ISAKMP_NEXT_CR (Certificate Request) */ + &isakmp_hash_desc, /* 8 ISAKMP_NEXT_HASH (Hash) */ + &isakmp_signature_desc, /* 9 ISAKMP_NEXT_SIG (Signature) */ + &isakmp_nonce_desc, /* 10 ISAKMP_NEXT_NONCE (Nonce) */ + &isakmp_notification_desc, /* 11 ISAKMP_NEXT_N (Notification) */ + &isakmp_delete_desc, /* 12 ISAKMP_NEXT_D (Delete) */ + &isakmp_vendor_id_desc, /* 13 ISAKMP_NEXT_VID (Vendor ID) */ + &isakmp_attr_desc, /* 14 ISAKMP_NEXT_ATTR (Mode Config) */ + NULL, /* 15 */ + NULL, /* 16 */ + NULL, /* 17 */ + NULL, /* 18 */ + NULL, /* 19 */ + &isakmp_nat_d, /* 20=130 ISAKMP_NEXT_NATD (NAT-D) */ + &isakmp_nat_oa, /* 20=131 ISAKMP_NEXT_NATOA (NAT-OA) */ }; void init_pbs(pb_stream *pbs, u_int8_t *start, size_t len, const char *name) { - pbs->container = NULL; - pbs->desc = NULL; - pbs->name = name; - pbs->start = pbs->cur = start; - pbs->roof = start + len; - pbs->lenfld = NULL; - pbs->lenfld_desc = NULL; + pbs->container = NULL; + pbs->desc = NULL; + pbs->name = name; + pbs->start = pbs->cur = start; + pbs->roof = start + len; + pbs->lenfld = NULL; + pbs->lenfld_desc = NULL; } #ifdef DEBUG @@ -648,85 +646,85 @@ void DBG_print_struct(const char *label, const void *struct_ptr , struct_desc *sd, bool len_meaningful) { - bool immediate = FALSE; - const u_int8_t *inp = struct_ptr; - field_desc *fp; - - DBG_log("%s%s:", label, sd->name); + bool immediate = FALSE; + const u_int8_t *inp = struct_ptr; + field_desc *fp; - for (fp = sd->fields; fp->field_type != ft_end; fp++) - { - int i = fp->size; - u_int32_t n = 0; + DBG_log("%s%s:", label, sd->name); - switch (fp->field_type) + for (fp = sd->fields; fp->field_type != ft_end; fp++) { - case ft_mbz: /* must be zero */ - inp += i; - break; - case ft_nat: /* natural number (may be 0) */ - case ft_len: /* length of this struct and any following crud */ - case ft_lv: /* length/value field of attribute */ - case ft_enum: /* value from an enumeration */ - case ft_loose_enum: /* value from an enumeration with only some names known */ - case ft_af_enum: /* Attribute Format + value from an enumeration */ - case ft_af_loose_enum: /* Attribute Format + value from an enumeration */ - case ft_set: /* bits representing set */ - switch (i) - { - case 8/BITS_PER_BYTE: - n = *(const u_int8_t *)inp; - break; - case 16/BITS_PER_BYTE: - n = *(const u_int16_t *)inp; - break; - case 32/BITS_PER_BYTE: - n = *(const u_int32_t *)inp; - break; - default: - bad_case(i); - } - switch (fp->field_type) - { - case ft_len: /* length of this struct and any following crud */ - case ft_lv: /* length/value field of attribute */ - if (!immediate && !len_meaningful) - break; - /* FALL THROUGH */ - case ft_nat: /* natural number (may be 0) */ - DBG_log(" %s: %lu", fp->name, (unsigned long)n); - break; - case ft_af_enum: /* Attribute Format + value from an enumeration */ - case ft_af_loose_enum: /* Attribute Format + value from an enumeration */ - if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV) - immediate = TRUE; - /* FALL THROUGH */ - case ft_enum: /* value from an enumeration */ - case ft_loose_enum: /* value from an enumeration with only some names known */ - DBG_log(" %s: %s", fp->name, enum_show(fp->desc, n)); - break; - case ft_set: /* bits representing set */ - DBG_log(" %s: %s", fp->name, bitnamesof(fp->desc, n)); - break; - default: - bad_case(fp->field_type); - } - inp += i; - break; - - case ft_raw: /* bytes to be left in network-order */ - { - char m[50]; /* arbitrary limit on name width in log */ - - snprintf(m, sizeof(m), " %s:", fp->name); - DBG_dump(m, inp, i); - inp += i; - } - break; - default: - bad_case(fp->field_type); + int i = fp->size; + u_int32_t n = 0; + + switch (fp->field_type) + { + case ft_mbz: /* must be zero */ + inp += i; + break; + case ft_nat: /* natural number (may be 0) */ + case ft_len: /* length of this struct and any following crud */ + case ft_lv: /* length/value field of attribute */ + case ft_enum: /* value from an enumeration */ + case ft_loose_enum: /* value from an enumeration with only some names known */ + case ft_af_enum: /* Attribute Format + value from an enumeration */ + case ft_af_loose_enum: /* Attribute Format + value from an enumeration */ + case ft_set: /* bits representing set */ + switch (i) + { + case 8/BITS_PER_BYTE: + n = *(const u_int8_t *)inp; + break; + case 16/BITS_PER_BYTE: + n = *(const u_int16_t *)inp; + break; + case 32/BITS_PER_BYTE: + n = *(const u_int32_t *)inp; + break; + default: + bad_case(i); + } + switch (fp->field_type) + { + case ft_len: /* length of this struct and any following crud */ + case ft_lv: /* length/value field of attribute */ + if (!immediate && !len_meaningful) + break; + /* FALL THROUGH */ + case ft_nat: /* natural number (may be 0) */ + DBG_log(" %s: %lu", fp->name, (unsigned long)n); + break; + case ft_af_enum: /* Attribute Format + value from an enumeration */ + case ft_af_loose_enum: /* Attribute Format + value from an enumeration */ + if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV) + immediate = TRUE; + /* FALL THROUGH */ + case ft_enum: /* value from an enumeration */ + case ft_loose_enum: /* value from an enumeration with only some names known */ + DBG_log(" %s: %s", fp->name, enum_show(fp->desc, n)); + break; + case ft_set: /* bits representing set */ + DBG_log(" %s: %s", fp->name, bitnamesof(fp->desc, n)); + break; + default: + bad_case(fp->field_type); + } + inp += i; + break; + + case ft_raw: /* bytes to be left in network-order */ + { + char m[50]; /* arbitrary limit on name width in log */ + + snprintf(m, sizeof(m), " %s:", fp->name); + DBG_dump(m, inp, i); + inp += i; + } + break; + default: + bad_case(fp->field_type); + } } - } } static void @@ -734,35 +732,35 @@ DBG_prefix_print_struct(const pb_stream *pbs , const char *label, const void *struct_ptr , struct_desc *sd, bool len_meaningful) { - /* print out a title, with a prefix of asterisks to show - * the nesting level. - */ - char space[40]; /* arbitrary limit on label+flock-of-* */ - size_t len = strlen(label); - - if (sizeof(space) <= len) - { - DBG_print_struct(label, struct_ptr, sd, len_meaningful); - } - else - { - const pb_stream *p = pbs; - char *pre = &space[sizeof(space) - (len + 1)]; - - strcpy(pre, label); - - /* put at least one * out */ - for (;;) + /* print out a title, with a prefix of asterisks to show + * the nesting level. + */ + char space[40]; /* arbitrary limit on label+flock-of-* */ + size_t len = strlen(label); + + if (sizeof(space) <= len) + { + DBG_print_struct(label, struct_ptr, sd, len_meaningful); + } + else { - if (pre <= space) - break; - *--pre = '*'; - if (p == NULL) - break; - p = p->container; + const pb_stream *p = pbs; + char *pre = &space[sizeof(space) - (len + 1)]; + + strcpy(pre, label); + + /* put at least one * out */ + for (;;) + { + if (pre <= space) + break; + *--pre = '*'; + if (p == NULL) + break; + p = p->container; + } + DBG_print_struct(pre, struct_ptr, sd, len_meaningful); } - DBG_print_struct(pre, struct_ptr, sd, len_meaningful); - } } #endif @@ -785,191 +783,191 @@ bool in_struct(void *struct_ptr, struct_desc *sd , pb_stream *ins, pb_stream *obj_pbs) { - err_t ugh = NULL; - u_int8_t *cur = ins->cur; - - if (ins->roof - cur < (ptrdiff_t)sd->size) - { - ugh = builddiag("not enough room in input packet for %s", sd->name); - } - else - { - u_int8_t *roof = cur + sd->size; /* may be changed by a length field */ - u_int8_t *outp = struct_ptr; - bool immediate = FALSE; - field_desc *fp; + err_t ugh = NULL; + u_int8_t *cur = ins->cur; - for (fp = sd->fields; ugh == NULL; fp++) + if (ins->roof - cur < (ptrdiff_t)sd->size) { - size_t i = fp->size; - - passert(ins->roof - cur >= (ptrdiff_t)i); - passert(cur - ins->cur <= (ptrdiff_t)(sd->size - i)); - passert(outp - (cur - ins->cur) == struct_ptr); - -#if 0 - DBG(DBG_PARSING, DBG_log("%d %s" - , (int) (cur - ins->cur), fp->name == NULL? "" : fp->name)); -#endif - switch (fp->field_type) - { - case ft_mbz: /* must be zero */ - for (; i != 0; i--) - { - if (*cur++ != 0) - { - ugh = builddiag("byte %d of %s must be zero, but is not" - , (int) (cur - ins->cur), sd->name); - break; - } - *outp++ = '\0'; /* probably redundant */ - } - break; - - case ft_nat: /* natural number (may be 0) */ - case ft_len: /* length of this struct and any following crud */ - case ft_lv: /* length/value field of attribute */ - case ft_enum: /* value from an enumeration */ - case ft_loose_enum: /* value from an enumeration with only some names known */ - case ft_af_enum: /* Attribute Format + value from an enumeration */ - case ft_af_loose_enum: /* Attribute Format + value from an enumeration */ - case ft_set: /* bits representing set */ - { - u_int32_t n = 0; - - for (; i != 0; i--) - n = (n << BITS_PER_BYTE) | *cur++; + ugh = builddiag("not enough room in input packet for %s", sd->name); + } + else + { + u_int8_t *roof = cur + sd->size; /* may be changed by a length field */ + u_int8_t *outp = struct_ptr; + bool immediate = FALSE; + field_desc *fp; - switch (fp->field_type) - { - case ft_len: /* length of this struct and any following crud */ - case ft_lv: /* length/value field of attribute */ - { - u_int32_t len = fp->field_type == ft_len? n - : immediate? sd->size : n + sd->size; - - if (len < sd->size) - { - ugh = builddiag("%s of %s is smaller than minimum" - , fp->name, sd->name); - } - else if (pbs_left(ins) < len) - { - ugh = builddiag("%s of %s is larger than can fit" - , fp->name, sd->name); - } - else - { - roof = ins->cur + len; - } - break; - } - case ft_af_loose_enum: /* Attribute Format + value from an enumeration */ - if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV) - immediate = TRUE; - break; - case ft_af_enum: /* Attribute Format + value from an enumeration */ - if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV) - immediate = TRUE; - /* FALL THROUGH */ - case ft_enum: /* value from an enumeration */ - if (enum_name(fp->desc, n) == NULL) - { - ugh = builddiag("%s of %s has an unknown value: %lu" - , fp->name, sd->name, (unsigned long)n); - } - /* FALL THROUGH */ - case ft_loose_enum: /* value from an enumeration with only some names known */ - break; - case ft_set: /* bits representing set */ - if (!testset(fp->desc, n)) - { - ugh = builddiag("bitset %s of %s has unknown member(s): %s" - , fp->name, sd->name, bitnamesof(fp->desc, n)); - } - break; - default: - break; - } - i = fp->size; - switch (i) + for (fp = sd->fields; ugh == NULL; fp++) { - case 8/BITS_PER_BYTE: - *(u_int8_t *)outp = n; - break; - case 16/BITS_PER_BYTE: - *(u_int16_t *)outp = n; - break; - case 32/BITS_PER_BYTE: - *(u_int32_t *)outp = n; - break; - default: - bad_case(i); - } - outp += i; - break; - } + size_t i = fp->size; - case ft_raw: /* bytes to be left in network-order */ - for (; i != 0; i--) - { - *outp++ = *cur++; - } - break; + passert(ins->roof - cur >= (ptrdiff_t)i); + passert(cur - ins->cur <= (ptrdiff_t)(sd->size - i)); + passert(outp - (cur - ins->cur) == struct_ptr); - case ft_end: /* end of field list */ - passert(cur == ins->cur + sd->size); - if (obj_pbs != NULL) - { - init_pbs(obj_pbs, ins->cur, roof - ins->cur, sd->name); - obj_pbs->container = ins; - obj_pbs->desc = sd; - obj_pbs->cur = cur; +#if 0 + DBG(DBG_PARSING, DBG_log("%d %s" + , (int) (cur - ins->cur), fp->name == NULL? "" : fp->name)); +#endif + switch (fp->field_type) + { + case ft_mbz: /* must be zero */ + for (; i != 0; i--) + { + if (*cur++ != 0) + { + ugh = builddiag("byte %d of %s must be zero, but is not" + , (int) (cur - ins->cur), sd->name); + break; + } + *outp++ = '\0'; /* probably redundant */ + } + break; + + case ft_nat: /* natural number (may be 0) */ + case ft_len: /* length of this struct and any following crud */ + case ft_lv: /* length/value field of attribute */ + case ft_enum: /* value from an enumeration */ + case ft_loose_enum: /* value from an enumeration with only some names known */ + case ft_af_enum: /* Attribute Format + value from an enumeration */ + case ft_af_loose_enum: /* Attribute Format + value from an enumeration */ + case ft_set: /* bits representing set */ + { + u_int32_t n = 0; + + for (; i != 0; i--) + n = (n << BITS_PER_BYTE) | *cur++; + + switch (fp->field_type) + { + case ft_len: /* length of this struct and any following crud */ + case ft_lv: /* length/value field of attribute */ + { + u_int32_t len = fp->field_type == ft_len? n + : immediate? sd->size : n + sd->size; + + if (len < sd->size) + { + ugh = builddiag("%s of %s is smaller than minimum" + , fp->name, sd->name); + } + else if (pbs_left(ins) < len) + { + ugh = builddiag("%s of %s is larger than can fit" + , fp->name, sd->name); + } + else + { + roof = ins->cur + len; + } + break; + } + case ft_af_loose_enum: /* Attribute Format + value from an enumeration */ + if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV) + immediate = TRUE; + break; + case ft_af_enum: /* Attribute Format + value from an enumeration */ + if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV) + immediate = TRUE; + /* FALL THROUGH */ + case ft_enum: /* value from an enumeration */ + if (enum_name(fp->desc, n) == NULL) + { + ugh = builddiag("%s of %s has an unknown value: %lu" + , fp->name, sd->name, (unsigned long)n); + } + /* FALL THROUGH */ + case ft_loose_enum: /* value from an enumeration with only some names known */ + break; + case ft_set: /* bits representing set */ + if (!testset(fp->desc, n)) + { + ugh = builddiag("bitset %s of %s has unknown member(s): %s" + , fp->name, sd->name, bitnamesof(fp->desc, n)); + } + break; + default: + break; + } + i = fp->size; + switch (i) + { + case 8/BITS_PER_BYTE: + *(u_int8_t *)outp = n; + break; + case 16/BITS_PER_BYTE: + *(u_int16_t *)outp = n; + break; + case 32/BITS_PER_BYTE: + *(u_int32_t *)outp = n; + break; + default: + bad_case(i); + } + outp += i; + break; + } + + case ft_raw: /* bytes to be left in network-order */ + for (; i != 0; i--) + { + *outp++ = *cur++; + } + break; + + case ft_end: /* end of field list */ + passert(cur == ins->cur + sd->size); + if (obj_pbs != NULL) + { + init_pbs(obj_pbs, ins->cur, roof - ins->cur, sd->name); + obj_pbs->container = ins; + obj_pbs->desc = sd; + obj_pbs->cur = cur; + } + ins->cur = roof; + DBG(DBG_PARSING + , DBG_prefix_print_struct(ins, "parse ", struct_ptr, sd, TRUE)); + return TRUE; + + default: + bad_case(fp->field_type); + } } - ins->cur = roof; - DBG(DBG_PARSING - , DBG_prefix_print_struct(ins, "parse ", struct_ptr, sd, TRUE)); - return TRUE; - - default: - bad_case(fp->field_type); - } } - } - /* some failure got us here: report it */ - loglog(RC_LOG_SERIOUS, ugh); - return FALSE; + /* some failure got us here: report it */ + loglog(RC_LOG_SERIOUS, ugh); + return FALSE; } bool in_raw(void *bytes, size_t len, pb_stream *ins, const char *name) { - if (pbs_left(ins) < len) - { - loglog(RC_LOG_SERIOUS, "not enough bytes left to get %s from %s", name, ins->name); - return FALSE; - } - else - { - if (bytes == NULL) + if (pbs_left(ins) < len) { - DBG(DBG_PARSING - , DBG_log("skipping %u raw bytes of %s (%s)" - , (unsigned) len, ins->name, name); - DBG_dump(name, ins->cur, len)); + loglog(RC_LOG_SERIOUS, "not enough bytes left to get %s from %s", name, ins->name); + return FALSE; } else { - memcpy(bytes, ins->cur, len); - DBG(DBG_PARSING - , DBG_log("parsing %u raw bytes of %s into %s" - , (unsigned) len, ins->name, name); - DBG_dump(name, bytes, len)); + if (bytes == NULL) + { + DBG(DBG_PARSING + , DBG_log("skipping %u raw bytes of %s (%s)" + , (unsigned) len, ins->name, name); + DBG_dump(name, ins->cur, len)); + } + else + { + memcpy(bytes, ins->cur, len); + DBG(DBG_PARSING + , DBG_log("parsing %u raw bytes of %s into %s" + , (unsigned) len, ins->name, name); + DBG_dump(name, bytes, len)); + } + ins->cur += len; + return TRUE; } - ins->cur += len; - return TRUE; - } } /* "emit" a host struct into a network packet. @@ -994,227 +992,227 @@ bool out_struct(const void *struct_ptr, struct_desc *sd , pb_stream *outs, pb_stream *obj_pbs) { - err_t ugh = NULL; - const u_int8_t *inp = struct_ptr; - u_int8_t *cur = outs->cur; - - DBG(DBG_EMITTING - , DBG_prefix_print_struct(outs, "emit ", struct_ptr, sd, obj_pbs==NULL)); - - if (outs->roof - cur < (ptrdiff_t)sd->size) - { - ugh = builddiag("not enough room left in output packet to place %s" - , sd->name); - } - else - { - bool immediate = FALSE; - pb_stream obj; - field_desc *fp; + err_t ugh = NULL; + const u_int8_t *inp = struct_ptr; + u_int8_t *cur = outs->cur; - obj.lenfld = NULL; /* until a length field is discovered */ - obj.lenfld_desc = NULL; + DBG(DBG_EMITTING + , DBG_prefix_print_struct(outs, "emit ", struct_ptr, sd, obj_pbs==NULL)); - for (fp = sd->fields; ugh == NULL; fp++) + if (outs->roof - cur < (ptrdiff_t)sd->size) { - size_t i = fp->size; - - passert(outs->roof - cur >= (ptrdiff_t)i); - passert(cur - outs->cur <= (ptrdiff_t)(sd->size - i)); - passert(inp - (cur - outs->cur) == struct_ptr); - -#if 0 - DBG(DBG_EMITTING, DBG_log("%d %s" - , (int) (cur - outs->cur), fp->name == NULL? "" : fp->name); -#endif - switch (fp->field_type) - { - case ft_mbz: /* must be zero */ - inp += i; - for (; i != 0; i--) - *cur++ = '\0'; - break; - case ft_nat: /* natural number (may be 0) */ - case ft_len: /* length of this struct and any following crud */ - case ft_lv: /* length/value field of attribute */ - case ft_enum: /* value from an enumeration */ - case ft_loose_enum: /* value from an enumeration with only some names known */ - case ft_af_enum: /* Attribute Format + value from an enumeration */ - case ft_af_loose_enum: /* Attribute Format + value from an enumeration */ - case ft_set: /* bits representing set */ - { - u_int32_t n = 0; + ugh = builddiag("not enough room left in output packet to place %s" + , sd->name); + } + else + { + bool immediate = FALSE; + pb_stream obj; + field_desc *fp; - switch (i) - { - case 8/BITS_PER_BYTE: - n = *(const u_int8_t *)inp; - break; - case 16/BITS_PER_BYTE: - n = *(const u_int16_t *)inp; - break; - case 32/BITS_PER_BYTE: - n = *(const u_int32_t *)inp; - break; - default: - bad_case(i); - } + obj.lenfld = NULL; /* until a length field is discovered */ + obj.lenfld_desc = NULL; - switch (fp->field_type) + for (fp = sd->fields; ugh == NULL; fp++) { - case ft_len: /* length of this struct and any following crud */ - case ft_lv: /* length/value field of attribute */ - if (immediate) - break; /* not a length */ - /* We can't check the length because it will likely - * be filled in after variable part is supplied. - * We do record where this is so that it can be - * filled in by a subsequent close_output_pbs(). - */ - passert(obj.lenfld == NULL); /* only one ft_len allowed */ - obj.lenfld = cur; - obj.lenfld_desc = fp; - break; - case ft_af_loose_enum: /* Attribute Format + value from an enumeration */ - if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV) - immediate = TRUE; - break; - case ft_af_enum: /* Attribute Format + value from an enumeration */ - if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV) - immediate = TRUE; - /* FALL THROUGH */ - case ft_enum: /* value from an enumeration */ - if (enum_name(fp->desc, n) == NULL) - { - ugh = builddiag("%s of %s has an unknown value: %lu" - , fp->name, sd->name, (unsigned long)n); - } - /* FALL THROUGH */ - case ft_loose_enum: /* value from an enumeration with only some names known */ - break; - case ft_set: /* bits representing set */ - if (!testset(fp->desc, n)) - { - ugh = builddiag("bitset %s of %s has unknown member(s): %s" - , fp->name, sd->name, bitnamesof(fp->desc, n)); - } - break; - default: - break; - } + size_t i = fp->size; - while (i-- != 0) - { - cur[i] = (u_int8_t)n; - n >>= BITS_PER_BYTE; - } - inp += fp->size; - cur += fp->size; - break; - } - case ft_raw: /* bytes to be left in network-order */ - for (; i != 0; i--) - *cur++ = *inp++; - break; - case ft_end: /* end of field list */ - passert(cur == outs->cur + sd->size); - - obj.container = outs; - obj.desc = sd; - obj.name = sd->name; - obj.start = outs->cur; - obj.cur = cur; - obj.roof = outs->roof; /* limit of possible */ - /* obj.lenfld and obj.lenfld_desc already set */ - - if (obj_pbs == NULL) - { - close_output_pbs(&obj); /* fill in length field, if any */ - } - else - { - /* We set outs->cur to outs->roof so that - * any attempt to output something into outs - * before obj is closed will trigger an error. - */ - outs->cur = outs->roof; + passert(outs->roof - cur >= (ptrdiff_t)i); + passert(cur - outs->cur <= (ptrdiff_t)(sd->size - i)); + passert(inp - (cur - outs->cur) == struct_ptr); - *obj_pbs = obj; +#if 0 + DBG(DBG_EMITTING, DBG_log("%d %s" + , (int) (cur - outs->cur), fp->name == NULL? "" : fp->name); +#endif + switch (fp->field_type) + { + case ft_mbz: /* must be zero */ + inp += i; + for (; i != 0; i--) + *cur++ = '\0'; + break; + case ft_nat: /* natural number (may be 0) */ + case ft_len: /* length of this struct and any following crud */ + case ft_lv: /* length/value field of attribute */ + case ft_enum: /* value from an enumeration */ + case ft_loose_enum: /* value from an enumeration with only some names known */ + case ft_af_enum: /* Attribute Format + value from an enumeration */ + case ft_af_loose_enum: /* Attribute Format + value from an enumeration */ + case ft_set: /* bits representing set */ + { + u_int32_t n = 0; + + switch (i) + { + case 8/BITS_PER_BYTE: + n = *(const u_int8_t *)inp; + break; + case 16/BITS_PER_BYTE: + n = *(const u_int16_t *)inp; + break; + case 32/BITS_PER_BYTE: + n = *(const u_int32_t *)inp; + break; + default: + bad_case(i); + } + + switch (fp->field_type) + { + case ft_len: /* length of this struct and any following crud */ + case ft_lv: /* length/value field of attribute */ + if (immediate) + break; /* not a length */ + /* We can't check the length because it will likely + * be filled in after variable part is supplied. + * We do record where this is so that it can be + * filled in by a subsequent close_output_pbs(). + */ + passert(obj.lenfld == NULL); /* only one ft_len allowed */ + obj.lenfld = cur; + obj.lenfld_desc = fp; + break; + case ft_af_loose_enum: /* Attribute Format + value from an enumeration */ + if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV) + immediate = TRUE; + break; + case ft_af_enum: /* Attribute Format + value from an enumeration */ + if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV) + immediate = TRUE; + /* FALL THROUGH */ + case ft_enum: /* value from an enumeration */ + if (enum_name(fp->desc, n) == NULL) + { + ugh = builddiag("%s of %s has an unknown value: %lu" + , fp->name, sd->name, (unsigned long)n); + } + /* FALL THROUGH */ + case ft_loose_enum: /* value from an enumeration with only some names known */ + break; + case ft_set: /* bits representing set */ + if (!testset(fp->desc, n)) + { + ugh = builddiag("bitset %s of %s has unknown member(s): %s" + , fp->name, sd->name, bitnamesof(fp->desc, n)); + } + break; + default: + break; + } + + while (i-- != 0) + { + cur[i] = (u_int8_t)n; + n >>= BITS_PER_BYTE; + } + inp += fp->size; + cur += fp->size; + break; + } + case ft_raw: /* bytes to be left in network-order */ + for (; i != 0; i--) + *cur++ = *inp++; + break; + case ft_end: /* end of field list */ + passert(cur == outs->cur + sd->size); + + obj.container = outs; + obj.desc = sd; + obj.name = sd->name; + obj.start = outs->cur; + obj.cur = cur; + obj.roof = outs->roof; /* limit of possible */ + /* obj.lenfld and obj.lenfld_desc already set */ + + if (obj_pbs == NULL) + { + close_output_pbs(&obj); /* fill in length field, if any */ + } + else + { + /* We set outs->cur to outs->roof so that + * any attempt to output something into outs + * before obj is closed will trigger an error. + */ + outs->cur = outs->roof; + + *obj_pbs = obj; + } + return TRUE; + + default: + bad_case(fp->field_type); + } } - return TRUE; - - default: - bad_case(fp->field_type); - } } - } - /* some failure got us here: report it */ - loglog(RC_LOG_SERIOUS, ugh); /* ??? serious, but errno not relevant */ - return FALSE; + /* some failure got us here: report it */ + loglog(RC_LOG_SERIOUS, ugh); /* ??? serious, but errno not relevant */ + return FALSE; } bool out_generic(u_int8_t np, struct_desc *sd , pb_stream *outs, pb_stream *obj_pbs) { - struct isakmp_generic gen; + struct isakmp_generic gen; - passert(sd->fields == isakmp_generic_desc.fields); - gen.isag_np = np; - return out_struct(&gen, sd, outs, obj_pbs); + passert(sd->fields == isakmp_generic_desc.fields); + gen.isag_np = np; + return out_struct(&gen, sd, outs, obj_pbs); } bool out_generic_raw(u_int8_t np, struct_desc *sd , pb_stream *outs, const void *bytes, size_t len, const char *name) { - pb_stream pbs; + pb_stream pbs; - if (!out_generic(np, sd, outs, &pbs) - || !out_raw(bytes, len, &pbs, name)) - return FALSE; - close_output_pbs(&pbs); - return TRUE; + if (!out_generic(np, sd, outs, &pbs) + || !out_raw(bytes, len, &pbs, name)) + return FALSE; + close_output_pbs(&pbs); + return TRUE; } bool out_raw(const void *bytes, size_t len, pb_stream *outs, const char *name) { - if (pbs_left(outs) < len) - { - loglog(RC_LOG_SERIOUS, "not enough room left to place %lu bytes of %s in %s" - , (unsigned long) len, name, outs->name); - return FALSE; - } - else - { - DBG(DBG_EMITTING - , DBG_log("emitting %u raw bytes of %s into %s" - , (unsigned) len, name, outs->name); - DBG_dump(name, bytes, len)); - memcpy(outs->cur, bytes, len); - outs->cur += len; - return TRUE; - } + if (pbs_left(outs) < len) + { + loglog(RC_LOG_SERIOUS, "not enough room left to place %lu bytes of %s in %s" + , (unsigned long) len, name, outs->name); + return FALSE; + } + else + { + DBG(DBG_EMITTING + , DBG_log("emitting %u raw bytes of %s into %s" + , (unsigned) len, name, outs->name); + DBG_dump(name, bytes, len)); + memcpy(outs->cur, bytes, len); + outs->cur += len; + return TRUE; + } } bool out_zero(size_t len, pb_stream *outs, const char *name) { - if (pbs_left(outs) < len) - { - loglog(RC_LOG_SERIOUS, "not enough room left to place %s in %s", name, outs->name); - return FALSE; - } - else - { - DBG(DBG_EMITTING, DBG_log("emitting %u zero bytes of %s into %s" - , (unsigned) len, name, outs->name)); - memset(outs->cur, 0x00, len); - outs->cur += len; - return TRUE; - } + if (pbs_left(outs) < len) + { + loglog(RC_LOG_SERIOUS, "not enough room left to place %s in %s", name, outs->name); + return FALSE; + } + else + { + DBG(DBG_EMITTING, DBG_log("emitting %u zero bytes of %s into %s" + , (unsigned) len, name, outs->name)); + memset(outs->cur, 0x00, len); + outs->cur += len; + return TRUE; + } } /* Record current length. @@ -1224,21 +1222,21 @@ out_zero(size_t len, pb_stream *outs, const char *name) void close_output_pbs(pb_stream *pbs) { - if (pbs->lenfld != NULL) - { - u_int32_t len = pbs_offset(pbs); - int i = pbs->lenfld_desc->size; - - if (pbs->lenfld_desc->field_type == ft_lv) - len -= sizeof(struct isakmp_attribute); - DBG(DBG_EMITTING, DBG_log("emitting length of %s: %lu" - , pbs->name, (unsigned long) len)); - while (i-- != 0) + if (pbs->lenfld != NULL) { - pbs->lenfld[i] = (u_int8_t)len; - len >>= BITS_PER_BYTE; + u_int32_t len = pbs_offset(pbs); + int i = pbs->lenfld_desc->size; + + if (pbs->lenfld_desc->field_type == ft_lv) + len -= sizeof(struct isakmp_attribute); + DBG(DBG_EMITTING, DBG_log("emitting length of %s: %lu" + , pbs->name, (unsigned long) len)); + while (i-- != 0) + { + pbs->lenfld[i] = (u_int8_t)len; + len >>= BITS_PER_BYTE; + } } - } - if (pbs->container != NULL) - pbs->container->cur = pbs->cur; /* pass space utilization up */ + if (pbs->container != NULL) + pbs->container->cur = pbs->cur; /* pass space utilization up */ } |