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>
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/packet.h>
46 #include <epan/ipv6-utils.h>
48 static int proto_dhcpv6 = -1;
49 static int hf_dhcpv6_msgtype = -1;
51 static gint ett_dhcpv6 = -1;
52 static gint ett_dhcpv6_option = -1;
54 #define UDP_PORT_DHCPV6_DOWNSTREAM 546
55 #define UDP_PORT_DHCPV6_UPSTREAM 547
57 #define DHCPV6_LEASEDURATION_INFINITY 0xffffffff
68 #define RECONFIGURE 10
69 #define INFORMATION_REQUEST 11
71 #define RELAY_REPLY 13
73 #define OPTION_CLIENTID 1
74 #define OPTION_SERVERID 2
75 #define OPTION_IA_NA 3
76 #define OPTION_IA_TA 4
77 #define OPTION_IAADDR 5
79 #define OPTION_PREFERENCE 7
80 #define OPTION_ELAPSED_TIME 8
81 #define OPTION_RELAY_MSG 9
82 /* #define OPTION_SERVER_MSG 10 */
83 #define OPTION_AUTH 11
84 #define OPTION_UNICAST 12
85 #define OPTION_STATUS_CODE 13
86 #define OPTION_RAPID_COMMIT 14
87 #define OPTION_USER_CLASS 15
88 #define OPTION_VENDOR_CLASS 16
89 #define OPTION_VENDOR_OPTS 17
90 #define OPTION_INTERFACE_ID 18
91 #define OPTION_RECONF_MSG 19
92 #define OPTION_RECONF_ACCEPT 20
93 #define OPTION_SIP_SERVER_D 21
94 #define OPTION_SIP_SERVER_A 22
95 #define OPTION_DNS_SERVERS 23
96 #define OPTION_DOMAIN_LIST 24
97 #define OPTION_IA_PD 25
98 #define OPTION_IAPREFIX 26
101 * The followings are unassigned numbers.
103 #define OPTION_NIS_SERVERS 35
104 #define OPTION_NISP_SERVERS 36
105 #define OPTION_NIS_DOMAIN_NAME 37
106 #define OPTION_NISP_DOMAIN_NAME 38
107 #define OPTION_NTP_SERVERS 40
108 #define OPTION_TIME_ZONE 41
113 #define DUID_LL_OLD 4
115 static const value_string msgtype_vals[] = {
116 { SOLICIT, "Solicit" },
117 { ADVERTISE, "Advertise" },
118 { REQUEST, "Request" },
119 { CONFIRM, "Confirm" },
121 { REBIND, "Rebind" },
123 { RELEASE, "Release" },
124 { DECLINE, "Decline" },
125 { RECONFIGURE, "Reconfigure" },
126 { INFORMATION_REQUEST, "Information-request" },
127 { RELAY_FORW, "Relay-forw" },
128 { RELAY_REPLY, "Relay-reply" },
132 static const value_string opttype_vals[] = {
133 { OPTION_CLIENTID, "Client Identifier" },
134 { OPTION_SERVERID, "Server Identifier" },
135 { OPTION_IA_NA, "Identify Association" },
136 { OPTION_IA_TA, "Identify Association for Temporary Address" },
137 { OPTION_IAADDR, "IA Address" },
138 { OPTION_ORO, "Option Request" },
139 { OPTION_PREFERENCE, "Preference" },
140 { OPTION_ELAPSED_TIME, "Elapsed time" },
141 { OPTION_RELAY_MSG, "Relay Message" },
142 /* { OPTION_SERVER_MSG, "Server message" }, */
143 { OPTION_AUTH, "Authentication" },
144 { OPTION_UNICAST, "Server unicast" },
145 { OPTION_STATUS_CODE, "Status code" },
146 { OPTION_RAPID_COMMIT, "Rapid Commit" },
147 { OPTION_USER_CLASS, "User Class" },
148 { OPTION_VENDOR_CLASS, "Vendor Class" },
149 { OPTION_VENDOR_OPTS, "Vendor-specific Information" },
150 { OPTION_INTERFACE_ID, "Interface-Id" },
151 { OPTION_RECONF_MSG, "Reconfigure Message" },
152 { OPTION_RECONF_ACCEPT, "Reconfigure Accept" },
153 { OPTION_SIP_SERVER_D, "SIP Server Domain Name List" },
154 { OPTION_SIP_SERVER_A, "SIP Servers IPv6 Address List" },
155 { OPTION_DNS_SERVERS, "DNS recursive name server" },
156 { OPTION_DOMAIN_LIST, "Domain Search List" },
157 { OPTION_IA_PD, "Identify Association for Prefix Delegation" },
158 { OPTION_IAPREFIX, "IA Prefix" },
159 { OPTION_NIS_SERVERS, "Network Information Server" },
160 { OPTION_NISP_SERVERS, "Network Information Server V2" },
161 { OPTION_NIS_DOMAIN_NAME, "Network Information Server Domain Name" },
162 { OPTION_NISP_DOMAIN_NAME,"Network Information Server V2 Domain Name" },
163 { OPTION_NTP_SERVERS, "Network Time Protocol Server" },
164 { OPTION_TIME_ZONE, "Time zone" },
168 static const value_string statuscode_vals[] =
175 {5, "UseMulticast" },
176 {6, "NoPrefixAvail" },
180 static const value_string duidtype_vals[] =
182 { DUID_LLT, "link-layer address plus time" },
183 { DUID_EN, "assigned by vendor based on Enterprise number" },
184 { DUID_LL, "link-layer address" },
185 { DUID_LL_OLD, "link-layer address (old)" },
189 /* Returns the number of bytes consumed by this option. */
191 dhcpv6_option(tvbuff_t *tvb, proto_tree *bp_tree, int off, int eoff,
196 guint16 temp_optlen = 0;
200 struct e_in6_addr in6;
203 /* option type and length must be present */
204 if (eoff - off < 4) {
209 opttype = tvb_get_ntohs(tvb, off);
210 optlen = tvb_get_ntohs(tvb, off + 2);
212 /* all option data must be present */
213 if (eoff - off < 4 + optlen) {
218 ti = proto_tree_add_text(bp_tree, tvb, off, 4 + optlen,
219 "%s", val_to_str(opttype, opttype_vals, "DHCP option %u"));
221 subtree = proto_item_add_subtree(ti, ett_dhcpv6_option);
222 proto_tree_add_text(subtree, tvb, off, 2, "option type: %d", opttype);
223 proto_tree_add_text(subtree, tvb, off + 2, 2, "option length: %d",
228 case OPTION_CLIENTID:
229 case OPTION_SERVERID:
231 proto_tree_add_text(subtree, tvb, off, optlen,
232 "DUID: malformed option");
235 duidtype = tvb_get_ntohs(tvb, off);
236 proto_tree_add_text(subtree, tvb, off, 2,
237 "DUID type: %s (%u)",
239 duidtype_vals, "Unknown"),
244 proto_tree_add_text(subtree, tvb, off,
245 optlen, "DUID: malformed option");
248 /* XXX seconds since Jan 1 2000 */
249 proto_tree_add_text(subtree, tvb, off + 2, 2,
251 tvb_get_ntohs(tvb, off + 2));
252 proto_tree_add_text(subtree, tvb, off + 4, 4,
253 "Time: %u", tvb_get_ntohl(tvb, off + 4));
255 proto_tree_add_text(subtree, tvb, off + 8,
256 optlen - 8, "Link-layer address");
261 proto_tree_add_text(subtree, tvb, off,
262 optlen, "DUID: malformed option");
265 proto_tree_add_text(subtree, tvb, off + 2, 4,
266 "enterprise-number");
268 proto_tree_add_text(subtree, tvb, off + 6,
269 optlen - 6, "identifier");
275 proto_tree_add_text(subtree, tvb, off,
276 optlen, "DUID: malformed option");
279 proto_tree_add_text(subtree, tvb, off + 2, 2,
281 tvb_get_ntohs(tvb, off + 2));
283 proto_tree_add_text(subtree, tvb, off + 4,
284 optlen - 4, "Link-layer address");
292 if (opttype == OPTION_IA_NA)
293 proto_tree_add_text(subtree, tvb, off,
294 optlen, "IA_NA: malformed option");
296 proto_tree_add_text(subtree, tvb, off,
297 optlen, "IA_PD: malformed option");
300 proto_tree_add_text(subtree, tvb, off, 4,
302 tvb_get_ntohl(tvb, off));
303 proto_tree_add_text(subtree, tvb, off+4, 4,
304 "T1: %u", tvb_get_ntohl(tvb, off+4));
305 proto_tree_add_text(subtree, tvb, off+8, 4,
306 "T2: %u", tvb_get_ntohl(tvb, off+8));
309 while ((optlen - temp_optlen) > 0) {
310 temp_optlen += dhcpv6_option(tvb, subtree, off+temp_optlen,
311 off + optlen, at_end);
313 /* Bad option - just skip to the end */
314 temp_optlen = optlen;
320 proto_tree_add_text(subtree, tvb, off,
321 optlen, "IA_TA: malformed option");
324 proto_tree_add_text(subtree, tvb, off, 4,
326 tvb_get_ntohl(tvb, off));
328 while ((optlen - temp_optlen) > 0) {
329 temp_optlen += dhcpv6_option(tvb, subtree, off+temp_optlen,
330 off + optlen, at_end);
332 /* Bad option - just skip to the end */
333 temp_optlen = optlen;
339 guint32 preferred_lifetime, valid_lifetime;
342 proto_tree_add_text(subtree, tvb, off,
343 optlen, "IAADDR: malformed option");
346 tvb_memcpy(tvb, (guint8 *)&in6, off, sizeof(in6));
347 proto_tree_add_text(subtree, tvb, off,
348 sizeof(in6), "IPv6 address: %s",
351 preferred_lifetime = tvb_get_ntohl(tvb, off + 16);
352 valid_lifetime = tvb_get_ntohl(tvb, off + 20);
354 if (preferred_lifetime == DHCPV6_LEASEDURATION_INFINITY) {
355 proto_tree_add_text(subtree, tvb, off + 16, 4,
356 "Preferred lifetime: infinity");
358 proto_tree_add_text(subtree, tvb, off + 16, 4,
359 "Preferred lifetime: %u", preferred_lifetime);
361 if (valid_lifetime == DHCPV6_LEASEDURATION_INFINITY) {
362 proto_tree_add_text(subtree, tvb, off + 20, 4,
363 "Valid lifetime: infinity");
365 proto_tree_add_text(subtree, tvb, off + 20, 4,
366 "Valid lifetime: %u", valid_lifetime);
370 while ((optlen - temp_optlen) > 0) {
371 temp_optlen += dhcpv6_option(tvb, subtree, off+temp_optlen,
372 off + optlen, at_end);
374 /* Bad option - just skip to the end */
375 temp_optlen = optlen;
381 for (i = 0; i < optlen; i += 2) {
382 guint16 requested_opt_code;
383 requested_opt_code = tvb_get_ntohs(tvb, off + i);
384 proto_tree_add_text(subtree, tvb, off + i,
385 2, "Requested Option code: %s (%d)",
386 val_to_str(requested_opt_code,
392 case OPTION_PREFERENCE:
394 proto_tree_add_text(subtree, tvb, off,
395 optlen, "PREFERENCE: malformed option");
398 proto_tree_add_text(subtree, tvb, off, 1,
400 (guint32)tvb_get_guint8(tvb, off));
402 case OPTION_ELAPSED_TIME:
404 proto_tree_add_text(subtree, tvb, off,
405 optlen, "ELAPSED-TIME: malformed option");
408 proto_tree_add_text(subtree, tvb, off, 2,
409 "elapsed-time: %d sec",
410 (guint32)tvb_get_ntohs(tvb, off));
412 case OPTION_RELAY_MSG:
414 proto_tree_add_text(subtree, tvb, off,
415 optlen, "RELAY-MSG: malformed option");
418 /* XXX - shouldn't we be dissecting a full DHCP message
420 dhcpv6_option(tvb, subtree, off, off + optlen, at_end);
427 proto_tree_add_text(subtree, tvb, off,
428 optlen, "AUTH: malformed option");
431 proto_tree_add_text(subtree, tvb, off, 1,
433 (guint32)tvb_get_guint8(tvb, off));
434 proto_tree_add_text(subtree, tvb, off+1, 1,
436 (guint32)tvb_get_guint8(tvb, off+1));
437 proto_tree_add_text(subtree, tvb, off+2, 1,
439 (guint32)tvb_get_guint8(tvb, off+2));
440 proto_tree_add_text(subtree, tvb, off+3, 8,
443 proto_tree_add_text(subtree, tvb, off+11, optlen-11,
444 "Authentication Information");
448 proto_tree_add_text(subtree, tvb, off,
449 optlen, "UNICAST: malformed option");
452 tvb_memcpy(tvb, (guint8 *)&in6, off, sizeof(in6));
453 proto_tree_add_text(subtree, tvb, off,
454 sizeof(in6), "IPv6 address: %s",
457 case OPTION_STATUS_CODE:
460 char *status_message = 0;
461 status_code = tvb_get_ntohs(tvb, off);
462 proto_tree_add_text(subtree, tvb, off, 2,
463 "Status Code: %s (%d)",
464 val_to_str(status_code, statuscode_vals,
468 if (optlen - 2 > 0) {
469 status_message = tvb_get_string(tvb, off + 2, optlen - 2);
470 proto_tree_add_text(subtree, tvb, off + 2, optlen - 2,
471 "Status Message: %s",
473 g_free(status_message);
477 case OPTION_VENDOR_CLASS:
479 proto_tree_add_text(subtree, tvb, off,
480 optlen, "VENDOR_CLASS: malformed option");
483 proto_tree_add_text(subtree, tvb, off, 4,
484 "enterprise-number: %u",
485 tvb_get_ntohl(tvb, off));
487 proto_tree_add_text(subtree, tvb, off+4, optlen-4,
488 "vendor-class-data");
491 case OPTION_VENDOR_OPTS:
493 proto_tree_add_text(subtree, tvb, off,
494 optlen, "VENDOR_OPTS: malformed option");
497 proto_tree_add_text(subtree, tvb, off, 4,
498 "enterprise-number: %u",
499 tvb_get_ntohl(tvb, off));
501 proto_tree_add_text(subtree, tvb, off+4, optlen-4,
505 case OPTION_INTERFACE_ID:
507 proto_tree_add_text(subtree, tvb, off,
508 optlen, "INTERFACE_ID: malformed option");
511 proto_tree_add_text(subtree, tvb, off, optlen, "Interface-ID");
513 case OPTION_RECONF_MSG:
515 proto_tree_add_text(subtree, tvb, off,
516 optlen, "RECONF_MSG: malformed option");
519 proto_tree_add_text(subtree, tvb, off, optlen,
520 "Reconfigure-type: %s",
521 val_to_str(tvb_get_guint8(tvb, off),
525 case OPTION_SIP_SERVER_D:
527 proto_tree_add_text(subtree, tvb, off, optlen,
528 "SIP Servers Domain Search List");
530 case OPTION_SIP_SERVER_A:
532 proto_tree_add_text(subtree, tvb, off, optlen,
533 "SIP servers address: malformed option");
536 for (i = 0; i < optlen; i += 16) {
537 tvb_memcpy(tvb, (guint8 *)&in6, off + i, sizeof(in6));
538 proto_tree_add_text(subtree, tvb, off + i,
539 sizeof(in6), "SIP servers address: %s",
543 case OPTION_DNS_SERVERS:
545 proto_tree_add_text(subtree, tvb, off, optlen,
546 "DNS servers address: malformed option");
549 for (i = 0; i < optlen; i += 16) {
550 tvb_memcpy(tvb, (guint8 *)&in6, off + i, sizeof(in6));
551 proto_tree_add_text(subtree, tvb, off + i,
552 sizeof(in6), "DNS servers address: %s",
556 case OPTION_DOMAIN_LIST:
558 proto_tree_add_text(subtree, tvb, off, optlen, "DNS Domain Search List");
561 case OPTION_NIS_SERVERS:
563 proto_tree_add_text(subtree, tvb, off, optlen,
564 "NIS servers address: malformed option");
567 for (i = 0; i < optlen; i += 16) {
568 tvb_memcpy(tvb, (guint8 *)&in6, off + i, sizeof(in6));
569 proto_tree_add_text(subtree, tvb, off + i,
570 sizeof(in6), "NIS servers address: %s",
574 case OPTION_NISP_SERVERS:
576 proto_tree_add_text(subtree, tvb, off, optlen,
577 "NISP servers address: malformed option");
580 for (i = 0; i < optlen; i += 16) {
581 tvb_memcpy(tvb, (guint8 *)&in6, off + i, sizeof(in6));
582 proto_tree_add_text(subtree, tvb, off + i,
583 sizeof(in6), "NISP servers address: %s",
587 case OPTION_NIS_DOMAIN_NAME:
589 proto_tree_add_text(subtree, tvb, off, optlen, "nis-domain-name");
592 case OPTION_NISP_DOMAIN_NAME:
594 proto_tree_add_text(subtree, tvb, off, optlen, "nisp-domain-name");
597 case OPTION_NTP_SERVERS:
599 proto_tree_add_text(subtree, tvb, off, optlen,
600 "NTP servers address: malformed option");
603 for (i = 0; i < optlen; i += 16) {
604 tvb_memcpy(tvb, (guint8 *)&in6, off + i, sizeof(in6));
605 proto_tree_add_text(subtree, tvb, off + i,
606 sizeof(in6), "NTP servers address: %s",
610 case OPTION_TIME_ZONE:
612 proto_tree_add_text(subtree, tvb, off, optlen, "time-zone");
615 case OPTION_IAPREFIX:
617 guint32 preferred_lifetime, valid_lifetime;
618 guint8 prefix_length;
619 struct e_in6_addr in6;
622 proto_tree_add_text(subtree, tvb, off,
623 optlen, "IAPREFIX: malformed option");
627 preferred_lifetime = tvb_get_ntohl(tvb, off);
628 valid_lifetime = tvb_get_ntohl(tvb, off + 4);
629 prefix_length = tvb_get_guint8(tvb, off + 8);
630 if (preferred_lifetime == DHCPV6_LEASEDURATION_INFINITY) {
631 proto_tree_add_text(subtree, tvb, off, 4,
632 "Preferred lifetime: infinity");
634 proto_tree_add_text(subtree, tvb, off, 4,
635 "Preferred lifetime: %u", preferred_lifetime);
637 if (valid_lifetime == DHCPV6_LEASEDURATION_INFINITY) {
638 proto_tree_add_text(subtree, tvb, off + 4, 4,
639 "Valid lifetime: infinity");
641 proto_tree_add_text(subtree, tvb, off + 4, 4,
642 "Valid lifetime: %u", valid_lifetime);
644 proto_tree_add_text(subtree, tvb, off + 8, 1,
645 "Prefix length: %d", prefix_length);
646 tvb_memcpy(tvb, (guint8 *)&in6, off + 9 , sizeof(in6));
647 proto_tree_add_text(subtree, tvb, off + 9,
648 16, "Prefix address: %s",
652 while ((optlen - temp_optlen) > 0) {
653 temp_optlen += dhcpv6_option(tvb, subtree, off+temp_optlen,
654 off + optlen, at_end);
656 /* Bad option - just skip to the end */
657 temp_optlen = optlen;
669 dissect_dhcpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
672 proto_tree *bp_tree = NULL;
674 guint8 msgtype, hop_count ;
678 struct e_in6_addr in6;
680 gboolean relay_msg_option = FALSE;
683 eoff = tvb_reported_length(tvb);
684 downstream = 0; /* feature reserved */
685 if (check_col(pinfo->cinfo, COL_PROTOCOL))
686 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DHCPv6");
687 if (check_col(pinfo->cinfo, COL_INFO))
688 col_clear(pinfo->cinfo, COL_INFO);
690 msgtype = tvb_get_guint8(tvb, off);
693 ti = proto_tree_add_item(tree, proto_dhcpv6, tvb, 0, -1, FALSE);
694 bp_tree = proto_item_add_subtree(ti, ett_dhcpv6);
697 while (msgtype == RELAY_FORW || msgtype == RELAY_REPLY) {
699 if (check_col(pinfo->cinfo, COL_INFO)) {
700 col_set_str(pinfo->cinfo, COL_INFO,
706 proto_tree_add_uint(bp_tree, hf_dhcpv6_msgtype, tvb, off, 1, msgtype);
708 hop_count = tvb_get_guint8(tvb, off+1);
709 proto_tree_add_text(bp_tree, tvb, off+1, 1, "Hop count: %d", hop_count);
711 tvb_memcpy(tvb, (guint8 *)&in6, off+2, sizeof(in6));
712 proto_tree_add_text(bp_tree, tvb, off+2, sizeof(in6),
713 "Link-address: %s",ip6_to_str(&in6));
715 tvb_memcpy(tvb, (guint8 *)&in6, off+18, sizeof(in6));
716 proto_tree_add_text(bp_tree, tvb, off+18, sizeof(in6),
717 "Peer-address: %s",ip6_to_str(&in6));
720 relay_msg_option = FALSE;
722 while (!relay_msg_option && off < eoff) {
723 length = dhcpv6_option(tvb, bp_tree, off, eoff, &at_end);
727 if (tvb_get_ntohs(tvb, off) == OPTION_RELAY_MSG) {
728 relay_msg_option = TRUE;
735 proto_tree_add_text(bp_tree, tvb, off, eoff, "Message: malformed");
741 msgtype = tvb_get_guint8(tvb, off);
744 xid = tvb_get_ntohl(tvb, off) & 0x00ffffff;
747 if (check_col(pinfo->cinfo, COL_INFO)) {
748 col_set_str(pinfo->cinfo, COL_INFO,
756 proto_tree_add_uint(bp_tree, hf_dhcpv6_msgtype, tvb, off, 1,
758 proto_tree_add_text(bp_tree, tvb, off+1, 3, "Transaction-ID: 0x%08x", xid);
760 tvb_memcpy(tvb, (guint8 *)&in6, 4, sizeof(in6));
761 proto_tree_add_text(bp_tree, tvb, 4, sizeof(in6),
762 "Server address: %s", ip6_to_str(&in6));
769 while (off < eoff && !at_end)
770 off += dhcpv6_option(tvb, bp_tree, off, eoff, &at_end);
774 dissect_dhcpv6_downstream(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
776 dissect_dhcpv6(tvb, pinfo, tree, TRUE);
780 dissect_dhcpv6_upstream(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
782 dissect_dhcpv6(tvb, pinfo, tree, FALSE);
787 proto_register_dhcpv6(void)
789 static hf_register_info hf[] = {
790 { &hf_dhcpv6_msgtype,
791 { "Message type", "dhcpv6.msgtype", FT_UINT8,
792 BASE_DEC, VALS(msgtype_vals), 0x0,
795 static gint *ett[] = {
800 proto_dhcpv6 = proto_register_protocol("DHCPv6", "DHCPv6", "dhcpv6");
801 proto_register_field_array(proto_dhcpv6, hf, array_length(hf));
802 proto_register_subtree_array(ett, array_length(ett));
806 proto_reg_handoff_dhcpv6(void)
808 dissector_handle_t dhcpv6_handle;
810 dhcpv6_handle = create_dissector_handle(dissect_dhcpv6_downstream,
812 dissector_add("udp.port", UDP_PORT_DHCPV6_DOWNSTREAM, dhcpv6_handle);
813 dhcpv6_handle = create_dissector_handle(dissect_dhcpv6_upstream,
815 dissector_add("udp.port", UDP_PORT_DHCPV6_UPSTREAM, dhcpv6_handle);