From: itojun Date: Fri, 14 Jun 2002 15:45:59 +0000 (+0000) Subject: dhcpv6 i-d revision 26, by jinmei@kame X-Git-Tag: tcpdump-3.8-bp~463 X-Git-Url: https://git.tcpdump.org/tcpdump/commitdiff_plain/9e8f54ad61e557e00fec59931a34c5c4018505a2 dhcpv6 i-d revision 26, by jinmei@kame --- diff --git a/print-dhcp6.c b/print-dhcp6.c index 066759ae..09b5a7f4 100644 --- a/print-dhcp6.c +++ b/print-dhcp6.c @@ -27,12 +27,12 @@ * SUCH DAMAGE. */ /* - * draft-ietf-dhc-dhcpv6-22.txt + * draft-ietf-dhc-dhcpv6-26.txt */ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-dhcp6.c,v 1.18 2002-06-11 17:08:44 itojun Exp $"; + "@(#) $Header: /tcpdump/master/tcpdump/print-dhcp6.c,v 1.19 2002-06-14 15:45:59 itojun Exp $"; #endif #ifdef HAVE_CONFIG_H @@ -53,6 +53,9 @@ static const char rcsid[] = #include "interface.h" #include "addrtoname.h" +/* lease duration */ +#define DHCP6_DURATITION_INFINITE 0xffffffff + /* Error Values */ #define DH6ERR_FAILURE 16 #define DH6ERR_AUTHFAIL 17 @@ -61,6 +64,12 @@ static const char rcsid[] = #define DH6ERR_OPTUNAVAIL 20 /* Message type */ +#define DH6_SOLICIT 1 +#define DH6_ADVERTISE 2 +#define DH6_REQUEST 3 +#define DH6_CONFIRM 4 +#define DH6_RENEW 5 +#define DH6_REBIND 6 #define DH6_REPLY 7 #define DH6_INFORM_REQ 11 @@ -70,7 +79,6 @@ struct dhcp6 { u_int8_t m; u_int32_t x; } dh6_msgtypexid; - struct in6_addr dh6_servaddr; /* options follow */ } __attribute__ ((__packed__)); #define dh6_msgtype dh6_msgtypexid.m @@ -78,21 +86,131 @@ struct dhcp6 { #define DH6_XIDMASK 0x00ffffff /* option */ -#define DH6OPT_DUID 1 /* TBD */ -#define DH6OPT_DNS 11 /* TBD */ +#define DH6OPT_CLIENTID 1 +#define DH6OPT_SERVERID 2 +#define DH6OPT_IA 3 +#define DH6OPT_IA_TMP 4 +#define DH6OPT_IADDR 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_CLIENT_MSG 9 +#define DH6OPT_SERVER_MSG 10 +#define DH6OPT_AUTH 11 +#define DH6OPT_UNICAST 12 +#define DH6OPT_STATUS_CODE 13 +# define DH6OPT_STCODE_SUCCESS 0 +# define DH6OPT_STCODE_UNSPECFAIL 1 +# define DH6OPT_STCODE_AUTHFAILED 2 +# define DH6OPT_STCODE_ADDRUNAVAIL 3 +# define DH6OPT_STCODE_NOADDRAVAIL 4 +# define DH6OPT_STCODE_NOBINDING 5 +# define DH6OPT_STCODE_CONFNOMATCH 6 +# define DH6OPT_STCODE_NOTONLINK 7 +# define DH6OPT_STCODE_USEMULTICAST 8 +#define DH6OPT_RAPID_COMMIT 14 +#define DH6OPT_USER_CLASS 15 +#define DH6OPT_VENDOR_CLASS 16 +#define DH6OPT_VENDOR_OPTS 17 +#define DH6OPT_INTERFACE_ID 18 +#define DH6OPT_RECONF_MSG 19 + +/* + * 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_DNS 25 +#define DH6OPT_PREFIX_DELEGATION 30 +#define DH6OPT_PREFIX_INFORMATION 31 +#define DH6OPT_PREFIX_REQUEST 32 + struct dhcp6opt { u_int16_t dh6opt_type; u_int16_t dh6opt_len; /* type-dependent data follows */ } __attribute__ ((__packed__)); +static char * +dhcp6opt_name(int type) +{ + static char genstr[sizeof("opt_65535") + 1]; /* XXX thread unsafe */ + + if (type > 65535) + return "INVALID option"; + + switch(type) { + case DH6OPT_CLIENTID: + return "client ID"; + case DH6OPT_SERVERID: + return "server ID"; + case DH6OPT_ORO: + return "option request"; + case DH6OPT_PREFERENCE: + return "preference"; + case DH6OPT_STATUS_CODE: + return "status code"; + case DH6OPT_RAPID_COMMIT: + return "rapid commit"; + case DH6OPT_DNS: + return "DNS"; + case DH6OPT_PREFIX_DELEGATION: + return "prefix delegation"; + case DH6OPT_PREFIX_INFORMATION: + return "prefix information"; + default: + sprintf(genstr, "opt_%d", type); + return(genstr); + } +} + +static char * +dhcp6stcode(int code) +{ + static char genstr[sizeof("code255") + 1]; /* XXX thread unsafe */ + + if (code > 255) + return "INVALID code"; + + switch(code) { + case DH6OPT_STCODE_SUCCESS: + return "success"; + case DH6OPT_STCODE_UNSPECFAIL: + return "unspec failure"; + case DH6OPT_STCODE_AUTHFAILED: + return "auth fail"; + case DH6OPT_STCODE_ADDRUNAVAIL: + return "address unavailable"; + case DH6OPT_STCODE_NOADDRAVAIL: + return "no addresses"; + case DH6OPT_STCODE_NOBINDING: + return "no binding"; + case DH6OPT_STCODE_CONFNOMATCH: + return "confirm no match"; + case DH6OPT_STCODE_NOTONLINK: + return "not on-link"; + case DH6OPT_STCODE_USEMULTICAST: + return "use multicast"; + default: + sprintf(genstr, "code%d", code); + return(genstr); + } +} + static void dhcp6opt_print(u_char *cp, u_char *ep) { struct dhcp6opt *dh6o; u_char *tp; - int i; + int i, opttype; size_t optlen; + u_int16_t val16; + u_int32_t val32; + struct in6_addr addr6; if (cp == ep) return; @@ -103,9 +221,11 @@ dhcp6opt_print(u_char *cp, u_char *ep) optlen = ntohs(dh6o->dh6opt_len); if (ep - cp < sizeof(*dh6o) + optlen) goto trunc; - switch (ntohs(dh6o->dh6opt_type)) { - case DH6OPT_DUID: - printf(" (duid"); /*)*/ + opttype = ntohs(dh6o->dh6opt_type); + printf(" (%s", dhcp6opt_name(opttype)); + switch (opttype) { + case DH6OPT_CLIENTID: + case DH6OPT_SERVERID: if (optlen < 2) { /*(*/ printf(" ??)"); @@ -115,9 +235,9 @@ dhcp6opt_print(u_char *cp, u_char *ep) switch (ntohs(*(u_int16_t *)tp)) { case 1: if (optlen >= 2 + 6) { - printf(" hwaddr/time time %u type %u ", - ntohl(*(u_int32_t *)&tp[2]), - ntohs(*(u_int16_t *)&tp[6])); + printf(" hwaddr/time type %u time %u ", + ntohs(*(u_int16_t *)&tp[2]), + ntohl(*(u_int32_t *)&tp[4])); for (i = 8; i < optlen; i++) printf("%02x", tp[i]); /*(*/ @@ -151,22 +271,74 @@ dhcp6opt_print(u_char *cp, u_char *ep) /*(*/ printf(" ??)"); } + break; + default: + printf(" type %d)", ntohs(*(u_int16_t *)tp)); + break; } break; + case DH6OPT_ORO: + 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(")"); + break; + case DH6OPT_PREFERENCE: + if (optlen != 1) { + printf(" ??)"); + break; + } + printf(" %d)", *((u_char *)(dh6o + 1) + 1)); + break; + case DH6OPT_RAPID_COMMIT: /* nothing todo */ + printf(")"); + break; case DH6OPT_DNS: - printf(" (dnsserver"); /*)*/ if (optlen % 16) { - /*(*/ printf(" ??)"); break; } tp = (u_char *)(dh6o + 1); for (i = 0; i < optlen; i += 16) 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(" ??)"); + memcpy(&val16, (u_char *)(dh6o + 1), sizeof(val16)); + val16 = ntohs(val16); + printf(" %s)", dhcp6stcode(val16)); + break; default: - printf(" (opt-%u)", ntohs(dh6o->dh6opt_type)); + printf(")", ntohs(dh6o->dh6opt_type)); break; } @@ -195,8 +367,26 @@ dhcp6_print(register const u_char *cp, u_int length, ep = (u_char *)snapend; dh6 = (struct dhcp6 *)cp; - TCHECK(dh6->dh6_servaddr); + TCHECK(dh6->dh6_xid); switch (dh6->dh6_msgtype) { + case DH6_SOLICIT: + name = "solicit"; + break; + case DH6_ADVERTISE: + name = "advertise"; + break; + case DH6_REQUEST: + name = "request"; + break; + case DH6_CONFIRM: + name = "confirm"; + break; + case DH6_RENEW: + name = "renew"; + break; + case DH6_REBIND: + name = "rebind"; + break; case DH6_REPLY: name = "reply"; break; @@ -223,7 +413,6 @@ dhcp6_print(register const u_char *cp, u_int length, else printf(" msgtype-%u (", dh6->dh6_msgtype); /*)*/ printf("xid=%x", ntohl(dh6->dh6_xid) & DH6_XIDMASK); - printf(" server=%s", ip6addr_string(&dh6->dh6_servaddr)); extp = (u_char *)(dh6 + 1); dhcp6opt_print(extp, ep); /*(*/