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>
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
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.
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.
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.
39 #include <epan/packet.h>
40 #include "packet-ntp.h"
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;
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;
118 /* Port used for Mobile IP */
119 #define UDP_PORT_MIP 434
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
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"},
140 static const value_string mip_reply_codes[]= {
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"},
201 static const value_string mip_nattt_nexthdr[]= {
204 {55, "Minimal IP Encapsulation Header"},
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 */
225 PMIPv4_SKIP_EXT = 147, /* draft-leung-mip4-proxy-mode */
226 SKIP_EXP_EXT = 255 /* RFC 4064 */
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"},
251 static const value_string mip_gaext_stypes[]= {
252 {1, "MN AAA Extension"},
256 static const value_string mip_dhaext_stypes[]= {
257 {1, "Requested HA Extension"},
258 {2, "Redirected HA Extension"},
262 static const value_string mip_mstrext_stypes[]= {
268 static const value_string mip_utrqext_stypes[]= {
273 static const value_string mip_utrqext_encap_types[]= {
276 {55, "Minimal IP Encapsulation Header"},
280 static const value_string mip_utrpext_stypes[]= {
285 static const value_string mip_utrpext_codes[]= {
286 {0, "Will do Tunneling"},
287 {64, "Tunneling Declined, Reason Unspecified"},
291 static const value_string mip_pmipv4nonskipext_stypes[]= {
293 {1, "Per-Node Authentication Method"},
297 static const value_string mip_pmipv4nonskipext_pernodeauthmethod_types[]= {
299 {1, "FA-HA Authentication"},
300 {2, "IPSec Authentication"},
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[]= {
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"},
317 static const value_string mip_pmipv4skipext_deviceid_types[]= {
319 {1, "Ethernet MAC address"},
320 {2, "Mobile Equipment Identifier (MEID)"},
321 {3, "International Mobile Equipment Identity (IMEI)"},
322 {4, "Electronic Serial Number (ESN)"},
326 static const value_string mip_pmipv4skipext_subscriberid_types[]= {
328 {1, "International Mobile Subscriber Identity (IMSI)"},
332 static const value_string mip_pmipv4skipext_accesstechnology_types[]= {
338 {5, "3GPP EUTRAN/LTE"},
339 {6, "3GPP UTRAN/GERAN"},
340 {7, "3GPP2 1xRTT/HRPD"},
345 static dissector_handle_t ip_handle;
347 /* Code to dissect extensions */
349 dissect_mip_extensions( tvbuff_t *tvb, int offset, proto_tree *tree)
352 proto_tree *exts_tree=NULL;
353 proto_tree *ext_tree;
355 proto_tree *ext_flags_tree;
357 proto_tree *pmipv4_tree;
360 guint8 ext_subtype=0;
361 guint8 pmipv4skipext_type;
365 /* None of this really matters if we don't have a tree */
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);
372 /* And, handle each extension */
373 while (tvb_reported_length_remaining(tvb, offset) > 0) {
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) {
379 * Very nasty . . breaks normal extensions, since the length is
380 * in the wrong place :(
382 ext_subtype = tvb_get_guint8(tvb, offset + 1);
383 ext_len = tvb_get_ntohs(tvb, offset + 2);
386 ext_len = tvb_get_guint8(tvb, offset + 1);
390 ti = proto_tree_add_text(exts_tree, tvb, offset, ext_len + hdrLen,
392 val_to_str(ext_type, mip_ext_types,
393 "Unknown Extension %u"));
394 ext_tree = proto_item_add_subtree(ti, ett_mip_ext);
396 proto_tree_add_item(ext_tree, hf_mip_ext_type, tvb, offset, 1, ext_type);
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);
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,
414 proto_tree_add_item(ext_tree, hf_mip_next_nai, tvb, offset,
418 case GEN_AUTH_EXT: /* RFC 3012 */
420 * Very nasty . . breaks normal extensions, since the length is
421 * in the wrong place :(
423 proto_tree_add_uint(ext_tree, hf_mip_gaext_stype, tvb, offset, 1, ext_subtype);
425 proto_tree_add_uint(ext_tree, hf_mip_ext_len, tvb, offset, 2, ext_len);
428 proto_tree_add_item(ext_tree, hf_mip_aext_spi, tvb, offset, 4, FALSE);
430 proto_tree_add_item(ext_tree, hf_mip_aext_auth, tvb, offset + 4,
434 case REV_SUPP_EXT: /* RFC 3543 */
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);
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);
446 case DYN_HA_EXT: /* RFC 4433 */
448 proto_tree_add_item(ext_tree, hf_mip_dhaext_stype, tvb, offset, 1, FALSE);
450 proto_tree_add_item(ext_tree, hf_mip_dhaext_addr, tvb, offset + 1, 4, FALSE);
454 proto_tree_add_item(ext_tree, hf_mip_mstrext_stype, tvb, offset, 1, FALSE);
457 proto_tree_add_item(ext_tree, hf_mip_mstrext_text, tvb, offset + 1, ext_len-1, FALSE);
459 case UDP_TUN_REQ_EXT: /* RFC 3519 */
461 proto_tree_add_item(ext_tree, hf_mip_utrqext_stype, tvb, offset, 1, FALSE);
464 proto_tree_add_item(ext_tree, hf_mip_utrqext_reserved1, tvb, offset + 1, 1, FALSE);
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);
474 proto_tree_add_uint(ext_flags_tree, hf_mip_utrqext_reserved2, tvb, offset + 2, 1, flags);
476 proto_tree_add_item(ext_tree, hf_mip_utrqext_encap_type, tvb, offset + 3, 1, FALSE);
479 proto_tree_add_item(ext_tree, hf_mip_utrqext_reserved3, tvb, offset + 4, 2, FALSE);
481 case UDP_TUN_REP_EXT: /* RFC 3519 */
483 proto_tree_add_item(ext_tree, hf_mip_utrpext_stype, tvb, offset, 1, FALSE);
486 proto_tree_add_item(ext_tree, hf_mip_utrpext_code, tvb, offset + 1, 1, FALSE);
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);
495 proto_tree_add_uint(ext_flags_tree, hf_mip_utrpext_reserved, tvb, offset + 2, 2, flags);
497 /* keepalive interval */
498 proto_tree_add_item(ext_tree, hf_mip_utrpext_keepalive, tvb, offset + 4, 2, FALSE);
500 case PMIPv4_NON_SKIP_EXT: /* draft-leung-mip4-proxy-mode */
502 proto_tree_add_item(ext_tree, hf_mip_pmipv4nonskipext_stype, tvb, offset, 1, ext_subtype);
505 proto_tree_add_item(ext_tree, hf_mip_ext_len, tvb, offset, 2, ext_len);
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);
512 case PMIPv4_SKIP_EXT: /* draft-leung-mip4-proxy-mode */
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);
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);
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);
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. */
545 proto_tree_add_item(ext_tree, hf_mip_ext, tvb, offset, ext_len, FALSE);
550 } /* while data remaining */
552 } /* dissect_mip_extensions */
554 /* Code to actually dissect the packets */
556 dissect_mip( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
558 /* Set up structures we will need to add the protocol subtree and manage it */
560 proto_tree *mip_tree=NULL;
562 proto_tree *flags_tree;
566 const guint8 *reftime;
569 /* Make entries in Protocol column and Info column on summary display */
571 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MobileIP");
572 col_clear(pinfo->cinfo, COL_INFO);
574 type = tvb_get_guint8(tvb, offset);
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)));
585 ti = proto_tree_add_item(tree, proto_mip, tvb, offset, -1, FALSE);
586 mip_tree = proto_item_add_subtree(ti, ett_mip);
589 proto_tree_add_uint(mip_tree, hf_mip_type, tvb, offset, 1, type);
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);
607 proto_tree_add_item(mip_tree, hf_mip_life, tvb, offset, 2, FALSE);
611 proto_tree_add_item(mip_tree, hf_mip_homeaddr, tvb, offset, 4, FALSE);
614 /* home agent address */
615 proto_tree_add_item(mip_tree, hf_mip_haaddr, tvb, offset, 4, FALSE);
618 /* Care of Address */
619 proto_tree_add_item(mip_tree, hf_mip_coa, tvb, offset, 4, FALSE);
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,
626 "Identification: %s",
627 ntp_fmt_ts(reftime));
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));
642 ti = proto_tree_add_item(tree, proto_mip, tvb, offset, -1, FALSE);
643 mip_tree = proto_item_add_subtree(ti, ett_mip);
646 proto_tree_add_uint(mip_tree, hf_mip_type, tvb, offset, 1, type);
650 proto_tree_add_item(mip_tree, hf_mip_code, tvb, offset, 1, FALSE);
653 /* Registration Lifetime */
654 proto_tree_add_item(mip_tree, hf_mip_life, tvb, offset, 2, FALSE);
658 proto_tree_add_item(mip_tree, hf_mip_homeaddr, tvb, offset, 4, FALSE);
661 /* Home Agent Address */
662 proto_tree_add_item(mip_tree, hf_mip_haaddr, tvb, offset, 4, FALSE);
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,
669 "Identification: %s",
670 ntp_fmt_ts(reftime));
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));
681 ti = proto_tree_add_item(tree, proto_mip, tvb, offset, -1, FALSE);
682 mip_tree = proto_item_add_subtree(ti, ett_mip);
685 proto_tree_add_uint(mip_tree, hf_mip_type, tvb, offset, 1, type);
689 proto_tree_add_item(mip_tree, hf_mip_nattt_nexthdr, tvb, offset, 1, FALSE);
693 proto_tree_add_item(mip_tree, hf_mip_nattt_reserved, tvb, offset, 2, FALSE);
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);
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)));
713 ti = proto_tree_add_item(tree, proto_mip, tvb, offset, -1, FALSE);
714 mip_tree = proto_item_add_subtree(ti, ett_mip);
717 proto_tree_add_uint(mip_tree, hf_mip_type, tvb, offset, 1, type);
721 proto_tree_add_item(mip_tree, hf_mip_rev_reserved, tvb, offset, 1, FALSE);
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);
732 proto_tree_add_uint(flags_tree, hf_mip_rev_reserved, tvb, offset, 2, flags);
736 proto_tree_add_item(mip_tree, hf_mip_homeaddr, tvb, offset, 4, FALSE);
739 /* home domain address */
740 proto_tree_add_item(mip_tree, hf_mip_hda, tvb, offset, 4, FALSE);
743 /* foreign domain address */
744 proto_tree_add_item(mip_tree, hf_mip_fda, tvb, offset, 4, FALSE);
747 /* revocation identifier */
748 proto_tree_add_item(mip_tree, hf_mip_revid, tvb, offset, 4, FALSE);
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)));
758 ti = proto_tree_add_item(tree, proto_mip, tvb, offset, -1, FALSE);
759 mip_tree = proto_item_add_subtree(ti, ett_mip);
762 proto_tree_add_uint(mip_tree, hf_mip_type, tvb, offset, 1, type);
766 proto_tree_add_item(mip_tree, hf_mip_ack_reserved, tvb, offset, 1, FALSE);
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);
776 proto_tree_add_uint(flags_tree, hf_mip_ack_reserved, tvb, offset, 2, flags);
780 proto_tree_add_item(mip_tree, hf_mip_homeaddr, tvb, offset, 4, FALSE);
783 /* revocation identifier */
784 proto_tree_add_item(mip_tree, hf_mip_revid, tvb, offset, 4, FALSE);
791 if (tvb_reported_length_remaining(tvb, offset) > 0)
792 dissect_mip_extensions(tvb, offset, mip_tree);
796 /* Register the protocol with Wireshark */
797 void proto_register_mip(void)
800 /* Setup list of header fields */
801 static hf_register_info hf[] = {
803 { "Message Type", "mip.type",
804 FT_UINT8, BASE_DEC, VALS(mip_types), 0,
805 "Mobile IP Message type.", HFILL }
808 {"Flags", "mip.flags",
809 FT_UINT8, BASE_HEX, NULL, 0x0,
813 {"Simultaneous Bindings", "mip.s",
815 FT_BOOLEAN, 8, NULL, 128,
816 "Simultaneous Bindings Allowed", HFILL }
819 {"Broadcast Datagrams", "mip.b",
820 FT_BOOLEAN, 8, NULL, 64,
821 "Broadcast Datagrams requested", HFILL }
824 { "Co-located Care-of Address", "mip.d",
825 FT_BOOLEAN, 8, NULL, 32,
826 "MN using Co-located Care-of address", HFILL }
829 {"Minimal Encapsulation", "mip.m",
830 FT_BOOLEAN, 8, NULL, 16,
831 "MN wants Minimal encapsulation", HFILL }
835 FT_BOOLEAN, 8, NULL, 8,
836 "MN wants GRE encapsulation", HFILL }
839 { "Van Jacobson", "mip.v",
840 FT_BOOLEAN, 8, NULL, 4,
844 { "Reverse Tunneling", "mip.t",
845 FT_BOOLEAN, 8, NULL, 2,
846 "Reverse tunneling requested", HFILL }
849 { "Reserved", "mip.x",
850 FT_BOOLEAN, 8, NULL, 1,
854 { "Reply Code", "mip.code",
855 FT_UINT8, BASE_DEC, VALS(mip_reply_codes), 0,
856 "Mobile IP Reply code.", HFILL }
859 { "Lifetime", "mip.life",
860 FT_UINT16, BASE_DEC, NULL, 0,
861 "Mobile IP Lifetime.", HFILL }
864 { "Home Address", "mip.homeaddr",
865 FT_IPv4, BASE_NONE, NULL, 0,
866 "Mobile Node's home address.", HFILL }
870 { "Home Agent", "mip.haaddr",
871 FT_IPv4, BASE_NONE, NULL, 0,
872 "Home agent IP Address.", HFILL }
875 { "Care of Address", "mip.coa",
876 FT_IPv4, BASE_NONE, NULL, 0,
877 "Care of Address.", HFILL }
880 { "Identification", "mip.ident",
881 FT_BYTES, BASE_NONE, NULL, 0,
882 "MN Identification.", HFILL }
885 { "Extension Type", "mip.ext.type",
886 FT_UINT8, BASE_DEC, VALS(mip_ext_types), 0,
887 "Mobile IP Extension Type.", HFILL }
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 }
895 { "Extension Length", "mip.ext.len",
896 FT_UINT16, BASE_DEC, NULL, 0,
897 "Mobile IP Extension Length.", HFILL }
900 { "Extension", "mip.extension",
901 FT_BYTES, BASE_NONE, NULL, 0,
905 { "SPI", "mip.auth.spi",
906 FT_UINT32, BASE_HEX, NULL, 0,
907 "Authentication Header Security Parameter Index.", HFILL }
910 { "Authenticator", "mip.auth.auth",
911 FT_BYTES, BASE_NONE, NULL, 0,
912 "Authenticator.", HFILL }
916 FT_STRING, BASE_NONE, NULL, 0,
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}
925 { "'I' bit Support", "mip.ext.rev.i",
926 FT_BOOLEAN, 16, NULL, 32768,
927 "Agent supports Inform bit in Revocation", HFILL }
929 { &hf_mip_rext_reserved,
930 { "Reserved", "mip.ext.rev.reserved",
931 FT_UINT16, BASE_HEX, NULL, 0x7fff,
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 }
939 { &hf_mip_rev_reserved,
940 { "Reserved", "mip.rev.reserved",
941 FT_UINT8, BASE_HEX, NULL, 0x0,
945 { "Home Agent", "mip.rev.a",
946 FT_BOOLEAN, 16, NULL, 32768,
947 "Revocation sent by Home Agent", HFILL }
950 { "Inform", "mip.rev.i",
951 FT_BOOLEAN, 16, NULL, 16384,
952 "Inform Mobile Node", HFILL }
954 { &hf_mip_rev_reserved2,
955 { "Reserved", "mip.rev.reserved2",
956 FT_UINT16, BASE_HEX, NULL, 0x3fff,
959 { "Home Domain Address", "mip.rev.hda",
960 FT_IPv4, BASE_NONE, NULL, 0,
961 "Revocation Home Domain IP Address", HFILL }
964 { "Foreign Domain Address", "mip.rev.fda",
965 FT_IPv4, BASE_NONE, NULL, 0,
966 "Revocation Foreign Domain IP Address", HFILL }
969 { "Revocation Identifier", "mip.revid",
970 FT_UINT32, BASE_DEC, NULL, 0,
971 "Revocation Identifier of Initiating Agent", HFILL }
973 { &hf_mip_ack_reserved,
974 { "Reserved", "mip.ack.reserved",
975 FT_UINT8, BASE_HEX, NULL, 0x0,
979 { "Inform", "mip.ack.i",
980 FT_BOOLEAN, 16, NULL, 32768,
981 "Inform Mobile Node", HFILL }
983 { &hf_mip_ack_reserved2,
984 { "Reserved", "mip.ack.reserved2",
985 FT_UINT16, BASE_HEX, NULL, 0x7fff,
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 }
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 }
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 }
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 }
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 }
1012 { &hf_mip_nattt_reserved,
1013 { "Reserved", "mip.nattt.reserved",
1014 FT_UINT16, BASE_HEX, NULL , 0x0,
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 }
1022 { &hf_mip_utrqext_reserved1,
1023 { "Reserved 1", "mip.ext.utrq.reserved1",
1024 FT_UINT8, BASE_HEX, NULL, 0x0,
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 }
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 }
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 }
1042 { &hf_mip_utrqext_reserved2,
1043 { "Reserved 2", "mip.ext.utrq.reserved2",
1044 FT_UINT8, BASE_HEX, NULL, 0x3f,
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 }
1052 { &hf_mip_utrqext_reserved3,
1053 { "Reserved 3", "mip.ext.utrq.reserved3",
1054 FT_UINT16, BASE_HEX, NULL, 0x0,
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 }
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 }
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 }
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 }
1077 { &hf_mip_utrpext_reserved,
1078 { "Reserved", "mip.ext.utrp.reserved",
1079 FT_UINT16, BASE_HEX, NULL, 0x7fff,
1082 { &hf_mip_utrpext_keepalive,
1083 { "Keepalive Interval", "mip.ext.utrp.keepalive",
1084 FT_UINT16, BASE_DEC, NULL, 0,
1085 "NAT Keepalive Interval", HFILL }
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 }
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,
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 }
1102 { &hf_mip_pmipv4skipext_interfaceid,
1103 { "Interface ID", "mip.ext.pmipv4skipext.interfaceid",
1104 FT_BYTES, BASE_NONE, NULL, 0,
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 }
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 }
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 }
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 }
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,
1134 /* Setup protocol subtree array */
1135 static gint *ett[] = {
1140 &ett_mip_pmipv4_ext,
1143 /* Register the protocol name and description */
1144 proto_mip = proto_register_protocol("Mobile IP", "Mobile IP", "mip");
1146 /* Register the dissector by name */
1147 register_dissector("mip", dissect_mip, proto_mip);
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));
1155 proto_reg_handoff_mip(void)
1157 dissector_handle_t mip_handle;
1159 mip_handle = find_dissector("mip");
1160 ip_handle = find_dissector("ip");
1161 dissector_add("udp.port", UDP_PORT_MIP, mip_handle);