]> The Tcpdump Group git mirrors - tcpdump/commitdiff
dhcpv6 i-d revision 26, by jinmei@kame
authoritojun <itojun>
Fri, 14 Jun 2002 15:45:59 +0000 (15:45 +0000)
committeritojun <itojun>
Fri, 14 Jun 2002 15:45:59 +0000 (15:45 +0000)
print-dhcp6.c

index 066759aefbc1f69693e4f90be41ba1c5bc3e515b..09b5a7f4c7fab3e233809736ff172a9ea5b6b447 100644 (file)
  * 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);
        /*(*/