X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/bbc1cfa669a5f51ed26bae3784447076e3fbc80f..a9a7c86c7875a38358a9ff1f2a35e93febf6f41e:/print-dhcp6.c diff --git a/print-dhcp6.c b/print-dhcp6.c index 20c50375..a75da823 100644 --- a/print-dhcp6.c +++ b/print-dhcp6.c @@ -30,14 +30,17 @@ * RFC3315: DHCPv6 * supported DHCPv6 options: * RFC3319, - * draft-ietf-dhc-dhcpv6-opt-dnsconfig-04.txt, - * draft-ietf-dhc-dhcpv6-opt-prefix-delegation-05.txt - * draft-ietf-dhc-dhcpv6-opt-timeconfig-02.txt, + * RFC3633, + * RFC3646, + * RFC3898, + * RFC4075, + * RFC4242, + * RFC4280, */ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-dhcp6.c,v 1.30 2003-11-16 09:36:17 guy Exp $"; + "@(#) $Header: /tcpdump/master/tcpdump/print-dhcp6.c,v 1.37 2008-02-06 10:26:09 guy Exp $"; #endif #ifdef HAVE_CONFIG_H @@ -77,6 +80,8 @@ static const char rcsid[] _U_ = #define DH6_INFORM_REQ 11 #define DH6_RELAY_FORW 12 #define DH6_RELAY_REPLY 13 +#define DH6_LEASEQUERY 14 +#define DH6_LQ_REPLY 15 /* DHCP6 base packet format */ struct dhcp6 { @@ -103,16 +108,21 @@ struct dhcp6_relay { #define DH6OPT_CLIENTID 1 #define DH6OPT_SERVERID 2 #define DH6OPT_IA_NA 3 -#define DH6OPT_IA_TMP 4 -#define DH6OPT_IADDR 5 +#define DH6OPT_IA_TA 4 +#define DH6OPT_IA_ADDR 5 #define DH6OPT_ORO 6 #define DH6OPT_PREFERENCE 7 -# define DH6OPT_PREF_UNDEF -1 # define DH6OPT_PREF_MAX 255 #define DH6OPT_ELAPSED_TIME 8 #define DH6OPT_RELAY_MSG 9 /*#define DH6OPT_SERVER_MSG 10 deprecated */ #define DH6OPT_AUTH 11 +# define DH6OPT_AUTHPROTO_DELAYED 2 +# define DH6OPT_AUTHPROTO_RECONFIG 3 +# define DH6OPT_AUTHALG_HMACMD5 1 +# define DH6OPT_AUTHRDM_MONOCOUNTER 0 +# define DH6OPT_AUTHRECONFIG_KEY 1 +# define DH6OPT_AUTHRECONFIG_HMACMD5 2 #define DH6OPT_UNICAST 12 #define DH6OPT_STATUS_CODE 13 # define DH6OPT_STCODE_SUCCESS 0 @@ -122,6 +132,10 @@ struct dhcp6_relay { # define DH6OPT_STCODE_NOTONLINK 4 # define DH6OPT_STCODE_USEMULTICAST 5 # define DH6OPT_STCODE_NOPREFIXAVAIL 6 +# define DH6OPT_STCODE_UNKNOWNQUERYTYPE 7 +# define DH6OPT_STCODE_MALFORMEDQUERY 8 +# define DH6OPT_STCODE_NOTCONFIGURED 9 +# define DH6OPT_STCODE_NOTALLOWED 10 #define DH6OPT_RAPID_COMMIT 14 #define DH6OPT_USER_CLASS 15 #define DH6OPT_VENDOR_CLASS 16 @@ -133,25 +147,29 @@ struct dhcp6_relay { #define DH6OPT_SIP_SERVER_A 22 #define DH6OPT_DNS 23 #define DH6OPT_DNSNAME 24 - -/* - * The option type has not been assigned for the following options. - * We temporarily adopt values used in the service specification document - * (200206xx version) by NTT Communications. - * Note that we'll change the following definitions if different type values - * are officially assigned. - */ -#define DH6OPT_PREFIX_DELEGATION 30 -#define DH6OPT_PREFIX_INFORMATION 31 -#define DH6OPT_PREFIX_REQUEST 32 - -/* - * The followings are also unassigned numbers. - * We temporarily use values as of KAME snap 20031013. - */ -#define DH6OPT_IA_PD 33 -#define DH6OPT_IA_PD_PREFIX 34 -#define DH6OPT_NTP_SERVERS 35 +#define DH6OPT_IA_PD 25 +#define DH6OPT_IA_PD_PREFIX 26 +#define DH6OPT_NIS_SERVERS 27 +#define DH6OPT_NISP_SERVERS 28 +#define DH6OPT_NIS_NAME 29 +#define DH6OPT_NISP_NAME 30 +#define DH6OPT_NTP_SERVERS 31 +#define DH6OPT_LIFETIME 32 +#define DH6OPT_BCMCS_SERVER_D 33 +#define DH6OPT_BCMCS_SERVER_A 34 +#define DH6OPT_GEOCONF_CIVIC 36 +#define DH6OPT_REMOTE_ID 37 +#define DH6OPT_SUBSCRIBER_ID 38 +#define DH6OPT_CLIENT_FQDN 39 +#define DH6OPT_PANA_AGENT 40 +#define DH6OPT_NEW_POSIX_TIMEZONE 41 +#define DH6OPT_NEW_TZDB_TIMEZONE 42 +#define DH6OPT_ERO 43 +#define DH6OPT_LQ_QUERY 44 +#define DH6OPT_CLIENT_DATA 45 +#define DH6OPT_CLT_TIME 46 +#define DH6OPT_LQ_RELAY_DATA 47 +#define DH6OPT_LQ_CLIENT_LINK 48 struct dhcp6opt { u_int16_t dh6opt_type; @@ -159,72 +177,107 @@ struct dhcp6opt { /* type-dependent data follows */ }; -struct dhcp6_ia { - u_int16_t dh6opt_ia_type; - u_int16_t dh6opt_ia_len; - u_int32_t dh6opt_ia_iaid; - u_int32_t dh6opt_ia_t1; - u_int32_t dh6opt_ia_t2; -}; - -struct dhcp6_ia_prefix { - u_int16_t dh6opt_ia_prefix_type; - u_int16_t dh6opt_ia_prefix_len; - u_int32_t dh6opt_ia_prefix_pltime; - u_int32_t dh6opt_ia_prefix_vltime; - u_int8_t dh6opt_ia_prefix_plen; - struct in6_addr dh6opt_ia_prefix_addr; -} __attribute__ ((__packed__)); - static const char * dhcp6opt_name(int type) { static char genstr[sizeof("opt_65535") + 1]; /* XXX thread unsafe */ if (type > 65535) - return "INVALID option"; + return "INVALID-option"; switch(type) { case DH6OPT_CLIENTID: - return "client ID"; + return "client-ID"; case DH6OPT_SERVERID: - return "server ID"; + return "server-ID"; case DH6OPT_IA_NA: return "IA_NA"; + case DH6OPT_IA_TA: + return "IA_TA"; + case DH6OPT_IA_ADDR: + return "IA_ADDR"; case DH6OPT_ORO: - return "option request"; + return "option-request"; case DH6OPT_PREFERENCE: return "preference"; case DH6OPT_ELAPSED_TIME: - return "elapsed time"; + return "elapsed-time"; case DH6OPT_RELAY_MSG: - return "relay message"; + return "relay-message"; + case DH6OPT_AUTH: + return "authentication"; + case DH6OPT_UNICAST: + return "server-unicast"; case DH6OPT_STATUS_CODE: - return "status code"; + return "status-code"; case DH6OPT_RAPID_COMMIT: - return "rapid commit"; + return "rapid-commit"; + case DH6OPT_USER_CLASS: + return "user-class"; + case DH6OPT_VENDOR_CLASS: + return "vendor-class"; + case DH6OPT_VENDOR_OPTS: + return "vendor-specific-info"; case DH6OPT_INTERFACE_ID: - return "interface ID"; + return "interface-ID"; case DH6OPT_RECONF_MSG: - return "reconfigure message"; + return "reconfigure-message"; case DH6OPT_RECONF_ACCEPT: - return "reconfigure accept"; + return "reconfigure-accept"; case DH6OPT_SIP_SERVER_D: - return "SIP Servers Domain"; + return "SIP-servers-domain"; case DH6OPT_SIP_SERVER_A: - return "SIP Servers Address"; + return "SIP-servers-address"; case DH6OPT_DNS: - return "DNS"; - case DH6OPT_PREFIX_DELEGATION: - return "prefix delegation"; - case DH6OPT_PREFIX_INFORMATION: - return "prefix information"; + return "DNS-server"; + case DH6OPT_DNSNAME: + return "DNS-search-list"; case DH6OPT_IA_PD: return "IA_PD"; case DH6OPT_IA_PD_PREFIX: - return "IA_PD prefix"; + return "IA_PD-prefix"; case DH6OPT_NTP_SERVERS: - return "NTP Server"; + return "NTP-server"; + case DH6OPT_LIFETIME: + return "lifetime"; + case DH6OPT_NIS_SERVERS: + return "NIS-server"; + case DH6OPT_NISP_SERVERS: + return "NIS+-server"; + case DH6OPT_NIS_NAME: + return "NIS-domain-name"; + case DH6OPT_NISP_NAME: + return "NIS+-domain-name"; + case DH6OPT_BCMCS_SERVER_D: + return "BCMCS-domain-name"; + case DH6OPT_BCMCS_SERVER_A: + return "BCMCS-server"; + case DH6OPT_GEOCONF_CIVIC: + return "Geoconf-Civic"; + case DH6OPT_REMOTE_ID: + return "Remote-ID"; + case DH6OPT_SUBSCRIBER_ID: + return "Subscriber-ID"; + case DH6OPT_CLIENT_FQDN: + return "Client-FQDN"; + case DH6OPT_PANA_AGENT: + return "PANA-agent"; + case DH6OPT_NEW_POSIX_TIMEZONE: + return "POSIX-timezone"; + case DH6OPT_NEW_TZDB_TIMEZONE: + return "POSIX-tz-database"; + case DH6OPT_ERO: + return "Echo-request-option"; + case DH6OPT_LQ_QUERY: + return "Lease-query"; + case DH6OPT_CLIENT_DATA: + return "LQ-client-data"; + case DH6OPT_CLT_TIME: + return "Clt-time"; + case DH6OPT_LQ_RELAY_DATA: + return "LQ-relay-data"; + case DH6OPT_LQ_CLIENT_LINK: + return "LQ-client-link"; default: snprintf(genstr, sizeof(genstr), "opt_%d", type); return(genstr); @@ -254,6 +307,14 @@ dhcp6stcode(int code) return "use multicast"; case DH6OPT_STCODE_NOPREFIXAVAIL: return "no prefixes"; + case DH6OPT_STCODE_UNKNOWNQUERYTYPE: + return "unknown query type"; + case DH6OPT_STCODE_MALFORMEDQUERY: + return "malformed query"; + case DH6OPT_STCODE_NOTCONFIGURED: + return "not configured"; + case DH6OPT_STCODE_NOTALLOWED: + return "not allowed"; default: snprintf(genstr, sizeof(genstr), "code%d", code); return(genstr); @@ -268,11 +329,8 @@ dhcp6opt_print(const u_char *cp, const u_char *ep) size_t i; u_int16_t opttype; size_t optlen; - u_int16_t val16; - u_int32_t val32; - struct in6_addr addr6; - struct dhcp6_ia ia; - struct dhcp6_ia_prefix ia_prefix; + u_int8_t auth_proto; + u_int authinfolen, authrealmlen; if (cp == ep) return; @@ -339,17 +397,33 @@ dhcp6opt_print(const u_char *cp, const u_char *ep) break; } break; + case DH6OPT_IA_ADDR: + if (optlen < 24) { + /*(*/ + printf(" ?)"); + break; + } + tp = (u_char *)(dh6o + 1); + printf(" %s", ip6addr_string(&tp[0])); + printf(" pltime:%u vltime:%u", + EXTRACT_32BITS(&tp[16]), + EXTRACT_32BITS(&tp[20])); + if (optlen > 24) { + /* there are sub-options */ + dhcp6opt_print(tp + 24, tp + 24 + optlen); + } + printf(")"); + break; case DH6OPT_ORO: + case DH6OPT_ERO: if (optlen % 2) { printf(" ?)"); break; } tp = (u_char *)(dh6o + 1); for (i = 0; i < optlen; i += 2) { - u_int16_t opt; - - memcpy(&opt, &tp[i], sizeof(opt)); - printf(" %s", dhcp6opt_name(ntohs(opt))); + printf(" %s", + dhcp6opt_name(EXTRACT_16BITS(&tp[i]))); } printf(")"); break; @@ -358,32 +432,128 @@ dhcp6opt_print(const u_char *cp, const u_char *ep) printf(" ?)"); break; } - printf(" %d)", *((u_char *)(dh6o + 1) + 1)); + tp = (u_char *)(dh6o + 1); + printf(" %d)", *tp); break; case DH6OPT_ELAPSED_TIME: if (optlen != 2) { printf(" ?)"); break; } - memcpy(&val16, dh6o + 1, sizeof(val16)); - val16 = ntohs(val16); - printf(" %d)", (int)val16); + tp = (u_char *)(dh6o + 1); + printf(" %d)", EXTRACT_16BITS(tp)); break; case DH6OPT_RELAY_MSG: printf(" ("); - dhcp6_print((const u_char *)(dh6o + 1), optlen, 0, 0); + tp = (u_char *)(dh6o + 1); + dhcp6_print(tp, optlen); + printf(")"); + break; + case DH6OPT_AUTH: + if (optlen < 11) { + printf(" ?)"); + break; + } + tp = (u_char *)(dh6o + 1); + auth_proto = *tp; + switch (auth_proto) { + case DH6OPT_AUTHPROTO_DELAYED: + printf(" proto: delayed"); + break; + case DH6OPT_AUTHPROTO_RECONFIG: + printf(" proto: reconfigure"); + break; + default: + printf(" proto: %d", auth_proto); + break; + } + tp++; + switch (*tp) { + case DH6OPT_AUTHALG_HMACMD5: + /* XXX: may depend on the protocol */ + printf(", alg: HMAC-MD5"); + break; + default: + printf(", alg: %d", *tp); + break; + } + tp++; + switch (*tp) { + case DH6OPT_AUTHRDM_MONOCOUNTER: + printf(", RDM: mono"); + break; + default: + printf(", RDM: %d", *tp); + break; + } + tp++; + printf(", RD:"); + for (i = 0; i < 4; i++, tp += 2) + printf(" %04x", EXTRACT_16BITS(tp)); + + /* protocol dependent part */ + authinfolen = optlen - 11; + switch (auth_proto) { + case DH6OPT_AUTHPROTO_DELAYED: + if (authinfolen == 0) + break; + if (authinfolen < 20) { + printf(" ??"); + break; + } + authrealmlen = authinfolen - 20; + if (authrealmlen > 0) { + printf(", realm: "); + } + for (i = 0; i < authrealmlen; i++, tp++) + printf("%02x", *tp); + printf(", key ID: %08x", EXTRACT_32BITS(tp)); + tp += 4; + printf(", HMAC-MD5:"); + for (i = 0; i < 4; i++, tp+= 4) + printf(" %08x", EXTRACT_32BITS(tp)); + break; + case DH6OPT_AUTHPROTO_RECONFIG: + if (authinfolen != 17) { + printf(" ??"); + break; + } + switch (*tp++) { + case DH6OPT_AUTHRECONFIG_KEY: + printf(" reconfig-key"); + break; + case DH6OPT_AUTHRECONFIG_HMACMD5: + printf(" type: HMAC-MD5"); + break; + default: + printf(" type: ??"); + break; + } + printf(" value:"); + for (i = 0; i < 4; i++, tp+= 4) + printf(" %08x", EXTRACT_32BITS(tp)); + break; + default: + printf(" ??"); + break; + } + printf(")"); break; case DH6OPT_RAPID_COMMIT: /* nothing todo */ printf(")"); break; case DH6OPT_INTERFACE_ID: + case DH6OPT_SUBSCRIBER_ID: /* * Since we cannot predict the encoding, print hex dump * at most 10 characters. */ + tp = (u_char *)(dh6o + 1); + printf(" "); for (i = 0; i < optlen && i < 10; i++) - printf("%02x", ((u_char *)(dh6o + 1))[i]); + printf("%02x", tp[i]); + printf("...)"); break; case DH6OPT_RECONF_MSG: tp = (u_char *)(dh6o + 1); @@ -405,6 +575,11 @@ dhcp6opt_print(const u_char *cp, const u_char *ep) case DH6OPT_SIP_SERVER_A: case DH6OPT_DNS: case DH6OPT_NTP_SERVERS: + case DH6OPT_NIS_SERVERS: + case DH6OPT_NISP_SERVERS: + case DH6OPT_BCMCS_SERVER_A: + case DH6OPT_PANA_AGENT: + case DH6OPT_LQ_CLIENT_LINK: if (optlen % 16) { printf(" ?)"); break; @@ -414,79 +589,129 @@ dhcp6opt_print(const u_char *cp, const u_char *ep) printf(" %s", ip6addr_string(&tp[i])); printf(")"); break; - case DH6OPT_PREFIX_DELEGATION: - dhcp6opt_print((u_char *)(dh6o + 1), - (u_char *)(dh6o + 1) + optlen); - printf(")"); - break; - case DH6OPT_PREFIX_INFORMATION: - if (optlen % 21) - printf(" ?)"); - memcpy(&addr6, (u_char *)(dh6o + 1) + 5, - sizeof(addr6)); - printf(" %s/%d", ip6addr_string(&addr6), - (int)*((u_char *)(dh6o + 1) + 4)); - memcpy(&val32, dh6o + 1, sizeof(val32)); - val32 = ntohl(val32); - if (val32 == DHCP6_DURATITION_INFINITE) - printf(" lease-duration: infinite)"); - else - printf(" lease-duration: %u)", val32); - break; case DH6OPT_STATUS_CODE: if (optlen < 2) { printf(" ?)"); break; } - memcpy(&val16, (u_char *)(dh6o + 1), sizeof(val16)); - val16 = ntohs(val16); - printf(" %s)", dhcp6stcode(val16)); + tp = (u_char *)(dh6o + 1); + printf(" %s)", dhcp6stcode(EXTRACT_16BITS(&tp[0]))); break; case DH6OPT_IA_NA: case DH6OPT_IA_PD: - if (optlen < sizeof(ia) - 4) { + if (optlen < 12) { + printf(" ?)"); + break; + } + tp = (u_char *)(dh6o + 1); + printf(" IAID:%u T1:%u T2:%u", + EXTRACT_32BITS(&tp[0]), + EXTRACT_32BITS(&tp[4]), + EXTRACT_32BITS(&tp[8])); + if (optlen > 12) { + /* there are sub-options */ + dhcp6opt_print(tp + 12, tp + 12 + optlen); + } + printf(")"); + break; + case DH6OPT_IA_TA: + if (optlen < 4) { printf(" ?)"); break; } - memcpy(&ia, (u_char *)dh6o, sizeof(ia)); - ia.dh6opt_ia_iaid = ntohl(ia.dh6opt_ia_iaid); - ia.dh6opt_ia_t1 = ntohl(ia.dh6opt_ia_t1); - ia.dh6opt_ia_t2 = ntohl(ia.dh6opt_ia_t2); - printf(" IAID:%lu T1:%lu T2:%lu", - (unsigned long)ia.dh6opt_ia_iaid, - (unsigned long)ia.dh6opt_ia_t1, - (unsigned long)ia.dh6opt_ia_t2); - if (optlen > sizeof(ia) - 4) { + tp = (u_char *)(dh6o + 1); + printf(" IAID:%u", EXTRACT_32BITS(tp)); + if (optlen > 4) { /* there are sub-options */ - dhcp6opt_print((u_char *)dh6o + sizeof(ia), - (u_char *)(dh6o + 1) + optlen); + dhcp6opt_print(tp + 4, tp + 4 + optlen); } printf(")"); break; case DH6OPT_IA_PD_PREFIX: - if (optlen < sizeof(ia_prefix) - 4) { + if (optlen < 25) { printf(" ?)"); break; } - memcpy(&ia_prefix, (u_char *)dh6o, sizeof(ia_prefix)); - printf(" %s/%d", - ip6addr_string(&ia_prefix.dh6opt_ia_prefix_addr), - ia_prefix.dh6opt_ia_prefix_plen); - ia_prefix.dh6opt_ia_prefix_pltime = - ntohl(ia_prefix.dh6opt_ia_prefix_pltime); - ia_prefix.dh6opt_ia_prefix_vltime = - ntohl(ia_prefix.dh6opt_ia_prefix_vltime); - printf(" pltime:%lu vltime:%lu", - (unsigned long)ia_prefix.dh6opt_ia_prefix_pltime, - (unsigned long)ia_prefix.dh6opt_ia_prefix_vltime); - if (optlen > sizeof(ia_prefix) - 4) { + tp = (u_char *)(dh6o + 1); + printf(" %s/%d", ip6addr_string(&tp[9]), tp[8]); + printf(" pltime:%u vltime:%u", + EXTRACT_32BITS(&tp[0]), + EXTRACT_32BITS(&tp[4])); + if (optlen > 25) { /* there are sub-options */ - dhcp6opt_print((u_char *)dh6o + - sizeof(ia_prefix), - (u_char *)(dh6o + 1) + optlen); + dhcp6opt_print(tp + 25, tp + 25 + optlen); + } + printf(")"); + break; + case DH6OPT_LIFETIME: + case DH6OPT_CLT_TIME: + if (optlen != 4) { + printf(" ?)"); + break; + } + tp = (u_char *)(dh6o + 1); + printf(" %d)", EXTRACT_32BITS(tp)); + break; + case DH6OPT_REMOTE_ID: + if (optlen < 4) { + printf(" ?)"); + break; + } + tp = (u_char *)(dh6o + 1); + printf(" %d ", EXTRACT_32BITS(tp)); + /* + * Print hex dump first 10 characters. + */ + for (i = 4; i < optlen && i < 14; i++) + printf("%02x", tp[i]); + printf("...)"); + break; + case DH6OPT_LQ_QUERY: + if (optlen < 17) { + printf(" ?)"); + break; + } + tp = (u_char *)(dh6o + 1); + switch (*tp) { + case 1: + printf(" by-address"); + break; + case 2: + printf(" by-clientID"); + break; + default: + printf(" type_%d", (int)*tp); + break; + } + printf(" %s", ip6addr_string(&tp[1])); + if (optlen > 17) { + /* there are query-options */ + dhcp6opt_print(tp + 17, tp + optlen); } printf(")"); break; + case DH6OPT_CLIENT_DATA: + tp = (u_char *)(dh6o + 1); + if (optlen > 0) { + /* there are encapsulated options */ + dhcp6opt_print(tp, tp + optlen); + } + printf(")"); + break; + case DH6OPT_LQ_RELAY_DATA: + if (optlen < 16) { + printf(" ?)"); + break; + } + tp = (u_char *)(dh6o + 1); + printf(" %s ", ip6addr_string(&tp[0])); + /* + * Print hex dump first 10 characters. + */ + for (i = 16; i < optlen && i < 26; i++) + printf("%02x", tp[i]); + printf("...)"); + break; default: printf(")"); break; @@ -504,8 +729,7 @@ trunc: * Print dhcp6 packets */ void -dhcp6_print(const u_char *cp, u_int length, - u_int16_t sport, u_int16_t dport) +dhcp6_print(const u_char *cp, u_int length) { struct dhcp6 *dh6; struct dhcp6_relay *dh6relay; @@ -562,6 +786,12 @@ dhcp6_print(const u_char *cp, u_int length, case DH6_RELAY_REPLY: name= "relay-reply"; break; + case DH6_LEASEQUERY: + name= "leasequery"; + break; + case DH6_LQ_REPLY: + name= "leasequery-reply"; + break; default: name = NULL; break;