X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/f59615e6d109e39f35e8b8776dd3e8d94ff7e595..ea5736c8c68f0fc3699cff8205f2823f97a05f8b:/print-dhcp6.c diff --git a/print-dhcp6.c b/print-dhcp6.c index 73b7b383..26855ccb 100644 --- a/print-dhcp6.c +++ b/print-dhcp6.c @@ -32,13 +32,15 @@ * RFC3319, * RFC3633, * RFC3646, - * draft-ietf-dhc-dhcpv6-opt-timeconfig-03.txt, - * draft-ietf-dhc-lifetime-00.txt, + * RFC3898, + * RFC4075, + * RFC4242, + * RFC4280, */ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-dhcp6.c,v 1.35 2004-07-06 22:16:03 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 @@ -78,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 { @@ -104,8 +108,8 @@ 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_MAX 255 @@ -128,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 @@ -141,21 +149,27 @@ struct dhcp6_relay { #define DH6OPT_DNSNAME 24 #define DH6OPT_IA_PD 25 #define DH6OPT_IA_PD_PREFIX 26 - -/* - * The old prefix delegation option used in the service specification document - * (200206xx version) by NTT Communications. - */ -#define DH6OPT_PREFIX_DELEGATION 30 -#define DH6OPT_PREFIX_INFORMATION 31 -#define DH6OPT_PREFIX_REQUEST 32 - -/* - * The following one is an unassigned number. - * We temporarily use values as of KAME snap 20040322. - */ -#define DH6OPT_NTP_SERVERS 35 -#define DH6OPT_LIFETIME 36 +#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; @@ -163,96 +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__)); - -struct dhcp6_auth { - u_int16_t dh6opt_auth_type; - u_int16_t dh6opt_auth_len; - u_int8_t dh6opt_auth_proto; - u_int8_t dh6opt_auth_alg; - u_int8_t dh6opt_auth_rdm; - u_int8_t dh6opt_auth_rdinfo[8]; - /* authentication information follows */ -} __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"; + 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"; + return "user-class"; case DH6OPT_VENDOR_CLASS: - return "vendor class"; + return "vendor-class"; case DH6OPT_VENDOR_OPTS: - return "vendor-specific info"; + 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_DNSNAME: - return "DNS name"; - case DH6OPT_PREFIX_DELEGATION: - return "prefix delegation"; - case DH6OPT_PREFIX_INFORMATION: - return "prefix information"; + return "DNS-name"; 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); @@ -282,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); @@ -296,12 +329,7 @@ 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; - struct dhcp6_auth authopt; + u_int8_t auth_proto; u_int authinfolen, authrealmlen; if (cp == ep) @@ -369,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; @@ -388,29 +432,31 @@ 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); + tp = (u_char *)(dh6o + 1); + dhcp6_print(tp, optlen); printf(")"); break; case DH6OPT_AUTH: - if (optlen < sizeof(authopt) - sizeof(*dh6o)) { + if (optlen < 11) { printf(" ?)"); break; } - memcpy(&authopt, dh6o, sizeof(authopt)); - switch (authopt.dh6opt_auth_proto) { + tp = (u_char *)(dh6o + 1); + auth_proto = *tp; + switch (auth_proto) { case DH6OPT_AUTHPROTO_DELAYED: printf(" proto: delayed"); break; @@ -418,37 +464,36 @@ dhcp6opt_print(const u_char *cp, const u_char *ep) printf(" proto: reconfigure"); break; default: - printf(" proto: %d", - authopt.dh6opt_auth_proto); + printf(" proto: %d", auth_proto); break; } - switch (authopt.dh6opt_auth_alg) { + tp++; + switch (*tp) { case DH6OPT_AUTHALG_HMACMD5: /* XXX: may depend on the protocol */ printf(", alg: HMAC-MD5"); break; default: - printf(", alg: %d", authopt.dh6opt_auth_alg); + printf(", alg: %d", *tp); break; } - switch (authopt.dh6opt_auth_rdm) { + tp++; + switch (*tp) { case DH6OPT_AUTHRDM_MONOCOUNTER: printf(", RDM: mono"); break; default: - printf(", RDM: %d", authopt.dh6opt_auth_rdm); + printf(", RDM: %d", *tp); break; } - tp = (u_char *)&authopt.dh6opt_auth_rdinfo; + tp++; printf(", RD:"); - for (i = 0; i < 4; i++, tp += sizeof(val16)) + for (i = 0; i < 4; i++, tp += 2) printf(" %04x", EXTRACT_16BITS(tp)); /* protocol dependent part */ - tp = (u_char *)dh6o + sizeof(authopt); - authinfolen = - optlen + sizeof(*dh6o) - sizeof(authopt); - switch (authopt.dh6opt_auth_proto) { + authinfolen = optlen - 11; + switch (auth_proto) { case DH6OPT_AUTHPROTO_DELAYED: if (authinfolen == 0) break; @@ -499,12 +544,16 @@ dhcp6opt_print(const u_char *cp, const u_char *ep) 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); @@ -526,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; @@ -535,87 +589,128 @@ 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; } - 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 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((u_char *)dh6o + sizeof(ia), - (u_char *)(dh6o + 1) + optlen); + dhcp6opt_print(tp + 12, tp + 12 + optlen); + } + printf(")"); + break; + case DH6OPT_IA_TA: + if (optlen < 4) { + printf(" ?)"); + break; + } + tp = (u_char *)(dh6o + 1); + printf(" IAID:%u", EXTRACT_32BITS(tp)); + if (optlen > 4) { + /* there are sub-options */ + 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; } - memcpy(&val32, dh6o + 1, sizeof(val32)); - val32 = ntohl(val32); - printf(" %d)", (int)val32); + 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(")"); @@ -691,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;