diff options
author | Hakan Olsson <ho@cvs.openbsd.org> | 2001-04-10 16:10:22 +0000 |
---|---|---|
committer | Hakan Olsson <ho@cvs.openbsd.org> | 2001-04-10 16:10:22 +0000 |
commit | 23534ed119d195536c6dbe341264f2f45ffdae5a (patch) | |
tree | 26c7c4c6f6e10f1ddd6f67f484e1b5fcdf06480d | |
parent | fc2967ade54fa7e225277efa4fe43dd03dc2e4e8 (diff) |
Add IKE mode-config (as described in draft-dukes-ike-mode-cfg-01.txt)
decoding. Also some cleanup of attribute handling plus length checks.
-rw-r--r-- | usr.sbin/tcpdump/ike.h | 44 | ||||
-rw-r--r-- | usr.sbin/tcpdump/print-ike.c | 218 |
2 files changed, 215 insertions, 47 deletions
diff --git a/usr.sbin/tcpdump/ike.h b/usr.sbin/tcpdump/ike.h index 2f37201cd01..5192b2384d4 100644 --- a/usr.sbin/tcpdump/ike.h +++ b/usr.sbin/tcpdump/ike.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ike.h,v 1.2 2001/04/09 21:44:40 ho Exp $ */ +/* $OpenBSD: ike.h,v 1.3 2001/04/10 16:10:21 ho Exp $ */ #define ISAKMP_DOI 0 #define IPSEC_DOI 1 @@ -82,6 +82,7 @@ #define PAYLOAD_NOTIFICATION 11 #define PAYLOAD_DELETE 12 #define PAYLOAD_VENDOR 13 +#define PAYLOAD_ATTRIBUTE 14 #define IKE_PAYLOAD_TYPES_INITIALIZER \ { "NONE", /* 0 */ \ @@ -98,6 +99,7 @@ "NOTIFICATION", /* 11 */ \ "DELETE", /* 12 */ \ "VENDOR", /* 13 */ \ + "ATTRIBUTE", /* 14 (ikecfg) */ \ } /* Exchange types */ @@ -107,6 +109,7 @@ #define EXCHANGE_AUTH_ONLY 3 #define EXCHANGE_AGGRESSIVE 4 #define EXCHANGE_INFO 5 +#define EXCHANGE_TRANSACTION 6 #define EXCHANGE_QUICK_MODE 32 #define EXCHANGE_NEW_GROUP_MODE 33 @@ -118,6 +121,7 @@ "AUTH_ONLY", /* 3 */ \ "AGGRESSIVE", /* 4 */ \ "INFO", /* 5 */ \ + "TRANSACTION", /* 6 (ikecfg) */ \ /* step up to type 32 with unknowns */ \ "unknown", "unknown", "unknown", "unknown", \ "unknown", "unknown", "unknown", "unknown", \ @@ -125,7 +129,7 @@ "unknown", "unknown", "unknown", "unknown", \ "unknown", "unknown", "unknown", "unknown", \ "unknown", "unknown", "unknown", "unknown", \ - "unknown", "unknown", \ + "unknown", \ "QUICK_MODE", /* 32 */ \ "NEW_GROUP_MODE", /* 33 */ \ } @@ -285,3 +289,39 @@ #define IPSEC_ATTR_IPCOMP_INITIALIZER \ { "NONE", "OUI", "DEFLATE", "LZS", "V42BIS", \ } + +/* + * IKE mode config. + */ + +#define IKE_CFG_ATTRIBUTE_TYPE_INITIALIZER \ + { "RESERVED", "CFG_REQUEST", "CFG_REPLY", \ + "CFG_SET", "CFG_ACK", \ + } + +#define IKE_CFG_ATTR_INTERNAL_IP4_ADDRESS 1 +#define IKE_CFG_ATTR_INTERNAL_IP4_NETMASK 2 +#define IKE_CFG_ATTR_INTERNAL_IP4_DNS 3 +#define IKE_CFG_ATTR_INTERNAL_IP4_NBNS 4 +#define IKE_CFG_ATTR_INTERNAL_ADDRESS_EXPIRY 5 +#define IKE_CFG_ATTR_INTERNAL_IP4_DHCP 6 +#define IKE_CFG_ATTR_APPLICATION_VERSION 7 +#define IKE_CFG_ATTR_INTERNAL_IP6_ADDRESS 8 +#define IKE_CFG_ATTR_INTERNAL_IP6_NETMASK 9 +#define IKE_CFG_ATTR_INTERNAL_IP6_DNS 10 +#define IKE_CFG_ATTR_INTERNAL_IP6_NBNS 11 +#define IKE_CFG_ATTR_INTERNAL_IP6_DHCP 12 +#define IKE_CFG_ATTR_INTERNAL_IP4_SUBNET 13 +#define IKE_CFG_ATTR_SUPPORTED_ATTRIBUTES 14 +#define IKE_CFG_ATTR_INTERNAL_IP6_SUBNET 15 + +#define IKE_CFG_ATTRIBUTE_INITIALIZER \ + { "RESERVED", "INTERNAL_IP4_ADDRESS", \ + "INTERNAL_IP4_NETMASK", "INTERNAL_IP4_DNS", \ + "INTERNAL_IP4_NBNS", "INTERNAL_ADDRESS_EXPIRY", \ + "INTERNAL_IP4_DHCP", "APPLICATION_VERSION", \ + "INTERNAL_IP6_ADDRESS", "INTERNAL_IP6_NETMASK", \ + "INTERNAL_IP6_DNS", "INTERNAL_IP6_NBNS", \ + "INTERNAL_IP6_DHCP", "INTERNAL_IP4_SUBNET", \ + "SUPPORTED_ATTRIBUTES", "INTERNAL_IP6_SUBNET", \ + } diff --git a/usr.sbin/tcpdump/print-ike.c b/usr.sbin/tcpdump/print-ike.c index 793b552ea7a..7fbfd8cec3b 100644 --- a/usr.sbin/tcpdump/print-ike.c +++ b/usr.sbin/tcpdump/print-ike.c @@ -1,4 +1,4 @@ -/* $OpenBSD: print-ike.c,v 1.5 2001/04/09 21:44:40 ho Exp $ */ +/* $OpenBSD: print-ike.c,v 1.6 2001/04/10 16:10:21 ho Exp $ */ /* * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999 @@ -31,7 +31,7 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /cvs/OpenBSD/src/usr.sbin/tcpdump/print-ike.c,v 1.5 2001/04/09 21:44:40 ho Exp $ (XXX)"; + "@(#) $Header: /cvs/OpenBSD/src/usr.sbin/tcpdump/print-ike.c,v 1.6 2001/04/10 16:10:21 ho Exp $ (XXX)"; #endif #include <sys/param.h> @@ -199,7 +199,7 @@ trunc: } void -ike_sa_print (register u_char *buf, register int len) +ike_pl_sa_print (register u_char *buf, register int len) { u_int32_t situation = ntohl(*(u_int32_t *)(buf + 4)); u_char ike_doi = ntohl((*(u_int32_t *)buf)); @@ -221,7 +221,7 @@ ike_sa_print (register u_char *buf, register int len) } int -ike_attribute_print (register u_char *buf, u_char doi) +ike_attribute_print (register u_char *buf, u_char doi, register int maxlen) { static char *attrs[] = IKE_ATTR_INITIALIZER; static char *attr_enc[] = IKE_ATTR_ENCRYPT_INITIALIZER; @@ -235,36 +235,45 @@ ike_attribute_print (register u_char *buf, u_char doi) static char *ipsec_attr_auth[] = IPSEC_ATTR_AUTH_INITIALIZER; static char *ipsec_attr_ltype[] = IPSEC_ATTR_DURATION_INITIALIZER; - unsigned short type = buf[0]<<8 | buf[1]; - unsigned short length = 0, p; + u_char af = buf[0] >> 7; + u_int16_t type = (buf[0] & 0x7f) << 8 | buf[1]; + u_int16_t len = buf[2] << 8 | buf[3], val; if (doi == ISAKMP_DOI) printf("\n\t%sattribute %s = ", ike_tab_offset(), - ((type & 0x7fff) < sizeof attrs / sizeof attrs[0] ? - attrs[type & 0x7fff] : "unknown")); + (type < sizeof attrs / sizeof attrs[0] ? + attrs[type] : "<unknown>")); else printf("\n\t%sattribute %s = ", ike_tab_offset(), - ((type & 0x7fff) < - (sizeof ipsec_attrs / sizeof ipsec_attrs[0]) ? - ipsec_attrs[type & 0x7fff] : "unknown")); - - if (!(type >> 15)) { - length = buf[2]<<8 | buf[3]; - for (p = 0; p < length; p++) - printf("%02x", (char)*(buf + 4 + p)); - } else { - p = buf[2]<<8 | buf[3]; + (type < (sizeof ipsec_attrs / sizeof ipsec_attrs[0]) ? + ipsec_attrs[type] : "<unknown>")); + + if ((af == 1 && maxlen < 4) || + (af == 0 && maxlen < (len + 4))) { + printf ("\n\t%s[|attr]", ike_tab_offset()); + return maxlen; + } + + if (af == 0) { + /* AF=0; print the variable length attribute value */ + for (val = 0; val < len; val++) + printf("%02x", (char)*(buf + 4 + val)); + return len + 4; + } + + val = len; /* For AF=1, this field is the "VALUE" */ + len = 4; /* and with AF=1, length is always 4 */ #define CASE_PRINT(TYPE,var) \ case TYPE : \ - if (p < sizeof var / sizeof var [0]) \ - printf("%s", var [p]); \ - else \ - printf("%d (unknown)", p); \ - break; - + if (val < sizeof var / sizeof var [0]) \ + printf("%s", var [val]); \ + else \ + printf("%d (unknown)", val); \ + break; + if (doi == ISAKMP_DOI) - switch(type & 0x7fff) { + switch(type) { CASE_PRINT(IKE_ATTR_ENCRYPTION_ALGORITHM, attr_enc); CASE_PRINT(IKE_ATTR_HASH_ALGORITHM, attr_hash); CASE_PRINT(IKE_ATTR_AUTHENTICATION_METHOD, attr_auth); @@ -272,32 +281,32 @@ ike_attribute_print (register u_char *buf, u_char doi) CASE_PRINT(IKE_ATTR_GROUP_TYPE, attr_gtype); CASE_PRINT(IKE_ATTR_LIFE_TYPE, attr_ltype); default: - printf("%d", p); + printf("%d", val); } else - switch(type & 0x7fff) { + switch(type) { CASE_PRINT(IPSEC_ATTR_SA_LIFE_TYPE, ipsec_attr_ltype); CASE_PRINT(IPSEC_ATTR_ENCAPSULATION_MODE, ipsec_attr_encap); CASE_PRINT(IPSEC_ATTR_AUTHENTICATION_ALGORITHM, ipsec_attr_auth); default: - printf ("%d", p); + printf ("%d", val); } - } + #undef CASE_PRINT - return length + 4; + return len; } void -ike_transform_print (register u_char *buf, register int len, u_char doi) +ike_pl_transform_print (register u_char *buf, register int len, u_char doi) { const char *ah[] = IPSEC_AH_INITIALIZER; const char *esp[] = IPSEC_ESP_INITIALIZER; u_char *attr = buf + 4; - printf("\n\t%stransform: %d ID: ", ike_tab_offset(), (char)buf[0]); + printf("\n\t%stransform: %u ID: ", ike_tab_offset(), buf[0]); switch (doi) { case ISAKMP_DOI: @@ -329,12 +338,12 @@ ike_transform_print (register u_char *buf, register int len, u_char doi) ike_tab_level++; while((int)(attr - buf) < len - 4) /* Skip last 'NONE' attr */ - attr += ike_attribute_print(attr, doi); + attr += ike_attribute_print(attr, doi, len - (attr-buf)); ike_tab_level--; } void -ike_proposal_print (register u_char *buf, register int len, u_char doi) +ike_pl_proposal_print (register u_char *buf, register int len, u_char doi) { printf(" proposal: %d proto: %s spisz: %d xforms: %d", buf[0], (buf[1] < (sizeof ike / sizeof ike[0]) ? ike[buf[1]] : @@ -356,7 +365,7 @@ ike_proposal_print (register u_char *buf, register int len, u_char doi) } void -ike_ke_print (register u_char *buf, register int len, u_char doi) +ike_pl_ke_print (register u_char *buf, register int len, u_char doi) { if (doi != IPSEC_DOI) return; @@ -412,7 +421,7 @@ ipsec_id_print (register u_char *buf, register int len, u_char doi) case IPSEC_ID_USER_FQDN: printf ("\""); for(p = buf + 4; (int)(p - buf) < len; p++) - printf("%c",(isprint(*p) ? *p : '.')); + printf ("%c",(isprint(*p) ? *p : '.')); printf ("\""); break; @@ -426,7 +435,7 @@ ipsec_id_print (register u_char *buf, register int len, u_char doi) } void -ike_notification_print (register u_char *buf, register int len) +ike_pl_notification_print (register u_char *buf, register int len) { static const char *nftypes[] = IKE_NOTIFY_TYPES_INITIALIZER; struct notification_payload *np = (struct notification_payload *)buf; @@ -463,7 +472,8 @@ ike_notification_print (register u_char *buf, register int len) attr = &np->data[np->spi_size]; ike_tab_level++; while((int)(attr - buf) < len - 4) /* Skip last 'NONE' attr */ - attr += ike_attribute_print(attr, IPSEC_DOI); + attr += ike_attribute_print(attr, IPSEC_DOI, + len - (attr-buf)); ike_tab_level--; break; @@ -491,7 +501,7 @@ ike_notification_print (register u_char *buf, register int len) } void -ike_vendor_print (register u_char *buf, register int len, u_char doi) +ike_pl_vendor_print (register u_char *buf, register int len, u_char doi) { u_char *p = buf; @@ -504,6 +514,120 @@ ike_vendor_print (register u_char *buf, register int len, u_char doi) printf("\""); } +/* IKE mode-config. */ +int +ike_cfg_attribute_print (register u_char *buf, register int attr_type, + register int maxlen) +{ + static char *attrs[] = IKE_CFG_ATTRIBUTE_INITIALIZER; + char ntop_buf[INET6_ADDRSTRLEN]; + struct in_addr in; + + u_char af = buf[0] >> 7; + u_int16_t type = (buf[0] & 0x7f) << 8 | buf[1]; + u_int16_t len = buf[2] << 8 | buf[3], p; + + printf("\n\t\%sattribute %s = ", ike_tab_offset(), + type < (sizeof attrs / sizeof attrs[0]) ? attrs[type] : + "<unknown>"); + + if ((af == 1 && maxlen < 4) || + (af == 0 && maxlen < (len + 4))) { + printf ("\n\t%s[|attr]", ike_tab_offset()); + return maxlen; + } + + if (af == 0) { + for (p = 0; p < len; p++) + printf ("%02x", (char)*(buf + 4 + p)); + return len + 4; + } + + /* AF is 1 */ + if (len == 0) { + printf ("<none>"); + return 4; + } + + switch (type) { + case IKE_CFG_ATTR_INTERNAL_IP4_ADDRESS: + case IKE_CFG_ATTR_INTERNAL_IP4_NETMASK: + case IKE_CFG_ATTR_INTERNAL_IP4_DNS: + case IKE_CFG_ATTR_INTERNAL_IP4_NBNS: + case IKE_CFG_ATTR_INTERNAL_IP4_DHCP: + memcpy (&in.s_addr, buf + 4, sizeof in); + printf ("%s", inet_ntoa (in)); + break; + + case IKE_CFG_ATTR_INTERNAL_IP6_ADDRESS: + case IKE_CFG_ATTR_INTERNAL_IP6_NETMASK: + case IKE_CFG_ATTR_INTERNAL_IP6_DNS: + case IKE_CFG_ATTR_INTERNAL_IP6_NBNS: + case IKE_CFG_ATTR_INTERNAL_IP6_DHCP: + printf ("%s", inet_ntop (AF_INET6, buf + 4, ntop_buf, + sizeof ntop_buf)); + break; + + case IKE_CFG_ATTR_INTERNAL_IP4_SUBNET: + memcpy(&in.s_addr, buf + 4, sizeof in); + printf("%s/", inet_ntoa (in)); + memcpy(&in.s_addr, buf + 8, sizeof in); + printf("%s", inet_ntoa (in)); + break; + + case IKE_CFG_ATTR_INTERNAL_IP6_SUBNET: + printf("%s/%u", inet_ntop (AF_INET6, buf + 4, ntop_buf, + sizeof ntop_buf), + *(buf + 4 + 16)); + break; + + case IKE_CFG_ATTR_INTERNAL_ADDRESS_EXPIRY: + printf("%u seconds", *(u_int32_t *)(buf + 4)); + break; + + case IKE_CFG_ATTR_APPLICATION_VERSION: + for (p = 0; p < len; p++) + printf("%c", isprint(*(buf + 4 + p)) ? + *(buf + 4 + p) : '.'); + break; + + case IKE_CFG_ATTR_SUPPORTED_ATTRIBUTES: + printf("<%d attributes>", len / 2); + ike_tab_level++; + for (p = 0; p < len; p += 2) { + type = (buf[4 + p] << 8 | buf[4 + p + 1]) & 0x7fff; + printf("\n\t%s%s", ike_tab_offset(), + type < (sizeof attrs/sizeof attrs[0]) ? + attrs[type] : "<unknown>"); + } + ike_tab_level--; + break; + + default: + break; + } + return len + 4; +} + +void +ike_pl_attribute_print (register u_char *buf, register int len) +{ + static const char *pl_attr[] = IKE_CFG_ATTRIBUTE_TYPE_INITIALIZER; + u_char type, *attr; + u_int16_t id; + + type = buf[0]; + id = buf[2]<<8 | buf[3]; + attr = buf + 4; + + printf(" type: %s Id: %d", + type < (sizeof pl_attr/sizeof pl_attr[0]) ? pl_attr[type] : + "<unknown>", id); + + while((int)(attr - buf) < len - 4) + attr += ike_cfg_attribute_print(attr, type, len - (attr-buf)); +} + void ike_pl_print (register u_char type, register u_char *buf, u_char doi) { @@ -524,19 +648,19 @@ ike_pl_print (register u_char type, register u_char *buf, u_char doi) return; case PAYLOAD_SA: - ike_sa_print(buf+4, this_len); + ike_pl_sa_print(buf+4, this_len); break; case PAYLOAD_PROPOSAL: - ike_proposal_print(buf+4, this_len, doi); + ike_pl_proposal_print(buf+4, this_len, doi); break; case PAYLOAD_TRANSFORM: - ike_transform_print(buf+4, this_len, doi); + ike_pl_transform_print(buf+4, this_len, doi); break; case PAYLOAD_KE: - ike_ke_print(buf+4, this_len, doi); + ike_pl_ke_print(buf+4, this_len, doi); break; case PAYLOAD_ID: @@ -553,11 +677,15 @@ ike_pl_print (register u_char type, register u_char *buf, u_char doi) break; case PAYLOAD_NOTIFICATION: - ike_notification_print(buf, this_len); + ike_pl_notification_print(buf, this_len); break; case PAYLOAD_VENDOR: - ike_vendor_print(buf+4, this_len, doi); + ike_pl_vendor_print(buf+4, this_len, doi); + break; + + case PAYLOAD_ATTRIBUTE: + ike_pl_attribute_print(buf+4, this_len); break; default: |