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