Don't do fcn calls in arg of g_?to??(); Macro may very well eval args multiple times.
[obnox/wireshark/wip.git] / epan / dissectors / packet-mip6.c
1 /* packet-mip6.c
2  *
3  * $Id$
4  *
5  * Definitions and Routines for Mobile IPv6 dissection (RFC 3775)
6  * Copyright 2003 Oy L M Ericsson Ab <teemu.rinta-aho@ericsson.fi>
7  *
8  * FMIPv6 (RFC 4068) support added by Martin Andre <andre@clarinet.u-strasbg.fr>
9  * Copyright 2006, Nicolas DICHTEL - 6WIND - <nicolas.dichtel@6wind.com>
10  *
11  * Modifications for NEMO packets (RFC 3963): Bruno Deniaud
12  * (bdeniaud@irisa.fr, nono@chez.com) 12 Oct 2005
13  *
14  * Wireshark - Network traffic analyzer
15  * By Gerald Combs <gerald@wireshark.org>
16  * Copyright 1998 Gerald Combs
17  *
18  * This program is free software; you can redistribute it and/or
19  * modify it under the terms of the GNU General Public License
20  * as published by the Free Software Foundation; either version 2
21  * of the License, or (at your option) any later version.
22  *
23  * This program is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  * GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with this program; if not, write to the Free Software
30  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31  */
32
33 #ifdef HAVE_CONFIG_H
34 #include "config.h"
35 #endif
36
37 #include <epan/packet.h>
38
39 #include <epan/ipproto.h>
40 #include <epan/ip_opts.h>
41 #include <epan/expert.h>
42 #include <epan/sminmpec.h>
43
44 /* Mobility Header types */
45 typedef enum {
46     MIP6_BRR    =  0,
47     MIP6_HOTI   =  1,
48     MIP6_MHCOTI =  2,
49     MIP6_HOT    =  3,
50     MIP6_MHCOT  =  4,
51     MIP6_BU     =  5,
52     MIP6_BA     =  6,
53     MIP6_BE     =  7,
54     MIP6_FBU    =  8,
55     MIP6_FBACK  =  9,
56     MIP6_FNA    = 10,
57     MIP6_EMH    = 11,
58     MIP6_HAS    = 12,
59     MIP6_HB     = 13,
60     MIP6_HI     = 14,
61     MIP6_HAck   = 15,
62     MIP6_BR     = 16
63 } mhTypes;
64
65 /* http://www.iana.org/assignments/mobility-parameters/mobility-parameters.xhtml */
66 static const value_string mip6_mh_types[] = {
67     {MIP6_BRR,    "Binding Refresh Request"},           /* [RFC3775] */
68     {MIP6_HOTI,   "Home Test Init"},                    /* [RFC3775] */
69     {MIP6_MHCOTI, "Care-of Test Init"},                 /* [RFC3775] */
70     {MIP6_HOT,    "Home Test"},                         /* [RFC3775] */
71     {MIP6_MHCOT,  "Care-of Test"},                      /* [RFC3775] */
72     {MIP6_BU,     "Binding Update"},                    /* [RFC3775] */
73     {MIP6_BA,     "Binding Acknowledgement"},           /* [RFC3775] */
74     {MIP6_BE,     "Binding Error"},                     /* [RFC3775] */
75     {MIP6_FBU,    "Fast Binding Update"},               /* [RFC5568] */
76     {MIP6_FBACK,  "Fast Binding Acknowledgment"},       /* [RFC5568] */
77     {MIP6_FNA,    "Fast Neighbor Advertisement"},       /* [RFC5568] */
78     {MIP6_EMH,    "Experimental Mobility Header"},      /* [RFC5096] */
79     {MIP6_HAS,    "Home Agent Switch"},                 /* [RFC5142] */
80     {MIP6_HB,     "Heartbeat"},                         /* [RFC5847] */
81     {MIP6_HI,     "Handover Initiate"},                 /* [RFC5568] */
82     {MIP6_HAck,   "Handover Acknowledge"},              /* [RFC5568] */
83     {MIP6_BR,     "Binding Revocation"},                /* [RFC5846] */
84     {0,      NULL}
85 };
86
87
88 /* Mobility Option types
89  * http://www.iana.org/assignments/mobility-parameters/mobility-parameters.xhtml
90  */
91 typedef enum {
92     MIP6_PAD1      =  0,        /*  0 Pad1 [RFC3775] */
93     MIP6_PADN      =  1,        /*  1 PadN [RFC3775] */
94     MIP6_BRA       =  2,        /*  2 Binding Refresh Advice */
95     MIP6_ACOA      =  3,        /*  3 Alternate Care-of Address */
96     MIP6_NI        =  4,        /*  4 Nonce Indices */
97     MIP6_AUTD      =  5,        /*  5 Authorization Data */
98     MIP6_MNP       =  6,        /*  6 Mobile Network Prefix Option */
99     MIP6_MHLLA     =  7,        /*  7 Mobility Header Link-Layer Address option [RFC5568] */
100     MIP6_MNID      =  8,        /*  8 MN-ID-OPTION-TYPE */
101     MIP6_AUTH      =  9,        /*  9 AUTH-OPTION-TYPE */
102     MIP6_MESGID    = 10,        /* 10 MESG-ID-OPTION-TYPE [RFC4285]  */
103     MIP6_CGAPR     = 11,        /* 11 CGA Parameters Request [RFC4866]  */
104     MIP6_CGAR      = 12,        /* 12 CGA Parameters [RFC4866]  */
105     MIP6_SIGN      = 13,        /* 13 Signature [RFC4866]  */
106     MIP6_PHKT      = 14,        /* 14 Permanent Home Keygen Token [RFC4866]  */
107     MIP6_MOCOTI    = 15,        /* 15 Care-of Test Init [RFC4866]  */
108     MIP6_MOCOT     = 16,        /* 16 Care-of Test [RFC4866]  */
109     MIP6_DNSU      = 17,        /* 17 DNS-UPDATE-TYPE [RFC5026]  */
110     MIP6_EM        = 18,        /* 18 Experimental Mobility Option [RFC5096]  */
111     MIP6_VSM       = 19,        /* 19 Vendor Specific Mobility Option [RFC5094]  */
112     MIP6_SSM       = 20,        /* 20 Service Selection Mobility Option [RFC5149]  */
113     MIP6_BADFF     = 21,        /* 21 Binding Authorization Data for FMIPv6 (BADF) [RFC5568]  */
114     MIP6_HNP       = 22,        /* 22 Home Network Prefix Option [RFC5213]   */
115     MIP6_MOHI      = 23,        /* 23 Handoff Indicator Option [RFC5213]   */
116     MIP6_ATT       = 24,        /* 24 Access Technology Type Option [RFC5213]  */
117     MIP6_MNLLI     = 25,        /* 25 Mobile Node Link-layer Identifier Option [RFC5213]  */
118     MIP6_LLA       = 26,        /* 26 Link-local Address Option [RFC5213   */
119     MIP6_TS        = 27,        /* 27 Timestamp */
120     MIP6_RC        = 28,        /* 28 Restart Counter [RFC5847] */
121     MIP6_IPV4HA    = 29,        /* 29 IPv4 Home Address [RFC5555]  */
122     MIP6_IPV4AA    = 30,        /* 30 IPv4 Address Acknowledgement [RFC5555] */
123     MIP6_NATD      = 31,        /* 31 NAT Detection [RFC5555]  */
124     MIP6_IPV4COA   = 32,        /* 32 IPv4 Care-of Address [RFC5555]  */
125     MIP6_GREK      = 33,        /* 33 GRE Key Option [RFC5845]  */
126     MIP6_MHIPV6AP  = 34,        /* 34 Mobility Header IPv6 Address/Prefix [RFC5568]  */
127     MIP6_BI        = 35,        /* 35 Binding Identifier [RFC5648]  */
128     MIP6_IPV4HAREQ = 36,        /* 36 IPv4 Home Address Request [RFC5844] */
129     MIP6_IPV4HAREP = 37,        /* 37 IPv4 Home Address Reply [RFC5844] */
130     MIP6_IPV4DRA   = 38,        /* 38 IPv4 Default-Router Address [RFC5844] */
131     MIP6_IPV4DSM   = 39,        /* 39 IPv4 DHCP Support Mode [RFC5844] */
132     MIP6_CR        = 40,        /* 40 Context Request Option [RFC5949] */
133     MIP6_LMAA      = 41,        /* 41 Local Mobility Anchor Address Option [RFC5949] */
134     MIP6_MNLLAII   = 42,        /* 42 Mobile Node Link-local Address Interface Identifier Option [RFC5949] */
135     MIP6_TB        = 43,        /* 43 Transient Binding [RFC-ietf-mipshop-transient-bce-pmipv6-07] */
136     MIP6_FS        = 44,        /* 44 Flow Summary Mobility Option [RFC-ietf-mext-flow-binding-11] */
137     MIP6_FI        = 45         /* 45 Flow Identification Mobility Option [RFC-ietf-mext-flow-binding-11]] */
138
139 } optTypes;
140
141 /* Binding Update flag description */
142 static const true_false_string mip6_bu_a_flag_value = {
143     "Binding Acknowledgement requested",
144     "Binding Acknowledgement not requested"
145 };
146
147 static const true_false_string mip6_bu_h_flag_value = {
148     "Home Registration",
149     "No Home Registration"
150 };
151
152 static const true_false_string mip6_bu_l_flag_value = {
153     "Link-Local Address Compatibility",
154     "No Link-Local Address Compatibility"
155 };
156
157 static const true_false_string mip6_bu_k_flag_value = {
158     "Key Management Mobility Compatibility",
159     "No Key Management Mobility Compatibility"
160 };
161
162 static const true_false_string mip6_bu_m_flag_value = {
163     "MAP Registration Compatibility",
164     "No MAP Registration Compatibility",
165 };
166
167 static const true_false_string mip6_nemo_bu_r_flag_value = {
168     "Mobile Router Compatibility",
169     "No Mobile Router Compatibility"
170 };
171
172 static const true_false_string pmip6_bu_p_flag_value = {
173     "Proxy Registration",
174     "No Proxy Registration"
175 };
176
177 static const true_false_string mip6_bu_f_flag_value = {
178     "Forcing UDP encapsulation used",
179     "No Forcing UDP encapsulation"
180 };
181
182 static const true_false_string pmip6_bu_t_flag_value = {
183     "TLV-header format used",
184     "No TLV-header format"
185 };
186
187 /* Binding Acknowledgement status values
188  * http://www.iana.org/assignments/mobility-parameters/mobility-parameters.xhtml
189  */
190 static const value_string mip6_ba_status_value[] = {
191     {   0, "Binding Update accepted" },
192     {   1, "Accepted but prefix discovery necessary" },
193     {   2, "GRE_KEY_OPTION_NOT_REQUIRED" },                 /* [RFC5845] */
194     {   3, "GRE_TUNNELING_BUT_TLV_HEADER_NOT_SUPPORTED" },  /* [RFC5845] */
195     {   4, "MCOA NOTCOMPLETE" },                            /* [RFC5648] */
196     {   5, "MCOA RETURNHOME WO/NDP" },                      /* [RFC5648] */
197     {   6, "PBU_ACCEPTED_TB_IGNORED_SETTINGSMISMATCH" },    /* [RFC-ietf-mipshop-transient-bce-pmipv6-07] */
198     /* 7-127 Unassigned */
199
200     { 128, "Reason unspecified" },
201     { 129, "Administratively prohibited" },
202     { 130, "Insufficient resources" },
203     { 131, "Home registration not supported" },
204     { 132, "Not home subnet" },
205     { 133, "Not home agent for this mobile node" },
206     { 134, "Duplicate Address Detection failed" },
207     { 135, "Sequence number out of window" },
208     { 136, "Expired home nonce index" },
209     { 137, "Expired care-of nonce index" },
210     { 138, "Expired nonces" },
211     { 139, "Registration type change disallowed" },
212     { 140, "Mobile Router Operation not permitted" },
213     { 141, "Invalid Prefix" },
214     { 142, "Not Authorized for Prefix" },
215     { 143, "Mobile Network Prefix information unavailable" },
216     { 145, "Proxy Registration not supported by the LMA" },
217     { 146, "Proxy Registrations from this MAG not allowed" },
218     { 147, "No home address for this NAI" },
219     { 148, "Invalid Time Stamp Option" },
220     { 149, "Permanent home keygen token exists" },                  /* [RFC4866] */
221     { 150, "Non-null home nonce index expected" },                  /* [RFC4866] */
222     { 151, "SERVICE_AUTHORIZATION_FAILED" },                        /* [RFC5149] */
223     { 152, "PROXY_REG_NOT_ENABLED" },                               /* [RFC5213] */
224     { 153, "NOT_LMA_FOR_THIS_MOBILE_NODE" },                        /* [RFC5213] */
225     { 154, "MAG_NOT_AUTHORIZED_FOR_PROXY_REG" },                    /* [RFC5213] */
226     { 155, "NOT_AUTHORIZED_FOR_HOME_NETWORK_PREFIX" },              /* [RFC5213] */
227     { 156, "TIMESTAMP_MISMATCH" },                                  /* [RFC5213] */
228     { 157, "TIMESTAMP_LOWER_THAN_PREV_ACCEPTED" },                  /* [RFC5213] */
229     { 158, "MISSING_HOME_NETWORK_PREFIX_OPTION" },                  /* [RFC5213] */
230     { 159, "BCE_PBU_PREFIX_SET_DO_NOT_MATCH" },                     /* [RFC5213] */
231     { 160, "MISSING_MN_IDENTIFIER_OPTION" },                        /* [RFC5213] */
232     { 161, "MISSING_HANDOFF_INDICATOR_OPTION" },                    /* [RFC5213] */
233     { 162, "MISSING_ACCESS_TECH_TYPE_OPTION" },                     /* [RFC5213] */
234     { 163, "GRE_KEY_OPTION_REQUIRED" },                             /* [RFC5845] */
235     { 164, "MCOA MALFORMED" },                                      /* [RFC5648] */
236     { 165, "MCOA NON-MCOA BINDING EXISTS" },                        /* [RFC5648] */
237     { 166, "MCOA PROHIBITED" },                                     /* [RFC5648] */
238     { 167, "MCOA UNKNOWN COA" },                                    /* [RFC5648] */
239     { 168, "MCOA BULK REGISTRATION PROHIBITED" },                   /* [RFC5648] */
240     { 169, "MCOA SIMULTANEOUS HOME AND FOREIGN PROHIBITED" },       /* [RFC5648] */
241     { 170, "NOT_AUTHORIZED_FOR_IPV4_MOBILITY_SERVICE" },            /* [RFC5844] */
242     { 171, "NOT_AUTHORIZED_FOR_IPV4_HOME_ADDRESS" },                /* [RFC5844] */
243     { 172, "NOT_AUTHORIZED_FOR_IPV6_MOBILITY_SERVICE" },            /* [RFC5844] */
244     { 173, "MULTIPLE_IPV4_HOME_ADDRESS_ASSIGNMENT_NOT_SUPPORTED" }, /* [RFC5844] */
245
246     {   0, NULL }
247 };
248
249 /* Binding Error status values */
250 static const value_string mip6_be_status_value[] = {
251     { 1, "Unknown binding for Home Address destination option" },
252     { 2, "Unrecognized MH type value" },
253     { 0, NULL }
254 };
255
256 /* Fast Binding Update flag description */
257 static const true_false_string fmip6_fbu_a_flag_value = {
258     "Fast Binding Acknowledgement requested",
259     "Fast Binding Acknowledgement not requested"
260 };
261
262 static const true_false_string fmip6_fbu_h_flag_value = {
263     "Home Registration",
264     "No Home Registration"
265 };
266
267 static const true_false_string fmip6_fbu_l_flag_value = {
268     "Link-Local Address Compatibility",
269     "No Link-Local Address Compatibility"
270 };
271
272 static const true_false_string fmip6_fbu_k_flag_value = {
273     "Key Management Mobility Compatibility",
274     "No Key Management Mobility Compatibility"
275 };
276
277 /* Fast Binding Acknowledgement status values */
278 static const value_string fmip6_fback_status_value[] = {
279     {   0, "Fast Binding Update accepted" },
280     {   1, "Accepted but use supplied NCoA" },
281     { 128, "Reason unspecified" },
282     { 129, "Administratively prohibited" },
283     { 130, "Insufficient resources" },
284     { 131, "Incorrect interface identifier length" },
285     {   0, NULL }
286 };
287
288 /* Heartbeat flag description */
289 static const true_false_string mip6_hb_u_flag_value = {
290     "Unsolicited Heartbeat Response",
291     "Otherwise"
292 };
293
294 static const true_false_string mip6_hb_r_flag_value = {
295     "Heartbeat Response",
296     "Heartbeat Request"
297 };
298
299 /* MH LLA Option code */
300 static const value_string fmip6_lla_optcode_value[] = {
301     {   2, "Link Layer Address of the MN" },
302     {   0, NULL }
303 };
304
305 /* Mobile Node Identifier Option code */
306 static const value_string mip6_mnid_subtype_value[] = {
307     {   1, "Network Access Identifier (NAI)" },
308     {   0, NULL }
309 };
310
311 /* mobile network prefix flag description */
312 static const true_false_string mip6_ipv4ha_p_flag_value = {
313     "mobile network prefixt requested",
314     "mobile network prefix not requested"
315 };
316
317 /* Vendor-Specific Mobility Option */
318 static const value_string mip6_vsm_subtype_value[] = {
319     {   0, NULL }
320 };
321
322 /* Vendor-Specific Mobility Option (3GPP TS29.282) */
323 static const value_string mip6_vsm_subtype_3gpp_value[] = {
324     {   1, "Protocol Configuration Options" },
325     {   2, "3GPP Specific PMIPv6 Error Code" },
326     {   3, "PMIPv6 PDN GW IP Address" },
327     {   4, "PMIPv6 DHCPv4 Address Allocation Procedure Indication" },
328     {   5, "PMIPv6 Fully Qualified PDN Connection Set Identifier" },
329     {   6, "PMIPv6 PDN type indication" },
330     {   7, "Charging ID" },
331     {   8, "Selection Mode" },
332     {   9, "I-WLAN Mobility Access Point Name (APN)" },
333     {  10, "Charging Characteristics" },
334     {  11, "Mobile Equipment Identity (MEI)" },
335     {  12, "MSISDN" },
336     {  13, "Serving Network" },
337     {  14, "APN Restriction" },
338     {  15, "Maximum APN Restriction" },
339     {  16, "Unauthenticated IMSI" },
340     {  17, "PDN Connection ID" },
341     {   0, NULL }
342 };
343
344 /* Handoff Indicator Option type */
345 static const value_string pmip6_hi_opttype_value[] = {
346     {   0, "Reserved" },
347     {   1, "Attachment over a new interface" },
348     {   2, "Handoff between two different interfaces of the mobile node" },
349     {   3, "Handoff between mobile access gateways for the same interface" },
350     {   4, "Handoff state unknown" },
351     {   5, "Handoff state not changed (Re-registration)" },
352     {   0, NULL }
353 };
354
355 /* Access Technology Type Option type */
356 static const value_string pmip6_att_opttype_value[] = {
357     {   0, "Reserved" },
358     {   1, "Virtual" },
359     {   2, "PPP" },
360     {   3, "IEEE 802.3" },
361     {   4, "IEEE 802.11a/b/g" },
362     {   5, "IEEE 802.16e" },
363     {   6, "3GPP GERAN" },
364     {   7, "3GPP UTRAN" },
365     {   8, "3GPP E-UTRAN" },
366     {   9, "3GPP2 eHRPD" },
367     {  10, "3GPP2 HRPD" },
368     {  11, "3GPP2 1xRTT" },
369     {  12, "3GPP2 UMB" },
370     {   0, NULL }
371 };
372
373 /* PMIP6 BRI R. Trigger values */
374 static const value_string pmip6_bri_rtrigger[] = {
375     { 0x00, "Unspecified"},
376     { 0x01,     "Administrative Reason"},
377     { 0x02,     "Inter-MAG Handover - same Access Type"},
378     { 0x03,     "Inter-MAG Handover - different Access Type"},
379     { 0x04,     "Inter-MAG Handover - Unknown"},
380     { 0x05,     "User Initiated Session(s) Termination"},
381     { 0x06,     "Access Network Session(s) Termination"},
382     { 0x07,     "Possible Out-of Sync BCE State"},
383     /* 8-127 Unassigned  */
384     { 0x128,    "Per-Peer Policy"},
385     { 0x129,    "Revoking Mobility Node Local Policy"},
386     /* 130-249 Unassigned  */
387     /* 250-255 Reserved for Testing Purposes Only */
388     { 0,        NULL},
389 };
390
391 /* PMIP6 BRI Status values */
392 static const value_string pmip6_bri_status[] = {
393     { 0x00,     "Success"},
394     { 0x01,     "Partial Success"},
395     { 0x02,     "Binding Does NOT Exist"},
396     { 0x03,     "IPv4 HoA Binding Does NOT Exist"},
397     { 0x04,     "Global Revocation NOT Authorized"},
398     { 0x05,     "CAN NOT Identify Binding"},
399     { 0x06,     "Revocation Failed, MN is Attached"},
400     { 0,        NULL},
401 };
402
403 /* Handoff Indicator values */
404 static const range_string handoff_indicator[] = {
405     { 0x00, 0x00,   "Reserved"                              },
406     { 0x01, 0x01,   "Attachment over a new interface"       },
407     { 0x02, 0x02,   "Handoff between two different interfaces of the mobile node"   },
408     { 0x03, 0x03,   "Handoff between mobile access gateways for the same interface" },
409     { 0x04, 0x04,   "Handoff state unknown"                                         },
410     { 0x05, 0x05,   "Handoff state not changed (Re-registration)"                   },
411     { 0x06, 0xff,   "Unassigned"                                                    },
412     { 0,    0,      NULL                                                            }
413 };
414
415 /* Mobility Option types
416  * http://www.iana.org/assignments/mobility-parameters/mobility-parameters.xhtml
417  */
418
419 static const value_string mip6_mobility_options[] = {
420     { MIP6_PAD1,   "Pad1"},                                         /* RFC3775 */
421     { MIP6_PADN,   "PadN"},                                         /* RFC3775 */
422     { MIP6_BRA,    "Binding Refresh Advice"},                       /* RFC3775 */
423     { MIP6_ACOA,   "Alternate Care-of Address"},                    /* RFC3775 */
424     { MIP6_NI,     "Nonce Indices"},                                /* RFC3775 */
425     { MIP6_AUTD,   "Authorization Data"},                           /* RFC3775 */
426     { MIP6_MNP,    "Mobile Network Prefix Option"},                 /* RFC3963 */
427     { MIP6_MHLLA,  "Mobility Header Link-Layer Address option"},    /* RFC5568 */
428     { MIP6_MNID,   "MN-ID-OPTION-TYPE"},                            /* RFC4283 */
429     { MIP6_AUTH,   "AUTH-OPTION-TYPE"},                             /* RFC4285 */
430     { MIP6_MESGID, "MESG-ID-OPTION-TYPE"},                          /* RFC4285 */
431     { MIP6_CGAPR,  "CGA Parameters Request"},                       /* RFC4866 */
432     { MIP6_CGAR,   "CGA Parameters"},                               /* RFC4866 */
433     { MIP6_SIGN,   "Signature"},                                    /* RFC4866 */
434     { MIP6_PHKT,   "Permanent Home Keygen Token"},                  /* RFC4866 */
435     { MIP6_MOCOTI, "Care-of Test Init"},                            /* RFC4866 */
436     { MIP6_MOCOT,  "Care-of Test"},                                 /* RFC4866 */
437     { MIP6_DNSU,   "DNS-UPDATE-TYPE"},                              /* RFC5026 */
438     { MIP6_EM,     "Experimental Mobility Option"},                 /* RFC5096 */
439     { MIP6_VSM,    "Vendor Specific Mobility Option"},              /* RFC5094 */
440     { MIP6_SSM,    "Service Selection Mobility Option"},            /* RFC5149 */
441     { MIP6_BADFF,  "Binding Authorization Data for FMIPv6 (BADF)"}, /* RFC5568 */
442     { MIP6_HNP,    "Home Network Prefix Option"},                   /* RFC5213 */
443     { MIP6_MOHI,   "Handoff Indicator Option"},                     /* RFC5213 */
444     { MIP6_ATT,    "Access Technology Type Option"},                /* RFC5213 */
445     { MIP6_MNLLI,  "Mobile Node Link-layer Identifier Option"},     /* RFC5213 */
446     { MIP6_LLA,    "Link-local Address Option"},                    /* RFC5213 */
447     { MIP6_TS,     "Timestamp Option"},                             /* RFC5213 */
448     { MIP6_RC,     "Restart Counter"},                              /* RFC5847 */
449     { MIP6_IPV4HA, "IPv4 Home Address"},                            /* RFC5555 */
450     { MIP6_IPV4AA, "IPv4 Address Acknowledgement"},                 /* RFC5555 */
451     { MIP6_NATD,   "NAT Detection"},                                /* RFC5555 */
452     { MIP6_IPV4COA,"IPv4 Care-of Address"},                         /* RFC5555 */
453     { MIP6_GREK,   "GRE Key Option"},                               /* RFC5845 */
454     { MIP6_MHIPV6AP,  "Mobility Header IPv6 Address/Prefix"},       /* RFC5568 */
455     { MIP6_BI,        "Binding Identifier"},                        /* RFC5648 */
456     { MIP6_IPV4HAREQ, "IPv4 Home Address Request"},                 /* RFC5844 */
457     { MIP6_IPV4HAREP, "IPv4 Home Address Reply"},                   /* RFC5844 */
458     { MIP6_IPV4DRA,   "IPv4 Default-Router Address"},               /* RFC5844 */
459     { MIP6_IPV4DSM,   "IPv4 DHCP Support Mode"},                    /* RFC5844 */
460     { MIP6_CR,        "Context Request Option"},                    /* RFC5949 */
461     { MIP6_LMAA,      "Local Mobility Anchor Address Option"},      /* RFC5949 */
462     { MIP6_MNLLAII,   "Mobile Node Link-local Address Interface Identifier Option"}, /* RFC5949 */
463     { MIP6_TB,        "Transient Binding"},                         /* [RFC-ietf-mipshop-transient-bce-pmipv6-07] */
464     { MIP6_FS,        "Flow Summary"},                              /* [RFC-ietf-mext-flow-binding-11] */
465     { MIP6_FI,        "Flow Identification"},                       /* [RFC-ietf-mext-flow-binding-11]] */
466
467     { 0, NULL }
468 };
469
470 /* Message lengths */
471 #define MIP6_BRR_LEN          2
472 #define MIP6_HOTI_LEN        10
473 #define MIP6_COTI_LEN        10
474 #define MIP6_HOT_LEN         18
475 #define MIP6_COT_LEN         18
476 #define MIP6_BU_LEN           6
477 #define MIP6_BA_LEN           6
478 #define MIP6_BE_LEN          18
479 #define FMIP6_FBU_LEN         6
480 #define FMIP6_FBACK_LEN       6
481 #define FMIP6_FNA_LEN         2
482 #define MIP6_EMH_LEN          0
483 #define MIP6_HAS_LEN         18
484 #define MIP6_HB_LEN           6
485 #define MIP6_HI_LEN           4
486 #define MIP6_HAck_LEN         4
487 #define MIP6_BR_LEN           6
488 /* PMIP BRI */
489 #define PMIP6_BRI_LEN         6
490
491 /* Field offsets & lengths for mobility headers */
492 #define MIP6_PROTO_OFF        0
493 #define MIP6_HLEN_OFF         1
494 #define MIP6_TYPE_OFF         2
495 #define MIP6_RES_OFF          3
496 #define MIP6_CSUM_OFF         4
497 #define MIP6_DATA_OFF         6
498 #define MIP6_PROTO_LEN        1
499 #define MIP6_HLEN_LEN         1
500 #define MIP6_TYPE_LEN         1
501 #define MIP6_RES_LEN          1
502 #define MIP6_CSUM_LEN         2
503
504 #define MIP6_BRR_RES_OFF      6
505 #define MIP6_BRR_OPTS_OFF     8
506 #define MIP6_BRR_RES_LEN      2
507
508 #define MIP6_HOTI_RES_OFF     6
509 #define MIP6_HOTI_COOKIE_OFF  8
510 #define MIP6_HOTI_OPTS_OFF   16
511 #define MIP6_HOTI_RES_LEN     2
512 #define MIP6_HOTI_COOKIE_LEN  8
513
514 #define MIP6_COTI_RES_OFF     6
515 #define MIP6_COTI_COOKIE_OFF  8
516 #define MIP6_COTI_OPTS_OFF   16
517 #define MIP6_COTI_RES_LEN     2
518 #define MIP6_COTI_COOKIE_LEN  8
519
520 #define MIP6_HOT_INDEX_OFF    6
521 #define MIP6_HOT_COOKIE_OFF   8
522 #define MIP6_HOT_TOKEN_OFF   16
523 #define MIP6_HOT_OPTS_OFF    24
524 #define MIP6_HOT_INDEX_LEN    2
525 #define MIP6_HOT_COOKIE_LEN   8
526 #define MIP6_HOT_TOKEN_LEN    8
527
528 #define MIP6_COT_INDEX_OFF    6
529 #define MIP6_COT_COOKIE_OFF   8
530 #define MIP6_COT_TOKEN_OFF   16
531 #define MIP6_COT_OPTS_OFF    24
532 #define MIP6_COT_INDEX_LEN    2
533 #define MIP6_COT_COOKIE_LEN   8
534 #define MIP6_COT_TOKEN_LEN    8
535
536 #define MIP6_BU_SEQNR_OFF     6
537 #define MIP6_BU_FLAGS_OFF     8
538 #define MIP6_BU_RES_OFF       9
539 #define MIP6_BU_LIFETIME_OFF 10
540 #define MIP6_BU_OPTS_OFF     12
541 #define MIP6_BU_SEQNR_LEN     2
542 #define MIP6_BU_FLAGS_LEN     2
543 #define MIP6_BU_RES_LEN       0
544 #define MIP6_BU_LIFETIME_LEN  2
545
546 #define MIP6_BA_STATUS_OFF    6
547 #define MIP6_BA_FLAGS_OFF     7
548 #define MIP6_BA_SEQNR_OFF     8
549 #define MIP6_BA_LIFETIME_OFF 10
550 #define MIP6_BA_OPTS_OFF     12
551 #define MIP6_BA_STATUS_LEN    1
552 #define MIP6_BA_FLAGS_LEN     1
553 #define MIP6_BA_SEQNR_LEN     2
554 #define MIP6_BA_LIFETIME_LEN  2
555
556 #define MIP6_BE_STATUS_OFF    6
557 #define MIP6_BE_RES_OFF       7
558 #define MIP6_BE_HOA_OFF       8
559 #define MIP6_BE_OPTS_OFF     24
560 #define MIP6_BE_STATUS_LEN    1
561 #define MIP6_BE_RES_LEN       1
562 #define MIP6_BE_HOA_LEN      16
563
564 #define FMIP6_FBU_SEQNR_OFF     6
565 #define FMIP6_FBU_FLAGS_OFF     8
566 #define FMIP6_FBU_RES_OFF       9
567 #define FMIP6_FBU_LIFETIME_OFF 10
568 #define FMIP6_FBU_OPTS_OFF     12
569 #define FMIP6_FBU_SEQNR_LEN     2
570 #define FMIP6_FBU_FLAGS_LEN     1
571 #define FMIP6_FBU_RES_LEN       1
572 #define FMIP6_FBU_LIFETIME_LEN  2
573
574 #define FMIP6_FBACK_STATUS_OFF    6
575 #define FMIP6_FBACK_FLAGS_OFF     7
576 #define FMIP6_FBACK_SEQNR_OFF     8
577 #define FMIP6_FBACK_LIFETIME_OFF 10
578 #define FMIP6_FBACK_OPTS_OFF     12
579 #define FMIP6_FBACK_STATUS_LEN    1
580 #define FMIP6_FBACK_FLAGS_LEN     1
581 #define FMIP6_FBACK_SEQNR_LEN     2
582 #define FMIP6_FBACK_LIFETIME_LEN  2
583
584 #define FMIP6_FNA_RES_OFF     6
585 #define FMIP6_FNA_OPTS_OFF    8
586 #define FMIP6_FNA_RES_LEN     2
587
588 #define MIP6_HAS_NRADR_OFF    6
589 #define MIP6_HAS_RES_OFF      7
590 #define MIP6_HAS_HAA_OFF      8
591 #define MIP6_HAS_OPTS_OFF    24
592 #define MIP6_HAS_NRADR_LEN    1
593 #define MIP6_HAS_RES_LEN      1
594 #define MIP6_HAS_HAA_LEN     16
595
596 #define MIP6_HB_RES_OFF       6
597 #define MIP6_HB_FLAGS_OFF     7
598 #define MIP6_HB_SEQNR_OFF     8
599 #define MIP6_HB_OPTS_OFF     12
600 #define MIP6_HB_RES_LEN       1
601 #define MIP6_HB_FLAGS_LEN     1
602 #define MIP6_HB_SEQNR_LEN     4
603
604 #define MIP6_HI_SEQNR_OFF     6
605 #define MIP6_HI_FLAGS_OFF     8
606 #define MIP6_HI_CODE_OFF      9
607 #define MIP6_HI_OPTS_OFF     10
608 #define MIP6_HI_SEQNR_LEN     2
609 #define MIP6_HI_FLAGS_LEN     1
610 #define MIP6_HI_CODE_LEN      1
611
612 #define MIP6_HAck_SEQNR_OFF   6
613 #define MIP6_HAck_RES_OFF     8
614 #define MIP6_HAck_CODE_OFF    9
615 #define MIP6_HAck_OPTS_OFF   10
616 #define MIP6_HAck_SEQNR_LEN   2
617 #define MIP6_HAck_RES_LEN     1
618 #define MIP6_HAck_CODE_LEN    1
619
620 #define MIP6_BR_TYPE_OFF      6
621 #define MIP6_BR_TRGR_OFF      7
622 #define MIP6_BR_SEQNR_OFF     8
623 #define MIP6_BR_FLAGS_OFF    10
624 #define MIP6_BR_RES_OFF      11
625 #define MIP6_BR_OPTS_OFF     12
626 #define MIP6_BR_TYPE_LEN      1
627 #define MIP6_BR_TRGR_LEN      1
628 #define MIP6_BR_SEQNR_LEN     2
629 #define MIP6_BR_FLAGS_LEN     1
630 #define MIP6_BR_RES_LEN       1
631
632 /* PMIP BRI */
633 #define PMIP6_BRI_BRTYPE_OFF     6
634 #define PMIP6_BRI_RTRIGGER_OFF   7
635 #define PMIP6_BRI_STATUS_OFF     7
636 #define PMIP6_BRI_SEQNR_OFF      8
637 #define PMIP6_BRI_FLAGS_OFF     10
638 #define PMIP6_BRI_RES_OFF       11
639 #define PMIP6_BRI_BRTYPE_LEN     1
640 #define PMIP6_BRI_RTRIGGER_LEN   1
641 #define PMIP6_BRI_STATUS_LEN     1
642 #define PMIP6_BRI_SEQNR_LEN      2
643 #define PMIP6_BRI_FLAGS_LEN      1
644 #define PMIP6_BRI_RES_LEN        1
645
646 /* Field offsets & field and option lengths for mobility options.
647  * The option length does *not* include the option type and length
648  * fields.  The field offsets, however, do include the type and
649  * length fields. */
650 #define MIP6_BRA_LEN          2
651 #define MIP6_BRA_RI_OFF       2
652 #define MIP6_BRA_RI_LEN       2
653
654 #define MIP6_ACOA_LEN        16
655 #define MIP6_ACOA_ACOA_OFF    2
656 #define MIP6_ACOA_ACOA_LEN   16
657
658 #define MIP6_NEMO_MNP_LEN         18
659 #define MIP6_NEMO_MNP_PL_OFF       3
660 #define MIP6_NEMO_MNP_MNP_OFF      4
661 #define MIP6_NEMO_MNP_MNP_LEN     16
662
663 #define MIP6_NI_LEN           4
664 #define MIP6_NI_HNI_OFF       2
665 #define MIP6_NI_CNI_OFF       4
666 #define MIP6_NI_HNI_LEN       2
667 #define MIP6_NI_CNI_LEN       2
668
669 #define MIP6_BAD_AUTH_OFF     2
670
671 #define FMIP6_LLA_MINLEN      1
672 #define FMIP6_LLA_OPTCODE_OFF 2
673 #define FMIP6_LLA_LLA_OFF     3
674 #define FMIP6_LLA_OPTCODE_LEN 1
675
676 #define MIP6_MNID_MINLEN      2
677 #define MIP6_MNID_SUBTYPE_OFF 2
678 #define MIP6_MNID_SUBTYPE_LEN 1
679 #define MIP6_MNID_MNID_OFF    3
680
681 #define MIP6_VSM_MINLEN       2
682 #define MIP6_VSM_VID_OFF      2
683 #define MIP6_VSM_VID_LEN      4
684 #define MIP6_VSM_SUBTYPE_OFF  6
685 #define MIP6_VSM_SUBTYPE_LEN  1
686 #define MIP6_VSM_DATA_OFF     7
687
688
689 #define MIP6_SSM_MINLEN       2
690 #define MIP6_SSM_SSM_OFF      2
691
692 #define PMIP6_HI_LEN          2
693 #define PMIP6_HI_HI_OFF       3
694 #define PMIP6_HI_HI_LEN       1
695
696 #define PMIP6_ATT_LEN         2
697 #define PMIP6_ATT_ATT_OFF     3
698 #define PMIP6_ATT_ATT_LEN     1
699
700 #define PMIP6_LLA_LEN         16
701
702 #define PMIP6_TS_LEN          8
703
704 #define PMIP6_RC_LEN          4
705 #define PMIP6_RC_RC_OFF       2
706 #define PMIP6_RC_RC_LEN       4
707
708 #define MIP6_IPV4HA_LEN         6
709 #define MIP6_IPV4HA_PREFIXL_OFF 2
710 #define MIP6_IPV4HA_PREFIXL_LEN 1
711 #define MIP6_IPV4HA_HA_OFF      4
712 #define MIP6_IPV4HA_HA_LEN      4
713
714 #define MIP6_IPV4AA_LEN         6
715 #define MIP6_IPV4AA_STATUS_OFF  2
716 #define MIP6_IPV4AA_STATUS_LEN  1
717 #define MIP6_IPV4AA_PREFIXL_OFF 3
718 #define MIP6_IPV4AA_PREFIXL_LEN 1
719 #define MIP6_IPV4AA_HA_OFF      4
720 #define MIP6_IPV4AA_HA_LEN      4
721
722 #define PMIP6_GREK_LEN        6
723 #define PMIP6_GREK_ID_OFF     4
724 #define PMIP6_GREK_ID_LEN     4
725
726 #define MIP6_IPV4HAREQ_LEN         6
727 #define MIP6_IPV4HAREQ_PREFIXL_OFF 2
728 #define MIP6_IPV4HAREQ_PREFIXL_LEN 1
729 #define MIP6_IPV4HAREQ_HA_OFF      4
730 #define MIP6_IPV4HAREQ_HA_LEN      4
731
732 #define MIP6_IPV4HAREP_LEN         6
733 #define MIP6_IPV4HAREP_STATUS_OFF  2
734 #define MIP6_IPV4HAREP_STATUS_LEN  1
735 #define MIP6_IPV4HAREP_PREFIXL_OFF 3
736 #define MIP6_IPV4HAREP_PREFIXL_LEN 1
737 #define MIP6_IPV4HAREP_HA_OFF      4
738 #define MIP6_IPV4HAREP_HA_LEN      4
739
740 #define MIP6_IPV4DRA_LEN      6
741 #define MIP6_IPV4DRA_RES_OFF  2
742 #define MIP6_IPV4DRA_RES_LEN  2
743 #define MIP6_IPV4DRA_DRA_OFF  4
744 #define MIP6_IPV4DRA_DRA_LEN  4
745
746 static dissector_table_t ip_dissector_table;
747
748 /* Initialize the protocol and registered header fields */
749 static int proto_mip6 = -1;
750 static int proto_nemo = -1;
751 static int hf_mip6_proto = -1;
752 static int hf_mip6_hlen = -1;
753 static int hf_mip6_mhtype = -1;
754 static int hf_mip6_reserved = -1;
755 static int hf_mip6_csum = -1;
756
757 static int hf_mip6_hoti_cookie = -1;
758
759 static int hf_mip6_coti_cookie = -1;
760
761 static int hf_mip6_hot_nindex = -1;
762 static int hf_mip6_hot_cookie = -1;
763 static int hf_mip6_hot_token = -1;
764
765 static int hf_mip6_cot_nindex = -1;
766 static int hf_mip6_cot_cookie = -1;
767 static int hf_mip6_cot_token = -1;
768
769 static int hf_mip6_bu_seqnr = -1;
770 static int hf_mip6_bu_a_flag = -1;
771 static int hf_mip6_bu_h_flag = -1;
772 static int hf_mip6_bu_l_flag = -1;
773 static int hf_mip6_bu_k_flag = -1;
774 static int hf_mip6_bu_m_flag = -1;
775 static int hf_mip6_nemo_bu_r_flag = -1;
776 static int hf_pmip6_bu_p_flag = -1;
777 static int hf_mip6_bu_f_flag = -1;
778 static int hf_pmip6_bu_t_flag = -1;
779 static int hf_mip6_bu_lifetime = -1;
780
781 static int hf_mip6_ba_status = -1;
782 static int hf_mip6_ba_k_flag = -1;
783 static int hf_mip6_nemo_ba_r_flag = -1;
784 static int hf_pmip6_ba_p_flag = -1;
785 static int hf_pmip6_ba_t_flag = -1;
786 static int hf_mip6_ba_seqnr = -1;
787 static int hf_mip6_ba_lifetime = -1;
788
789 static int hf_mip6_be_status = -1;
790 static int hf_mip6_be_haddr = -1;
791
792 static int hf_fmip6_fbu_seqnr = -1;
793 static int hf_fmip6_fbu_a_flag = -1;
794 static int hf_fmip6_fbu_h_flag = -1;
795 static int hf_fmip6_fbu_l_flag = -1;
796 static int hf_fmip6_fbu_k_flag = -1;
797 static int hf_fmip6_fbu_lifetime = -1;
798
799 static int hf_fmip6_fback_status = -1;
800 static int hf_fmip6_fback_k_flag = -1;
801 static int hf_fmip6_fback_seqnr = -1;
802 static int hf_fmip6_fback_lifetime = -1;
803
804 static int hf_mip6_hb_u_flag = -1;
805 static int hf_mip6_hb_r_flag = -1;
806 static int hf_mip6_hb_seqnr = -1;
807
808 static int hf_mip6_bra_interval = -1;
809
810 static int hf_mip6_acoa_acoa = -1;
811 static int hf_mip6_nemo_mnp_mnp = -1;
812 static int hf_mip6_nemo_mnp_pfl = -1;
813
814 static int hf_mip6_ni_hni = -1;
815 static int hf_mip6_ni_cni = -1;
816
817 static int hf_mip6_bad_auth = -1;
818
819 static int hf_fmip6_lla_optcode = -1;
820
821 static int hf_mip6_mnid_subtype = -1;
822 static int hf_mip6_vsm_vid = -1;
823 static int hf_mip6_vsm_subtype = -1;
824 static int hf_mip6_vsm_subtype_3gpp = -1;
825
826 static int hf_pmip6_hi_opttype = -1;
827 static int hf_pmip6_att_opttype = -1;
828
829 static int hf_pmip6_timestamp = -1;
830 static int hf_pmip6_rc = -1;
831 static int hf_mip6_ipv4ha_preflen = -1;
832 static int hf_mip6_ipv4ha_p_flag = -1;
833 static int hf_mip6_ipv4ha_ha = -1;
834 static int hf_mip6_ipv4aa_status = -1;
835 static int hf_pmip6_gre_key = -1;
836 static int hf_mip6_ipv4dra_dra = -1;
837 static int hf_mip6_mobility_opt = -1;
838
839 /* PMIP BRI */
840 static int hf_pmip6_bri_brtype = -1;
841 static int hf_pmip6_bri_rtrigger = -1;
842 static int hf_pmip6_bri_status = -1;
843 static int hf_pmip6_bri_seqnr = -1;
844 static int hf_pmip6_bri_ip_flag = -1;
845 static int hf_pmip6_bri_ap_flag = -1;
846 static int hf_pmip6_bri_ia_flag = -1;
847 static int hf_pmip6_bri_ig_flag = -1;
848 static int hf_pmip6_bri_ag_flag = -1;
849 static int hf_pmip6_bri_res = -1;
850
851 static int hf_pmip6_opt_lila_lla = -1;
852
853 /* Initialize the subtree pointers */
854 static gint ett_mip6 = -1;
855 static gint ett_mip6_opt_padn = -1;
856 static gint ett_mip6_opt_bra = -1;
857 static gint ett_mip6_opt_acoa = -1;
858 static gint ett_mip6_opt_ni = -1;
859 static gint ett_mip6_opt_bad = -1;
860 static gint ett_mip6_nemo_opt_mnp = -1;
861 static gint ett_fmip6_opt_lla = -1;
862 static gint ett_mip6_opt_mnid = -1;
863 static gint ett_mip6_opt_vsm = -1;
864 static gint ett_mip6_opt_ssm = -1;
865 static gint ett_pmip6_opt_hnp = -1;
866 static gint ett_pmip6_opt_hi = -1;
867 static gint ett_pmip6_opt_att = -1;
868 static gint ett_pmip6_opt_lla = -1;
869 static gint ett_pmip6_opt_ts = -1;
870 static gint ett_pmip6_opt_rc = -1;
871 static gint ett_mip6_opt_ipv4ha = -1;
872 static gint ett_mip6_opt_ipv4aa = -1;
873 static gint ett_pmip6_opt_grek = -1;
874 static gint ett_mip6_opt_ipv4hareq = -1;
875 static gint ett_mip6_opt_ipv4harep = -1;
876 static gint ett_mip6_opt_ipv4dra = -1;
877
878 /* Functions to dissect the mobility headers */
879
880 static int
881 dissect_mip6_brr(tvbuff_t *tvb, proto_tree *mip6_tree, packet_info *pinfo)
882 {
883     /*proto_tree *data_tree = NULL;*/
884     /*proto_item *ti;*/
885
886     col_set_str(pinfo->cinfo, COL_INFO, "Binding Refresh Request");
887
888     if (mip6_tree) {
889         /*ti = */proto_tree_add_text(mip6_tree, tvb, MIP6_DATA_OFF,
890                                      MIP6_BRR_LEN, "Binding Refresh Request");
891         /*data_tree = proto_item_add_subtree(ti, ett_mip6);*/
892     }
893
894     return MIP6_DATA_OFF + MIP6_BRR_LEN;
895 }
896
897 static int
898 dissect_mip6_hoti(tvbuff_t *tvb, proto_tree *mip6_tree, packet_info *pinfo)
899 {
900     proto_tree *data_tree = NULL;
901     proto_item *ti;
902
903     col_set_str(pinfo->cinfo, COL_INFO, "Home Test Init");
904
905     if (mip6_tree) {
906         ti = proto_tree_add_text(mip6_tree, tvb, MIP6_DATA_OFF,
907                 MIP6_HOTI_LEN, "Home Test Init");
908         data_tree = proto_item_add_subtree(ti, ett_mip6);
909
910         proto_tree_add_item(data_tree, hf_mip6_hoti_cookie, tvb,
911                 MIP6_HOTI_COOKIE_OFF, MIP6_HOTI_COOKIE_LEN, ENC_BIG_ENDIAN);
912     }
913
914     return MIP6_DATA_OFF + MIP6_HOTI_LEN;
915 }
916
917 static int
918 dissect_mip6_coti(tvbuff_t *tvb, proto_tree *mip6_tree, packet_info *pinfo)
919 {
920     proto_tree *data_tree = NULL;
921     proto_item *ti;
922
923     col_set_str(pinfo->cinfo, COL_INFO, "Care-of Test Init");
924
925     if (mip6_tree) {
926         ti = proto_tree_add_text(mip6_tree, tvb, MIP6_DATA_OFF,
927                 MIP6_COTI_LEN, "Care-of Test Init");
928         data_tree = proto_item_add_subtree(ti, ett_mip6);
929
930         proto_tree_add_item(data_tree, hf_mip6_coti_cookie, tvb,
931                 MIP6_COTI_COOKIE_OFF, MIP6_COTI_COOKIE_LEN, ENC_BIG_ENDIAN);
932     }
933
934     return MIP6_DATA_OFF + MIP6_COTI_LEN;
935 }
936
937 static int
938 dissect_mip6_hot(tvbuff_t *tvb, proto_tree *mip6_tree, packet_info *pinfo)
939 {
940     proto_tree *data_tree = NULL;
941     proto_item *ti;
942
943     col_set_str(pinfo->cinfo, COL_INFO, "Home Test");
944
945     if (mip6_tree) {
946         ti = proto_tree_add_text(mip6_tree, tvb, MIP6_DATA_OFF,
947                 MIP6_HOT_LEN, "Home Test");
948         data_tree = proto_item_add_subtree(ti, ett_mip6);
949
950         proto_tree_add_item(data_tree, hf_mip6_hot_nindex, tvb,
951                 MIP6_HOT_INDEX_OFF, MIP6_HOT_INDEX_LEN, ENC_BIG_ENDIAN);
952         proto_tree_add_item(data_tree, hf_mip6_hot_cookie, tvb,
953                 MIP6_HOT_COOKIE_OFF, MIP6_HOT_COOKIE_LEN, ENC_BIG_ENDIAN);
954         proto_tree_add_item(data_tree, hf_mip6_hot_token, tvb,
955                 MIP6_HOT_TOKEN_OFF, MIP6_HOT_TOKEN_LEN, ENC_BIG_ENDIAN);
956     }
957
958     return MIP6_DATA_OFF + MIP6_HOT_LEN;
959 }
960
961 static int
962 dissect_mip6_cot(tvbuff_t *tvb, proto_tree *mip6_tree, packet_info *pinfo)
963 {
964     proto_tree *data_tree = NULL;
965     proto_item *ti;
966
967     col_set_str(pinfo->cinfo, COL_INFO, "Care-of Test");
968
969     if (mip6_tree) {
970         ti = proto_tree_add_text(mip6_tree, tvb, MIP6_DATA_OFF,
971                 MIP6_COT_LEN, "Care-of Test");
972         data_tree = proto_item_add_subtree(ti, ett_mip6);
973
974         proto_tree_add_item(data_tree, hf_mip6_cot_nindex, tvb,
975                 MIP6_COT_INDEX_OFF, MIP6_COT_INDEX_LEN, ENC_BIG_ENDIAN);
976         proto_tree_add_item(data_tree, hf_mip6_cot_cookie, tvb,
977                 MIP6_COT_COOKIE_OFF, MIP6_COT_COOKIE_LEN, ENC_BIG_ENDIAN);
978         proto_tree_add_item(data_tree, hf_mip6_hot_token, tvb,
979                 MIP6_COT_TOKEN_OFF, MIP6_COT_TOKEN_LEN, ENC_BIG_ENDIAN);
980     }
981
982     return MIP6_DATA_OFF + MIP6_COT_LEN;
983 }
984
985 /* RFC3775 */
986 static int
987 dissect_mip6_bu(tvbuff_t *tvb, proto_tree *mip6_tree, packet_info *pinfo)
988 {
989     proto_tree *data_tree = NULL;
990     proto_item *ti;
991     int lifetime;
992
993     col_set_str(pinfo->cinfo, COL_INFO, "Binding Update");
994
995     if (mip6_tree) {
996         ti = proto_tree_add_text(mip6_tree, tvb, MIP6_DATA_OFF,
997                 MIP6_BU_LEN, "Binding Update");
998         data_tree = proto_item_add_subtree(ti, ett_mip6);
999
1000         proto_tree_add_item(data_tree, hf_mip6_bu_seqnr, tvb,
1001                 MIP6_BU_SEQNR_OFF, MIP6_BU_SEQNR_LEN, ENC_BIG_ENDIAN);
1002
1003         proto_tree_add_item(data_tree, hf_mip6_bu_a_flag, tvb,
1004                 MIP6_BU_FLAGS_OFF, MIP6_BU_FLAGS_LEN, ENC_BIG_ENDIAN);
1005         proto_tree_add_item(data_tree, hf_mip6_bu_h_flag, tvb,
1006                 MIP6_BU_FLAGS_OFF, MIP6_BU_FLAGS_LEN, ENC_BIG_ENDIAN);
1007         proto_tree_add_item(data_tree, hf_mip6_bu_l_flag, tvb,
1008                 MIP6_BU_FLAGS_OFF, MIP6_BU_FLAGS_LEN, ENC_BIG_ENDIAN);
1009         proto_tree_add_item(data_tree, hf_mip6_bu_k_flag, tvb,
1010                 MIP6_BU_FLAGS_OFF, MIP6_BU_FLAGS_LEN, ENC_BIG_ENDIAN);
1011         proto_tree_add_item(data_tree, hf_mip6_bu_m_flag, tvb,
1012                 MIP6_BU_FLAGS_OFF, MIP6_BU_FLAGS_LEN, ENC_BIG_ENDIAN);
1013         proto_tree_add_item(data_tree, hf_mip6_nemo_bu_r_flag, tvb,
1014                 MIP6_BU_FLAGS_OFF, MIP6_BU_FLAGS_LEN, ENC_BIG_ENDIAN);
1015         proto_tree_add_item(data_tree, hf_pmip6_bu_p_flag, tvb,
1016                 MIP6_BU_FLAGS_OFF, MIP6_BU_FLAGS_LEN, ENC_BIG_ENDIAN);
1017         proto_tree_add_item(data_tree, hf_mip6_bu_f_flag, tvb,
1018                 MIP6_BU_FLAGS_OFF, MIP6_BU_FLAGS_LEN, ENC_BIG_ENDIAN);
1019         proto_tree_add_item(data_tree, hf_pmip6_bu_t_flag, tvb,
1020                 MIP6_BU_FLAGS_OFF, MIP6_BU_FLAGS_LEN, ENC_BIG_ENDIAN);
1021
1022         if ((tvb_get_guint8(tvb, MIP6_BU_FLAGS_OFF) & 0x0004 ) == 0x0004)
1023             proto_nemo = 1;
1024
1025         lifetime = tvb_get_ntohs(tvb, MIP6_BU_LIFETIME_OFF);
1026         proto_tree_add_uint_format(data_tree, hf_mip6_bu_lifetime, tvb,
1027                 MIP6_BU_LIFETIME_OFF,
1028                 MIP6_BU_LIFETIME_LEN, lifetime,
1029                 "Lifetime: %d (%ld seconds)",
1030                 lifetime, (long)lifetime * 4);
1031     }
1032
1033     return MIP6_DATA_OFF + MIP6_BU_LEN;
1034 }
1035
1036 static int
1037 dissect_mip6_ba(tvbuff_t *tvb, proto_tree *mip6_tree, packet_info *pinfo)
1038 {
1039     proto_tree *data_tree = NULL;
1040     proto_item *ti;
1041     int lifetime;
1042
1043     col_set_str(pinfo->cinfo, COL_INFO, "Binding Acknowledgement");
1044
1045     if (mip6_tree) {
1046         ti = proto_tree_add_text(mip6_tree, tvb, MIP6_DATA_OFF,
1047                 MIP6_BA_LEN, "Binding Acknowledgement");
1048         data_tree = proto_item_add_subtree(ti, ett_mip6);
1049
1050         proto_tree_add_item(data_tree, hf_mip6_ba_status, tvb,
1051                 MIP6_BA_STATUS_OFF, MIP6_BA_STATUS_LEN, ENC_BIG_ENDIAN);
1052         proto_tree_add_item(data_tree, hf_mip6_ba_k_flag, tvb,
1053                 MIP6_BA_FLAGS_OFF, MIP6_BA_FLAGS_LEN, ENC_BIG_ENDIAN);
1054         proto_tree_add_item(data_tree, hf_mip6_nemo_ba_r_flag, tvb,
1055                 MIP6_BA_FLAGS_OFF, MIP6_BA_FLAGS_LEN, ENC_BIG_ENDIAN);
1056         proto_tree_add_item(data_tree, hf_pmip6_ba_p_flag, tvb,
1057                 MIP6_BA_FLAGS_OFF, MIP6_BA_FLAGS_LEN, ENC_BIG_ENDIAN);
1058         proto_tree_add_item(data_tree, hf_pmip6_ba_t_flag, tvb,
1059                 MIP6_BA_FLAGS_OFF, MIP6_BA_FLAGS_LEN, ENC_BIG_ENDIAN);
1060         if ((tvb_get_guint8(tvb, MIP6_BA_FLAGS_OFF) & 0x0040 ) == 0x0040)
1061             proto_nemo = 1;
1062
1063         proto_tree_add_item(data_tree, hf_mip6_ba_seqnr, tvb,
1064                 MIP6_BA_SEQNR_OFF, MIP6_BA_SEQNR_LEN, ENC_BIG_ENDIAN);
1065
1066         lifetime = tvb_get_ntohs(tvb, MIP6_BA_LIFETIME_OFF);
1067         proto_tree_add_uint_format(data_tree, hf_mip6_ba_lifetime, tvb,
1068                 MIP6_BA_LIFETIME_OFF,
1069                 MIP6_BA_LIFETIME_LEN, lifetime,
1070                 "Lifetime: %d (%ld seconds)",
1071                 lifetime, (long)lifetime * 4);
1072     }
1073
1074     return MIP6_DATA_OFF + MIP6_BA_LEN;
1075 }
1076
1077 static int
1078 dissect_mip6_be(tvbuff_t *tvb, proto_tree *mip6_tree, packet_info *pinfo)
1079 {
1080     proto_tree *data_tree = NULL;
1081     proto_item *ti;
1082
1083     col_set_str(pinfo->cinfo, COL_INFO, "Binding Error");
1084
1085     if (mip6_tree) {
1086         ti = proto_tree_add_text(mip6_tree, tvb, MIP6_DATA_OFF,
1087                 MIP6_BE_LEN, "Binding Error");
1088         data_tree = proto_item_add_subtree(ti, ett_mip6);
1089
1090         proto_tree_add_item(data_tree, hf_mip6_be_status, tvb,
1091                 MIP6_BE_STATUS_OFF, MIP6_BE_STATUS_LEN, ENC_BIG_ENDIAN);
1092         proto_tree_add_item(data_tree, hf_mip6_be_haddr, tvb,
1093                 MIP6_BE_HOA_OFF, MIP6_BE_HOA_LEN, ENC_NA);
1094     }
1095
1096     return MIP6_DATA_OFF + MIP6_BE_LEN;
1097 }
1098
1099 static int
1100 dissect_mip6_hb(tvbuff_t *tvb, proto_tree *mip6_tree, packet_info *pinfo)
1101 {
1102     proto_tree *data_tree = NULL;
1103     proto_item *ti;
1104
1105     col_set_str(pinfo->cinfo, COL_INFO, "Heartbeat");
1106
1107     if (mip6_tree) {
1108         ti = proto_tree_add_text(mip6_tree, tvb, MIP6_DATA_OFF,
1109                 MIP6_HB_LEN, "Heartbeat");
1110         data_tree = proto_item_add_subtree(ti, ett_mip6);
1111
1112         proto_tree_add_item(data_tree, hf_mip6_hb_u_flag, tvb,
1113                 MIP6_HB_FLAGS_OFF, MIP6_HB_FLAGS_LEN, ENC_BIG_ENDIAN);
1114         proto_tree_add_item(data_tree, hf_mip6_hb_r_flag, tvb,
1115                 MIP6_HB_FLAGS_OFF, MIP6_HB_FLAGS_LEN, ENC_BIG_ENDIAN);
1116
1117         proto_tree_add_item(data_tree, hf_mip6_hb_seqnr, tvb,
1118                 MIP6_HB_SEQNR_OFF, MIP6_HB_SEQNR_LEN, ENC_BIG_ENDIAN);
1119
1120     }
1121
1122     return MIP6_DATA_OFF + MIP6_HB_LEN;
1123 }
1124
1125 static int
1126 dissect_mip6_unknown(tvbuff_t *tvb, proto_tree *mip6_tree, packet_info *pinfo)
1127 {
1128     /*proto_tree *data_tree = NULL;*/
1129     /*proto_item *ti;*/
1130
1131     col_set_str(pinfo->cinfo, COL_INFO, "Unknown MH Type");
1132
1133     if (mip6_tree) {
1134         /*ti = */proto_tree_add_text(mip6_tree, tvb, MIP6_DATA_OFF,
1135                 MIP6_DATA_OFF + 1, "Unknown MH Type");
1136         /*data_tree = proto_item_add_subtree(ti, ett_mip6);*/
1137     }
1138
1139     return MIP6_DATA_OFF + 1;
1140 }
1141
1142 static int
1143 dissect_fmip6_fbu(tvbuff_t *tvb, proto_tree *mip6_tree, packet_info *pinfo)
1144 {
1145     proto_tree *data_tree = NULL;
1146     proto_item *ti;
1147     int lifetime;
1148
1149     col_set_str(pinfo->cinfo, COL_INFO, "Fast Binding Update");
1150
1151     if (mip6_tree) {
1152         ti = proto_tree_add_text(mip6_tree, tvb, MIP6_DATA_OFF,
1153                 MIP6_BU_LEN, "Fast Binding Update");
1154         data_tree = proto_item_add_subtree(ti, ett_mip6);
1155
1156         proto_tree_add_item(data_tree, hf_fmip6_fbu_seqnr, tvb,
1157                 FMIP6_FBU_SEQNR_OFF, FMIP6_FBU_SEQNR_LEN, ENC_BIG_ENDIAN);
1158
1159         proto_tree_add_item(data_tree, hf_fmip6_fbu_a_flag, tvb,
1160                 FMIP6_FBU_FLAGS_OFF, FMIP6_FBU_FLAGS_LEN, ENC_BIG_ENDIAN);
1161         proto_tree_add_item(data_tree, hf_fmip6_fbu_h_flag, tvb,
1162                 FMIP6_FBU_FLAGS_OFF, FMIP6_FBU_FLAGS_LEN, ENC_BIG_ENDIAN);
1163         proto_tree_add_item(data_tree, hf_fmip6_fbu_l_flag, tvb,
1164                 FMIP6_FBU_FLAGS_OFF, FMIP6_FBU_FLAGS_LEN, ENC_BIG_ENDIAN);
1165         proto_tree_add_item(data_tree, hf_fmip6_fbu_k_flag, tvb,
1166                 FMIP6_FBU_FLAGS_OFF, FMIP6_FBU_FLAGS_LEN, ENC_BIG_ENDIAN);
1167
1168         lifetime = tvb_get_ntohs(tvb, FMIP6_FBU_LIFETIME_OFF);
1169         proto_tree_add_uint_format(data_tree, hf_fmip6_fbu_lifetime, tvb,
1170                 FMIP6_FBU_LIFETIME_OFF,
1171                 FMIP6_FBU_LIFETIME_LEN, lifetime,
1172                 "Lifetime: %d (%ld seconds)",
1173                 lifetime, (long)lifetime * 4);
1174     }
1175
1176     return MIP6_DATA_OFF + FMIP6_FBU_LEN;
1177 }
1178
1179 static int
1180 dissect_fmip6_fback(tvbuff_t *tvb, proto_tree *mip6_tree, packet_info *pinfo)
1181 {
1182     proto_tree *data_tree = NULL;
1183     proto_item *ti;
1184     int lifetime;
1185
1186     col_set_str(pinfo->cinfo, COL_INFO, "Fast Binding Acknowledgement");
1187
1188     if (mip6_tree) {
1189         ti = proto_tree_add_text(mip6_tree, tvb, MIP6_DATA_OFF,
1190                 FMIP6_FBACK_LEN, "Fast Binding Acknowledgement");
1191         data_tree = proto_item_add_subtree(ti, ett_mip6);
1192
1193         proto_tree_add_item(data_tree, hf_fmip6_fback_status, tvb,
1194                 FMIP6_FBACK_STATUS_OFF, FMIP6_FBACK_STATUS_LEN, ENC_BIG_ENDIAN);
1195         proto_tree_add_item(data_tree, hf_fmip6_fback_k_flag, tvb,
1196                 FMIP6_FBACK_FLAGS_OFF, FMIP6_FBACK_FLAGS_LEN, ENC_BIG_ENDIAN);
1197         proto_tree_add_item(data_tree, hf_fmip6_fback_seqnr, tvb,
1198                 FMIP6_FBACK_SEQNR_OFF, FMIP6_FBACK_SEQNR_LEN, ENC_BIG_ENDIAN);
1199         lifetime = tvb_get_ntohs(tvb, FMIP6_FBACK_LIFETIME_OFF);
1200         proto_tree_add_uint_format(data_tree, hf_fmip6_fback_lifetime, tvb,
1201                 FMIP6_FBACK_LIFETIME_OFF,
1202                 FMIP6_FBACK_LIFETIME_LEN, lifetime,
1203                 "Lifetime: %d (%ld seconds)",
1204                 lifetime, (long)lifetime * 4);
1205     }
1206
1207     return MIP6_DATA_OFF + FMIP6_FBACK_LEN;
1208 }
1209
1210 static int
1211 dissect_fmip6_fna(tvbuff_t *tvb, proto_tree *mip6_tree, packet_info *pinfo)
1212 {
1213     /*proto_tree *data_tree = NULL;*/
1214     /*proto_item *ti;*/
1215
1216     col_set_str(pinfo->cinfo, COL_INFO, "Fast Neighbor Advertisement");
1217
1218     if (mip6_tree) {
1219         /*ti = */proto_tree_add_text(mip6_tree, tvb, MIP6_DATA_OFF,
1220                 FMIP6_FNA_LEN, "Fast Neighbor Advertisement");
1221         /*data_tree = proto_item_add_subtree(ti, ett_mip6);*/
1222     }
1223
1224     return MIP6_DATA_OFF + FMIP6_FNA_LEN;
1225 }
1226
1227 /* PMIP Binding Revocation Indication / Acknowledge */
1228 static int
1229 dissect_pmip6_bri(tvbuff_t *tvb, proto_tree *mip6_tree, packet_info *pinfo)
1230 {
1231 #define INDICATION  1
1232 #define ACKNOWLEDGE     2
1233
1234     proto_item  *ti;
1235     proto_tree  *field_tree;
1236     guint8      br_type;
1237
1238     br_type = tvb_get_guint8(tvb, PMIP6_BRI_BRTYPE_OFF);
1239
1240     /* Branch between BR Indication and BR Acknowledge */
1241     if ( br_type == INDICATION )
1242     {
1243         col_set_str(pinfo->cinfo, COL_INFO, "Binding Revocation Indication");
1244
1245         if (mip6_tree)
1246         {
1247             ti = proto_tree_add_text(mip6_tree, tvb, MIP6_DATA_OFF,
1248                 PMIP6_BRI_LEN, "Binding Revocation Indication");
1249
1250             field_tree = proto_item_add_subtree(ti, ett_mip6);
1251
1252             proto_tree_add_item(field_tree, hf_pmip6_bri_brtype, tvb,
1253                 PMIP6_BRI_BRTYPE_OFF, PMIP6_BRI_BRTYPE_LEN, ENC_BIG_ENDIAN);
1254
1255             proto_tree_add_item(field_tree, hf_pmip6_bri_rtrigger, tvb,
1256                 PMIP6_BRI_RTRIGGER_OFF, PMIP6_BRI_RTRIGGER_LEN, ENC_BIG_ENDIAN);
1257
1258             proto_tree_add_item(field_tree, hf_pmip6_bri_seqnr, tvb,
1259                 PMIP6_BRI_SEQNR_OFF, PMIP6_BRI_SEQNR_LEN, ENC_BIG_ENDIAN);
1260
1261             proto_tree_add_item(field_tree, hf_pmip6_bri_ip_flag, tvb,
1262                 PMIP6_BRI_FLAGS_OFF, PMIP6_BRI_FLAGS_LEN, ENC_BIG_ENDIAN);
1263
1264             proto_tree_add_item(field_tree, hf_pmip6_bri_ia_flag, tvb,
1265                 PMIP6_BRI_FLAGS_OFF, PMIP6_BRI_FLAGS_LEN, ENC_BIG_ENDIAN);
1266
1267             proto_tree_add_item(field_tree, hf_pmip6_bri_ig_flag, tvb,
1268                 PMIP6_BRI_FLAGS_OFF, PMIP6_BRI_FLAGS_LEN, ENC_BIG_ENDIAN);
1269
1270             proto_tree_add_item(field_tree, hf_pmip6_bri_res, tvb,
1271                 PMIP6_BRI_RES_OFF, PMIP6_BRI_RES_LEN, ENC_BIG_ENDIAN);
1272         }
1273     } else if ( br_type == ACKNOWLEDGE ) {
1274         if (check_col(pinfo->cinfo, COL_INFO))
1275         col_set_str(pinfo->cinfo, COL_INFO, "Binding Revocation Acknowledge");
1276
1277         if (mip6_tree)
1278         {
1279             ti = proto_tree_add_text(mip6_tree, tvb, MIP6_DATA_OFF,
1280                 PMIP6_BRI_LEN, "Binding Revocation Acknowledge");
1281
1282             field_tree = proto_item_add_subtree(ti, ett_mip6);
1283
1284             proto_tree_add_item(field_tree, hf_pmip6_bri_brtype, tvb,
1285                 PMIP6_BRI_BRTYPE_OFF, PMIP6_BRI_BRTYPE_LEN, ENC_BIG_ENDIAN);
1286
1287             proto_tree_add_item(field_tree, hf_pmip6_bri_status, tvb,
1288                 PMIP6_BRI_STATUS_OFF, PMIP6_BRI_STATUS_LEN, ENC_BIG_ENDIAN);
1289
1290             proto_tree_add_item(field_tree, hf_pmip6_bri_seqnr, tvb,
1291                 PMIP6_BRI_SEQNR_OFF, PMIP6_BRI_SEQNR_LEN, ENC_BIG_ENDIAN);
1292
1293             proto_tree_add_item(field_tree, hf_pmip6_bri_ap_flag, tvb,
1294                 PMIP6_BRI_FLAGS_OFF, PMIP6_BRI_FLAGS_LEN, ENC_BIG_ENDIAN);
1295
1296             proto_tree_add_item(field_tree, hf_pmip6_bri_ag_flag, tvb,
1297                 PMIP6_BRI_FLAGS_OFF, PMIP6_BRI_FLAGS_LEN, ENC_BIG_ENDIAN);
1298
1299             proto_tree_add_item(field_tree, hf_pmip6_bri_res, tvb,
1300                 PMIP6_BRI_RES_OFF, PMIP6_BRI_RES_LEN, ENC_BIG_ENDIAN);
1301         }
1302     }
1303
1304     return MIP6_DATA_OFF + PMIP6_BRI_LEN;
1305 }
1306
1307 /* Functions to dissect the mobility options */
1308 static void
1309 dissect_mip6_opt_padn(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
1310               guint optlen, packet_info *pinfo _U_,
1311               proto_tree *opt_tree)
1312 {
1313     proto_tree_add_text(opt_tree, tvb, offset, optlen,
1314             "%s: %u bytes", optp->name, optlen);
1315 }
1316
1317 static void
1318 dissect_mip6_opt_bra(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
1319              guint optlen, packet_info *pinfo _U_,
1320              proto_tree *opt_tree)
1321 {
1322     int ri;
1323
1324     ri = tvb_get_ntohs(tvb, offset + MIP6_BRA_RI_OFF);
1325     proto_tree_add_uint_format(opt_tree, hf_mip6_bra_interval, tvb,
1326             offset, optlen,
1327             ri, "Refresh interval: %d (%ld seconds)",
1328             ri, (long)ri * 4);
1329 }
1330
1331 static void
1332 dissect_mip6_opt_acoa(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
1333               guint optlen, packet_info *pinfo _U_,
1334               proto_tree *opt_tree)
1335 {
1336     proto_tree_add_ipv6(opt_tree, hf_mip6_acoa_acoa, tvb, offset, optlen,
1337             tvb_get_ptr(tvb, offset + MIP6_ACOA_ACOA_OFF, MIP6_ACOA_ACOA_LEN));
1338 }
1339
1340 static void
1341 dissect_mip6_nemo_opt_mnp(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
1342               guint optlen, packet_info *pinfo _U_,
1343               proto_tree *opt_tree)
1344 {
1345     proto_tree *field_tree = NULL;
1346     proto_item *tf;
1347     tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s", optp->name);
1348     field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1349     proto_tree_add_item(field_tree, hf_mip6_nemo_mnp_pfl, tvb,
1350             offset + MIP6_NEMO_MNP_PL_OFF, 1, ENC_BIG_ENDIAN);
1351
1352     proto_tree_add_item(field_tree, hf_mip6_nemo_mnp_mnp, tvb,
1353             offset + MIP6_NEMO_MNP_MNP_OFF, MIP6_NEMO_MNP_MNP_LEN, ENC_NA);
1354 }
1355
1356 static void
1357 dissect_mip6_opt_ni(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
1358             guint optlen, packet_info *pinfo _U_,
1359             proto_tree *opt_tree)
1360 {
1361     proto_tree *field_tree = NULL;
1362     proto_item *tf;
1363
1364     tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s", optp->name);
1365     field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1366
1367     proto_tree_add_item(field_tree, hf_mip6_ni_hni, tvb,
1368             offset + MIP6_NI_HNI_OFF, MIP6_NI_HNI_LEN, ENC_BIG_ENDIAN);
1369     proto_tree_add_item(field_tree, hf_mip6_ni_cni, tvb,
1370             offset + MIP6_NI_CNI_OFF, MIP6_NI_CNI_LEN, ENC_BIG_ENDIAN);
1371 }
1372
1373 /* 5 Authorization Data */
1374 static void
1375 dissect_mip6_opt_bad(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
1376              guint optlen, packet_info *pinfo _U_,
1377              proto_tree *opt_tree)
1378 {
1379     proto_tree *field_tree = NULL;
1380     proto_item *tf;
1381
1382     tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s", optp->name);
1383     field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1384
1385     proto_tree_add_item(field_tree, hf_mip6_bad_auth, tvb,
1386             offset + MIP6_BAD_AUTH_OFF,
1387             optlen - MIP6_BAD_AUTH_OFF, ENC_NA);
1388 }
1389
1390 /* 7 Mobility Header Link-Layer Address option [RFC5568] */
1391 static void
1392 dissect_fmip6_opt_lla(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
1393               guint optlen, packet_info *pinfo _U_,
1394               proto_tree *opt_tree)
1395 {
1396     proto_tree *field_tree = NULL;
1397     proto_item *tf;
1398     int len, p;
1399
1400     tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s", optp->name);
1401     field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1402
1403     proto_tree_add_item(field_tree, hf_fmip6_lla_optcode, tvb,
1404             offset + FMIP6_LLA_OPTCODE_OFF, FMIP6_LLA_OPTCODE_LEN, ENC_BIG_ENDIAN);
1405
1406     p = offset + FMIP6_LLA_LLA_OFF;
1407     len = optlen - FMIP6_LLA_LLA_OFF;
1408
1409     if (len > 0) {
1410         /*
1411          * I'm not sure what "The format of the option when the LLA is 6
1412          * bytes is shown in Figure 15.  When the LLA size is different,
1413          * the option MUST be aligned appropriately.  See Section 6.2 in
1414          * [3]." in RFC 4068 says should be done with an LLA size other
1415          * than 6 bytes; section 6.2 in RFC 3775 (reference 3 in RFC 4068)
1416          * says "Mobility options may have alignment requirements.  Following
1417          * the convention in IPv6, these options are aligned in a packet so
1418          * that multi-octet values within the Option Data field of each
1419          * option fall on natural boundaries (i.e., fields of width n octets
1420          * are placed at an integer multiple of n octets from the start of
1421          * the header, for n = 1, 2, 4, or 8) [11]."
1422          *
1423          * Reference 11 in RFC 3775 is RFC 2460, the IPv6 spec; nothing
1424          * in there seems to talk about inserting padding *inside* the
1425          * data value of an option, so I'm not sure what the extra pad0
1426          * is doing there, unless the idea is to arrange that the LLA is
1427          * at least aligned on a 2-byte boundary, in which case presumably
1428          * it's always present.  We'll assume that.
1429          */
1430         if (len > 1) {
1431             /* Skip padding. */
1432             p += 1;
1433             len -= 1;
1434             proto_tree_add_text(field_tree, tvb,
1435                     p, len, "Link-layer address: %s",
1436                     tvb_bytes_to_str_punct(tvb, p, len, ':'));
1437         }
1438     }
1439 }
1440
1441 /* 8 MN-ID-OPTION-TYPE */
1442 static void
1443 dissect_mip6_opt_mnid(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
1444               guint optlen, packet_info *pinfo _U_, proto_tree *opt_tree)
1445 {
1446     proto_tree *field_tree = NULL;
1447     proto_item *tf;
1448     int len, p;
1449
1450     tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s", optp->name);
1451     field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1452
1453     proto_tree_add_item(field_tree, hf_mip6_mnid_subtype, tvb,
1454             offset + MIP6_MNID_SUBTYPE_OFF, MIP6_MNID_SUBTYPE_LEN, ENC_BIG_ENDIAN);
1455
1456     p = offset + MIP6_MNID_MNID_OFF;
1457     len = optlen - MIP6_MNID_MNID_OFF;
1458
1459     if (len > 0)
1460         proto_tree_add_text(field_tree, tvb, p, len, "Identifier: %s", tvb_format_text(tvb, p, len));
1461 }
1462
1463 /* 19 Vendor Specific Mobility Option [RFC5094]  */
1464 static void
1465 dissect_mip6_opt_vsm(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
1466              guint optlen, packet_info *pinfo _U_, proto_tree *opt_tree)
1467 {
1468     proto_tree *field_tree = NULL;
1469     proto_item *tf;
1470     int len, p;
1471     guint32 vendorid;
1472     int hf_mip6_vsm_subtype_local;
1473
1474     tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s", optp->name);
1475     field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1476
1477     proto_tree_add_item(field_tree, hf_mip6_vsm_vid, tvb,
1478             offset + MIP6_VSM_VID_OFF, MIP6_VSM_VID_LEN, ENC_BIG_ENDIAN);
1479
1480     vendorid = tvb_get_ntohl(tvb, offset+MIP6_VSM_VID_OFF);
1481     switch (vendorid) {
1482     case VENDOR_THE3GPP:
1483         hf_mip6_vsm_subtype_local = hf_mip6_vsm_subtype_3gpp;
1484         break;
1485     default:
1486         hf_mip6_vsm_subtype_local = hf_mip6_vsm_subtype;
1487         break;
1488     }
1489     proto_tree_add_item(field_tree, hf_mip6_vsm_subtype_local, tvb,
1490             offset + MIP6_VSM_SUBTYPE_OFF, MIP6_VSM_SUBTYPE_LEN, ENC_BIG_ENDIAN);
1491
1492     p = offset + MIP6_VSM_DATA_OFF;
1493     len = optlen - MIP6_VSM_DATA_OFF;
1494     if (len > 0)
1495         proto_tree_add_text(field_tree, tvb, p, len, "Data");
1496
1497 }
1498
1499 /* 20 Service Selection Mobility Option [RFC5149]  */
1500 static void
1501 dissect_mip6_opt_ssm(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
1502              guint optlen, packet_info *pinfo _U_, proto_tree *opt_tree)
1503 {
1504     int len, p;
1505
1506     p = offset + MIP6_SSM_SSM_OFF;
1507     len = optlen - MIP6_SSM_SSM_OFF;
1508
1509     if (len > 0)
1510         proto_tree_add_text(opt_tree, tvb, p, len, "Identifier: %s", tvb_format_text(tvb, p, len));
1511 }
1512
1513  /* 23 Handoff Indicator Option [RFC5213]   */
1514 static void
1515 dissect_pmip6_opt_hi(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
1516              guint optlen _U_, packet_info *pinfo _U_, proto_tree *opt_tree)
1517 {
1518
1519     proto_tree_add_item(opt_tree, hf_pmip6_hi_opttype, tvb,
1520             offset + PMIP6_HI_HI_OFF, PMIP6_HI_HI_LEN, ENC_BIG_ENDIAN);
1521 }
1522
1523 /* 24 Access Technology Type Option [RFC5213]  */
1524 static void
1525 dissect_pmip6_opt_att(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
1526               guint optlen _U_, packet_info *pinfo _U_, proto_tree *opt_tree)
1527 {
1528
1529     proto_tree_add_item(opt_tree, hf_pmip6_att_opttype, tvb,
1530             offset + PMIP6_ATT_ATT_OFF, PMIP6_ATT_ATT_LEN, ENC_BIG_ENDIAN);
1531 }
1532
1533 /* 26 Link-local Address Option [RFC5213   */
1534 static void dissect_pmip6_opt_lla(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
1535                         guint optlen, packet_info *pinfo _U_, proto_tree *opt_tree)
1536 {
1537     proto_item      *ti;
1538     proto_tree      *field_tree;
1539
1540     if (opt_tree){
1541     ti = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s", optp->name);
1542         field_tree = proto_item_add_subtree(ti, *optp->subtree_index);
1543
1544         proto_tree_add_item(field_tree, hf_pmip6_opt_lila_lla, tvb, offset + 2, 16, ENC_NA);
1545    }
1546 }
1547
1548 /* 27 Timestamp */
1549 static void
1550 dissect_pmip6_opt_ts(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
1551              guint optlen _U_, packet_info *pinfo _U_, proto_tree *opt_tree)
1552 {
1553     proto_tree_add_item(opt_tree, hf_pmip6_timestamp, tvb, offset+2, 8,
1554                 ENC_TIME_NTP|ENC_BIG_ENDIAN);
1555 }
1556
1557  /* 28 Restart Counter [RFC5847] */
1558 static void
1559 dissect_pmip6_opt_rc(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
1560              guint optlen _U_, packet_info *pinfo _U_, proto_tree *opt_tree)
1561 {
1562     proto_tree_add_item(opt_tree, hf_pmip6_rc, tvb,
1563             offset + PMIP6_RC_RC_OFF, PMIP6_RC_RC_LEN, ENC_BIG_ENDIAN);
1564
1565 }
1566
1567 /* 29 IPv4 Home Address [RFC5555]  */
1568 static void
1569 dissect_pmip6_opt_ipv4ha(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
1570              guint optlen, packet_info *pinfo _U_, proto_tree *opt_tree)
1571 {
1572     proto_tree *field_tree = NULL;
1573     proto_item *tf;
1574     int len, p;
1575
1576     tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s", optp->name);
1577     field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1578
1579     p = offset + MIP6_IPV4HA_PREFIXL_OFF;
1580     len = MIP6_IPV4HA_PREFIXL_LEN;
1581
1582     proto_tree_add_item(field_tree, hf_mip6_ipv4ha_preflen, tvb, p, len, ENC_BIG_ENDIAN);
1583     proto_tree_add_item(field_tree, hf_mip6_ipv4ha_p_flag, tvb, p, len+1, ENC_BIG_ENDIAN);
1584
1585     proto_tree_add_item(field_tree, hf_mip6_ipv4ha_ha, tvb,
1586             offset + MIP6_IPV4HA_HA_OFF, MIP6_IPV4HA_HA_LEN, ENC_BIG_ENDIAN);
1587
1588 }
1589
1590 /* 30 IPv4 Address Acknowledgement [RFC5555] */
1591 static void
1592 dissect_pmip6_opt_ipv4aa(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
1593              guint optlen, packet_info *pinfo _U_, proto_tree *opt_tree)
1594 {
1595     proto_tree *field_tree = NULL;
1596     proto_item *tf;
1597
1598     tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s", optp->name);
1599     field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1600
1601     proto_tree_add_item(field_tree, hf_mip6_ipv4aa_status, tvb,
1602             offset + MIP6_IPV4AA_STATUS_OFF, MIP6_IPV4AA_STATUS_LEN, ENC_BIG_ENDIAN);
1603
1604     proto_tree_add_item(field_tree, hf_mip6_ipv4ha_preflen, tvb,
1605             offset + MIP6_IPV4AA_PREFIXL_OFF, MIP6_IPV4AA_PREFIXL_LEN, ENC_BIG_ENDIAN);
1606
1607     proto_tree_add_item(field_tree, hf_mip6_ipv4ha_ha, tvb,
1608             offset + MIP6_IPV4AA_HA_OFF, MIP6_IPV4AA_HA_LEN, ENC_BIG_ENDIAN);
1609
1610 }
1611
1612 /* 33 GRE Key Option [RFC5845]  */
1613 static void
1614 dissect_pmip6_opt_grek(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
1615                guint optlen _U_, packet_info *pinfo _U_, proto_tree *opt_tree)
1616 {
1617     proto_tree_add_item(opt_tree, hf_pmip6_gre_key, tvb,
1618             offset + PMIP6_GREK_ID_OFF, PMIP6_GREK_ID_LEN, ENC_BIG_ENDIAN);
1619
1620 }
1621
1622 /* 36 IPv4 Home Address Request [RFC5844] */
1623 static void
1624 dissect_pmip6_opt_ipv4hareq(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
1625                 guint optlen, packet_info *pinfo _U_, proto_tree *opt_tree)
1626 {
1627     proto_tree *field_tree = NULL;
1628     proto_item *tf;
1629
1630     tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s", optp->name);
1631     field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1632
1633     proto_tree_add_item(field_tree, hf_mip6_ipv4ha_preflen, tvb,
1634             offset + MIP6_IPV4HAREQ_PREFIXL_OFF, MIP6_IPV4HAREQ_PREFIXL_LEN, ENC_BIG_ENDIAN);
1635
1636     proto_tree_add_item(field_tree, hf_mip6_ipv4ha_ha, tvb,
1637             offset + MIP6_IPV4HAREQ_HA_OFF, MIP6_IPV4HAREQ_HA_LEN, ENC_BIG_ENDIAN);
1638
1639 }
1640
1641 /* 37 IPv4 Home Address Reply [RFC5844] */
1642 static void
1643 dissect_pmip6_opt_ipv4harep(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
1644                 guint optlen, packet_info *pinfo _U_, proto_tree *opt_tree)
1645 {
1646     proto_tree *field_tree = NULL;
1647     proto_item *tf;
1648
1649     tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s", optp->name);
1650     field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1651
1652     proto_tree_add_item(field_tree, hf_mip6_ipv4aa_status, tvb,
1653             offset + MIP6_IPV4HAREP_STATUS_OFF, MIP6_IPV4HAREP_STATUS_LEN, ENC_BIG_ENDIAN);
1654
1655     proto_tree_add_item(field_tree, hf_mip6_ipv4ha_preflen, tvb,
1656             offset + MIP6_IPV4HAREP_PREFIXL_OFF, MIP6_IPV4HAREP_PREFIXL_LEN, ENC_BIG_ENDIAN);
1657
1658     proto_tree_add_item(field_tree, hf_mip6_ipv4ha_ha, tvb,
1659             offset + MIP6_IPV4HAREP_HA_OFF, MIP6_IPV4HAREP_HA_LEN, ENC_BIG_ENDIAN);
1660
1661 }
1662
1663 /* 38 IPv4 Default-Router Address [RFC5844] */
1664 static void
1665 dissect_pmip6_opt_ipv4dra(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
1666               guint optlen, packet_info *pinfo _U_, proto_tree *opt_tree)
1667 {
1668     proto_tree *field_tree = NULL;
1669     proto_item *tf;
1670
1671     tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s", optp->name);
1672     field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1673
1674     proto_tree_add_item(field_tree, hf_mip6_ipv4dra_dra, tvb,
1675             offset + MIP6_IPV4DRA_DRA_OFF, MIP6_IPV4DRA_DRA_LEN, ENC_BIG_ENDIAN);
1676
1677 }
1678
1679 static const ip_tcp_opt mip6_opts[] = {
1680 {
1681     MIP6_PAD1,                  /* 0 Pad1 [RFC3775] */
1682     "Pad1",
1683     NULL,
1684     NO_LENGTH,
1685     0,
1686     NULL,
1687 },
1688 {
1689     MIP6_PADN,                  /* 1 PadN [RFC3775] */
1690     "PadN",
1691     &ett_mip6_opt_padn,
1692     VARIABLE_LENGTH,
1693     0,
1694     dissect_mip6_opt_padn
1695 },
1696 {
1697     MIP6_BRA,                   /* 2 Binding Refresh Advice */
1698     "Binding Refresh Advice",
1699     &ett_mip6_opt_bra,
1700     FIXED_LENGTH,
1701     MIP6_BRA_LEN,
1702     dissect_mip6_opt_bra
1703 },
1704 {
1705     MIP6_ACOA,                  /*3  Alternate Care-of Address */
1706     "Alternate Care-of Address",
1707     &ett_mip6_opt_acoa,
1708     FIXED_LENGTH,
1709     MIP6_ACOA_LEN,
1710     dissect_mip6_opt_acoa
1711 },
1712 {
1713     MIP6_NI,                    /* 4 Nonce Indices */
1714     "Nonce Indices",
1715     &ett_mip6_opt_ni,
1716     FIXED_LENGTH,
1717     MIP6_NI_LEN,
1718     dissect_mip6_opt_ni
1719 },
1720 {
1721     MIP6_AUTD,                  /* 5 Authorization Data */
1722     "Authorization Data",
1723     &ett_mip6_opt_bad,
1724     VARIABLE_LENGTH,
1725     0,
1726     dissect_mip6_opt_bad
1727 },
1728 {
1729     MIP6_MNP,                   /* 6 Mobile Network Prefix Option */
1730     "Mobile Network Prefix",
1731     &ett_mip6_nemo_opt_mnp,
1732     FIXED_LENGTH,
1733     MIP6_NEMO_MNP_LEN,
1734     dissect_mip6_nemo_opt_mnp
1735 },
1736 {
1737     MIP6_MHLLA,                 /* 7 Mobility Header Link-Layer Address option [RFC5568] */
1738     "Mobility Header Link-Layer Address option",
1739     &ett_fmip6_opt_lla,
1740     VARIABLE_LENGTH,
1741     FMIP6_LLA_MINLEN,
1742     dissect_fmip6_opt_lla
1743 },
1744 {
1745     MIP6_MNID,                  /* 8 MN-ID-OPTION-TYPE */
1746     "Mobile Node Identifier",
1747     &ett_mip6_opt_mnid,
1748     VARIABLE_LENGTH,
1749     MIP6_MNID_MINLEN,
1750     dissect_mip6_opt_mnid
1751 },
1752 {
1753     MIP6_VSM,                   /* 19 Vendor Specific Mobility Option [RFC5094]  */
1754     "Vendor Specific Mobility",
1755     &ett_mip6_opt_vsm,
1756     VARIABLE_LENGTH,
1757     MIP6_VSM_MINLEN,
1758     dissect_mip6_opt_vsm
1759 },
1760 {
1761     MIP6_SSM,                   /* 20 Service Selection Mobility Option [RFC5149]  */
1762     "Service Selection Mobility",
1763     &ett_mip6_opt_ssm,
1764     VARIABLE_LENGTH,
1765     MIP6_SSM_MINLEN,
1766     dissect_mip6_opt_ssm
1767 },
1768 {
1769     MIP6_HNP,                   /* 22 Home Network Prefix Option [RFC5213]   */
1770     "Home Network Prefix",
1771     &ett_pmip6_opt_hnp,
1772     FIXED_LENGTH,
1773     MIP6_NEMO_MNP_LEN,
1774     dissect_mip6_nemo_opt_mnp
1775 },
1776 {
1777     MIP6_MOHI,                  /* 23 Handoff Indicator Option [RFC5213]   */
1778     "Handoff Indicator Option",
1779     &ett_pmip6_opt_hi,
1780     FIXED_LENGTH,
1781     PMIP6_HI_LEN,
1782     dissect_pmip6_opt_hi
1783 },
1784 {
1785     MIP6_ATT,                   /* 24 Access Technology Type Option [RFC5213]  */
1786     "Access Technology Type Option",
1787     &ett_pmip6_opt_att,
1788     FIXED_LENGTH,
1789     PMIP6_ATT_LEN,
1790     dissect_pmip6_opt_att
1791 },
1792 {
1793     MIP6_LLA,                        /* 26 Link-local Address Option [RFC5213   */
1794     "Link-local Address",
1795     &ett_pmip6_opt_lla,
1796     FIXED_LENGTH,
1797     PMIP6_LLA_LEN,
1798     dissect_pmip6_opt_lla
1799 },
1800
1801 {
1802     MIP6_TS,                    /* 27 Timestamp */
1803     "Timestamp",
1804     &ett_pmip6_opt_ts,
1805     FIXED_LENGTH,
1806     PMIP6_TS_LEN,
1807     dissect_pmip6_opt_ts
1808 },
1809 {
1810     MIP6_RC,                    /* 28 Restart Counter [RFC5847] */
1811     "Restart Counter",
1812     &ett_pmip6_opt_rc,
1813     FIXED_LENGTH,
1814     PMIP6_RC_LEN,
1815     dissect_pmip6_opt_rc
1816 },
1817 {
1818     MIP6_IPV4HA,                /* 29 IPv4 Home Address [RFC5555]  */
1819     "IPv4 Home Address",
1820     &ett_mip6_opt_ipv4ha,
1821     FIXED_LENGTH,
1822     MIP6_IPV4HA_LEN,
1823     dissect_pmip6_opt_ipv4ha
1824 },
1825 {
1826     MIP6_IPV4AA,                /* 30 IPv4 Address Acknowledgement [RFC5555] */
1827     "IPv4 Address Acknowledgement",
1828     &ett_mip6_opt_ipv4aa,
1829     FIXED_LENGTH,
1830     MIP6_IPV4AA_LEN,
1831     dissect_pmip6_opt_ipv4aa
1832 },
1833 {
1834     MIP6_GREK,                  /* 33 GRE Key Option [RFC5845]  */
1835     "GRE Key",
1836     &ett_pmip6_opt_grek,
1837     FIXED_LENGTH,
1838     PMIP6_GREK_LEN,
1839     dissect_pmip6_opt_grek
1840 },
1841 {
1842     MIP6_IPV4HAREQ,             /* 36 IPv4 Home Address Request [RFC5844] */
1843     "IPv4 Home Address Request",
1844     &ett_mip6_opt_ipv4hareq,
1845     FIXED_LENGTH,
1846     MIP6_IPV4HAREQ_LEN,
1847     dissect_pmip6_opt_ipv4hareq
1848 },
1849 {
1850     MIP6_IPV4HAREP,            /* 37 IPv4 Home Address Reply [RFC5844] */
1851     "IPv4 Home Address Reply",
1852     &ett_mip6_opt_ipv4harep,
1853     FIXED_LENGTH,
1854     MIP6_IPV4HAREP_LEN,
1855     dissect_pmip6_opt_ipv4harep
1856 },
1857 {
1858     MIP6_IPV4DRA,               /* 38 IPv4 Default-Router Address [RFC5844] */
1859     "IPv4 Default-Router Address",
1860     &ett_mip6_opt_ipv4dra,
1861     FIXED_LENGTH,
1862     MIP6_IPV4DRA_LEN,
1863     dissect_pmip6_opt_ipv4dra
1864 },
1865 };
1866
1867 #define N_MIP6_OPTS (sizeof mip6_opts / sizeof mip6_opts[0])
1868
1869
1870 /* Like "dissect_ip_tcp_options()", but assumes the length of an option
1871  * *doesn't* include the type and length bytes.  The option parsers,
1872  * however, are passed a length that *does* include them.
1873  */
1874 static void
1875 dissect_mipv6_options(tvbuff_t *tvb, int offset, guint length,
1876               const ip_tcp_opt *opttab, int nopts, int eol,
1877               packet_info *pinfo, proto_tree *opt_tree)
1878 {
1879     proto_item       *ti;
1880     guchar            opt;
1881     const ip_tcp_opt  *optp;
1882     opt_len_type      len_type;
1883     unsigned int      optlen;
1884     const char        *name;
1885     char              name_str[7+1+1+2+2+1+1];  /* "Unknown (0x%02x)" */
1886     void              (*dissect)(const struct ip_tcp_opt *, tvbuff_t *,
1887                          int, guint, packet_info *, proto_tree *);
1888     guint             len;
1889
1890     while (length > 0) {
1891         opt = tvb_get_guint8(tvb, offset);
1892         for (optp = &opttab[0]; optp < &opttab[nopts]; optp++) {
1893             if (optp->optcode == opt)
1894                 break;
1895         }
1896         if (optp == &opttab[nopts]) {
1897             /* We assume that the only NO_LENGTH options are Pad1 options,
1898              * so that we can treat unknown options as VARIABLE_LENGTH with a
1899              * minimum of 0, and at least be able to move on to the next option
1900              * by using the length in the option.
1901              */
1902             optp = NULL;    /* indicate that we don't know this option */
1903             len_type = VARIABLE_LENGTH;
1904             optlen = 0;
1905             g_snprintf(name_str, sizeof name_str, "Unknown (0x%02x)", opt);
1906             name = name_str;
1907             dissect = NULL;
1908         } else {
1909             len_type = optp->len_type;
1910             optlen = optp->optlen;
1911             name = optp->name;
1912             dissect = optp->dissect;
1913         }
1914         --length;      /* account for type byte */
1915         if (len_type != NO_LENGTH) {
1916             /* Option has a length. Is it in the packet? */
1917             if (length == 0) {
1918                 /* Bogus - packet must at least include
1919                  * option code byte and length byte!
1920                  */
1921                 proto_tree_add_text(opt_tree, tvb, offset,      1,
1922                         "%s (length byte past end of options)", name);
1923                 return;
1924             }
1925             len = tvb_get_guint8(tvb, offset + 1);  /* Size specified in option */
1926             --length;    /* account for length byte */
1927             if (len > length) {
1928                 /* Bogus - option goes past the end of the header. */
1929                 proto_tree_add_text(opt_tree, tvb, offset,      length,
1930                         "%s (option length = %u byte%s says option goes past end of options)",
1931                         name, len, plurality(len, "", "s"));
1932                 return;
1933             } else if (len_type == FIXED_LENGTH && len != optlen) {
1934                 /* Bogus - option length isn't what it's supposed to be for this
1935                    option. */
1936                 proto_tree_add_text(opt_tree, tvb, offset, len + 2,
1937                         "%s (with option length = %u byte%s; should be %u)", name,
1938                         len, plurality(len, "", "s"), optlen);
1939                 return;
1940             } else if (len_type == VARIABLE_LENGTH && len < optlen) {
1941                 /* Bogus - option length is less than what it's supposed to be for
1942                    this option. */
1943                 proto_tree_add_text(opt_tree, tvb, offset, len + 2,
1944                         "%s (with option length = %u byte%s; should be >= %u)", name,
1945                         len, plurality(len, "", "s"), optlen);
1946                 return;
1947             } else {
1948                 ti = proto_tree_add_item(opt_tree, hf_mip6_mobility_opt, tvb, offset, 1, ENC_BIG_ENDIAN);
1949                 if (optp == NULL) {
1950                     proto_item *expert_item;
1951                     proto_item_append_text(ti, "(%u byte%s)",len, plurality(len, "", "s"));
1952                     expert_item = proto_tree_add_text(opt_tree, tvb,  offset+2, len, "IE data not dissected yet");
1953                     expert_add_info_format(pinfo, expert_item, PI_PROTOCOL, PI_NOTE, "IE data not dissected yet");
1954                     PROTO_ITEM_SET_GENERATED(expert_item);
1955                 } else {
1956                     if (dissect != NULL) {
1957                         /* Option has a dissector. */
1958                         if (opt == MIP6_MHLLA)
1959                             (*dissect)(optp, tvb, offset,
1960                                    len + 2 + FMIP6_LLA_OPTCODE_LEN, pinfo, opt_tree);
1961                         else
1962                             (*dissect)(optp, tvb, offset, len + 2, pinfo, opt_tree);
1963                     }
1964                 }
1965                 /* RFC4068 Section 6.4.4
1966                  *   Length         The size of this option in octets not including the
1967                  *                  Type, Length, and Option-Code fields.
1968                  */
1969                 if (opt == MIP6_MHLLA)
1970                     offset += len + 2 + FMIP6_LLA_OPTCODE_LEN;
1971                 else
1972                     offset += len + 2;
1973             }
1974             if (opt == MIP6_MHLLA)
1975                 length -= (len + FMIP6_LLA_OPTCODE_LEN);
1976             else
1977                 length -= len;
1978         } else {
1979             proto_tree_add_text(opt_tree, tvb, offset, 1, "%s", name);
1980             offset += 1;
1981         }
1982         if (opt == eol)
1983             break;
1984     }
1985 }
1986
1987 /* Function to dissect mobility options */
1988 static int
1989 dissect_mip6_options(tvbuff_t *tvb, proto_tree *mip6_tree, int offset, int len,
1990              packet_info *pinfo)
1991 {
1992     proto_tree *opts_tree = NULL;
1993     proto_item *ti;
1994
1995     if (!mip6_tree)
1996         return len;
1997
1998     ti = proto_tree_add_text(mip6_tree, tvb, offset, len, "Mobility Options");
1999     opts_tree = proto_item_add_subtree(ti, ett_mip6);
2000
2001     dissect_mipv6_options(tvb, offset, len, mip6_opts, N_MIP6_OPTS, -1, pinfo, opts_tree);
2002
2003     return len;
2004 }
2005
2006 /* Function that dissects the whole MIPv6 packet */
2007 static void
2008 dissect_mip6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2009 {
2010     proto_tree *mip6_tree = NULL;
2011     proto_item *ti;
2012     guint8     type, pproto;
2013     guint      len, offset = 0, start_offset = offset;
2014
2015     /* Make entries in Protocol column and Info column on summary display */
2016     col_set_str(pinfo->cinfo, COL_PROTOCOL, "MIPv6");
2017     col_clear(pinfo->cinfo, COL_INFO);
2018
2019     len = (tvb_get_guint8(tvb, MIP6_HLEN_OFF) + 1) * 8;
2020     pproto = tvb_get_guint8(tvb, MIP6_PROTO_OFF);
2021     if (tree) {
2022         ti = proto_tree_add_item(tree, proto_mip6, tvb, 0, len, ENC_NA);
2023         mip6_tree = proto_item_add_subtree(ti, ett_mip6);
2024
2025         /* Process header fields */
2026         proto_tree_add_uint_format(mip6_tree, hf_mip6_proto, tvb,
2027                 MIP6_PROTO_OFF, 1,
2028                 tvb_get_guint8(tvb, MIP6_PROTO_OFF),
2029                 "Payload protocol: %s (0x%02x)",
2030                 ipprotostr(
2031                     tvb_get_guint8(tvb, MIP6_PROTO_OFF)),
2032                 tvb_get_guint8(tvb, MIP6_PROTO_OFF));
2033
2034         proto_tree_add_uint_format(mip6_tree, hf_mip6_hlen, tvb,
2035                 MIP6_HLEN_OFF, 1,
2036                 tvb_get_guint8(tvb, MIP6_HLEN_OFF),
2037                 "Header length: %u (%u bytes)",
2038                 tvb_get_guint8(tvb, MIP6_HLEN_OFF),
2039                 len);
2040
2041         proto_tree_add_item(mip6_tree, hf_mip6_mhtype, tvb,
2042                 MIP6_TYPE_OFF, 1, ENC_BIG_ENDIAN);
2043
2044         proto_tree_add_item(mip6_tree, hf_mip6_reserved, tvb,
2045                 MIP6_RES_OFF, 1, ENC_BIG_ENDIAN);
2046
2047         proto_tree_add_item(mip6_tree, hf_mip6_csum, tvb,
2048                 MIP6_CSUM_OFF, 2, ENC_BIG_ENDIAN);
2049     }
2050
2051     /* Process mobility header */
2052     type = tvb_get_guint8(tvb, MIP6_TYPE_OFF);
2053     switch (type) {
2054     case MIP6_BRR:
2055         /* Binding Refresh Request */
2056         offset = dissect_mip6_brr(tvb, mip6_tree, pinfo);
2057         break;
2058     case MIP6_HOTI:
2059         /* Home Test Init */
2060         offset = dissect_mip6_hoti(tvb, mip6_tree, pinfo);
2061         break;
2062     case MIP6_MHCOTI:
2063         /* Care-of Test Init */
2064         offset = dissect_mip6_coti(tvb, mip6_tree, pinfo);
2065         break;
2066     case MIP6_HOT:
2067         /* Home Test */
2068         offset = dissect_mip6_hot(tvb, mip6_tree, pinfo);
2069         break;
2070     case MIP6_MHCOT:
2071         /* Care-of Test */
2072         offset = dissect_mip6_cot(tvb, mip6_tree, pinfo);
2073         break;
2074     case MIP6_BU:
2075         /* Binding Update */
2076         offset = dissect_mip6_bu(tvb, mip6_tree, pinfo);
2077         if (proto_nemo == 1) {
2078             col_set_str(pinfo->cinfo, COL_PROTOCOL, "NEMO");
2079         }
2080         break;
2081     case MIP6_BA:
2082         /* Binding Acknowledgement */
2083         offset = dissect_mip6_ba(tvb, mip6_tree, pinfo);
2084         if (proto_nemo == 1) {
2085             col_set_str(pinfo->cinfo, COL_PROTOCOL, "NEMO");
2086         }
2087         break;
2088     case MIP6_BE:
2089         /* Binding Error */
2090         offset = dissect_mip6_be(tvb, mip6_tree, pinfo);
2091         break;
2092     case MIP6_FBU:
2093         /* Fast Binding Update */
2094         offset = dissect_fmip6_fbu(tvb, mip6_tree, pinfo);
2095         break;
2096     case MIP6_FBACK:
2097         /* Fast Binding Acknowledgment */
2098         offset = dissect_fmip6_fback(tvb, mip6_tree, pinfo);
2099         break;
2100     case MIP6_FNA:
2101         /* Fast Neighbor Advertisement */
2102         offset = dissect_fmip6_fna(tvb, mip6_tree, pinfo);
2103         break;
2104     case MIP6_HB:
2105         /* Heartbeat */
2106         offset = dissect_mip6_hb(tvb, mip6_tree, pinfo);
2107         break;
2108     case MIP6_BR:
2109         /* Binding Revocation Indication / Acknowledge */
2110         offset = dissect_pmip6_bri(tvb, mip6_tree, pinfo);
2111         break;
2112     default:
2113         dissect_mip6_unknown(tvb, mip6_tree, pinfo);
2114         offset = len;
2115         break;
2116     }
2117
2118     /* Process mobility options */
2119     if (offset < len) {
2120         if (len < (offset - start_offset)) {
2121             proto_tree_add_text(tree, tvb, 0, 0, "Bogus header length");
2122             return;
2123         }
2124         len -= (offset - start_offset);
2125         dissect_mip6_options(tvb, mip6_tree, offset, len, pinfo);
2126     }
2127
2128     if (type == MIP6_FNA && pproto == IP_PROTO_IPV6) {
2129         tvbuff_t *ipv6_tvb;
2130
2131         ipv6_tvb = tvb_new_subset_remaining(tvb, len + 8);
2132
2133         /* Call the IPv6 dissector */
2134         dissector_try_uint(ip_dissector_table, pproto, ipv6_tvb, pinfo, tree);
2135
2136         col_set_str(pinfo->cinfo, COL_INFO, "Fast Neighbor Advertisement[Fast Binding Update]");
2137     }
2138 }
2139
2140 /* Register the protocol with Wireshark */
2141 void
2142 proto_register_mip6(void)
2143 {
2144     /* Setup list of header fields */
2145     static hf_register_info hf[] = {
2146
2147     { &hf_mip6_proto,           { "Payload protocol", "mip6.proto",
2148                                   FT_UINT8, BASE_DEC, NULL, 0,
2149                                   NULL, HFILL }},
2150     { &hf_mip6_hlen,            { "Header length", "mip6.hlen",
2151                                   FT_UINT8, BASE_DEC, NULL, 0,
2152                                   NULL, HFILL }},
2153     { &hf_mip6_mhtype,          { "Mobility Header Type", "mip6.mhtype",
2154                                   FT_UINT8, BASE_DEC, VALS(mip6_mh_types), 0,
2155                                   NULL, HFILL }},
2156     { &hf_mip6_reserved,        { "Reserved", "mip6.reserved",
2157                                   FT_UINT8, BASE_HEX, NULL, 0,
2158                                   NULL, HFILL }},
2159     { &hf_mip6_csum,            { "Checksum", "mip6.csum",
2160                                   FT_UINT16, BASE_HEX, NULL, 0,
2161                                   "Header Checksum", HFILL }},
2162
2163     { &hf_mip6_hoti_cookie,     { "Home Init Cookie", "mip6.hoti.cookie",
2164                                   FT_UINT64, BASE_HEX, NULL, 0,
2165                                   NULL, HFILL }},
2166
2167     { &hf_mip6_coti_cookie,     { "Care-of Init Cookie", "mip6.coti.cookie",
2168                                   FT_UINT64, BASE_HEX, NULL, 0,
2169                                   NULL, HFILL }},
2170
2171     { &hf_mip6_hot_nindex,      { "Home Nonce Index", "mip6.hot.nindex",
2172                                   FT_UINT16, BASE_DEC, NULL, 0,
2173                                   NULL, HFILL }},
2174     { &hf_mip6_hot_cookie,      { "Home Init Cookie", "mip6.hot.cookie",
2175                                   FT_UINT64, BASE_HEX, NULL, 0,
2176                                   NULL, HFILL }},
2177     { &hf_mip6_hot_token,       { "Home Keygen Token", "mip6.hot.token",
2178                                    FT_UINT64, BASE_HEX, NULL, 0,
2179                                    NULL, HFILL }},
2180
2181     { &hf_mip6_cot_nindex,      { "Care-of Nonce Index", "mip6.cot.nindex",
2182                                   FT_UINT16, BASE_DEC, NULL, 0,
2183                                   NULL, HFILL }},
2184     { &hf_mip6_cot_cookie,      { "Care-of Init Cookie", "mip6.cot.cookie",
2185                                   FT_UINT64, BASE_HEX, NULL, 0,
2186                                   NULL, HFILL }},
2187     { &hf_mip6_cot_token,       { "Care-of Keygen Token", "mip6.cot.token",
2188                                   FT_UINT64, BASE_HEX, NULL, 0,
2189                                   NULL, HFILL }},
2190
2191     { &hf_mip6_bu_seqnr,        { "Sequence number", "mip6.bu.seqnr",
2192                                   FT_UINT16, BASE_DEC, NULL, 0,
2193                                   NULL, HFILL }},
2194     { &hf_mip6_bu_a_flag,       { "Acknowledge (A) flag", "mip6.bu.a_flag",
2195                                   FT_BOOLEAN, 16, TFS(&mip6_bu_a_flag_value),
2196                                   0x8000, NULL, HFILL }},
2197     { &hf_mip6_bu_h_flag,       { "Home Registration (H) flag",
2198                                   "mip6.bu.h_flag",
2199                                   FT_BOOLEAN, 16, TFS(&mip6_bu_h_flag_value),
2200                                   0x4000, NULL, HFILL }},
2201     { &hf_mip6_bu_l_flag,       { "Link-Local Compatibility (L) flag",
2202                                   "mip6.bu.l_flag",
2203                                   FT_BOOLEAN, 16, TFS(&mip6_bu_l_flag_value),
2204                                   0x2000, "Home Registration (H) flag", HFILL }},
2205     { &hf_mip6_bu_k_flag,       { "Key Management Compatibility (K) flag",
2206                                   "mip6.bu.k_flag",
2207                                   FT_BOOLEAN, 16, TFS(&mip6_bu_k_flag_value),
2208                                   0x1000, NULL,
2209                                   HFILL }},
2210     { &hf_mip6_bu_m_flag,       { "MAP Registration Compatibility (M) flag",
2211                                   "mip6.bu.m_flag",
2212                                   FT_BOOLEAN, 16, TFS(&mip6_bu_m_flag_value),
2213                                   0x0800, NULL,
2214                                   HFILL }},
2215     { &hf_mip6_nemo_bu_r_flag,  { "Mobile Router (R) flag",
2216                                   "mip6.nemo.bu.r_flag",
2217                                   FT_BOOLEAN, 16, TFS(&mip6_nemo_bu_r_flag_value),
2218                                   0x0400, NULL,
2219                                   HFILL }},
2220     { &hf_pmip6_bu_p_flag,      { "Proxy Registration (P) flag",
2221                                   "mip6.bu.p_flag",
2222                                   FT_BOOLEAN, 16, TFS(&pmip6_bu_p_flag_value),
2223                                   0x0200, NULL,
2224                                   HFILL }},
2225     { &hf_mip6_bu_f_flag,       { "Forcing UDP encapsulation (F) flag",
2226                                   "mip6.bu.f_flag",
2227                                   FT_BOOLEAN, 16, TFS(&mip6_bu_f_flag_value),
2228                                   0x0100, NULL,
2229                                   HFILL }},
2230     { &hf_pmip6_bu_t_flag,      { "TLV-header format (T) flag",
2231                                   "mip6.bu.t_flag",
2232                                   FT_BOOLEAN, 16, TFS(&pmip6_bu_t_flag_value),
2233                                   0x0080, NULL,
2234                                   HFILL }},
2235     { &hf_mip6_bu_lifetime,     { "Lifetime", "mip6.bu.lifetime",
2236                                   FT_UINT16, BASE_DEC, NULL, 0,
2237                                   NULL, HFILL }},
2238
2239     { &hf_mip6_ba_status,       { "Status", "mip6.ba.status",
2240                                   FT_UINT8, BASE_DEC,
2241                                   VALS(mip6_ba_status_value), 0,
2242                                   "Binding Acknowledgement status", HFILL }},
2243     { &hf_mip6_ba_k_flag,       { "Key Management Compatibility (K) flag",
2244                                   "mip6.ba.k_flag",
2245                                   FT_BOOLEAN, 8, TFS(&mip6_bu_k_flag_value),
2246                                   0x80, NULL,
2247                                   HFILL }},
2248     { &hf_mip6_nemo_ba_r_flag,  { "Mobile Router (R) flag",
2249                                   "mip6.nemo.ba.r_flag",
2250                                   FT_BOOLEAN, 8, TFS(&mip6_nemo_bu_r_flag_value),
2251                                   0x40, NULL,
2252                                   HFILL }},
2253     { &hf_pmip6_ba_p_flag,      { "Proxy Registration (P) flag",
2254                                   "mip6.ba.p_flag",
2255                                   FT_BOOLEAN, 8, TFS(&pmip6_bu_p_flag_value),
2256                                   0x20, NULL,
2257                                   HFILL }},
2258     { &hf_pmip6_ba_t_flag,      { "TLV-header format (T) flag",
2259                                   "mip6.ba.t_flag",
2260                                   FT_BOOLEAN, 8, TFS(&pmip6_bu_t_flag_value),
2261                                   0x10, NULL,
2262                                   HFILL }},
2263
2264     { &hf_mip6_ba_seqnr,        { "Sequence number", "mip6.ba.seqnr",
2265                                   FT_UINT16, BASE_DEC, NULL, 0,
2266                                   NULL, HFILL }},
2267     { &hf_mip6_ba_lifetime,     { "Lifetime", "mip6.ba.lifetime",
2268                                   FT_UINT16, BASE_DEC, NULL, 0,
2269                                   NULL, HFILL }},
2270
2271     { &hf_mip6_be_status,       { "Status", "mip6.be.status",
2272                                   FT_UINT8, BASE_DEC,
2273                                   VALS(mip6_be_status_value), 0,
2274                                   "Binding Error status", HFILL }},
2275     { &hf_mip6_be_haddr,        { "Home Address", "mip6.be.haddr",
2276                                   FT_IPv6, BASE_NONE, NULL, 0,
2277                                   NULL, HFILL }},
2278
2279     { &hf_fmip6_fbu_seqnr,      { "Sequence number", "fmip6.fbu.seqnr",
2280                                   FT_UINT16, BASE_DEC, NULL, 0,
2281                                   NULL, HFILL }},
2282     { &hf_fmip6_fbu_a_flag,     { "Acknowledge (A) flag", "fmip6.fbu.a_flag",
2283                                   FT_BOOLEAN, 8, TFS(&fmip6_fbu_a_flag_value),
2284                                   0x80, NULL, HFILL }},
2285     { &hf_fmip6_fbu_h_flag,     { "Home Registration (H) flag",
2286                                   "fmip6.fbu.h_flag",
2287                                   FT_BOOLEAN, 8, TFS(&fmip6_fbu_h_flag_value),
2288                                   0x40, NULL, HFILL }},
2289     { &hf_fmip6_fbu_l_flag,     { "Link-Local Compatibility (L) flag",
2290                                   "fmip6.fbu.l_flag",
2291                                   FT_BOOLEAN, 8, TFS(&fmip6_fbu_l_flag_value),
2292                                   0x20, "Home Registration (H) flag", HFILL }},
2293     { &hf_fmip6_fbu_k_flag,     { "Key Management Compatibility (K) flag",
2294                                   "fmip6.fbu.k_flag",
2295                                   FT_BOOLEAN, 8, TFS(&fmip6_fbu_k_flag_value),
2296                                   0x10, NULL,
2297                                   HFILL }},
2298     { &hf_fmip6_fbu_lifetime,   { "Lifetime", "fmip6.fbu.lifetime",
2299                                   FT_UINT16, BASE_DEC, NULL, 0,
2300                                   NULL, HFILL }},
2301
2302     { &hf_fmip6_fback_status,   { "Status", "fmip6.fback.status",
2303                                   FT_UINT8, BASE_DEC,
2304                                   VALS(fmip6_fback_status_value), 0,
2305                                   "Fast Binding Acknowledgement status", HFILL }},
2306     { &hf_fmip6_fback_k_flag,   { "Key Management Compatibility (K) flag",
2307                                   "fmip6.fback.k_flag",
2308                                   FT_BOOLEAN, 8, TFS(&fmip6_fbu_k_flag_value),
2309                                   0x80, NULL,
2310                                   HFILL }},
2311     { &hf_fmip6_fback_seqnr,    { "Sequence number", "fmip6.fback.seqnr",
2312                                  FT_UINT16, BASE_DEC, NULL, 0,
2313                                  NULL, HFILL }},
2314     { &hf_fmip6_fback_lifetime, { "Lifetime", "fmip6.fback.lifetime",
2315                                   FT_UINT16, BASE_DEC, NULL, 0,
2316                                   NULL, HFILL }},
2317
2318     { &hf_mip6_hb_u_flag,       { "Unsolicited (U) flag", "mip6.hb.u_flag",
2319                                   FT_BOOLEAN, 8, TFS(&mip6_hb_u_flag_value),
2320                                   0x02, NULL, HFILL }},
2321     { &hf_mip6_hb_r_flag,       { "Response (R) flag", "mip6.hb.r_flag",
2322                                   FT_BOOLEAN, 8, TFS(&mip6_hb_r_flag_value),
2323                                   0x01, NULL, HFILL }},
2324     { &hf_mip6_hb_seqnr,        { "Sequence number", "mip6.hb.seqnr",
2325                                   FT_UINT32, BASE_DEC, NULL, 0,
2326                                   NULL, HFILL }},
2327
2328     { &hf_mip6_bra_interval,    { "Refresh interval", "mip6.bra.interval",
2329                                   FT_UINT16, BASE_DEC, NULL, 0,
2330                                  NULL, HFILL }},
2331
2332     { &hf_mip6_acoa_acoa,       { "Alternate care-of address", "mip6.acoa.acoa",
2333                                   FT_IPv6, BASE_NONE, NULL, 0,
2334                                   NULL, HFILL }},
2335
2336     { &hf_mip6_ni_hni,          { "Home nonce index", "mip6.ni.hni",
2337                                   FT_UINT16, BASE_DEC, NULL, 0,
2338                                   NULL, HFILL }},
2339     { &hf_mip6_ni_cni,          { "Care-of nonce index", "mip6.ni.cni",
2340                                   FT_UINT16, BASE_DEC, NULL, 0,
2341                                   NULL, HFILL }},
2342
2343     { &hf_mip6_bad_auth,        { "Authenticator", "mip6.bad.auth",
2344                                   FT_BYTES, BASE_NONE, NULL, 0,
2345                                   NULL, HFILL }},
2346
2347     { &hf_fmip6_lla_optcode,    { "Option-Code", "mip6.lla.optcode",
2348                                   FT_UINT8, BASE_DEC, VALS(fmip6_lla_optcode_value), 0,
2349                                   NULL, HFILL }},
2350
2351     { &hf_mip6_nemo_mnp_pfl,    { "Mobile Network Prefix Length", "mip6.nemo.mnp.pfl",
2352                                   FT_UINT8, BASE_DEC, NULL, 0,
2353                                   NULL, HFILL }},
2354
2355     { &hf_mip6_nemo_mnp_mnp,    { "Mobile Network Prefix", "mip6.nemo.mnp.mnp",
2356                                   FT_IPv6, BASE_NONE, NULL, 0,
2357                                   NULL, HFILL }},
2358
2359     { &hf_mip6_mnid_subtype,    { "Subtype", "mip6.mnid.subtype",
2360                       FT_UINT8, BASE_DEC, VALS(mip6_mnid_subtype_value), 0,
2361                       NULL, HFILL }},
2362
2363     { &hf_mip6_vsm_vid,         { "VendorId", "mip6.vsm.vendorId",
2364                       FT_UINT32, BASE_DEC|BASE_EXT_STRING, &sminmpec_values_ext, 0x0,
2365                       NULL, HFILL }},
2366
2367     { &hf_mip6_vsm_subtype,     { "Subtype", "mip6.vsm.subtype",
2368                       FT_UINT8, BASE_DEC, VALS(mip6_vsm_subtype_value), 0,
2369                       NULL, HFILL }},
2370
2371     { &hf_mip6_vsm_subtype_3gpp, { "Subtype", "mip6.vsm.subtype",
2372                        FT_UINT8, BASE_DEC, VALS(mip6_vsm_subtype_3gpp_value), 0,
2373                        NULL, HFILL }},
2374
2375     { &hf_pmip6_hi_opttype,     { "Handoff Indicator Option type", "mip6.hi",
2376                       FT_UINT8, BASE_DEC, VALS(pmip6_hi_opttype_value), 0,
2377                       NULL, HFILL }},
2378
2379     { &hf_pmip6_att_opttype,    { "Access Technology Type Option type", "mip6.att",
2380                       FT_UINT8, BASE_DEC, VALS(pmip6_att_opttype_value), 0,
2381                       NULL, HFILL }},
2382
2383     { &hf_pmip6_timestamp,      { "Timestamp", "mip6.timestamp",
2384                       FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0, NULL, HFILL }},
2385
2386     { &hf_pmip6_opt_lila_lla,       { "Link-local Address", "mip6.lila_lla",
2387                                     FT_IPv6, BASE_NONE, NULL, 0x0, "", HFILL }},
2388
2389     { &hf_pmip6_rc,             { "Restart Counter", "mip6.rc",
2390                       FT_UINT32, BASE_DEC, NULL, 0x0,
2391                       NULL, HFILL}},
2392
2393     { &hf_mip6_ipv4ha_preflen,  { "Prefix-len", "mip6.ipv4ha.preflen",
2394                       FT_UINT8, BASE_DEC, NULL, 0xfc,
2395                       NULL, HFILL}},
2396
2397     { &hf_mip6_ipv4ha_p_flag,   { "mobile network prefix (P) flag", "mip6.ipv4ha.p_flag",
2398                       FT_BOOLEAN, 16, TFS(&mip6_ipv4ha_p_flag_value), 0x0200,
2399                       NULL, HFILL }},
2400
2401     { &hf_mip6_ipv4ha_ha,       { "IPv4 Home Address", "mip6.ipv4ha.ha",
2402                       FT_IPv4, BASE_NONE, NULL, 0x0,
2403                       NULL, HFILL }},
2404
2405     { &hf_mip6_ipv4aa_status,   { "Status", "mip6.ipv4aa.sts",
2406                       FT_UINT8, BASE_DEC, NULL, 0x0,
2407                       NULL, HFILL}},
2408
2409     { &hf_pmip6_gre_key,        { "GRE Key", "mip6.gre_key",
2410                       FT_UINT32, BASE_DEC, NULL, 0x0,
2411                       NULL, HFILL}},
2412
2413     { &hf_mip6_ipv4dra_dra,       { "IPv4 Default-Router Address", "mip6.ipv4dra.dra",
2414                     FT_IPv4, BASE_NONE, NULL, 0x0,
2415                     NULL, HFILL }},
2416
2417     { &hf_mip6_mobility_opt,    { "Mobility Options", "mip6.mobility_opt",
2418                       FT_UINT8, BASE_DEC, VALS(mip6_mobility_options), 0,
2419                       NULL, HFILL }},
2420     { &hf_pmip6_bri_brtype,     { "B.R. Type",  "mip6.bri_br.type",
2421                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2422
2423     { &hf_pmip6_bri_rtrigger,   { "R. Trigger", "mip6.bri_r.trigger",
2424                     FT_UINT8, BASE_DEC, VALS(pmip6_bri_rtrigger), 0x0, NULL, HFILL }},
2425
2426     { &hf_pmip6_bri_status,     { "Status", "mip6.bri_status",
2427                     FT_UINT8, BASE_DEC, VALS(pmip6_bri_status), 0x0, NULL, HFILL }},
2428
2429     { &hf_pmip6_bri_seqnr,      { "Sequence Number", "mip6._bri_seqnr",
2430                     FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2431
2432     { &hf_pmip6_bri_ip_flag,    { "Proxy Binding (P) Flag", "mip6.bri_ip",
2433                     FT_BOOLEAN, 8, TFS(&tfs_set_notset),
2434                     0x80, NULL, HFILL }},
2435
2436     { &hf_pmip6_bri_ia_flag,    { "Acknowledge (A) Flag", "mip6.bri_ia",
2437                     FT_BOOLEAN, 8, TFS(&tfs_set_notset),
2438                     0x40, NULL, HFILL }},
2439
2440     { &hf_pmip6_bri_ig_flag,    { "Global (G) Flag", "mip6.bri_ig",
2441                     FT_BOOLEAN, 8, TFS(&tfs_set_notset),
2442                     0x20, NULL, HFILL }},
2443
2444     { &hf_pmip6_bri_ap_flag,    { "Proxy Binding (P) Flag", "mip6.bri_ap",
2445                     FT_BOOLEAN, 8, TFS(&tfs_set_notset),
2446                     0x80, NULL, HFILL }},
2447
2448     { &hf_pmip6_bri_ag_flag,    { "Global (G) Flag", "mip6.bri_ag",
2449                     FT_BOOLEAN, 8, TFS(&tfs_set_notset),
2450                     0x40, NULL, HFILL }},
2451
2452     { &hf_pmip6_bri_res,        { "Reserved: 1 byte", "mip6.bri_res",
2453                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2454
2455     };
2456
2457     /* Setup protocol subtree array */
2458     static gint *ett[] = {
2459         &ett_mip6,
2460         &ett_mip6_opt_padn,
2461         &ett_mip6_opt_bra,
2462         &ett_mip6_opt_acoa,
2463         &ett_mip6_opt_ni,
2464         &ett_mip6_opt_bad,
2465         &ett_fmip6_opt_lla,
2466         &ett_mip6_nemo_opt_mnp,
2467         &ett_mip6_opt_mnid,
2468         &ett_mip6_opt_vsm,
2469         &ett_mip6_opt_ssm,
2470         &ett_pmip6_opt_hnp,
2471         &ett_pmip6_opt_hi,
2472         &ett_pmip6_opt_att,
2473         &ett_pmip6_opt_lla,
2474         &ett_pmip6_opt_ts,
2475         &ett_pmip6_opt_rc,
2476         &ett_mip6_opt_ipv4ha,
2477         &ett_mip6_opt_ipv4aa,
2478         &ett_pmip6_opt_grek,
2479         &ett_mip6_opt_ipv4hareq,
2480         &ett_mip6_opt_ipv4harep,
2481         &ett_mip6_opt_ipv4dra,
2482     };
2483
2484     /* Register the protocol name and description */
2485     proto_mip6 = proto_register_protocol("Mobile IPv6 / Network Mobility", "MIPv6", "mipv6");
2486
2487     /* Register the dissector by name */
2488     /* register_dissector("mipv6", dissect_nemo, proto_nemo); */
2489
2490     /* Required function calls to register the header fields and subtrees used */
2491     proto_register_field_array(proto_mip6, hf, array_length(hf));
2492     proto_register_subtree_array(ett, array_length(ett));
2493 }
2494
2495 void
2496 proto_reg_handoff_mip6(void)
2497 {
2498     dissector_handle_t mip6_handle;
2499
2500     /* mip6_handle = find_dissector("mipv6"); */
2501     mip6_handle = create_dissector_handle(dissect_mip6, proto_mip6);
2502     dissector_add_uint("ip.proto", IP_PROTO_MIPV6_OLD, mip6_handle);
2503     dissector_add_uint("ip.proto", IP_PROTO_MIPV6, mip6_handle);
2504     ip_dissector_table = find_dissector_table("ip.proto");
2505 }