Ethereal-dev: [Ethereal-dev] IKEv2 support
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Shoichi Sakane <sakane@xxxxxxxx>
Date: Wed, 23 Feb 2005 11:17:38 +0900
Hi, I improved packet-isakmp.c to support parsing the IKEv2 packets. I made a diff from ethereal-0.10.9-SVN-13409. I have checked it with our IKEv2 implementation, and it looks working fine. So could you merge it to the main tree if you allow it ? or could you give me comments or advise if you can not ? I attached the diff to this mail. Best regards,
*** packet-isakmp.c.orig Wed Feb 23 11:05:04 2005
--- packet-isakmp.c Wed Feb 23 10:56:05 2005
***************
*** 4,9 ****
--- 4,13 ----
* for ISAKMP (RFC 2407)
* Brad Robel-Forrest <brad.robel-forrest@xxxxxxxxxxxxxx>
*
+ * Added routines for the Internet Key Exchange (IKEv2) Protocol
+ * (draft-ietf-ipsec-ikev2-17.txt)
+ * Shoichi Sakane <sakane@xxxxxxxx>
+ *
* $Id: packet-isakmp.c 12621 2004-11-29 19:30:12Z gerald $
*
* Ethereal - Network traffic analyzer
***************
*** 45,56 ****
--- 49,77 ----
#define isakmp_min(a, b) ((a<b) ? a : b)
+ #define ARLEN(a) (sizeof(a)/sizeof(a[0]))
+
+ #define FIND_TYPE2STR(list, t) \
+ do { \
+ guint i; \
+ for (i = 0; i < ARLEN(list); i++) { \
+ if (t == list[i].type) return list[i].str; \
+ } \
+ } while (0)
+
+ struct type2str_t {
+ guint type;
+ const char *str;
+ };
+
static int proto_isakmp = -1;
static gint ett_isakmp = -1;
static gint ett_isakmp_flags = -1;
static gint ett_isakmp_payload = -1;
+ static int isakmp_version = 0;
+
#define UDP_PORT_ISAKMP 500
#define TCP_PORT_ISAKMP 500
***************
*** 164,188 ****
"LZJH"
};
- #define NUM_ID_TYPES 12
- #define id2str(t) \
- ((t < NUM_ID_TYPES) ? idtypestr[t] : "UNKNOWN-ID-TYPE")
-
- static const char *idtypestr[NUM_ID_TYPES] = {
- "RESERVED",
- "IPV4_ADDR",
- "FQDN",
- "USER_FQDN",
- "IPV4_ADDR_SUBNET",
- "IPV6_ADDR",
- "IPV6_ADDR_SUBNET",
- "IPV4_ADDR_RANGE",
- "IPV6_ADDR_RANGE",
- "DER_ASN1_DN",
- "DER_ASN1_GN",
- "KEY_ID"
- };
-
#define NUM_GRPDESC_TYPES 19
#define grpdesc2str(t) ((t < NUM_GRPDESC_TYPES) ? grpdescstr[t] : "UNKNOWN-GROUP-DESCRIPTION")
--- 185,190 ----
***************
*** 218,223 ****
--- 220,228 ----
#define E_FLAG 0x01
#define C_FLAG 0x02
#define A_FLAG 0x04
+ #define I_FLAG 0x08
+ #define V_FLAG 0x10
+ #define R_FLAG 0x20
guint32 message_id;
guint32 length;
};
***************
*** 231,236 ****
--- 236,243 ----
packet_info *, int);
static void dissect_transform(tvbuff_t *, int, int, proto_tree *,
packet_info *, int);
+ static void dissect_transform2(tvbuff_t *, int, int, proto_tree *,
+ packet_info *, int);
static void dissect_key_exch(tvbuff_t *, int, int, proto_tree *,
packet_info *, int);
static void dissect_id(tvbuff_t *, int, int, proto_tree *,
***************
*** 241,246 ****
--- 248,255 ----
packet_info *, int);
static void dissect_hash(tvbuff_t *, int, int, proto_tree *,
packet_info *, int);
+ static void dissect_auth(tvbuff_t *, int, int, proto_tree *,
+ packet_info *, int);
static void dissect_sig(tvbuff_t *, int, int, proto_tree *,
packet_info *, int);
static void dissect_nonce(tvbuff_t *, int, int, proto_tree *,
***************
*** 257,270 ****
--- 266,289 ----
packet_info *, int);
static void dissect_nat_original_address(tvbuff_t *, int, int, proto_tree *,
packet_info *, int);
+ static void dissect_ts(tvbuff_t *, int, int, proto_tree *,
+ packet_info *, int);
+ static void dissect_enc(tvbuff_t *, int, int, proto_tree *,
+ packet_info *, int);
+ static void dissect_eap(tvbuff_t *, int, int, proto_tree *,
+ packet_info *, int);
static const char *payloadtype2str(guint8);
static const char *exchtype2str(guint8);
static const char *doitype2str(guint32);
static const char *msgtype2str(guint16);
static const char *situation2str(guint32);
+ static const char *v2_attrvalue2str(guint16, guint32);
static const char *value2str(int, guint16, guint32);
static const char *attrtype2str(guint8);
+ static const char *id2str(guint8);
+ static const char *v2_tstype2str(guint8);
+ static const char *v2_auth2str(guint8);
static const char *cfgattrident2str(guint16);
static const char *certtype2str(guint8);
***************
*** 273,303 ****
#define LOAD_TYPE_NONE 0 /* payload type for None */
#define LOAD_TYPE_PROPOSAL 2 /* payload type for Proposal */
#define LOAD_TYPE_TRANSFORM 3 /* payload type for Transform */
- #define NUM_LOAD_TYPES 17
! static struct strfunc {
const char * str;
void (*func)(tvbuff_t *, int, int, proto_tree *, packet_info *, int);
- } strfuncs[NUM_LOAD_TYPES] = {
- {"NONE", NULL },
- {"Security Association", dissect_sa },
- {"Proposal", dissect_proposal },
- {"Transform", dissect_transform },
- {"Key Exchange", dissect_key_exch },
- {"Identification", dissect_id },
- {"Certificate", dissect_cert },
- {"Certificate Request", dissect_certreq },
- {"Hash", dissect_hash },
- {"Signature", dissect_sig },
- {"Nonce", dissect_nonce },
- {"Notification", dissect_notif },
- {"Delete", dissect_delete },
- {"Vendor ID", dissect_vid },
- {"Attrib", dissect_config },
- {"NAT-Discovery", dissect_nat_discovery }, /* draft-ietf-ipsec-nat-t-ike-04 */
- {"NAT-Original Address", dissect_nat_original_address } /* draft-ietf-ipsec-nat-t-ike */
};
#define VID_LEN 16
#define VID_MS_LEN 20
static const guint8 VID_MS_W2K_WXP[VID_MS_LEN] = {0x1E, 0x2B, 0x51, 0x69, 0x5, 0x99, 0x1C, 0x7D, 0x7C, 0x96, 0xFC, 0xBF, 0xB5, 0x87, 0xE4, 0x61, 0x0, 0x0, 0x0, 0x2}; /* according to http://www.microsoft.com/technet/treeview/default.asp?url=/technet/columns/cableguy/cg0602.asp */
--- 292,347 ----
#define LOAD_TYPE_NONE 0 /* payload type for None */
#define LOAD_TYPE_PROPOSAL 2 /* payload type for Proposal */
#define LOAD_TYPE_TRANSFORM 3 /* payload type for Transform */
! struct strfunc {
! gint8 type;
const char * str;
void (*func)(tvbuff_t *, int, int, proto_tree *, packet_info *, int);
};
+ static struct strfunc strfuncs[] = {
+ { 0, "NONE", NULL },
+ { 1, "Security Association", dissect_sa },
+ { 2, "Proposal", dissect_proposal },
+ { 3, "Transform", dissect_transform },
+ { 4, "Key Exchange", dissect_key_exch },
+ { 5, "Identification", dissect_id },
+ { 6, "Certificate", dissect_cert },
+ { 7, "Certificate Request", dissect_certreq },
+ { 8, "Hash", dissect_hash },
+ { 9, "Signature", dissect_sig },
+ { 10, "Nonce", dissect_nonce },
+ { 11, "Notification", dissect_notif },
+ { 12, "Delete", dissect_delete },
+ { 13, "Vendor ID", dissect_vid },
+ { 14, "Attrib", dissect_config },
+ { 15, "NAT-Discovery", dissect_nat_discovery }, /* draft-ietf-ipsec-nat-t-ike-04 */
+ { 16, "NAT-Original Address", dissect_nat_original_address }, /* draft-ietf-ipsec-nat-t-ike */
+ };
+
+ static struct strfunc v2_strfuncs[] = {
+ { 2, "Proposal", dissect_proposal },
+ { 3, "Transform", dissect_transform2 },
+ { 33, "Security Association", dissect_sa },
+ { 34, "Key Exchange", dissect_key_exch },
+ { 35, "Identification - I", dissect_id },
+ { 36, "Identification - R", dissect_id },
+ { 37, "Certificate", dissect_cert },
+ { 38, "Certificate Request", dissect_certreq },
+ { 39, "Authentication", dissect_auth },
+ { 40, "Nonce", dissect_nonce },
+ { 41, "Notification", dissect_notif },
+ { 42, "Delete", dissect_delete },
+ { 43, "Vendor ID", dissect_vid },
+ { 44, "Traffic Selector - I", dissect_ts },
+ { 45, "Traffic Selector - R", dissect_ts },
+ { 46, "Encrypted", dissect_enc },
+ { 47, "Configuration", dissect_config },
+ { 48, "Extensible Authentication", dissect_eap },
+ };
+
+ static struct strfunc * getstrfunc(guint8);
+
#define VID_LEN 16
#define VID_MS_LEN 20
static const guint8 VID_MS_W2K_WXP[VID_MS_LEN] = {0x1E, 0x2B, 0x51, 0x69, 0x5, 0x99, 0x1C, 0x7D, 0x7C, 0x96, 0xFC, 0xBF, 0xB5, 0x87, 0xE4, 0x61, 0x0, 0x0, 0x0, 0x2}; /* according to http://www.microsoft.com/technet/treeview/default.asp?url=/technet/columns/cableguy/cg0602.asp */
***************
*** 423,428 ****
--- 467,473 ----
guint8 payload, next_payload;
guint16 payload_length;
proto_tree * ntree;
+ struct strfunc * f;
for (payload = initial_payload; length != 0; payload = next_payload) {
if (payload == LOAD_TYPE_NONE) {
***************
*** 440,449 ****
if (ntree == NULL)
break;
if (payload_length >= 4) { /* XXX = > 4? */
! if (payload < NUM_LOAD_TYPES && strfuncs[payload].func != NULL) {
! (*strfuncs[payload].func)(tvb, offset + 4, payload_length - 4, ntree,
! pinfo, -1);
! }
else {
if (payload == 130)
dissect_nat_discovery(tvb, offset + 4, payload_length - 4, ntree,
--- 485,492 ----
if (ntree == NULL)
break;
if (payload_length >= 4) { /* XXX = > 4? */
! if ((f = getstrfunc(payload)) != NULL)
! (*f->func)(tvb, offset + 4, payload_length - 4, ntree, pinfo, -1);
else {
if (payload == 130)
dissect_nat_discovery(tvb, offset + 4, payload_length - 4, ntree,
***************
*** 473,478 ****
--- 516,542 ----
}
}
+ static struct strfunc *
+ getstrfunc(guint8 payload)
+ {
+ struct strfunc *f = 0;
+ int i, len;
+
+ if (isakmp_version == 1) {
+ f = strfuncs;
+ len = ARLEN(strfuncs);
+ } else if (isakmp_version == 2) {
+ f = v2_strfuncs;
+ len = ARLEN(v2_strfuncs);
+ } else
+ return NULL;
+ for (i = 0; i < len; i++) {
+ if (f[i].type == payload)
+ return &f[i];
+ }
+ return NULL;
+ }
+
static void
dissect_isakmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
***************
*** 493,498 ****
--- 557,564 ----
hdr.length = tvb_get_ntohl(tvb, offset + sizeof(hdr) - sizeof(hdr.length));
hdr.exch_type = tvb_get_guint8(tvb, sizeof(hdr.icookie) + sizeof(hdr.rcookie) + sizeof(hdr.next_payload) + sizeof(hdr.version));
+ hdr.version = tvb_get_guint8(tvb, sizeof(hdr.icookie) + sizeof(hdr.rcookie) + sizeof(hdr.next_payload));
+ isakmp_version = hi_nibble(hdr.version); /* save the version */
if (check_col(pinfo->cinfo, COL_INFO))
col_add_str(pinfo->cinfo, COL_INFO, exchtype2str(hdr.exch_type));
***************
*** 513,519 ****
payloadtype2str(hdr.next_payload), hdr.next_payload);
offset += sizeof(hdr.next_payload);
- hdr.version = tvb_get_guint8(tvb, offset);
proto_tree_add_text(isakmp_tree, tvb, offset, sizeof(hdr.version),
"Version: %u.%u",
hi_nibble(hdr.version), lo_nibble(hdr.version));
--- 579,584 ----
***************
*** 533,547 ****
fti = proto_tree_add_text(isakmp_tree, tvb, offset, sizeof(hdr.flags), "Flags");
ftree = proto_item_add_subtree(fti, ett_isakmp_flags);
! proto_tree_add_text(ftree, tvb, offset, 1, "%s",
decode_boolean_bitfield(hdr.flags, E_FLAG, sizeof(hdr.flags)*8,
! "Encryption", "No encryption"));
! proto_tree_add_text(ftree, tvb, offset, 1, "%s",
decode_boolean_bitfield(hdr.flags, C_FLAG, sizeof(hdr.flags)*8,
"Commit", "No commit"));
! proto_tree_add_text(ftree, tvb, offset, 1, "%s",
decode_boolean_bitfield(hdr.flags, A_FLAG, sizeof(hdr.flags)*8,
"Authentication", "No authentication"));
offset += sizeof(hdr.flags);
}
--- 598,624 ----
fti = proto_tree_add_text(isakmp_tree, tvb, offset, sizeof(hdr.flags), "Flags");
ftree = proto_item_add_subtree(fti, ett_isakmp_flags);
! if (isakmp_version == 1) {
! proto_tree_add_text(ftree, tvb, offset, 1, "%s",
decode_boolean_bitfield(hdr.flags, E_FLAG, sizeof(hdr.flags)*8,
! "Encrypted", "Not encrypted"));
! proto_tree_add_text(ftree, tvb, offset, 1, "%s",
decode_boolean_bitfield(hdr.flags, C_FLAG, sizeof(hdr.flags)*8,
"Commit", "No commit"));
! proto_tree_add_text(ftree, tvb, offset, 1, "%s",
decode_boolean_bitfield(hdr.flags, A_FLAG, sizeof(hdr.flags)*8,
"Authentication", "No authentication"));
+ } else if (isakmp_version == 2) {
+ proto_tree_add_text(ftree, tvb, offset, 1, "%s",
+ decode_boolean_bitfield(hdr.flags, I_FLAG, sizeof(hdr.flags)*8,
+ "Initiator", "Responder"));
+ proto_tree_add_text(ftree, tvb, offset, 1, "%s",
+ decode_boolean_bitfield(hdr.flags, V_FLAG, sizeof(hdr.flags)*8,
+ "A higher version enabled", ""));
+ proto_tree_add_text(ftree, tvb, offset, 1, "%s",
+ decode_boolean_bitfield(hdr.flags, R_FLAG, sizeof(hdr.flags)*8,
+ "Response", "Request"));
+ }
offset += sizeof(hdr.flags);
}
***************
*** 604,609 ****
--- 681,691 ----
proto_tree_add_text(ntree, tvb, offset, 1,
"Next payload: %s (%u)",
payloadtype2str(next_payload), next_payload);
+ if (isakmp_version == 2) {
+ proto_tree_add_text(ntree, tvb, offset, 1, "%s",
+ decode_boolean_bitfield(tvb_get_guint8(tvb, 1), 0x80, 8,
+ "Critical", "Not critical"));
+ }
proto_tree_add_text(ntree, tvb, offset+2, 2, "Length: %u", payload_length);
*next_payload_p = next_payload;
***************
*** 624,657 ****
tvb_bytes_to_str(tvb, offset, length), length);
return;
}
! doi = tvb_get_ntohl(tvb, offset);
! proto_tree_add_text(tree, tvb, offset, 4,
"Domain of interpretation: %s (%u)",
doitype2str(doi), doi);
! offset += 4;
! length -= 4;
! if (doi == 1) {
! /* IPSEC */
! if (length < 4) {
! proto_tree_add_text(tree, tvb, offset, length,
"Situation: %s (length is %u, should be >= 4)",
tvb_bytes_to_str(tvb, offset, length), length);
! return;
! }
! situation = tvb_get_ntohl(tvb, offset);
! proto_tree_add_text(tree, tvb, offset, 4,
"Situation: %s (%u)",
situation2str(situation), situation);
! offset += 4;
! length -= 4;
! dissect_payloads(tvb, tree, LOAD_TYPE_PROPOSAL, offset, length, pinfo);
! } else {
! /* Unknown */
! proto_tree_add_text(tree, tvb, offset, length,
"Situation: %s",
tvb_bytes_to_str(tvb, offset, length));
}
}
--- 706,743 ----
tvb_bytes_to_str(tvb, offset, length), length);
return;
}
! if (isakmp_version == 1) {
! doi = tvb_get_ntohl(tvb, offset);
! proto_tree_add_text(tree, tvb, offset, 4,
"Domain of interpretation: %s (%u)",
doitype2str(doi), doi);
! offset += 4;
! length -= 4;
! if (doi == 1) {
! /* IPSEC */
! if (length < 4) {
! proto_tree_add_text(tree, tvb, offset, length,
"Situation: %s (length is %u, should be >= 4)",
tvb_bytes_to_str(tvb, offset, length), length);
! return;
! }
! situation = tvb_get_ntohl(tvb, offset);
! proto_tree_add_text(tree, tvb, offset, 4,
"Situation: %s (%u)",
situation2str(situation), situation);
! offset += 4;
! length -= 4;
! dissect_payloads(tvb, tree, LOAD_TYPE_PROPOSAL, offset, length, pinfo);
! } else {
! /* Unknown */
! proto_tree_add_text(tree, tvb, offset, length,
"Situation: %s",
tvb_bytes_to_str(tvb, offset, length));
+ }
+ } else if (isakmp_version == 2) {
+ dissect_payloads(tvb, tree, LOAD_TYPE_PROPOSAL, offset, length, pinfo);
}
}
***************
*** 711,719 ****
"Not enough room in payload for all transforms");
break;
}
! if (payload_length >= 4)
! dissect_transform(tvb, offset + 4, payload_length - 4, ntree,
pinfo, protocol_id);
else
proto_tree_add_text(ntree, tvb, offset + 4, payload_length - 4, "Payload");
offset += payload_length;
--- 797,810 ----
"Not enough room in payload for all transforms");
break;
}
! if (payload_length >= 4) {
! if (isakmp_version == 1)
! dissect_transform(tvb, offset + 4, payload_length - 4, ntree,
! pinfo, protocol_id);
! else if (isakmp_version == 2)
! dissect_transform2(tvb, offset + 4, payload_length - 4, ntree,
pinfo, protocol_id);
+ }
else
proto_tree_add_text(ntree, tvb, offset + 4, payload_length - 4, "Payload");
offset += payload_length;
***************
*** 811,820 ****
--- 902,1109 ----
}
}
+ /* For Transform Type 1 (Encryption Algorithm), defined Transform IDs */
+ static const char *
+ v2_tid2encstr(guint16 tid)
+ {
+ static const char *strs[] = {
+ "RESERVED",
+ "ENCR_DES_IV64",
+ "ENCR_DES",
+ "ENCR_3DE",
+ "ENCR_RC5",
+ "ENCR_IDEA",
+ "ENCR_CAST",
+ "ENCR_BLOWFISH",
+ "ENCR_3IDEA",
+ "ENCR_DES_IV32",
+ "RESERVED",
+ "ENCR_NULL",
+ "ENCR_AES_CBC",
+ "ENCR_AES_CTR",
+ };
+ if (tid < ARLEN(strs)) return strs[tid];
+ return "RESERVED";
+ }
+
+ /* For Transform Type 2 (Pseudo-random Function), defined Transform IDs */
+ static const char *
+ v2_tid2prfstr(guint16 tid)
+ {
+ static const char *strs[] = {
+ "RESERVED",
+ "PRF_HMAC_MD5",
+ "PRF_HMAC_SHA1",
+ "PRF_HMAC_TIGER",
+ "PRF_AES128_CBC",
+ };
+ if (tid < ARLEN(strs)) return strs[tid];
+ return "RESERVED";
+ }
+
+ /* For Transform Type 3 (Integrity Algorithm), defined Transform IDs */
+ static const char *
+ v2_tid2iastr(guint16 tid)
+ {
+ static const char *strs[] = {
+ "NONE",
+ "AUTH_HMAC_MD5_96",
+ "AUTH_HMAC_SHA1_96",
+ "AUTH_DES_MAC",
+ "AUTH_KPDK_MD5",
+ "AUTH_AES_XCBC_96",
+ };
+ if (tid < ARLEN(strs)) return strs[tid];
+ return "RESERVED";
+ }
+
+ /* For Transform Type 4 (Diffie-Hellman Group), defined Transform IDs */
+ static const char *
+ v2_tid2dhstr(guint16 tid)
+ {
+ static struct type2str_t strs[] = {
+ { 0, "NONE" },
+ { 1, "Group 1 - 768 Bit MODP" },
+ { 2, "Group 2 - 1024 Bit MODP" },
+ { 3, "RESERVED" },
+ { 4, "RESERVED" },
+ { 5, "group 5 - 1536 Bit MODP" },
+ { 14, "2048-bit MODP Group" },
+ { 15, "3072-bit MODP Group" },
+ { 16, "4096-bit MODP Group" },
+ { 17, "6144-bit MODP Group" },
+ { 18, "8192-bit MODP Group" },
+ };
+ FIND_TYPE2STR(strs, tid);
+ if ((tid >= 6 && tid <= 13) || (tid >= 19 && tid <= 1023))
+ return "RESERVED TO IANA";
+ if (tid >= 1024)
+ return "PRIVATE USE";
+ return "RESERVED";
+ }
+
+ /* For Transform Type 5 (Extended Sequence Numbers), defined Transform */
+ static const char *
+ v2_tid2esnstr(guint16 tid)
+ {
+ static const char *strs[] = {
+ "No Extended Sequence Numbers",
+ "Extended Sequence Numbers",
+ };
+ if (tid < sizeof(strs)/sizeof(strs[0])) return strs[tid];
+ return "RESERVED";
+ }
+
+ static struct {
+ const char *str;
+ const char *(*func)(guint16);
+ } trans2str[] = {
+ { "RESERVED", NULL, },
+ { "Encryption Algorithm (ENCR)", v2_tid2encstr },
+ { "Pseudo-random Function (PRF)", v2_tid2prfstr },
+ { "Integrity Algorithm (INTEG)", v2_tid2iastr },
+ { "Diffie-Hellman Group (D-H)", v2_tid2dhstr },
+ { "Extended Sequence Numbers (ESN)", v2_tid2esnstr },
+ };
+
+ static const char *
+ v2_trans2str(guint8 type)
+ {
+ if (type < ARLEN(trans2str)) return trans2str[type].str;
+ if (type < 240) return "RESERVED TO IANA";
+ return "PRIVATE USE";
+ }
+
+ static const char *
+ v2_tid2str(guint8 type, guint16 tid)
+ {
+ if (type < ARLEN(trans2str) && trans2str[type].func != NULL) {
+ return (trans2str[type].func)(tid);
+ }
+ return "RESERVED";
+ }
+
+ static const char *
+ v2_aft2str(guint16 aft)
+ {
+ if (aft < 14 || (aft > 14 && aft < 18)) return "RESERVED";
+ if (aft == 14) return "Key Length (in bits)";
+ if (aft >= 18 && aft < 16384) return "RESERVED TO IANA";
+ return "PRIVATE USE";
+ }
+
+ static void
+ dissect_transform2(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
+ packet_info *pinfo _U_, int unused _U_)
+ {
+ guint8 transform_type;
+ guint16 transform_id;
+
+ transform_type = tvb_get_guint8(tvb, offset);
+ proto_tree_add_text(tree, tvb, offset, 1,
+ "Transform type: %s (%u)", v2_trans2str(transform_type), transform_type);
+ offset += 2;
+ length -= 2;
+
+ transform_id = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_text(tree, tvb, offset, 2,
+ "Transform ID: %s (%u)", v2_tid2str(transform_type, transform_id),
+ transform_id);
+ offset += 2;
+ length -= 2;
+
+ while (length>0) {
+ const char *str;
+ guint16 aft = tvb_get_ntohs(tvb, offset);
+ guint16 type = aft & 0x7fff;
+ guint16 len;
+ guint32 val;
+ guint pack_len;
+
+ str = v2_aft2str(aft);
+
+ if (aft & 0x8000) {
+ val = tvb_get_ntohs(tvb, offset + 2);
+ proto_tree_add_text(tree, tvb, offset, 4,
+ "%s (%u): %s (%u)",
+ str, type,
+ v2_attrvalue2str(type, val), val);
+ offset += 4;
+ length -= 4;
+ }
+ else {
+ len = tvb_get_ntohs(tvb, offset + 2);
+ pack_len = 4 + len;
+ if (!get_num(tvb, offset + 4, len, &val)) {
+ proto_tree_add_text(tree, tvb, offset, pack_len,
+ "%s (%u): <too big (%u bytes)>",
+ str, type, len);
+ } else {
+ proto_tree_add_text(tree, tvb, offset, pack_len,
+ "%s (%u): %s (%u)",
+ str, type,
+ v2_attrvalue2str(type, val), val);
+ }
+ offset += pack_len;
+ length -= pack_len;
+ }
+ }
+ }
+
static void
dissect_key_exch(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
packet_info *pinfo _U_, int unused _U_)
{
+ guint16 dhgroup;
+
+ if (isakmp_version == 2) {
+ dhgroup = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_text(tree, tvb, offset, 2,
+ "DH Group #: %u", dhgroup);
+ offset += 4;
+ length -= 4;
+ }
+
proto_tree_add_text(tree, tvb, offset, length, "Key Exchange Data");
}
***************
*** 927,932 ****
--- 1216,1236 ----
}
static void
+ dissect_auth(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
+ packet_info *pinfo _U_, int unused _U_)
+ {
+ guint8 auth;
+
+ auth = tvb_get_guint8(tvb, offset);
+ proto_tree_add_text(tree, tvb, offset, 1,
+ "Auth Method: %s (%u)", v2_auth2str(auth), auth);
+ offset += 4;
+ length -= 4;
+
+ proto_tree_add_text(tree, tvb, offset, length, "Authentication Data");
+ }
+
+ static void
dissect_sig(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
packet_info *pinfo _U_, int unused _U_)
{
***************
*** 949,960 ****
guint8 spi_size;
guint16 msgtype;
! doi = tvb_get_ntohl(tvb, offset);
! proto_tree_add_text(tree, tvb, offset, 4,
! "Domain of Interpretation: %s (%u)",
! doitype2str(doi), doi);
! offset += 4;
! length -= 4;
protocol_id = tvb_get_guint8(tvb, offset);
proto_tree_add_text(tree, tvb, offset, 1,
--- 1253,1266 ----
guint8 spi_size;
guint16 msgtype;
! if (isakmp_version == 1) {
! doi = tvb_get_ntohl(tvb, offset);
! proto_tree_add_text(tree, tvb, offset, 4,
! "Domain of Interpretation: %s (%u)",
! doitype2str(doi), doi);
! offset += 4;
! length -= 4;
! }
protocol_id = tvb_get_guint8(tvb, offset);
proto_tree_add_text(tree, tvb, offset, 1,
***************
*** 1355,1377 ****
}
}
static const char *
! payloadtype2str(guint8 type) {
! if (type < NUM_LOAD_TYPES)
! return strfuncs[type].str;
! if (type < 128)
return "RESERVED";
! if (type == 130)
! return "NAT-D (draft-ietf-ipsec-nat-t-ike-01 to 03)";
! if (type == 131)
! return "NAT-OA (draft-ietf-ipsec-nat-t-ike-01 to 04)";
! return "Private USE";
}
static const char *
! exchtype2str(guint8 type) {
!
#define NUM_EXCHSTRS 7
static const char * exchstrs[NUM_EXCHSTRS] = {
"NONE",
--- 1661,1792 ----
}
}
+ static void
+ dissect_ts(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
+ packet_info *pinfo _U_, int unused _U_)
+ {
+ guint8 num, tstype, protocol_id, len, addrlen;
+ guint16 port;
+
+ proto_tree_add_text(tree, tvb, offset, length, "Traffic Selector");
+
+ num = tvb_get_guint8(tvb, offset);
+ proto_item_append_text(tree," # %d", num);
+ proto_tree_add_text(tree, tvb, offset, 1,
+ "Number of TSs: %u", num);
+ offset += 4;
+ length -= 4;
+
+ while (length > 0) {
+ tstype = tvb_get_guint8(tvb, offset);
+ proto_tree_add_text(tree, tvb, offset, 1,
+ "TS Type: %s (%u)",
+ v2_tstype2str(tstype), tstype);
+ switch (tstype) {
+ case 7:
+ addrlen = 4;
+ break;
+ case 8:
+ addrlen = 16;
+ break;
+ default:
+ addrlen = 255;
+ }
+ /*
+ * XXX should the remaining of the length check be done here ?
+ * it seems other routines don't check the length.
+ */
+ if (length < (8 + addrlen * 2)) {
+ proto_tree_add_text(tree, tvb, offset, length,
+ "Length mismatch (%u)", length);
+ return;
+ }
+ offset += 1;
+ length -= 1;
+
+ protocol_id = tvb_get_guint8(tvb, offset);
+ proto_tree_add_text(tree, tvb, offset, 1,
+ "Protocol ID: (%u)", protocol_id);
+ offset += 1;
+ length -= 1;
+
+ len = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_text(tree, tvb, offset, 2,
+ "Selector Length: %u", len);
+ offset += 2;
+ length -= 2;
+
+ port = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_text(tree, tvb, offset, 2,
+ "Start Port: (%u)", port);
+ offset += 2;
+ length -= 2;
+
+ port = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_text(tree, tvb, offset, 2,
+ "End Port: (%u)", port);
+ offset += 2;
+ length -= 2;
+
+ proto_tree_add_text(tree, tvb, offset, length,
+ "Starting Address: %s",
+ ip_to_str(tvb_get_ptr(tvb, offset, addrlen)));
+ offset += addrlen;
+ length -= addrlen;
+
+ proto_tree_add_text(tree, tvb, offset, length,
+ "Starting Address: %s",
+ ip_to_str(tvb_get_ptr(tvb, offset, addrlen)));
+ offset += addrlen;
+ length -= addrlen;
+ }
+ }
+
+ static void
+ dissect_enc(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
+ packet_info *pinfo _U_, int unused _U_)
+ {
+ proto_tree_add_text(tree, tvb, offset, 4, "Initialization Vector: 0x%s",
+ tvb_bytes_to_str(tvb, 8, 4));
+ proto_tree_add_text(tree, tvb, offset + 4, length, "Encrypted Data");
+ }
+
+ static void
+ dissect_eap(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
+ packet_info *pinfo _U_, int unused _U_)
+ {
+ proto_tree_add_text(tree, tvb, offset, length, "EAP Message");
+ }
+
static const char *
! payloadtype2str(guint8 type)
! {
! struct strfunc *f;
! if ((f = getstrfunc(type)) != NULL)
! return f->str;
! /* non-predefined type */
! if (isakmp_version == 1) {
! if (type < 128)
! return "RESERVED";
! if (type == 130)
! return "NAT-D (draft-ietf-ipsec-nat-t-ike-01 to 03)";
! if (type == 131)
! return "NAT-OA (draft-ietf-ipsec-nat-t-ike-01 to 04)";
! return "Private USE";
! } else if (isakmp_version == 2) {
! if (type > 127)
! return "PRIVATE USE";
! if (type > 48)
! return "RESERVED TO IANA";
return "RESERVED";
! }
! return "Unknown payload type";
}
static const char *
! exchtype2str(guint8 type)
! {
#define NUM_EXCHSTRS 7
static const char * exchstrs[NUM_EXCHSTRS] = {
"NONE",
***************
*** 1383,1409 ****
"Transaction (Config Mode)"
};
! if (type < NUM_EXCHSTRS) return exchstrs[type];
! if (type < 32) return "ISAKMP Future Use";
! switch (type) {
! case 32:
! return "Quick Mode";
! case 33:
! return "New Group Mode";
}
! if (type < 240)
! return "DOI Specific Use";
! return "Private Use";
}
static const char *
! doitype2str(guint32 type) {
if (type == 1) return "IPSEC";
return "Unknown DOI Type";
}
static const char *
! msgtype2str(guint16 type) {
#define NUM_PREDEFINED 31
static const char *msgs[NUM_PREDEFINED] = {
--- 1798,1843 ----
"Transaction (Config Mode)"
};
! static struct type2str_t v2_exchstr[] = {
! { 34, "IKE_SA_INIT" },
! { 35, "IKE_AUTH " },
! { 36, "CREATE_CHILD_SA" },
! { 37, "INFORMATIONAL"},
! };
!
! if (isakmp_version == 1) {
! if (type < NUM_EXCHSTRS) return exchstrs[type];
! if (type < 32) return "ISAKMP Future Use";
! switch (type) {
! case 32:
! return "Quick Mode";
! case 33:
! return "New Group Mode";
! }
! if (type < 240)
! return "DOI Specific Use";
! return "Private Use";
! } else if (isakmp_version == 2) {
! FIND_TYPE2STR(v2_exchstr, type);
! if (type < 34)
! return "RESERVED";
! if (type < 240)
! return "Reserved for IKEv2+";
! return "Reserved for private use";
}
! return "Unknown exchange type";
}
static const char *
! doitype2str(guint32 type)
! {
if (type == 1) return "IPSEC";
return "Unknown DOI Type";
}
static const char *
! msgtype2str(guint16 type)
! {
#define NUM_PREDEFINED 31
static const char *msgs[NUM_PREDEFINED] = {
***************
*** 1440,1462 ****
"UNEQUAL-PAYLOAD-LENGTHS"
};
! if (type < NUM_PREDEFINED) return msgs[type];
! if (type < 8192) return "RESERVED (Future Use)";
! if (type < 16384) return "Private Use";
! if (type < 16385) return "CONNECTED";
! if (type < 24576) return "RESERVED (Future Use) - status";
! if (type < 24577) return "RESPONDER-LIFETIME";
! if (type < 24578) return "REPLAY-STATUS";
! if (type < 24579) return "INITIAL-CONTACT";
! if (type < 32768) return "DOI-specific codes";
! if (type < 40960) return "Private Use - status";
! if (type < 65535) return "RESERVED (Future Use) - status (2)";
!
return "Huh? You should never see this! Shame on you!";
}
static const char *
! situation2str(guint32 type) {
#define SIT_MSG_NUM 1024
#define SIT_IDENTITY 0x01
--- 1874,1935 ----
"UNEQUAL-PAYLOAD-LENGTHS"
};
! static struct type2str_t v2_notifmsg[] = {
! { 0, "RESERVED" },
! { 4, "INVALID_IKE_SPI" },
! { 5, "INVALID_MAJOR_VERSION" },
! { 7, "INVALID_SYNTAX" },
! { 9, "INVALID_MESSAGE_ID" },
! { 11, "INVALID_SPI" },
! { 14, "NO_PROPOSAL_CHOSEN" },
! { 17, "INVALID_KE_PAYLOAD" },
! { 24, "AUTHENTICATION_FAILED" },
! { 34, "SINGLE_PAIR_REQUIRED" },
! { 35, "NO_ADDITIONAL_SAS" },
! { 36, "INTERNAL_ADDRESS_FAILURE" },
! { 37, "FAILED_CP_REQUIRED" },
! { 38, "TS_UNACCEPTABLE" },
! { 39, "INVALID_SELECTORS" },
! { 16384, "INITIAL_CONTACT" },
! { 16385, "SET_WINDOW_SIZE" },
! { 16386, "ADDITIONAL_TS_POSSIBLE" },
! { 16387, "IPCOMP_SUPPORTED" },
! { 16388, "NAT_DETECTION_SOURCE_IP" },
! { 16389, "NAT_DETECTION_DESTINATION_IP" },
! { 16390, "COOKIE" },
! { 16391, "USE_TRANSPORT_MODE" },
! { 16392, "HTTP_CERT_LOOKUP_SUPPORTED" },
! { 16393, "REKEY_SA" },
! { 16394, "ESP_TFC_PADDING_NOT_SUPPORTED" },
! { 16395, "NON_FIRST_FRAGMENTS_ALSO" },
! };
!
! if (isakmp_version == 1) {
! if (type < NUM_PREDEFINED) return msgs[type];
! if (type < 8192) return "RESERVED (Future Use)";
! if (type < 16384) return "Private Use";
! if (type < 16385) return "CONNECTED";
! if (type < 24576) return "RESERVED (Future Use) - status";
! if (type < 24577) return "RESPONDER-LIFETIME";
! if (type < 24578) return "REPLAY-STATUS";
! if (type < 24579) return "INITIAL-CONTACT";
! if (type < 32768) return "DOI-specific codes";
! if (type < 40960) return "Private Use - status";
! if (type < 65535) return "RESERVED (Future Use) - status (2)";
! } else if (isakmp_version == 2) {
! FIND_TYPE2STR(v2_notifmsg, type);
! if (type >= 40 && type <= 8191) return "RESERVED TO IANA - Error types";
! if (type >= 16396 && type <= 40959) return "RESERVED TO IANA - STATUS TYPES";
! if (type >= 8192 && type <= 16383) return "Private Use - Errors";
! if (type >= 40960 && type <= 65535) return "Private Use - STATUS TYPES";
!
! }
return "Huh? You should never see this! Shame on you!";
}
static const char *
! situation2str(guint32 type)
! {
#define SIT_MSG_NUM 1024
#define SIT_IDENTITY 0x01
***************
*** 1511,1517 ****
}
static const char *
! value2str(int ike_p1, guint16 att_type, guint32 value) {
if (value == 0) return "RESERVED";
--- 1984,2001 ----
}
static const char *
! v2_attrvalue2str(guint16 att_type, guint32 value)
! {
! value = 0; /* dummy to be less warning in compiling it */
! switch (att_type) {
! case 14: return "Key-Length";
! default: return "UNKNOWN-ATTRIBUTE-TYPE";
! }
! }
!
! static const char *
! value2str(int ike_p1, guint16 att_type, guint32 value)
! {
if (value == 0) return "RESERVED";
***************
*** 1648,1654 ****
}
static const char *
! attrtype2str(guint8 type) {
switch (type) {
case 0: return "Reserved";
case 1: return "ISAKMP_CFG_REQUEST";
--- 2132,2139 ----
}
static const char *
! attrtype2str(guint8 type)
! {
switch (type) {
case 0: return "Reserved";
case 1: return "ISAKMP_CFG_REQUEST";
***************
*** 1662,1668 ****
}
static const char *
! cfgattrident2str(guint16 ident) {
#define NUM_ATTR_DEFINED 12
static const char *msgs[NUM_PREDEFINED] = {
"RESERVED",
--- 2147,2225 ----
}
static const char *
! id2str(guint8 type)
! {
! static struct type2str_t idtypestr[] = {
! { 0, "RESERVED" },
! { 1, "IPV4_ADDR" },
! { 2, "FQDN" },
! { 3, "USER_FQDN" },
! { 4, "IPV4_ADDR_SUBNET" },
! { 5, "IPV6_ADDR" },
! { 6, "IPV6_ADDR_SUBNET" },
! { 7, "IPV4_ADDR_RANGE" },
! { 8, "IPV6_ADDR_RANGE" },
! { 9, "DER_ASN1_DN" },
! { 10, "DER_ASN1_GN" },
! { 11, "KEY_ID" },
! };
! static struct type2str_t v2_idtypestr[] = {
! { 0, "RESERVED" },
! { 1, "IPV4_ADDR" },
! { 2, "FQDN" },
! { 3, "USER_FQDN" },
! { 4, "IPV4_ADDR_SUBNET" },
! { 5, "IPV6_ADDR" },
! { 9, "DER_ASN1_DN" },
! { 10, "DER_ASN1_GN" },
! { 11, "KEY_ID" },
! };
!
! if (isakmp_version == 1)
! FIND_TYPE2STR(idtypestr, type);
! else if (isakmp_version == 2) {
! FIND_TYPE2STR(v2_idtypestr, type);
! if ((type >= 6 && type <=8) || (type >= 12 && type <= 200))
! return "Reserved to IANA";
! else if (type >= 201 && type <= 255)
! return "Reserved for private use";
! }
! return "UNKNOWN-ID-TYPE";
! }
!
! static const char *
! v2_tstype2str(guint8 type)
! {
! static struct type2str_t v2_tstypestr[] = {
! { 7, "TS_IPV4_ADDR_RANGE" },
! { 8, "TS_IPV6_ADDR_RANGE" },
! };
!
! FIND_TYPE2STR(v2_tstypestr, type);
! if (type <= 6) return "RESERVED";
! if (type >= 9 && type <= 240) return "RESERVED TO IANA";
! if (type >= 241 && type <= 255) return "PRIVATE USE";
! return "Huh? You should never see this! Shame on you!";
! }
!
! static const char *
! v2_auth2str(guint8 type)
! {
! static struct type2str_t v2_authstr[] = {
! { 1, "RSA Digital Signature" },
! { 2, "Shared Key Message Integrity Code" },
! { 3, "DSS Digital Signature" },
! };
!
! FIND_TYPE2STR(v2_authstr, type);
! if (type == 0 || (type >= 4 && type <= 200)) return "RESERVED TO IANA";
! if (type >= 201 && type <= 255) return "PRIVATE USE";
! return "Huh? You should never see this! Shame on you!";
! }
!
! static const char *
! cfgattrident2str(guint16 ident)
! {
#define NUM_ATTR_DEFINED 12
static const char *msgs[NUM_PREDEFINED] = {
"RESERVED",
***************
*** 1699,1726 ****
}
static const char *
! certtype2str(guint8 type) {
! #define NUM_CERTTYPE 11
! static const char *msgs[NUM_CERTTYPE] = {
! "NONE",
! "PKCS #7 wrapped X.509 certificate",
! "PGP Certificate",
! "DNS Signed Key",
! "X.509 Certificate - Signature",
! "X.509 Certificate - Key Exchange",
! "Kerberos Tokens",
! "Certificate Revocation List (CRL)",
! "Authority Revocation List (ARL)",
! "SPKI Certificate",
! "X.509 Certificate - Attribute",
};
! if(type > NUM_CERTTYPE)
! return "RESERVED";
! return msgs[type];
}
static gboolean
! get_num(tvbuff_t *tvb, int offset, guint16 len, guint32 *num_p) {
switch (len) {
case 1:
--- 2256,2307 ----
}
static const char *
! certtype2str(guint8 type)
! {
! static struct type2str_t certtypestr[] = {
! { 0, "NONE" },
! { 1, "PKCS #7 wrapped X.509 certificate" },
! { 2, "PGP Certificate" },
! { 3, "DNS Signed Key" },
! { 4, "X.509 Certificate - Signature" },
! { 5, "X.509 Certificate - Key Exchange" },
! { 6, "Kerberos Tokens" },
! { 7, "Certificate Revocation List (CRL)" },
! { 8, "Authority Revocation List (ARL)" },
! { 9, "SPKI Certificate" },
! { 10, "X.509 Certificate - Attribute" },
};
! static struct type2str_t v2_certtypestr[] = {
! { 0, "RESERVED" },
! { 1, "PKCS #7 wrapped X.509 certificate" },
! { 2, "PGP Certificate" },
! { 3, "DNS Signed Key" },
! { 4, "X.509 Certificate - Signature" },
! { 5, "*undefined by any document*" },
! { 6, "Kerberos Tokens" },
! { 7, "Certificate Revocation List (CRL)" },
! { 8, "Authority Revocation List (ARL)" },
! { 9, "SPKI Certificate" },
! { 10, "X.509 Certificate - Attribute" },
! { 11, "Raw RSA Key" },
! { 12, "Hash and URL of X.509 certificate" },
! { 13, "Hash and URL of X.509 bundle" },
! };
! if (isakmp_version == 1)
! FIND_TYPE2STR(certtypestr, type);
! else if (isakmp_version == 2) {
! FIND_TYPE2STR(v2_certtypestr, type);
! if (type >= 14 && type <= 200)
! return "RESERVED to IANA";
! else if (type >= 201 && type <= 255)
! return "PRIVATE USE";
! }
! return "RESERVED";
}
static gboolean
! get_num(tvbuff_t *tvb, int offset, guint16 len, guint32 *num_p)
! {
switch (len) {
case 1:
- Prev by Date: [Ethereal-dev] I've disabled the welcome pane...
- Next by Date: Re: [Ethereal-dev] Voip Calls analysis and Graph analysis
- Previous by thread: [Ethereal-dev] I've disabled the welcome pane...
- Next by thread: [Ethereal-dev] RTP stream name resolution
- Index(es):





