2 * Routines for DHCPv6 packet disassembly
3 * Jun-ichiro itojun Hagino <itojun@iijlab.net>
4 * IItom Tsutomu MIENO <iitom@utouto.com>
5 * SHIRASAKI Yasuhiro <yasuhiro@gnome.gr.jp>
6 * Tony Lindstrom <tony.lindstrom@ericsson.com>
8 * $Id: packet-dhcpv6.c,v 1.11 2004/02/25 09:31:05 guy Exp $
10 * The information used comes from:
15 * draft-ietf-dhc-dhcpv6-opt-nisconfig-02.txt
16 * draft-ietf-dhc-dhcpv6-opt-timeconfig-02.txt
17 * Note that protocol constants are still subject to change, based on IANA
18 * assignment decisions.
20 * Ethereal - Network traffic analyzer
21 * By Gerald Combs <gerald@ethereal.com>
22 * Copyright 1998 Gerald Combs
24 * This program is free software; you can redistribute it and/or
25 * modify it under the terms of the GNU General Public License
26 * as published by the Free Software Foundation; either version 2
27 * of the License, or (at your option) any later version.
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
34 * You should have received a copy of the GNU General Public License
35 * along with this program; if not, write to the Free Software
36 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
45 #include <epan/int-64bit.h>
46 #include <epan/packet.h>
47 #include <epan/ipv6-utils.h>
49 static int proto_dhcpv6 = -1;
50 static int hf_dhcpv6_msgtype = -1;
52 static guint ett_dhcpv6 = -1;
53 static guint ett_dhcpv6_option = -1;
55 #define UDP_PORT_DHCPV6_DOWNSTREAM 546
56 #define UDP_PORT_DHCPV6_UPSTREAM 547
58 #define DHCPV6_LEASEDURATION_INFINITY 0xffffffff
69 #define RECONFIGURE 10
70 #define INFORMATION_REQUEST 11
72 #define RELAY_REPLY 13
74 #define OPTION_CLIENTID 1
75 #define OPTION_SERVERID 2
76 #define OPTION_IA_NA 3
77 #define OPTION_IA_TA 4
78 #define OPTION_IAADDR 5
80 #define OPTION_PREFERENCE 7
81 #define OPTION_ELAPSED_TIME 8
82 #define OPTION_RELAY_MSG 9
83 /* #define OPTION_SERVER_MSG 10 */
84 #define OPTION_AUTH 11
85 #define OPTION_UNICAST 12
86 #define OPTION_STATUS_CODE 13
87 #define OPTION_RAPID_COMMIT 14
88 #define OPTION_USER_CLASS 15
89 #define OPTION_VENDOR_CLASS 16
90 #define OPTION_VENDOR_OPTS 17
91 #define OPTION_INTERFACE_ID 18
92 #define OPTION_RECONF_MSG 19
93 #define OPTION_RECONF_ACCEPT 20
94 #define OPTION_SIP_SERVER_D 21
95 #define OPTION_SIP_SERVER_A 22
96 #define OPTION_DNS_SERVERS 23
97 #define OPTION_DOMAIN_LIST 24
98 #define OPTION_IA_PD 25
99 #define OPTION_IAPREFIX 26
102 * The followings are unassigned numbers.
104 #define OPTION_NIS_SERVERS 35
105 #define OPTION_NISP_SERVERS 36
106 #define OPTION_NIS_DOMAIN_NAME 37
107 #define OPTION_NISP_DOMAIN_NAME 38
108 #define OPTION_NTP_SERVERS 40
109 #define OPTION_TIME_ZONE 41
114 #define DUID_LL_OLD 4
116 static const value_string msgtype_vals[] = {
117 { SOLICIT, "Solicit" },
118 { ADVERTISE, "Advertise" },
119 { REQUEST, "Request" },
120 { CONFIRM, "Confirm" },
122 { REBIND, "Rebind" },
124 { RELEASE, "Release" },
125 { DECLINE, "Decline" },
126 { RECONFIGURE, "Reconfigure" },
127 { INFORMATION_REQUEST, "Information-request" },
128 { RELAY_FORW, "Relay-forw" },
129 { RELAY_REPLY, "Relay-reply" },
133 static const value_string opttype_vals[] = {
134 { OPTION_CLIENTID, "Client Identifier" },
135 { OPTION_SERVERID, "Server Identifier" },
136 { OPTION_IA_NA, "Identify Association" },
137 { OPTION_IA_TA, "Identify Association for Temporary Address" },
138 { OPTION_IAADDR, "IA Address" },
139 { OPTION_ORO, "Option Request" },
140 { OPTION_PREFERENCE, "Preference" },
141 { OPTION_ELAPSED_TIME, "Elapsed time" },
142 { OPTION_RELAY_MSG, "Relay Message" },
143 /* { OPTION_SERVER_MSG, "Server message" }, */
144 { OPTION_AUTH, "Authentication" },
145 { OPTION_UNICAST, "Server unicast" },
146 { OPTION_STATUS_CODE, "Status code" },
147 { OPTION_RAPID_COMMIT, "Rapid Commit" },
148 { OPTION_USER_CLASS, "User Class" },
149 { OPTION_VENDOR_CLASS, "Vendor Class" },
150 { OPTION_VENDOR_OPTS, "Vendor-specific Information" },
151 { OPTION_INTERFACE_ID, "Interface-Id" },
152 { OPTION_RECONF_MSG, "Reconfigure Message" },
153 { OPTION_RECONF_ACCEPT, "Reconfigure Accept" },
154 { OPTION_SIP_SERVER_D, "SIP Server Domain Name List" },
155 { OPTION_SIP_SERVER_A, "SIP Servers IPv6 Address List" },
156 { OPTION_DNS_SERVERS, "DNS recursive name server" },
157 { OPTION_DOMAIN_LIST, "Domain Search List" },
158 { OPTION_IA_PD, "Identify Association for Prefix Delegation" },
159 { OPTION_IAPREFIX, "IA Prefix" },
160 { OPTION_NIS_SERVERS, "Network Information Server" },
161 { OPTION_NISP_SERVERS, "Network Information Server V2" },
162 { OPTION_NIS_DOMAIN_NAME, "Network Information Server Domain Name" },
163 { OPTION_NISP_DOMAIN_NAME,"Network Information Server V2 Domain Name" },
164 { OPTION_NTP_SERVERS, "Network Time Protocol Server" },
165 { OPTION_TIME_ZONE, "Time zone" },
169 static const value_string statuscode_vals[] =
176 {5, "UseMulticast" },
177 {6, "NoPrefixAvail" },
181 static const value_string duidtype_vals[] =
183 { DUID_LLT, "link-layer address plus time" },
184 { DUID_EN, "assigned by vendor based on Enterprise number" },
185 { DUID_LL, "link-layer address" },
186 { DUID_LL_OLD, "link-layer address (old)" },
190 /* Returns the number of bytes consumed by this option. */
192 dhcpv6_option(tvbuff_t *tvb, proto_tree *bp_tree, int off, int eoff,
197 guint16 temp_optlen = 0;
201 struct e_in6_addr in6;
204 /* option type and length must be present */
205 if (eoff - off < 4) {
210 opttype = tvb_get_ntohs(tvb, off);
211 optlen = tvb_get_ntohs(tvb, off + 2);
214 if (eoff - off < 4 + optlen) {
219 ti = proto_tree_add_text(bp_tree, tvb, off, 4 + optlen,
220 "%s", val_to_str(opttype, opttype_vals, "DHCP option %u"));
222 subtree = proto_item_add_subtree(ti, ett_dhcpv6_option);
223 proto_tree_add_text(subtree, tvb, off, 2, "option type: %d", opttype);
224 proto_tree_add_text(subtree, tvb, off + 2, 2, "option length: %d",
229 case OPTION_CLIENTID:
230 case OPTION_SERVERID:
232 proto_tree_add_text(subtree, tvb, off, optlen,
233 "DUID: malformed option");
236 duidtype = tvb_get_ntohs(tvb, off);
237 proto_tree_add_text(subtree, tvb, off, 2,
238 "DUID type: %s (%u)",
240 duidtype_vals, "Unknown"),
245 proto_tree_add_text(subtree, tvb, off,
246 optlen, "DUID: malformed option");
249 /* XXX seconds since Jan 1 2000 */
250 proto_tree_add_text(subtree, tvb, off + 2, 2,
252 tvb_get_ntohs(tvb, off + 2));
253 proto_tree_add_text(subtree, tvb, off + 4, 4,
254 "Time: %u", tvb_get_ntohl(tvb, off + 4));
256 proto_tree_add_text(subtree, tvb, off + 8,
257 optlen - 8, "Link-layer address");
262 proto_tree_add_text(subtree, tvb, off,
263 optlen, "DUID: malformed option");
266 proto_tree_add_text(subtree, tvb, off + 2, 4,
267 "enterprise-number");
269 proto_tree_add_text(subtree, tvb, off + 6,
270 optlen - 6, "identifier");
276 proto_tree_add_text(subtree, tvb, off,
277 optlen, "DUID: malformed option");
280 proto_tree_add_text(subtree, tvb, off + 2, 2,
282 tvb_get_ntohs(tvb, off + 2));
284 proto_tree_add_text(subtree, tvb, off + 4,
285 optlen - 4, "Link-layer address");
293 if (opttype == OPTION_IA_NA)
294 proto_tree_add_text(subtree, tvb, off,
295 optlen, "IA_NA: malformed option");
297 proto_tree_add_text(subtree, tvb, off,
298 optlen, "IA_PD: malformed option");
301 proto_tree_add_text(subtree, tvb, off, 4,
303 tvb_get_ntohl(tvb, off));
304 proto_tree_add_text(subtree, tvb, off+4, 4,
305 "T1: %u", tvb_get_ntohl(tvb, off+4));
306 proto_tree_add_text(subtree, tvb, off+8, 4,
307 "T2: %u", tvb_get_ntohl(tvb, off+8));
310 while ((optlen - temp_optlen) > 0) {
311 gboolean at_end_ = FALSE;
312 temp_optlen += dhcpv6_option(tvb, subtree, off+temp_optlen, off + optlen, &at_end_);
317 proto_tree_add_text(subtree, tvb, off,
318 optlen, "IA_TA: malformed option");
321 proto_tree_add_text(subtree, tvb, off, 4,
323 tvb_get_ntohl(tvb, off));
325 while ((optlen - temp_optlen) > 0) {
327 temp_optlen += dhcpv6_option(tvb, subtree, off+temp_optlen, off + optlen, &at_end_);
332 guint32 preferred_lifetime, valid_lifetime;
335 proto_tree_add_text(subtree, tvb, off,
336 optlen, "IAADDR: malformed option");
339 tvb_memcpy(tvb, (guint8 *)&in6, off, sizeof(in6));
340 proto_tree_add_text(subtree, tvb, off,
341 sizeof(in6), "IPv6 address: %s",
344 preferred_lifetime = tvb_get_ntohl(tvb, off + 16);
345 valid_lifetime = tvb_get_ntohl(tvb, off + 20);
347 if (preferred_lifetime == DHCPV6_LEASEDURATION_INFINITY) {
348 proto_tree_add_text(subtree, tvb, off + 16, 4,
349 "Preferred lifetime: infinity");
351 proto_tree_add_text(subtree, tvb, off + 16, 4,
352 "Preferred lifetime: %u", preferred_lifetime);
354 if (valid_lifetime == DHCPV6_LEASEDURATION_INFINITY) {
355 proto_tree_add_text(subtree, tvb, off + 20, 4,
356 "Valid lifetime: infinity");
358 proto_tree_add_text(subtree, tvb, off + 20, 4,
359 "Valid lifetime: %u", valid_lifetime);
363 while ((optlen - temp_optlen) > 0) {
365 temp_optlen += dhcpv6_option(tvb, subtree, off+temp_optlen, off + optlen, &at_end_);
370 for (i = 0; i < optlen; i += 2) {
371 guint16 requested_opt_code;
372 requested_opt_code = tvb_get_ntohs(tvb, off + i);
373 proto_tree_add_text(subtree, tvb, off + i,
374 2, "Requested Option code: %s (%d)",
375 val_to_str(requested_opt_code,
381 case OPTION_PREFERENCE:
383 proto_tree_add_text(subtree, tvb, off,
384 optlen, "PREFERENCE: malformed option");
387 proto_tree_add_text(subtree, tvb, off, 1,
389 (guint32)tvb_get_guint8(tvb, off));
391 case OPTION_ELAPSED_TIME:
393 proto_tree_add_text(subtree, tvb, off,
394 optlen, "ELAPSED-TIME: malformed option");
397 proto_tree_add_text(subtree, tvb, off, 2,
398 "elapsed-time: %d sec",
399 (guint32)tvb_get_ntohs(tvb, off));
401 case OPTION_RELAY_MSG:
403 proto_tree_add_text(subtree, tvb, off,
404 optlen, "RELAY-MSG: malformed option");
408 dhcpv6_option(tvb, subtree, off, off + optlen, &at_end_);
413 proto_tree_add_text(subtree, tvb, off,
414 optlen, "AUTH: malformed option");
417 proto_tree_add_text(subtree, tvb, off, 1,
419 (guint32)tvb_get_guint8(tvb, off));
420 proto_tree_add_text(subtree, tvb, off+1, 1,
422 (guint32)tvb_get_guint8(tvb, off+1));
423 proto_tree_add_text(subtree, tvb, off+2, 1,
425 (guint32)tvb_get_guint8(tvb, off+2));
426 proto_tree_add_text(subtree, tvb, off+3, 8,
428 proto_tree_add_text(subtree, tvb, off+11, optlen-11,
429 "Authentication Information");
433 proto_tree_add_text(subtree, tvb, off,
434 optlen, "UNICAST: malformed option");
437 tvb_memcpy(tvb, (guint8 *)&in6, off, sizeof(in6));
438 proto_tree_add_text(subtree, tvb, off,
439 sizeof(in6), "IPv6 address: %s",
442 case OPTION_STATUS_CODE:
445 char *status_message = 0;
446 status_code = tvb_get_ntohs(tvb, off);
447 proto_tree_add_text(subtree, tvb, off, 2,
448 "Status Code: %s (%d)",
449 val_to_str(status_code, statuscode_vals,
453 if (optlen - 2 > 0) {
454 status_message = tvb_get_string(tvb, off + 2, optlen - 2);
455 proto_tree_add_text(subtree, tvb, off + 2, optlen - 2,
456 "Status Message: %s",
458 g_free(status_message);
462 case OPTION_VENDOR_CLASS:
464 proto_tree_add_text(subtree, tvb, off,
465 optlen, "VENDOR_CLASS: malformed option");
468 proto_tree_add_text(subtree, tvb, off, 4,
469 "enterprise-number: %u",
470 tvb_get_ntohl(tvb, off));
472 proto_tree_add_text(subtree, tvb, off+4, optlen-4,
473 "vendor-class-data");
476 case OPTION_VENDOR_OPTS:
478 proto_tree_add_text(subtree, tvb, off,
479 optlen, "VENDOR_OPTS: malformed option");
482 proto_tree_add_text(subtree, tvb, off, 4,
483 "enterprise-number: %u",
484 tvb_get_ntohl(tvb, off));
486 proto_tree_add_text(subtree, tvb, off+4, optlen-4,
490 case OPTION_INTERFACE_ID:
492 proto_tree_add_text(subtree, tvb, off,
493 optlen, "INTERFACE_ID: malformed option");
496 proto_tree_add_text(subtree, tvb, off, optlen, "Interface-ID");
498 case OPTION_RECONF_MSG:
500 proto_tree_add_text(subtree, tvb, off,
501 optlen, "RECONF_MSG: malformed option");
504 proto_tree_add_text(subtree, tvb, off, optlen,
505 "Reconfigure-type: %s",
506 val_to_str(tvb_get_guint8(tvb, off),
510 case OPTION_SIP_SERVER_D:
512 proto_tree_add_text(subtree, tvb, off, optlen,
513 "SIP Servers Domain Search List");
515 case OPTION_SIP_SERVER_A:
517 proto_tree_add_text(subtree, tvb, off, optlen,
518 "SIP servers address: malformed option");
521 for (i = 0; i < optlen; i += 16) {
522 tvb_memcpy(tvb, (guint8 *)&in6, off + i, sizeof(in6));
523 proto_tree_add_text(subtree, tvb, off + i,
524 sizeof(in6), "SIP servers address: %s",
528 case OPTION_DNS_SERVERS:
530 proto_tree_add_text(subtree, tvb, off, optlen,
531 "DNS servers address: malformed option");
534 for (i = 0; i < optlen; i += 16) {
535 tvb_memcpy(tvb, (guint8 *)&in6, off + i, sizeof(in6));
536 proto_tree_add_text(subtree, tvb, off + i,
537 sizeof(in6), "DNS servers address: %s",
541 case OPTION_DOMAIN_LIST:
543 proto_tree_add_text(subtree, tvb, off, optlen, "DNS Domain Search List");
546 case OPTION_NIS_SERVERS:
548 proto_tree_add_text(subtree, tvb, off, optlen,
549 "NIS servers address: malformed option");
552 for (i = 0; i < optlen; i += 16) {
553 tvb_memcpy(tvb, (guint8 *)&in6, off + i, sizeof(in6));
554 proto_tree_add_text(subtree, tvb, off + i,
555 sizeof(in6), "NIS servers address: %s",
559 case OPTION_NISP_SERVERS:
561 proto_tree_add_text(subtree, tvb, off, optlen,
562 "NISP servers address: malformed option");
565 for (i = 0; i < optlen; i += 16) {
566 tvb_memcpy(tvb, (guint8 *)&in6, off + i, sizeof(in6));
567 proto_tree_add_text(subtree, tvb, off + i,
568 sizeof(in6), "NISP servers address: %s",
572 case OPTION_NIS_DOMAIN_NAME:
574 proto_tree_add_text(subtree, tvb, off, optlen, "nis-domain-name");
577 case OPTION_NISP_DOMAIN_NAME:
579 proto_tree_add_text(subtree, tvb, off, optlen, "nisp-domain-name");
582 case OPTION_NTP_SERVERS:
584 proto_tree_add_text(subtree, tvb, off, optlen,
585 "NTP servers address: malformed option");
588 for (i = 0; i < optlen; i += 16) {
589 tvb_memcpy(tvb, (guint8 *)&in6, off + i, sizeof(in6));
590 proto_tree_add_text(subtree, tvb, off + i,
591 sizeof(in6), "NTP servers address: %s",
595 case OPTION_TIME_ZONE:
597 proto_tree_add_text(subtree, tvb, off, optlen, "time-zone");
600 case OPTION_IAPREFIX:
602 guint32 preferred_lifetime, valid_lifetime;
603 guint8 prefix_length;
604 struct e_in6_addr in6;
607 proto_tree_add_text(subtree, tvb, off,
608 optlen, "IAPREFIX: malformed option");
612 preferred_lifetime = tvb_get_ntohl(tvb, off);
613 valid_lifetime = tvb_get_ntohl(tvb, off + 4);
614 prefix_length = tvb_get_guint8(tvb, off + 8);
615 if (preferred_lifetime == DHCPV6_LEASEDURATION_INFINITY) {
616 proto_tree_add_text(subtree, tvb, off, 4,
617 "Preferred lifetime: infinity");
619 proto_tree_add_text(subtree, tvb, off, 4,
620 "Preferred lifetime: %u", preferred_lifetime);
622 if (valid_lifetime == DHCPV6_LEASEDURATION_INFINITY) {
623 proto_tree_add_text(subtree, tvb, off + 4, 4,
624 "Valid lifetime: infinity");
626 proto_tree_add_text(subtree, tvb, off + 4, 4,
627 "Valid lifetime: %u", valid_lifetime);
629 proto_tree_add_text(subtree, tvb, off + 8, 1,
630 "Prefix length: %d", prefix_length);
631 tvb_memcpy(tvb, (guint8 *)&in6, off + 9 , sizeof(in6));
632 proto_tree_add_text(subtree, tvb, off + 9,
633 16, "Prefix address: %s",
637 while ((optlen - temp_optlen) > 0) {
639 temp_optlen += dhcpv6_option(tvb, subtree, off+temp_optlen, off + optlen, &at_end_);
650 dissect_dhcpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
653 proto_tree *bp_tree = NULL;
655 guint8 msgtype, hop_count ;
659 struct e_in6_addr in6;
661 gboolean relay_msg_option = FALSE;
664 eoff = tvb_reported_length(tvb);
665 downstream = 0; /* feature reserved */
666 if (check_col(pinfo->cinfo, COL_PROTOCOL))
667 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DHCPv6");
668 if (check_col(pinfo->cinfo, COL_INFO))
669 col_clear(pinfo->cinfo, COL_INFO);
671 msgtype = tvb_get_guint8(tvb, off);
674 ti = proto_tree_add_item(tree, proto_dhcpv6, tvb, 0, -1, FALSE);
675 bp_tree = proto_item_add_subtree(ti, ett_dhcpv6);
678 while (msgtype == RELAY_FORW || msgtype == RELAY_REPLY) {
680 if (check_col(pinfo->cinfo, COL_INFO)) {
681 col_set_str(pinfo->cinfo, COL_INFO,
687 proto_tree_add_uint(bp_tree, hf_dhcpv6_msgtype, tvb, off, 1, msgtype);
689 hop_count = tvb_get_guint8(tvb, off+1);
690 proto_tree_add_text(bp_tree, tvb, off+1, 1, "Hop count: %d", hop_count);
692 tvb_memcpy(tvb, (guint8 *)&in6, off+2, sizeof(in6));
693 proto_tree_add_text(bp_tree, tvb, off+2, sizeof(in6),
694 "Link-address: %s",ip6_to_str(&in6));
696 tvb_memcpy(tvb, (guint8 *)&in6, off+18, sizeof(in6));
697 proto_tree_add_text(bp_tree, tvb, off+18, sizeof(in6),
698 "Peer-address: %s",ip6_to_str(&in6));
701 relay_msg_option = FALSE;
703 while (!relay_msg_option && off < eoff) {
704 length = dhcpv6_option(tvb, bp_tree, off, eoff, &at_end);
706 if (tvb_get_ntohs(tvb, off) == OPTION_RELAY_MSG) {
707 relay_msg_option = TRUE;
714 proto_tree_add_text(bp_tree, tvb, off, eoff, "Message: malformed");
720 msgtype = tvb_get_guint8(tvb, off);
723 xid = tvb_get_ntohl(tvb, off) & 0x00ffffff;
726 if (check_col(pinfo->cinfo, COL_INFO)) {
727 col_set_str(pinfo->cinfo, COL_INFO,
735 proto_tree_add_uint(bp_tree, hf_dhcpv6_msgtype, tvb, off, 1,
737 proto_tree_add_text(bp_tree, tvb, off+1, 3, "Transaction-ID: 0x%08x", xid);
739 tvb_memcpy(tvb, (guint8 *)&in6, 4, sizeof(in6));
740 proto_tree_add_text(bp_tree, tvb, 4, sizeof(in6),
741 "Server address: %s", ip6_to_str(&in6));
748 while (off < eoff && !at_end)
749 off += dhcpv6_option(tvb, bp_tree, off, eoff, &at_end);
753 dissect_dhcpv6_downstream(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
755 dissect_dhcpv6(tvb, pinfo, tree, TRUE);
759 dissect_dhcpv6_upstream(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
761 dissect_dhcpv6(tvb, pinfo, tree, FALSE);
766 proto_register_dhcpv6(void)
768 static hf_register_info hf[] = {
769 { &hf_dhcpv6_msgtype,
770 { "Message type", "dhcpv6.msgtype", FT_UINT8,
771 BASE_DEC, VALS(msgtype_vals), 0x0,
774 static gint *ett[] = {
779 proto_dhcpv6 = proto_register_protocol("DHCPv6", "DHCPv6", "dhcpv6");
780 proto_register_field_array(proto_dhcpv6, hf, array_length(hf));
781 proto_register_subtree_array(ett, array_length(ett));
785 proto_reg_handoff_dhcpv6(void)
787 dissector_handle_t dhcpv6_handle;
789 dhcpv6_handle = create_dissector_handle(dissect_dhcpv6_downstream,
791 dissector_add("udp.port", UDP_PORT_DHCPV6_DOWNSTREAM, dhcpv6_handle);
792 dhcpv6_handle = create_dissector_handle(dissect_dhcpv6_upstream,
794 dissector_add("udp.port", UDP_PORT_DHCPV6_UPSTREAM, dhcpv6_handle);