081dd85a65a435d09d9567ee70c0b74576218c4b
[obnox/wireshark/wip.git] / epan / dissectors / packet-mip.c
1 /* packet-mip.c
2  * Routines for Mobile IP dissection
3  * Copyright 2000, Stefan Raab <sraab@cisco.com>
4  * Copyright 2007, Ville Nuorvala <Ville.Nuorvala@secgo.com>
5  * Copyright 2009, Ohuchi Munenori <ohuchi_at_iij.ad.jp>
6  * Copyright 2010, Yi Ren          <yi_ren1@agilent.com>
7  *
8  * $Id$
9  *
10  * Wireshark - Network traffic analyzer
11  * By Gerald Combs <gerald@wireshark.org>
12  * Copyright 1998 Gerald Combs
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27  */
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <stdlib.h>
34
35 #include <glib.h>
36 #include <time.h>
37
38 #include <epan/packet.h>
39 #include <epan/sminmpec.h>
40
41 /* Initialize the protocol and registered fields */
42 static int proto_mip = -1;
43 static int hf_mip_type = -1;
44 static int hf_mip_flags = -1;
45 static int hf_mip_s = -1;
46 static int hf_mip_b = -1;
47 static int hf_mip_d = -1;
48 static int hf_mip_m = -1;
49 static int hf_mip_g = -1;
50 static int hf_mip_v = -1;
51 static int hf_mip_t = -1;
52 static int hf_mip_x = -1;
53 static int hf_mip_code = -1;
54 static int hf_mip_life = -1;
55 static int hf_mip_homeaddr = -1;
56 static int hf_mip_haaddr = -1;
57 static int hf_mip_coa = -1;
58 static int hf_mip_ident = -1;
59 static int hf_mip_ext_type = -1;
60 static int hf_mip_gaext_stype = -1;
61 static int hf_mip_ext_len = -1;
62 static int hf_mip_ext = -1;
63 static int hf_mip_aext_spi = -1;
64 static int hf_mip_aext_auth = -1;
65 static int hf_mip_next_nai = -1;
66 static int hf_mip_rext_flags = -1;
67 static int hf_mip_rext_i = -1;
68 static int hf_mip_rext_reserved = -1;
69 static int hf_mip_rext_tstamp = -1;
70 static int hf_mip_rev_reserved = -1;
71 static int hf_mip_rev_a = -1;
72 static int hf_mip_rev_i = -1;
73 static int hf_mip_rev_reserved2 = -1;
74 static int hf_mip_ack_reserved = -1;
75 static int hf_mip_ack_i = -1;
76 static int hf_mip_ack_reserved2 = -1;
77 static int hf_mip_hda = -1;
78 static int hf_mip_fda = -1;
79 static int hf_mip_revid = -1;
80 static int hf_mip_dhaext_stype = -1;
81 static int hf_mip_dhaext_addr = -1;
82 static int hf_mip_mstrext_stype = -1;
83 static int hf_mip_mstrext_text = -1;
84 static int hf_mip_nattt_nexthdr = -1;
85 static int hf_mip_nattt_reserved = -1;
86 static int hf_mip_utrqext_stype = -1;
87 static int hf_mip_utrqext_reserved1 = -1;
88 static int hf_mip_utrqext_flags = -1;
89 static int hf_mip_utrqext_f = -1;
90 static int hf_mip_utrqext_r = -1;
91 static int hf_mip_utrqext_reserved2 = -1;
92 static int hf_mip_utrqext_encap_type = -1;
93 static int hf_mip_utrqext_reserved3 = -1;
94 static int hf_mip_utrpext_stype = -1;
95 static int hf_mip_utrpext_code = -1;
96 static int hf_mip_utrpext_flags = -1;
97 static int hf_mip_utrpext_f = -1;
98 static int hf_mip_utrpext_reserved = -1;
99 static int hf_mip_utrpext_keepalive = -1;
100 static int hf_mip_pmipv4nonskipext_stype = -1;
101 static int hf_mip_pmipv4nonskipext_pernodeauthmethod = -1;
102 static int hf_mip_pmipv4skipext_stype = -1;
103 static int hf_mip_pmipv4skipext_interfaceid = -1;
104 static int hf_mip_pmipv4skipext_deviceid_type = -1;
105 static int hf_mip_pmipv4skipext_deviceid_id = -1;
106 static int hf_mip_pmipv4skipext_subscriberid_type = -1;
107 static int hf_mip_pmipv4skipext_subscriberid_id = -1;
108 static int hf_mip_pmipv4skipext_accesstechnology_type = -1;
109 static int hf_mip_cvse_reserved = -1;
110 static int hf_mip_cvse_vendor_org_id = -1;
111 static int hf_mip_cvse_verizon_cvse_type = -1;
112 static int hf_mip_cvse_vendor_cvse_type = -1;
113 static int hf_mip_cvse_vendor_cvse_value = -1;
114
115 /* Initialize the subtree pointers */
116 static gint ett_mip = -1;
117 static gint ett_mip_flags = -1;
118 static gint ett_mip_ext = -1;
119 static gint ett_mip_exts = -1;
120 static gint ett_mip_pmipv4_ext = -1;
121
122 /* Port used for Mobile IP */
123 #define UDP_PORT_MIP    434
124
125 /* http://www.iana.org/assignments/mobileip-numbers */
126 typedef enum {
127   MIP_REGISTRATION_REQUEST = 1,
128   MIP_REGISTRATION_REPLY = 3,
129   MIP_NATT_TUNNEL_DATA = 4,
130   MIP_REGISTRATION_REVOCATION = 7,
131   MIP_REGISTRATION_REVOCATION_ACK = 15,
132   MIP_HANDOFF_REQEST = 16,
133   MIP_HANDOFF_REPLY = 17,
134   MIP_REGIONAL_REG_REQ = 18,
135   MIP_REGIONAL_REG_REP = 19,
136   MIP_FAST_BINDING_UPD = 20,
137   MIP_FAST_BINDING_ACK = 21,
138   MIP_EXPERIMENTAL_MESSAGE = 255
139 } mipMessageTypes;
140
141 static const value_string mip_types[] = {
142   {MIP_REGISTRATION_REQUEST,            "Registration Request"},
143   {MIP_REGISTRATION_REPLY,              "Registration Reply"},
144   {MIP_NATT_TUNNEL_DATA,                "NAT Traversal Tunnel Data"},
145   {MIP_REGISTRATION_REVOCATION,         "Registration Revocation"},
146   {MIP_REGISTRATION_REVOCATION_ACK,     "Registration Revocation Acknowledgement"},
147   {MIP_HANDOFF_REQEST,                  "NAT Traversal Tunnel Data"},
148   {MIP_HANDOFF_REPLY,                   "NAT Traversal Tunnel Data"},
149   {MIP_REGIONAL_REG_REQ,                "NAT Traversal Tunnel Data"},
150   {MIP_REGIONAL_REG_REP,                "NAT Traversal Tunnel Data"},
151   {MIP_FAST_BINDING_UPD,                "NAT Traversal Tunnel Data"},
152   {MIP_FAST_BINDING_ACK,                "NAT Traversal Tunnel Data"},
153   {MIP_EXPERIMENTAL_MESSAGE,            "Message for Experimental Use"},
154   {0, NULL}
155 };
156
157 static const value_string mip_reply_codes[]= {
158   {0, "Reg Accepted"},
159   {1, "Reg Accepted, but Simultaneous Bindings Unsupported"},
160   {64, "Reg Deny (FA)- Unspecified Reason"},
161   {65, "Reg Deny (FA)- Administratively Prohibited"},
162   {66, "Reg Deny (FA)- Insufficient Resources"},
163   {67, "Reg Deny (FA)- MN Failed Authentication"},
164   {68, "Reg Deny (FA)- HA Failed Authentication"},
165   {69, "Reg Deny (FA)- Requested Lifetime too Long"},
166   {70, "Reg Deny (FA)- Poorly Formed Request"},
167   {71, "Reg Deny (FA)- Poorly Formed Reply"},
168   {72, "Reg Deny (FA)- Requested Encapsulation Unavailable"},
169   {73, "Reg Deny (FA)- VJ Compression Unavailable"},
170   {74, "Reg Deny (FA)- Requested Reverse Tunnel Unavailable"},
171   {75, "Reg Deny (FA)- Reverse Tunnel Is Mandatory and 'T' Bit Not Set"},
172   {76, "Reg Deny (FA)- Mobile Node Too Distant"},
173   {77, "Reg Deny (FA)- Invalid Care-of Address"},
174   {78, "Reg Deny (FA)- Registration Timeout"},
175   {79, "Reg Deny (FA)- Delivery Style Not Supported"},
176   {80, "Reg Deny (FA)- Home Network Unreachable"},
177   {81, "Reg Deny (FA)- HA Host Unreachable"},
178   {82, "Reg Deny (FA)- HA Port Unreachable"},
179   {88, "Reg Deny (FA)- HA Unreachable"},
180   {89, "Reg Deny (FA)- Vendor-specific Reason"},
181   {90, "Reg Deny (FA)- Non-zero HA Address Required"},
182   {96, "Reg Deny (FA)(NAI) - Non-zero Home Address Required"},
183   {97, "Reg Deny (FA)(NAI) - Missing NAI"},
184   {98, "Reg Deny (FA)(NAI) - Missing Home Agent"},
185   {99, "Reg Deny (FA)(NAI) - Missing Home Address"},
186   {100, "Reg Deny (FA)- Unable to Interpret CVSE Sent by MN"},
187   {101, "Reg Deny (FA)- Unable to Interpret CVSE Sent by HA"},
188   {104, "Reg Deny (FA)- Unknown Challenge"},
189   {105, "Reg Deny (FA)- Missing Challenge"},
190   {106, "Reg Deny (FA)- Stale Challenge"},
191   {107, "Reg Deny (FA)- Missing MN-FA Key Generation Nonce Reply Extension"},
192   {108, "Reg Deny (FA)- MN Failed AAA Authentication"},
193   {109, "Reg Deny (FA)- HA Sent Wrong Challenge in Reply"},
194   {127, "Reg Deny (FA)- Error Code for Experimental Use"},
195   {128, "Reg Deny (HA)- Unspecified"},
196   {129, "Reg Deny (HA)- Administratively Prohibited"},
197   {130, "Reg Deny (HA)- Insufficient Resources"},
198   {131, "Reg Deny (HA)- MN Failed Authentication"},
199   {132, "Reg Deny (HA)- FA Failed Authentication"},
200   {133, "Reg Deny (HA)- Registration ID Mismatch"},
201   {134, "Reg Deny (HA)- Poorly Formed Request"},
202   {135, "Reg Deny (HA)- Too Many Simultaneous Bindings"},
203   {136, "Reg Deny (HA)- Unknown HA Address"},
204   {137, "Reg Deny (HA)- Requested Reverse Tunnel Unavailable"},
205   {138, "Reg Deny (HA)- Reverse Tunnel Is Mandatory and 'T' Bit Not Set"},
206   {139, "Reg Deny (HA)- Requested Encapsulation Unavailable"},
207   {140, "Reg Deny (HA)- Unable to Interpret CVSE Sent by MN"},
208   {141, "Reg Deny (HA)- Unable to Interpret CVSE Sent by FA"},
209   {142, "Reg Deny (HA)- UDP Encapsulation Unavailable"},
210   {143, "Reg Deny (HA)- Register with Redirected HA"},
211   {144, "Reg Deny (HA)- MN Failed AAA Authentication"},
212   {149, "Reg Deny (HA)- PMIP_UNSUPPORTED"},               /* draft-leung-mip4-proxy-mode */
213   {150, "Reg Deny (HA)- PMIP_DISALLOWED"},                /* draft-leung-mip4-proxy-mode */
214   {192, "Reg Deny (HA)- Error Code for Experimental Use"},
215   {0, NULL}
216 };
217
218 static const value_string mip_nattt_nexthdr[]= {
219   {4, "IP Header"},
220   {47, "GRE Header"},
221   {55, "Minimal IP Encapsulation Header"},
222   {0, NULL}
223 };
224
225 typedef enum {
226   MH_AUTH_EXT = 32,
227   MF_AUTH_EXT = 33,
228   FH_AUTH_EXT = 34,
229   GEN_AUTH_EXT = 36,         /* RFC 3012 */
230   OLD_CVSE_EXT = 37,         /* RFC 3115 */
231   CVSE_EXT = 38,             /* RFC 3115 */
232   UDP_TUN_REP_EXT = 44,      /* RFC 3519 */
233   MIP_FA_ERROR_EXT = 45,     /* [RFC4636] */
234   MIP_GFA_IP_ADDR_EXT = 46,  /* [RFC4857] */
235   PMIPv4_NON_SKIP_EXT = 47,  /* [RFC5563] */
236   MN_NAI_EXT = 131,       /* RFC 2794 */
237   MF_CHALLENGE_EXT = 132, /* RFC 3012 */
238   OLD_NVSE_EXT = 133,     /* RFC 3115 */
239   NVSE_EXT = 134,         /* RFC 3115 */
240   REV_SUPP_EXT = 137,     /* RFC 3543 */
241   DYN_HA_EXT = 139,       /* RFC 4433 */
242   UDP_TUN_REQ_EXT = 144,  /* RFC 3519 */
243   MSG_STR_EXT = 145,
244   PMIPv4_SKIP_EXT = 147,  /* draft-leung-mip4-proxy-mode */
245   SKIP_EXP_EXT = 255      /* RFC 4064 */
246 } MIP_EXTS;
247
248 static const value_string mip_ext_types[]= {
249   {MH_AUTH_EXT,         "Mobile-Home Authentication Extension"},
250   {MF_AUTH_EXT,         "Mobile-Foreign Authentication Extension"},
251   {FH_AUTH_EXT,         "Foreign-Home Authentication Extension"},
252   {GEN_AUTH_EXT,        "Generalized Mobile-IP Authentication Extension"},
253   {OLD_CVSE_EXT,        "Critical Vendor/Organization Specific Extension"},
254   {CVSE_EXT,            "Critical Vendor/Organization Specific Extension"},
255   {UDP_TUN_REP_EXT,     "UDP Tunnel Reply Extension"},
256   {MIP_FA_ERROR_EXT,    "FA Error Extension"},
257   {MIP_GFA_IP_ADDR_EXT, "GFA IP Address Extension"},
258   {PMIPv4_NON_SKIP_EXT, "Proxy Mobile IPv4 Non-skippable Extension"},
259   {128,                 "Deprecated (2001 Aug 31)"},
260   {129,                 "SKIP Firewall Traversal Extension"},                  /*[RFC2356]*/
261   {130,                 "Encapsulating Delivery Style Extension"},             /*[RFC3024]*/
262   {131,                 "Mobile Node NAI"},                                    /*[RFC2794]*/
263   {MN_NAI_EXT,          "Mobile Node NAI Extension"},
264   {MF_CHALLENGE_EXT,    "MN-FA Challenge Extension"},
265   {OLD_NVSE_EXT,        "Normal Vendor/Organization Specific Extension"},
266   {NVSE_EXT,            "Normal Vendor/Organization Specific Extension"},
267   {136,                 "NAI Carrying Extension"},                                /*[RFC3846]*/
268   {REV_SUPP_EXT,        "Revocation Support Extension"},
269   {138,                 "Generalized Link Layer Address Registration Extension"},   /*[RFC4881]*/
270   {DYN_HA_EXT,          "Dynamic HA Extension"},
271   {140,                 "Hierarchical Foreign Agent Extension"},                    /*[RFC4857]*/
272   {141,                 "Replay Protection Style"},                                 /*[RFC4857]*/
273   {142,                 "Regional Registration Lifetime Extension"},                /*[RFC4857]*/
274   {UDP_TUN_REQ_EXT,     "UDP Tunnel Request Extension"},
275   {MSG_STR_EXT,         "Message String Extension"},
276   {PMIPv4_SKIP_EXT,     "Proxy Mobile IPv4 Skippable Extension"},
277   {148,                 "Mobile Network Extension"},                                /*[RFC5177]*/
278   {149,                 "Trusted Networks Configured (TNC) Extension"},             /*[RFC5265]*/
279   {150,                 "Reserved"},
280   {151,                 "Service Selection Extension"},                             /*[RFC5446]*/
281   {152,                 "Dual Stack (DSMIPv4) Extension"},                          /*[RFC5454]*/
282   {SKIP_EXP_EXT,        "Skippable Extension for Experimental use"},
283   {0, NULL}
284 };
285
286 static const value_string mip_gaext_stypes[]= {
287   {1, "MN-AAA Authentication"},
288   {2, "FA-FA Authentication"},
289   {3, "MN-GFA Authentication"},
290   {4, "MN-PAR Auth Extension"},
291   {0, NULL}
292 };
293
294 /* UDP Tunnel Reply Extension: */
295 static const value_string mip_utrpext_stypes[]= {
296   {0, "Regular UDP Tunnel Reply Extension"},
297   {0, NULL}
298 };
299
300 /* Dynamic HA Extension subtypes */
301 static const value_string mip_dhaext_stypes[]= {
302   {1, "Requested HA Extension"},
303   {2, "Redirected HA Extension"},
304   {0, NULL}
305 };
306
307 static const value_string mip_mstrext_stypes[]= {
308   {1, "HA Extension"},
309   {2, "FA Extension"},
310   {0, NULL}
311 };
312
313 static const value_string mip_utrqext_stypes[]= {
314   {0, ""},
315   {0, NULL}
316 };
317
318 static const value_string mip_utrqext_encap_types[]= {
319   {4, "IP Header"},
320   {47, "GRE Header"},
321   {55, "Minimal IP Encapsulation Header"},
322   {0, NULL}
323 };
324
325
326 static const value_string mip_utrpext_codes[]= {
327   {0, "Will do Tunneling"},
328   {64, "Tunneling Declined, Reason Unspecified"},
329   {0, NULL}
330 };
331
332 static const value_string mip_pmipv4nonskipext_stypes[]= {
333   {0, "Unknown"},
334   {1, "Per-Node Authentication Method"},
335   {0, NULL}
336 };
337
338 /* PMIPv4 Per-Node Authentication Method Types */
339 static const value_string mip_pmipv4nonskipext_pernodeauthmethod_types[]= {
340   {0, "Reserved"},
341   {1, "FA-HA Authentication"},
342   {2, "IPSec Authentication"},
343   {0, NULL}
344 };
345
346 #define PMIPv4_SKIPEXT_STYPE_INTERFACE_ID   (1)
347 #define PMIPv4_SKIPEXT_STYPE_DEVICE_ID      (2)
348 #define PMIPv4_SKIPEXT_STYPE_SUBSCRIBER_ID  (3)
349 #define PMIPv4_SKIPEXT_STYPE_ACCESS_TECHNOLOGY  (4)
350 static const value_string mip_pmipv4skipext_stypes[]= {
351   {0, "Unknown"},
352   {PMIPv4_SKIPEXT_STYPE_INTERFACE_ID, "Interface ID"},
353   {PMIPv4_SKIPEXT_STYPE_DEVICE_ID, "Device ID"},
354   {PMIPv4_SKIPEXT_STYPE_SUBSCRIBER_ID, "Subscriber ID"},
355   {PMIPv4_SKIPEXT_STYPE_ACCESS_TECHNOLOGY, "Access Technology Type"},
356   {0, NULL}
357 };
358
359 /* PMIPv4 Device ID Types */
360 static const value_string mip_pmipv4skipext_deviceid_types[]= {
361   {0, "Reserved"},
362   {1, "Ethernet MAC address"},
363   {2, "Mobile Equipment Identifier (MEID)"},
364   {3, "International Mobile Equipment Identity (IMEI)"},
365   {4, "Electronic Serial Number (ESN)"},
366   {0, NULL}
367 };
368
369 /* PMIPv4 Subscriber ID Types */
370 static const value_string mip_pmipv4skipext_subscriberid_types[]= {
371   {0, "Reserved"},
372   {1, "International Mobile Subscriber Identity (IMSI)"},
373   {0, NULL}
374 };
375
376 /* Access Technology Types */
377 static const value_string mip_pmipv4skipext_accesstechnology_types[]= {
378   {0, "Reserved"},
379   {1, "802.3"},
380   {2, "802.11a/b/g"},
381   {3, "802.16e"},
382   {4, "802.16m"},
383   {5, "3GPP EUTRAN/LTE"},
384   {6, "3GPP UTRAN/GERAN"},
385   {7, "3GPP2 1xRTT/HRPD"},
386   {8, "3GPP2 UMB"},
387   {0, NULL}
388 };
389
390 static const value_string mip_cvse_verizon_cvse_types[]= {
391   {0, "Reserved"},
392   {1, "MIP Key Request"},
393   {2, "MIP Key Data"},
394   {3, "AAA Authenticator"},
395   {4, "Public Key Invalid"},
396   {0, NULL}
397 };
398
399 static dissector_handle_t ip_handle;
400
401 /* Code to dissect extensions */
402 static void
403 dissect_mip_extensions( tvbuff_t *tvb, int offset, proto_tree *tree)
404 {
405   proto_item   *ti;
406   proto_tree   *exts_tree=NULL;
407   proto_tree   *ext_tree;
408   proto_tree   *tf;
409   proto_tree   *ext_flags_tree;
410   proto_tree   *tp;
411   proto_tree   *pmipv4_tree;
412   gint          ext_len;
413   guint8        ext_type;
414   guint8        ext_subtype=0;
415   guint8        pmipv4skipext_subscriberid_type;
416   guint16       flags;
417   gint          hdrLen;
418   guint32       cvse_vendor_id;
419   guint16       cvse_vendor_type;
420   int           cvse_local_offset= 0;
421
422   /* None of this really matters if we don't have a tree */
423   if (!tree) return;
424
425   /* Add our tree, if we have extensions */
426   ti = proto_tree_add_text(tree, tvb, offset, -1, "Extensions");
427   exts_tree = proto_item_add_subtree(ti, ett_mip_exts);
428
429   /* And, handle each extension */
430   while (tvb_reported_length_remaining(tvb, offset) > 0) {
431
432     /* Get our extension info */
433     ext_type = tvb_get_guint8(tvb, offset);
434     if (ext_type == GEN_AUTH_EXT || ext_type == PMIPv4_NON_SKIP_EXT) {
435       /*
436        * Very nasty . . breaks normal extensions, since the length is
437        * in the wrong place :(
438        */
439       ext_subtype = tvb_get_guint8(tvb, offset + 1);
440       ext_len = tvb_get_ntohs(tvb, offset + 2);
441       hdrLen = 4;
442     }
443     else if(ext_type==CVSE_EXT){
444       /*
445        * CVSE also breaks since it added reserved field before
446        * the length field
447       */
448       ext_len = tvb_get_ntohs(tvb, offset + 2);
449       hdrLen = 4;
450     }
451     else {
452       ext_len = tvb_get_guint8(tvb, offset + 1);
453       hdrLen = 2;
454     }
455
456     ti = proto_tree_add_text(exts_tree, tvb, offset, ext_len + hdrLen,
457                  "Extension: %s",
458                  val_to_str(ext_type, mip_ext_types,
459                             "Unknown Extension %u"));
460     ext_tree = proto_item_add_subtree(ti, ett_mip_ext);
461
462     proto_tree_add_uint(ext_tree, hf_mip_ext_type, tvb, offset, 1, ext_type);
463     offset++;
464     if (ext_type != GEN_AUTH_EXT &&
465         ext_type != PMIPv4_NON_SKIP_EXT &&
466         ext_type != CVSE_EXT) {
467       /* Another nasty hack since GEN_AUTH_EXT and PMIPv4_NON_SKIP_EXT broke everything */
468       proto_tree_add_uint(ext_tree, hf_mip_ext_len, tvb, offset, 1, ext_len);
469       offset++;
470     }
471
472     switch (ext_type) {
473     case MH_AUTH_EXT:
474     case MF_AUTH_EXT:
475     case FH_AUTH_EXT:
476       /* All these extensions look the same.  4 byte SPI followed by a key */
477       proto_tree_add_item(ext_tree, hf_mip_aext_spi, tvb, offset, 4, ENC_BIG_ENDIAN);
478       proto_tree_add_item(ext_tree, hf_mip_aext_auth, tvb, offset+4, ext_len-4, ENC_NA);
479       break;
480     case MN_NAI_EXT:
481       proto_tree_add_item(ext_tree, hf_mip_next_nai, tvb, offset,
482                           ext_len, ENC_ASCII|ENC_NA);
483       break;
484
485     case GEN_AUTH_EXT:      /* RFC 3012 */
486       /*
487        * Very nasty . . breaks normal extensions, since the length is
488        * in the wrong place :(
489        */
490       proto_tree_add_uint(ext_tree, hf_mip_gaext_stype, tvb, offset, 1, ext_subtype);
491       offset++;
492       proto_tree_add_uint(ext_tree, hf_mip_ext_len, tvb, offset, 2, ext_len);
493       offset+=2;
494       /* SPI */
495       proto_tree_add_item(ext_tree, hf_mip_aext_spi, tvb, offset, 4, ENC_BIG_ENDIAN);
496       /* Key */
497       proto_tree_add_item(ext_tree, hf_mip_aext_auth, tvb, offset + 4,
498                           ext_len - 4, ENC_NA);
499
500       break;
501         case REV_SUPP_EXT:      /* RFC 3543 */
502       /* flags */
503       flags = tvb_get_ntohs(tvb, offset);
504       tf = proto_tree_add_uint(ext_tree, hf_mip_rext_flags, tvb, offset, 2, flags);
505       ext_flags_tree = proto_item_add_subtree(tf, ett_mip_flags);
506       proto_tree_add_boolean(ext_flags_tree, hf_mip_rext_i, tvb, offset, 2, flags);
507
508       /* reserved */
509       proto_tree_add_uint(ext_flags_tree, hf_mip_rext_reserved, tvb, offset, 2, flags);
510       /* registration revocation timestamp */
511       proto_tree_add_item(ext_tree, hf_mip_rext_tstamp, tvb, offset + 2, 4, ENC_BIG_ENDIAN);
512       break;
513     case DYN_HA_EXT:      /* RFC 4433 */
514       /* subtype */
515       proto_tree_add_item(ext_tree, hf_mip_dhaext_stype, tvb, offset, 1, ENC_BIG_ENDIAN);
516       /* Home Agent */
517       proto_tree_add_item(ext_tree, hf_mip_dhaext_addr, tvb, offset + 1, 4, ENC_BIG_ENDIAN);
518       break;
519     case MSG_STR_EXT:
520       /* sub-type */
521       proto_tree_add_item(ext_tree, hf_mip_mstrext_stype, tvb, offset, 1, ENC_BIG_ENDIAN);
522
523       /* text */
524       proto_tree_add_item(ext_tree, hf_mip_mstrext_text, tvb, offset + 1, ext_len-1, ENC_ASCII|ENC_NA);
525       break;
526     case UDP_TUN_REQ_EXT:   /* RFC 3519 */
527       /* sub-type */
528       proto_tree_add_item(ext_tree, hf_mip_utrqext_stype, tvb, offset, 1, ENC_BIG_ENDIAN);
529
530       /* reserved 1 */
531       proto_tree_add_item(ext_tree, hf_mip_utrqext_reserved1, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
532
533       /* flags */
534       flags = tvb_get_guint8(tvb, offset + 2);
535       tf = proto_tree_add_uint(ext_tree, hf_mip_utrqext_flags, tvb, offset + 2, 1, flags);
536       ext_flags_tree = proto_item_add_subtree(tf, ett_mip_flags);
537       proto_tree_add_boolean(ext_flags_tree, hf_mip_utrqext_f, tvb, offset + 2, 1, flags);
538       proto_tree_add_boolean(ext_flags_tree, hf_mip_utrqext_r, tvb, offset + 2, 1, flags);
539
540       /* reserved 2 */
541       proto_tree_add_uint(ext_flags_tree, hf_mip_utrqext_reserved2, tvb, offset + 2, 1, flags);
542       /* encapsulation */
543       proto_tree_add_item(ext_tree, hf_mip_utrqext_encap_type, tvb, offset + 3, 1, ENC_BIG_ENDIAN);
544
545       /* reserved 3 */
546       proto_tree_add_item(ext_tree, hf_mip_utrqext_reserved3, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
547       break;
548     case UDP_TUN_REP_EXT:   /* RFC 3519 */
549       /* sub-type */
550       proto_tree_add_item(ext_tree, hf_mip_utrpext_stype, tvb, offset, 1, ENC_BIG_ENDIAN);
551
552       /* code */
553       proto_tree_add_item(ext_tree, hf_mip_utrpext_code, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
554
555       /* flags */
556       flags = tvb_get_ntohs(tvb, offset+2);
557       tf = proto_tree_add_uint(ext_tree, hf_mip_utrpext_flags, tvb, offset + 2, 2, flags);
558       ext_flags_tree = proto_item_add_subtree(tf, ett_mip_flags);
559       proto_tree_add_boolean(ext_flags_tree, hf_mip_utrpext_f, tvb, offset + 2, 2, flags);
560
561       /* reserved */
562       proto_tree_add_uint(ext_flags_tree, hf_mip_utrpext_reserved, tvb, offset + 2, 2, flags);
563
564       /* keepalive interval */
565       proto_tree_add_item(ext_tree, hf_mip_utrpext_keepalive, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
566       break;
567     case PMIPv4_NON_SKIP_EXT:   /* draft-leung-mip4-proxy-mode */
568       /* sub-type */
569       proto_tree_add_uint(ext_tree, hf_mip_pmipv4nonskipext_stype, tvb, offset, 1, ext_subtype);
570       offset++;
571           /* len */
572       proto_tree_add_uint(ext_tree, hf_mip_ext_len, tvb, offset, 2, ext_len);
573       offset+=2;
574       if(ext_subtype == 1){
575         /* Sub-type == 1 : PMIPv4 Per-Node Authentication Method */
576         proto_tree_add_item(ext_tree, hf_mip_pmipv4nonskipext_pernodeauthmethod, tvb, offset, 1, ENC_BIG_ENDIAN);
577       }
578       break;
579     case PMIPv4_SKIP_EXT:   /* draft-leung-mip4-proxy-mode */
580       /* sub-type */
581       ext_subtype = tvb_get_guint8(tvb, offset);
582       tp = proto_tree_add_text(ext_tree, tvb, offset, ext_len,
583                    "PMIPv4 Sub-Type: %s",
584                    val_to_str(ext_subtype, mip_pmipv4skipext_stypes, "Unknown Sub-Type %u"));
585       pmipv4_tree = proto_item_add_subtree(tp, ett_mip_pmipv4_ext);
586       proto_tree_add_uint(pmipv4_tree, hf_mip_pmipv4skipext_stype, tvb, offset, 1, ext_subtype);
587
588       if (ext_subtype == PMIPv4_SKIPEXT_STYPE_INTERFACE_ID) {
589         proto_tree_add_item(pmipv4_tree, hf_mip_pmipv4skipext_interfaceid, tvb, offset + 1, ext_len-1, ENC_NA);
590       } else if (ext_subtype == PMIPv4_SKIPEXT_STYPE_DEVICE_ID) {
591         proto_tree_add_item(pmipv4_tree, hf_mip_pmipv4skipext_deviceid_type, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
592         proto_tree_add_item(pmipv4_tree, hf_mip_pmipv4skipext_deviceid_id, tvb, offset + 2, ext_len - 2, ENC_NA);
593       } else if (ext_subtype == PMIPv4_SKIPEXT_STYPE_SUBSCRIBER_ID) {
594         pmipv4skipext_subscriberid_type = tvb_get_guint8(tvb, offset + 1);
595         proto_tree_add_uint(pmipv4_tree, hf_mip_pmipv4skipext_subscriberid_type, tvb, offset + 1, 1, pmipv4skipext_subscriberid_type);
596         if (pmipv4skipext_subscriberid_type == 1) {
597           proto_tree_add_item(pmipv4_tree, hf_mip_pmipv4skipext_subscriberid_id, tvb, offset + 2, ext_len - 2, ENC_NA);
598         }
599       } else if (ext_subtype == PMIPv4_SKIPEXT_STYPE_ACCESS_TECHNOLOGY) {
600         proto_tree_add_item(pmipv4_tree, hf_mip_pmipv4skipext_accesstechnology_type, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
601       }
602       break;
603
604     case CVSE_EXT:          /* RFC 3115 */
605       /*
606        * Very nasty . . breaks normal extensions, since the length is
607        * in the wrong place :(
608        */
609       proto_tree_add_item(ext_tree, hf_mip_cvse_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
610       offset++;
611       proto_tree_add_uint(ext_tree, hf_mip_ext_len, tvb, offset, 2, ext_len);
612       offset+=2;
613       /* Vendor/Org ID */
614       /*Vendor ID & cvse type & cvse value are included in ext_len, so do not increment offset for them here.*/
615       cvse_local_offset = offset;
616       proto_tree_add_item(ext_tree, hf_mip_cvse_vendor_org_id, tvb, cvse_local_offset, 4, ENC_BIG_ENDIAN);
617       cvse_vendor_id = tvb_get_ntohl(tvb, cvse_local_offset);
618       cvse_local_offset+=4;
619       /*Vendor CVSE Type*/
620       if( cvse_vendor_id == VENDOR_VERIZON ){
621         /*Verizon CVSE type*/
622            proto_tree_add_item(ext_tree, hf_mip_cvse_verizon_cvse_type, tvb, cvse_local_offset, 2, ENC_BIG_ENDIAN);
623       }
624       else{
625         /*CVSE Type of Other vendor, just show raw numbers currently*/
626         cvse_vendor_type = tvb_get_ntohs(tvb, cvse_local_offset);
627         proto_tree_add_uint(ext_tree, hf_mip_cvse_vendor_cvse_type, tvb, cvse_local_offset, 2, cvse_vendor_type);
628       }
629       cvse_local_offset+=2;
630       /* Vendor-CVSE-Value */
631       /* Vendor CVSE Type+Vendor/Org ID = 6 bytes*/
632       proto_tree_add_item(ext_tree, hf_mip_cvse_vendor_cvse_value, tvb, cvse_local_offset, ext_len - 6, ENC_NA);
633       break;
634
635     case OLD_CVSE_EXT:      /* RFC 3115 */
636     case OLD_NVSE_EXT:      /* RFC 3115 */
637     case NVSE_EXT:          /* RFC 3115 */
638     case MF_CHALLENGE_EXT:  /* RFC 3012 */
639       /* The default dissector is good here.  The challenge is all hex anyway. */
640     default:
641       proto_tree_add_item(ext_tree, hf_mip_ext, tvb, offset, ext_len, ENC_NA);
642       break;
643     } /* ext type */
644
645     offset += ext_len;
646   } /* while data remaining */
647
648 } /* dissect_mip_extensions */
649
650 /* Code to actually dissect the packets */
651 static void
652 dissect_mip( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
653 {
654   /* Set up structures we will need to add the protocol subtree and manage it */
655   proto_item    *ti;
656   proto_tree    *mip_tree=NULL;
657   proto_item    *tf;
658   proto_tree    *flags_tree;
659   guint8         type;
660   guint16        flags;
661   gint           offset=0;
662   tvbuff_t      *next_tvb;
663
664   /* Make entries in Protocol column and Info column on summary display */
665
666   col_set_str(pinfo->cinfo, COL_PROTOCOL, "MobileIP");
667   col_clear(pinfo->cinfo, COL_INFO);
668
669   type = tvb_get_guint8(tvb, offset);
670   switch (type) {
671   case MIP_REGISTRATION_REQUEST:
672     col_add_fstr(pinfo->cinfo, COL_INFO,
673                "Reg Request: HoA=%s HA=%s CoA=%s",
674                tvb_ip_to_str(tvb, 4),
675                tvb_ip_to_str(tvb, 8),
676                tvb_ip_to_str(tvb, 12));
677
678     if (tree) {
679       ti = proto_tree_add_item(tree, proto_mip, tvb, offset, -1, ENC_NA);
680       mip_tree = proto_item_add_subtree(ti, ett_mip);
681
682       /* type */
683       proto_tree_add_uint(mip_tree, hf_mip_type, tvb, offset, 1, type);
684       offset++;
685
686       /* flags */
687       flags = tvb_get_guint8(tvb, offset);
688       tf = proto_tree_add_uint(mip_tree, hf_mip_flags, tvb, offset, 1, flags);
689       flags_tree = proto_item_add_subtree(tf, ett_mip_flags);
690       proto_tree_add_boolean(flags_tree, hf_mip_s, tvb, offset, 1, flags);
691       proto_tree_add_boolean(flags_tree, hf_mip_b, tvb, offset, 1, flags);
692       proto_tree_add_boolean(flags_tree, hf_mip_d, tvb, offset, 1, flags);
693       proto_tree_add_boolean(flags_tree, hf_mip_m, tvb, offset, 1, flags);
694       proto_tree_add_boolean(flags_tree, hf_mip_g, tvb, offset, 1, flags);
695       proto_tree_add_boolean(flags_tree, hf_mip_v, tvb, offset, 1, flags);
696       proto_tree_add_boolean(flags_tree, hf_mip_t, tvb, offset, 1, flags);
697       proto_tree_add_boolean(flags_tree, hf_mip_x, tvb, offset, 1, flags);
698       offset++;
699
700       /* lifetime */
701       proto_tree_add_item(mip_tree, hf_mip_life, tvb, offset, 2, ENC_BIG_ENDIAN);
702       offset += 2;
703
704       /* home address */
705       proto_tree_add_item(mip_tree, hf_mip_homeaddr, tvb, offset, 4, ENC_BIG_ENDIAN);
706       offset += 4;
707
708       /* home agent address */
709       proto_tree_add_item(mip_tree, hf_mip_haaddr, tvb, offset, 4, ENC_BIG_ENDIAN);
710       offset += 4;
711
712       /* Care of Address */
713       proto_tree_add_item(mip_tree, hf_mip_coa, tvb, offset, 4, ENC_BIG_ENDIAN);
714       offset += 4;
715
716       /* Identifier - assumed to be an NTP time here */
717       proto_tree_add_item(mip_tree, hf_mip_ident, tvb, offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
718       offset += 8;
719
720     } /* if tree */
721     break;
722   case MIP_REGISTRATION_REPLY:
723     col_add_fstr(pinfo->cinfo, COL_INFO,
724                "Reg Reply: HoA=%s HA=%s, Code=%u",
725                tvb_ip_to_str(tvb, 4),
726                tvb_ip_to_str(tvb, 8),
727                tvb_get_guint8(tvb,1));
728
729     if (tree) {
730       /* Add Subtree */
731       ti = proto_tree_add_item(tree, proto_mip, tvb, offset, -1, ENC_NA);
732       mip_tree = proto_item_add_subtree(ti, ett_mip);
733
734       /* Type */
735       proto_tree_add_uint(mip_tree, hf_mip_type, tvb, offset, 1, type);
736       offset++;
737
738       /* Reply Code */
739       proto_tree_add_item(mip_tree, hf_mip_code, tvb, offset, 1, ENC_BIG_ENDIAN);
740       offset++;
741
742       /* Registration Lifetime */
743       proto_tree_add_item(mip_tree, hf_mip_life, tvb, offset, 2, ENC_BIG_ENDIAN);
744       offset += 2;
745
746       /* Home address */
747       proto_tree_add_item(mip_tree, hf_mip_homeaddr, tvb, offset, 4, ENC_BIG_ENDIAN);
748       offset += 4;
749
750       /* Home Agent Address */
751       proto_tree_add_item(mip_tree, hf_mip_haaddr, tvb, offset, 4, ENC_BIG_ENDIAN);
752       offset += 4;
753
754       /* Identifier - assumed to be an NTP time here */
755       proto_tree_add_item(mip_tree, hf_mip_ident, tvb, offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
756       offset += 8;
757     } /* if tree */
758     break;
759   case MIP_NATT_TUNNEL_DATA:
760     col_add_fstr(pinfo->cinfo, COL_INFO, "Tunnel Data: Next Header=%u",
761                tvb_get_guint8(tvb,1));
762
763     if (tree) {
764       /* Add Subtree */
765       ti = proto_tree_add_item(tree, proto_mip, tvb, offset, -1, ENC_NA);
766       mip_tree = proto_item_add_subtree(ti, ett_mip);
767
768       /* Type */
769       proto_tree_add_uint(mip_tree, hf_mip_type, tvb, offset, 1, type);
770       offset++;
771
772       /* Next Header */
773       proto_tree_add_item(mip_tree, hf_mip_nattt_nexthdr, tvb, offset, 1, ENC_BIG_ENDIAN);
774       offset++;
775
776       /* reserved */
777       proto_tree_add_item(mip_tree, hf_mip_nattt_reserved, tvb, offset, 2, ENC_BIG_ENDIAN);
778       offset += 2;
779     } /* if tree */
780     else {
781       offset += 4;
782     }
783     /* encapsulated payload */
784     next_tvb = tvb_new_subset_remaining(tvb, 4);
785     call_dissector(ip_handle, next_tvb, pinfo, mip_tree);
786     offset += tvb_reported_length_remaining(tvb, offset);
787     break;
788   case MIP_REGISTRATION_REVOCATION:
789     col_add_fstr(pinfo->cinfo, COL_INFO,
790                "Reg Revocation: HoA=%s HDA=%s FDA=%s",
791                tvb_ip_to_str(tvb, 4),
792                tvb_ip_to_str(tvb, 8),
793                tvb_ip_to_str(tvb, 12));
794
795     if (tree) {
796       ti = proto_tree_add_item(tree, proto_mip, tvb, offset, -1, ENC_NA);
797       mip_tree = proto_item_add_subtree(ti, ett_mip);
798
799       /* type */
800       proto_tree_add_uint(mip_tree, hf_mip_type, tvb, offset, 1, type);
801       offset++;
802
803       /* reserved */
804       proto_tree_add_item(mip_tree, hf_mip_rev_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
805       offset++;
806
807       /* flags */
808       flags = tvb_get_ntohs(tvb, offset);
809       tf = proto_tree_add_uint(mip_tree, hf_mip_flags, tvb, offset, 2, flags);
810       flags_tree = proto_item_add_subtree(tf, ett_mip_flags);
811       proto_tree_add_boolean(flags_tree, hf_mip_rev_a, tvb, offset, 2, flags);
812       proto_tree_add_boolean(flags_tree, hf_mip_rev_i, tvb, offset, 2, flags);
813
814       /* reserved */
815       proto_tree_add_uint(flags_tree, hf_mip_rev_reserved, tvb, offset, 2, flags);
816       offset += 2;
817
818       /* home address */
819       proto_tree_add_item(mip_tree, hf_mip_homeaddr, tvb, offset, 4, ENC_BIG_ENDIAN);
820       offset += 4;
821
822       /* home domain address */
823       proto_tree_add_item(mip_tree, hf_mip_hda, tvb, offset, 4, ENC_BIG_ENDIAN);
824       offset += 4;
825
826       /* foreign domain address */
827       proto_tree_add_item(mip_tree, hf_mip_fda, tvb, offset, 4, ENC_BIG_ENDIAN);
828       offset += 4;
829
830       /* revocation identifier */
831       proto_tree_add_item(mip_tree, hf_mip_revid, tvb, offset, 4, ENC_BIG_ENDIAN);
832       offset += 4;
833     } /* if tree */
834     break;
835   case MIP_REGISTRATION_REVOCATION_ACK:
836       col_add_fstr(pinfo->cinfo, COL_INFO, "Reg Revocation Ack: HoA=%s",
837                tvb_ip_to_str(tvb, 4));
838
839     if (tree) {
840       ti = proto_tree_add_item(tree, proto_mip, tvb, offset, -1, ENC_NA);
841       mip_tree = proto_item_add_subtree(ti, ett_mip);
842
843       /* type */
844       proto_tree_add_uint(mip_tree, hf_mip_type, tvb, offset, 1, type);
845       offset++;
846
847       /* reserved */
848       proto_tree_add_item(mip_tree, hf_mip_ack_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
849       offset++;
850
851       /* flags */
852       flags = tvb_get_ntohs(tvb, offset);
853       tf = proto_tree_add_uint(mip_tree, hf_mip_flags, tvb, offset, 2, flags);
854       flags_tree = proto_item_add_subtree(tf, ett_mip_flags);
855       proto_tree_add_boolean(flags_tree, hf_mip_ack_i, tvb, offset, 2, flags);
856
857       /* reserved */
858       proto_tree_add_uint(flags_tree, hf_mip_ack_reserved, tvb, offset, 2, flags);
859       offset += 2;
860
861       /* home address */
862       proto_tree_add_item(mip_tree, hf_mip_homeaddr, tvb, offset, 4, ENC_BIG_ENDIAN);
863       offset += 4;
864
865       /* revocation identifier */
866       proto_tree_add_item(mip_tree, hf_mip_revid, tvb, offset, 4, ENC_BIG_ENDIAN);
867       offset += 4;
868     } /* if tree */
869     break;
870   } /* End switch */
871
872   if (tree) {
873     if (tvb_reported_length_remaining(tvb, offset) > 0)
874       dissect_mip_extensions(tvb, offset, mip_tree);
875   }
876 } /* dissect_mip */
877
878 /* Register the protocol with Wireshark */
879 void proto_register_mip(void)
880 {
881
882 /* Setup list of header fields */
883   static hf_register_info hf[] = {
884     { &hf_mip_type,
885       { "Message Type",           "mip.type",
886         FT_UINT8, BASE_DEC, VALS(mip_types), 0,
887         "Mobile IP Message type.", HFILL }
888     },
889     { &hf_mip_flags,
890       {"Flags", "mip.flags",
891        FT_UINT8, BASE_HEX, NULL, 0x0,
892        NULL, HFILL}
893     },
894     { &hf_mip_s,
895       {"Simultaneous Bindings",           "mip.s",
896
897        FT_BOOLEAN, 8, NULL, 128,
898        "Simultaneous Bindings Allowed", HFILL }
899     },
900     { &hf_mip_b,
901       {"Broadcast Datagrams",           "mip.b",
902        FT_BOOLEAN, 8, NULL, 64,
903        "Broadcast Datagrams requested", HFILL }
904     },
905     { &hf_mip_d,
906       { "Co-located Care-of Address",           "mip.d",
907         FT_BOOLEAN, 8, NULL, 32,
908         "MN using Co-located Care-of address", HFILL }
909     },
910     { &hf_mip_m,
911       {"Minimal Encapsulation",           "mip.m",
912        FT_BOOLEAN, 8, NULL, 16,
913        "MN wants Minimal encapsulation", HFILL }
914     },
915     { &hf_mip_g,
916       {"GRE",           "mip.g",
917        FT_BOOLEAN, 8, NULL, 8,
918        "MN wants GRE encapsulation", HFILL }
919     },
920     { &hf_mip_v,
921       { "Van Jacobson",           "mip.v",
922         FT_BOOLEAN, 8, NULL, 4,
923         NULL, HFILL }
924     },
925     { &hf_mip_t,
926       { "Reverse Tunneling",           "mip.t",
927         FT_BOOLEAN, 8, NULL, 2,
928         "Reverse tunneling requested", HFILL }
929     },
930     { &hf_mip_x,
931       { "Reserved",           "mip.x",
932         FT_BOOLEAN, 8, NULL, 1,
933         NULL, HFILL }
934     },
935     { &hf_mip_code,
936       { "Reply Code",           "mip.code",
937         FT_UINT8, BASE_DEC, VALS(mip_reply_codes), 0,
938         "Mobile IP Reply code.", HFILL }
939     },
940     { &hf_mip_life,
941       { "Lifetime",           "mip.life",
942         FT_UINT16, BASE_DEC, NULL, 0,
943         "Mobile IP Lifetime.", HFILL }
944     },
945     { &hf_mip_homeaddr,
946       { "Home Address",           "mip.homeaddr",
947         FT_IPv4, BASE_NONE, NULL, 0,
948         "Mobile Node's home address.", HFILL }
949     },
950
951     { &hf_mip_haaddr,
952       { "Home Agent",           "mip.haaddr",
953         FT_IPv4, BASE_NONE, NULL, 0,
954         "Home agent IP Address.", HFILL }
955     },
956     { &hf_mip_coa,
957       { "Care of Address",           "mip.coa",
958         FT_IPv4, BASE_NONE, NULL, 0,
959         "Care of Address.", HFILL }
960     },
961     { &hf_mip_ident,
962       { "Identification",           "mip.ident",
963         FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0,
964         "MN Identification.", HFILL }
965     },
966     { &hf_mip_ext_type,
967       { "Extension Type",           "mip.ext.type",
968         FT_UINT8, BASE_DEC, VALS(mip_ext_types), 0,
969         "Mobile IP Extension Type.", HFILL }
970     },
971     { &hf_mip_gaext_stype,
972       { "Gen Auth Ext SubType",           "mip.ext.auth.subtype",
973         FT_UINT8, BASE_DEC, VALS(mip_gaext_stypes), 0,
974         "Mobile IP Auth Extension Sub Type.", HFILL }
975     },
976     { &hf_mip_ext_len,
977       { "Extension Length",         "mip.ext.len",
978         FT_UINT16, BASE_DEC, NULL, 0,
979         "Mobile IP Extension Length.", HFILL }
980     },
981     { &hf_mip_ext,
982       { "Extension",                      "mip.extension",
983         FT_BYTES, BASE_NONE, NULL, 0,
984         NULL, HFILL }
985     },
986     { &hf_mip_aext_spi,
987       { "SPI",                      "mip.auth.spi",
988         FT_UINT32, BASE_HEX, NULL, 0,
989         "Authentication Header Security Parameter Index.", HFILL }
990     },
991     { &hf_mip_aext_auth,
992       { "Authenticator",            "mip.auth.auth",
993         FT_BYTES, BASE_NONE, NULL, 0,
994         "Authenticator.", HFILL }
995     },
996     { &hf_mip_next_nai,
997       { "NAI",                      "mip.nai",
998         FT_STRING, BASE_NONE, NULL, 0,
999         NULL, HFILL }
1000     },
1001     { &hf_mip_rext_flags,
1002       {"Rev Ext Flags",             "mip.ext.rev.flags",
1003        FT_UINT16, BASE_HEX, NULL, 0x0,
1004        "Revocation Support Extension Flags", HFILL}
1005     },
1006     { &hf_mip_rext_i,
1007       { "'I' bit Support",          "mip.ext.rev.i",
1008         FT_BOOLEAN, 16, NULL, 32768,
1009         "Agent supports Inform bit in Revocation", HFILL }
1010     },
1011     { &hf_mip_rext_reserved,
1012       { "Reserved",                 "mip.ext.rev.reserved",
1013         FT_UINT16, BASE_HEX, NULL, 0x7fff,
1014         NULL, HFILL }
1015     },
1016     { &hf_mip_rext_tstamp,
1017       { "Timestamp",                "mip.ext.rev.tstamp",
1018         FT_UINT32, BASE_DEC, NULL, 0,
1019         "Revocation Timestamp of Sending Agent", HFILL }
1020     },
1021     { &hf_mip_rev_reserved,
1022       { "Reserved",                 "mip.rev.reserved",
1023         FT_UINT8, BASE_HEX, NULL, 0x0,
1024         NULL, HFILL}
1025     },
1026     { &hf_mip_rev_a,
1027       { "Home Agent",               "mip.rev.a",
1028         FT_BOOLEAN, 16, NULL, 32768,
1029         "Revocation sent by Home Agent", HFILL }
1030     },
1031     { &hf_mip_rev_i,
1032       { "Inform",                   "mip.rev.i",
1033         FT_BOOLEAN, 16, NULL, 16384,
1034         "Inform Mobile Node", HFILL }
1035     },
1036     { &hf_mip_rev_reserved2,
1037       { "Reserved",                 "mip.rev.reserved2",
1038         FT_UINT16, BASE_HEX, NULL, 0x3fff,
1039         NULL, HFILL}},
1040     { &hf_mip_hda,
1041       { "Home Domain Address",      "mip.rev.hda",
1042         FT_IPv4, BASE_NONE, NULL, 0,
1043         "Revocation Home Domain IP Address", HFILL }
1044     },
1045     { &hf_mip_fda,
1046       { "Foreign Domain Address",   "mip.rev.fda",
1047         FT_IPv4, BASE_NONE, NULL, 0,
1048         "Revocation Foreign Domain IP Address", HFILL }
1049     },
1050     { &hf_mip_revid,
1051       { "Revocation Identifier",    "mip.revid",
1052         FT_UINT32, BASE_DEC, NULL, 0,
1053         "Revocation Identifier of Initiating Agent", HFILL }
1054     },
1055     { &hf_mip_ack_reserved,
1056       { "Reserved",                 "mip.ack.reserved",
1057         FT_UINT8, BASE_HEX, NULL, 0x0,
1058         NULL, HFILL}
1059     },
1060     { &hf_mip_ack_i,
1061       { "Inform",                   "mip.ack.i",
1062         FT_BOOLEAN, 16, NULL, 32768,
1063         "Inform Mobile Node", HFILL }
1064     },
1065     { &hf_mip_ack_reserved2,
1066       { "Reserved",                 "mip.ack.reserved2",
1067         FT_UINT16, BASE_HEX, NULL, 0x7fff,
1068         NULL, HFILL}},
1069     { &hf_mip_dhaext_stype,
1070       { "DynHA Ext SubType",        "mip.ext.dynha.subtype",
1071         FT_UINT8, BASE_DEC, VALS(mip_dhaext_stypes), 0,
1072         "Dynamic HA Extension Sub-type", HFILL }
1073     },
1074     { &hf_mip_dhaext_addr,
1075       { "DynHA Home Agent",         "mip.ext.dynha.ha",
1076         FT_IPv4, BASE_NONE, NULL, 0,
1077         "Dynamic Home Agent IP Address", HFILL }
1078     },
1079     { &hf_mip_mstrext_stype,
1080       { "MsgStr Ext SubType",       "mip.ext.msgstr.subtype",
1081         FT_UINT8, BASE_DEC, VALS(mip_mstrext_stypes), 0,
1082         "Message String Extension Sub-type", HFILL }
1083     },
1084     { &hf_mip_mstrext_text,
1085       { "MsgStr Text",              "mip.ext.msgstr.text",
1086         FT_STRING, BASE_NONE, NULL, 0,
1087         "Message String Extension Text", HFILL }
1088     },
1089     { &hf_mip_nattt_nexthdr,
1090       { "NATTT NextHeader",         "mip.nattt.nexthdr",
1091         FT_UINT8, BASE_DEC, VALS(mip_nattt_nexthdr), 0,
1092         "NAT Traversal Tunnel Next Header.", HFILL }
1093     },
1094     { &hf_mip_nattt_reserved,
1095       { "Reserved",                 "mip.nattt.reserved",
1096         FT_UINT16, BASE_HEX, NULL , 0x0,
1097         NULL, HFILL }
1098     },
1099     { &hf_mip_utrqext_stype,
1100       { "UDP TunReq Ext SubType",   "mip.ext.utrq.subtype",
1101         FT_UINT8, BASE_DEC, VALS(mip_utrqext_stypes), 0,
1102         "UDP Tunnel Request Extension Sub-type", HFILL }
1103     },
1104     { &hf_mip_utrqext_reserved1,
1105       { "Reserved 1",                "mip.ext.utrq.reserved1",
1106         FT_UINT8, BASE_HEX, NULL, 0x0,
1107         NULL, HFILL }
1108     },
1109     { &hf_mip_utrqext_flags,
1110       { "UDP TunReq Ext Flags",     "mip.ext.utrq.flags",
1111         FT_UINT8, BASE_HEX, NULL, 0x0,
1112         "UDP Tunnel Request Extension Flags", HFILL }
1113     },
1114     { &hf_mip_utrqext_f,
1115       { "Req Forced",               "mip.ext.utrq.f",
1116         FT_BOOLEAN, 8, NULL, 128,
1117         "MN wants to Force UDP Tunneling", HFILL }
1118     },
1119     { &hf_mip_utrqext_r,
1120       { "FA Registration Required", "mip.ext.utrq.r",
1121         FT_BOOLEAN, 8, NULL, 64,
1122         "Registration through FA Required", HFILL }
1123     },
1124     { &hf_mip_utrqext_reserved2,
1125       { "Reserved 2",                "mip.ext.utrq.reserved2",
1126         FT_UINT8, BASE_HEX, NULL, 0x3f,
1127         NULL, HFILL }
1128     },
1129     { &hf_mip_utrqext_encap_type,
1130       { "UDP Encap Type",           "mip.ext.utrq.encaptype",
1131         FT_UINT8, BASE_DEC, VALS(mip_utrqext_encap_types), 0,
1132         "UDP Encapsulation Type", HFILL }
1133     },
1134     { &hf_mip_utrqext_reserved3,
1135       { "Reserved 3",                "mip.ext.utrq.reserved3",
1136         FT_UINT16, BASE_HEX, NULL, 0x0,
1137         NULL, HFILL }
1138     },
1139     { &hf_mip_utrpext_stype,
1140       { "UDP TunRep Ext SubType",   "mip.ext.utrp.subtype",
1141         FT_UINT8, BASE_DEC, VALS(mip_utrpext_stypes), 0,
1142         "UDP Tunnel Reply Extension Sub-type", HFILL }
1143     },
1144     { &hf_mip_utrpext_code,
1145       { "UDP TunRep Code",           "mip.ext.utrp.code",
1146         FT_UINT8, BASE_DEC, VALS(mip_utrpext_codes), 0,
1147         "UDP Tunnel Reply Code", HFILL }
1148     },
1149     { &hf_mip_utrpext_flags,
1150       { "UDP TunRep Ext Flags",           "mip.ext.utrp.flags",
1151         FT_UINT16, BASE_HEX, NULL, 0x0,
1152         "UDP Tunnel Request Extension Flags", HFILL }
1153     },
1154     { &hf_mip_utrpext_f,
1155       { "Rep Forced",                    "mip.ext.utrp.f",
1156         FT_BOOLEAN, 16, NULL, 32768,
1157         "HA wants to Force UDP Tunneling", HFILL }
1158     },
1159     { &hf_mip_utrpext_reserved,
1160       { "Reserved",           "mip.ext.utrp.reserved",
1161         FT_UINT16, BASE_HEX, NULL, 0x7fff,
1162         NULL, HFILL }
1163     },
1164     { &hf_mip_utrpext_keepalive,
1165       { "Keepalive Interval",            "mip.ext.utrp.keepalive",
1166         FT_UINT16, BASE_DEC, NULL, 0,
1167         "NAT Keepalive Interval", HFILL }
1168     },
1169     { &hf_mip_pmipv4nonskipext_stype,
1170       { "Sub-type",  "mip.ext.pmipv4nonskipext.subtype",
1171         FT_UINT8, BASE_DEC, VALS(mip_pmipv4nonskipext_stypes), 0,
1172         "PMIPv4 Skippable Extension Sub-type", HFILL }
1173     },
1174     { &hf_mip_pmipv4nonskipext_pernodeauthmethod,
1175       { "Per-Node Authentication Method",        "mip.ext.pmipv4nonskipext.pernodeauthmethod",
1176         FT_UINT8, BASE_DEC, VALS(mip_pmipv4nonskipext_pernodeauthmethod_types), 0,
1177         NULL, HFILL }
1178     },
1179     { &hf_mip_pmipv4skipext_stype,
1180       { "Sub-type",  "mip.ext.pmipv4skipext.subtype",
1181         FT_UINT8, BASE_DEC, VALS(mip_pmipv4skipext_stypes), 0,
1182         "PMIPv4 Non-skippable Extension Sub-type", HFILL }
1183     },
1184     { &hf_mip_pmipv4skipext_interfaceid,
1185       { "Interface ID",      "mip.ext.pmipv4skipext.interfaceid",
1186         FT_BYTES, BASE_NONE, NULL, 0,
1187         NULL, HFILL }
1188     },
1189     { &hf_mip_pmipv4skipext_deviceid_type,
1190       { "ID-Type",       "mip.ext.pmipv4skipext.deviceid_type",
1191         FT_UINT8, BASE_DEC, VALS(mip_pmipv4skipext_deviceid_types), 0,
1192         "Device ID-Type", HFILL }
1193     },
1194     { &hf_mip_pmipv4skipext_deviceid_id,
1195       { "Identifier",    "mip.ext.pmipv4skipext.deviceid_id",
1196         FT_BYTES, BASE_NONE, NULL, 0,
1197         "Device ID Identifier", HFILL }
1198     },
1199     { &hf_mip_pmipv4skipext_subscriberid_type,
1200       { "ID-Type",   "mip.ext.pmipv4skipext.subscriberid_type",
1201         FT_UINT8, BASE_DEC, VALS(mip_pmipv4skipext_subscriberid_types), 0,
1202         "Subscriber ID-Type", HFILL }
1203     },
1204     { &hf_mip_pmipv4skipext_subscriberid_id,
1205       { "Identifier",    "mip.ext.pmipv4skipext.subscriberid_id",
1206         FT_BYTES, BASE_NONE, NULL, 0,
1207         "Subscriber ID Identifier", HFILL }
1208     },
1209     { &hf_mip_pmipv4skipext_accesstechnology_type,
1210       { "Access Technology Type",    "mip.ext.pmipv4skipext.accesstechnology_type",
1211         FT_UINT8, BASE_DEC, VALS(mip_pmipv4skipext_accesstechnology_types), 0,
1212         NULL, HFILL }
1213     },
1214     { &hf_mip_cvse_reserved,
1215       { "CVSE Reserved",                "mip.ext.cvse.reserved",
1216         FT_UINT8, BASE_HEX, NULL, 0x0,
1217         NULL, HFILL }
1218     },
1219     { &hf_mip_cvse_vendor_org_id,
1220       { "CVSE Vendor/org ID",                "mip.ext.cvse.vendor_id",
1221         FT_UINT32, BASE_DEC|BASE_EXT_STRING, &sminmpec_values_ext, 0,
1222         NULL, HFILL }
1223     },
1224     { &hf_mip_cvse_verizon_cvse_type ,
1225       { "Verizon CVSE Type",                "mip.ext.cvse.verizon_type",
1226         FT_UINT16, BASE_DEC, VALS(mip_cvse_verizon_cvse_types), 0,
1227         NULL, HFILL }
1228     },
1229     { &hf_mip_cvse_vendor_cvse_type ,
1230       { "Vendor CVSE Type",                "mip.ext.cvse.vendor_type",
1231         FT_UINT16, BASE_HEX, NULL, 0x0,
1232         NULL, HFILL }
1233     },
1234     { &hf_mip_cvse_vendor_cvse_value ,
1235       { "Vendor CVSE Value",                "mip.ext.cvse.vendor_value",
1236         FT_BYTES, BASE_NONE, NULL, 0,
1237         NULL, HFILL }
1238     }
1239   };
1240
1241   /* Setup protocol subtree array */
1242   static gint *ett[] = {
1243     &ett_mip,
1244     &ett_mip_flags,
1245     &ett_mip_ext,
1246     &ett_mip_exts,
1247     &ett_mip_pmipv4_ext,
1248   };
1249
1250   /* Register the protocol name and description */
1251   proto_mip = proto_register_protocol("Mobile IP", "Mobile IP", "mip");
1252
1253   /* Register the dissector by name */
1254   register_dissector("mip", dissect_mip, proto_mip);
1255
1256   /* Required function calls to register the header fields and subtrees used */
1257   proto_register_field_array(proto_mip, hf, array_length(hf));
1258   proto_register_subtree_array(ett, array_length(ett));
1259 }
1260
1261 void
1262 proto_reg_handoff_mip(void)
1263 {
1264   dissector_handle_t mip_handle;
1265
1266   mip_handle = find_dissector("mip");
1267   ip_handle = find_dissector("ip");
1268   dissector_add_uint("udp.port", UDP_PORT_MIP, mip_handle);
1269 }
1270
1271