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