2000-05-27 13:53:26 +00:00
|
|
|
/* packet-mip.c
|
|
|
|
* Routines for Mobile IP dissection
|
|
|
|
* Copyright 2000, Stefan Raab <Stefan.Raab@nextel.com>
|
|
|
|
*
|
2001-01-09 06:32:10 +00:00
|
|
|
* $Id: packet-mip.c,v 1.12 2001/01/09 06:31:38 guy Exp $
|
2000-05-27 13:53:26 +00:00
|
|
|
*
|
|
|
|
* Ethereal - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@unicom.net>
|
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_TYPES_H
|
|
|
|
# include <sys/types.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_NETINET_IN_H
|
|
|
|
# include <netinet/in.h>
|
|
|
|
#endif
|
|
|
|
|
2000-08-11 13:37:21 +00:00
|
|
|
#include <string.h>
|
|
|
|
#include <glib.h>
|
|
|
|
|
2000-05-27 13:53:26 +00:00
|
|
|
#ifdef NEED_SNPRINTF_H
|
|
|
|
# include "snprintf.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "packet.h"
|
|
|
|
|
|
|
|
/* Initialize the protocol and registered fields */
|
|
|
|
static int proto_mip = -1;
|
|
|
|
static int hf_mip_type = -1;
|
|
|
|
static int hf_mip_s = -1;
|
|
|
|
static int hf_mip_b = -1;
|
|
|
|
static int hf_mip_d = -1;
|
|
|
|
static int hf_mip_m = -1;
|
|
|
|
static int hf_mip_g = -1;
|
|
|
|
static int hf_mip_v = -1;
|
|
|
|
static int hf_mip_code = -1;
|
|
|
|
static int hf_mip_life = -1;
|
|
|
|
static int hf_mip_homeaddr = -1;
|
|
|
|
static int hf_mip_haaddr = -1;
|
|
|
|
static int hf_mip_coa = -1;
|
|
|
|
static int hf_mip_ident = -1;
|
|
|
|
|
|
|
|
/* Initialize the subtree pointers */
|
|
|
|
static gint ett_mip = -1;
|
|
|
|
|
|
|
|
/* Port used for Mobile IP */
|
|
|
|
#define UDP_PORT_MIP 434
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
struct mip_packet{
|
|
|
|
unsigned char type;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct mip_request_packet{
|
|
|
|
unsigned char type;
|
|
|
|
unsigned char code;
|
|
|
|
unsigned char life[2];
|
|
|
|
unsigned char homeaddr[4];
|
|
|
|
unsigned char haaddr[4];
|
|
|
|
unsigned char coa[4];
|
|
|
|
unsigned char ident[8];
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct mip_reply_packet{
|
|
|
|
unsigned char type;
|
|
|
|
unsigned char code;
|
|
|
|
unsigned char life[2];
|
|
|
|
unsigned char homeaddr[4];
|
|
|
|
unsigned char haaddr[4];
|
|
|
|
unsigned char ident[8];
|
|
|
|
|
|
|
|
};
|
|
|
|
*/
|
|
|
|
|
|
|
|
static const value_string mip_types[] = {
|
|
|
|
{1, "Registration Request"},
|
2001-01-03 16:41:08 +00:00
|
|
|
{3, "Registration Reply"},
|
|
|
|
{0, NULL},
|
2000-05-27 13:53:26 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string mip_reply_codes[]= {
|
|
|
|
{0, "Registration Accepted"},
|
|
|
|
{1, "Registration Accepted, no simul bindings"},
|
|
|
|
{64, "Registration Denied by FA, unspecified reason"},
|
|
|
|
{65, "Registration Denied by FA, Admin Prohibit"},
|
|
|
|
{66, "Registration Denied by FA, Insufficient Resources"},
|
|
|
|
{67, "Registration Denied by FA, MN failed Auth"},
|
|
|
|
{68, "Registration Denied by FA, HA failed Auth"},
|
|
|
|
{69, "Registration Denied by FA, Lifetime to long"},
|
|
|
|
{70, "Registration Denied by FA, Poorly Formed Request"},
|
|
|
|
{71, "Registration Denied by FA, Poorly Formed Reply"},
|
|
|
|
{72, "Registration Denied by FA, encap unavailable"},
|
|
|
|
{73, "Registration Denied by FA, VJ unavailable"},
|
|
|
|
{80, "Registration Denied by FA, Home net unreachable"},
|
|
|
|
{81, "Registration Denied by FA, Home Agent host unreachable"},
|
|
|
|
{82, "Registration Denied by FA, Home Agent port unreachable"},
|
|
|
|
{88, "Registration Denied by FA, Home Agent unreachable"},
|
|
|
|
{128, "Registration Denied by HA, unspecified"},
|
|
|
|
{129, "Registration Denied by HA, Admin Prohibit"},
|
|
|
|
{130, "Registration Denied by HA, insufficient resources"},
|
|
|
|
{131, "Registration Denied by HA, MN failed Auth"},
|
|
|
|
{132, "Registration Denied by HA, FA failed Auth"},
|
|
|
|
{133, "Registration Denied by HA, registration ID Mismatch"},
|
|
|
|
{134, "Registration Denied by HA, poorly formed request"},
|
|
|
|
{135, "Registration Denied by HA, too many simul bindings"},
|
|
|
|
{136, "Registration Denied by HA, unknown HA address"},
|
2001-01-03 16:41:08 +00:00
|
|
|
{0, NULL},
|
2000-05-27 13:53:26 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Code to actually dissect the packets */
|
|
|
|
static void
|
|
|
|
dissect_mip(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
|
|
|
|
{
|
|
|
|
|
|
|
|
/* Set up structures we will need to add the protocol subtree and manage it */
|
|
|
|
proto_item *ti;
|
|
|
|
proto_tree *mip_tree;
|
|
|
|
guint8 type, code;
|
|
|
|
|
|
|
|
/* Make our own tvb until the function call includes one */
|
|
|
|
tvbuff_t *tvb;
|
|
|
|
packet_info *pinfo = π
|
Convert IPX-and-friend dissectors in packet-ipx.c to use
tvbuffs.
In doing so, I realied that my recommendation for using
tvb_new_subset(pi.compat_top_tvb, -1, -1) was incorrect, because
some dissectors (ethernet!) change pi.len and pi.cap_len. So, I have
to take those two variables into account instead of using -1 and -1.
So, I provide a macro called tvb_create_from_top(offset), where
offset is the name of your offset variable. It is a wrapper around
tvb_new_subset().
I converted the lines that followed my suggestion to use
tvb_create_from_top().
In proto.c I added
proto_tree_add_debug_text(proto_tree*, const char*, ...)
It's much like proto_tree_add_text(), except that it takes no offset
or length; it's soley for temporarily putting debug text into the
proto_tree while debugging a dissector. In making sure that its
use is temporary, the funciton also prints the debug string to stdout
to remind the programmer that the debug code needs to be removed
before shipping the code.
svn path=/trunk/; revision=2068
2000-06-15 03:49:00 +00:00
|
|
|
tvb = tvb_create_from_top(offset);
|
2000-05-27 13:53:26 +00:00
|
|
|
|
Add the "Edit:Protocols..." feature which currently only implements
the following:
It is now possible to enable/disable a particular protocol decoding
(i.e. the protocol dissector is void or not). When a protocol
is disabled, it is displayed as Data and of course, all linked
sub-protocols are disabled as well.
Disabling a protocol could be interesting:
- in case of buggy dissectors
- in case of wrong heuristics
- for performance reasons
- to decode the data as another protocol (TODO)
Currently (if I am not wrong), all dissectors but NFS can be disabled
(and dissectors that do not register protocols :-)
I do not like the way the RPC sub-dissectors are disabled (in the
sub-dissectors) since this could be done in the RPC dissector itself,
knowing the sub-protocol hfinfo entry (this is why, I've not modified
the NFS one yet).
Two functions are added in proto.c :
gboolean proto_is_protocol_enabled(int n);
void proto_set_decoding(int n, gboolean enabled);
and two MACROs which can be used in dissectors:
OLD_CHECK_DISPLAY_AS_DATA(index, pd, offset, fd, tree)
CHECK_DISPLAY_AS_DATA(index, tvb, pinfo, tree)
See also the XXX in proto_dlg.c and proto.c around the new functions.
svn path=/trunk/; revision=2267
2000-08-13 14:09:15 +00:00
|
|
|
CHECK_DISPLAY_AS_DATA(proto_mip, tvb, pinfo, tree);
|
|
|
|
|
2000-05-27 13:53:26 +00:00
|
|
|
/* Make entries in Protocol column and Info column on summary display */
|
|
|
|
|
|
|
|
pinfo->current_proto = "Mobile IP";
|
|
|
|
if (check_col(fd, COL_PROTOCOL))
|
2000-11-19 08:54:37 +00:00
|
|
|
col_set_str(fd, COL_PROTOCOL, "mip");
|
2000-05-27 13:53:26 +00:00
|
|
|
|
|
|
|
type = tvb_get_guint8(tvb, 0);
|
|
|
|
|
|
|
|
if (type==1) {
|
|
|
|
|
|
|
|
if (check_col(fd, COL_INFO))
|
2000-11-19 08:54:37 +00:00
|
|
|
col_set_str(fd, COL_INFO, "Mobile IP Registration Request");
|
2000-05-27 13:53:26 +00:00
|
|
|
|
|
|
|
if (tree) {
|
2000-05-31 05:09:07 +00:00
|
|
|
ti = proto_tree_add_item(tree, proto_mip, tvb, 0, tvb_length(tvb), FALSE);
|
2000-05-27 13:53:26 +00:00
|
|
|
mip_tree = proto_item_add_subtree(ti, ett_mip);
|
2000-05-31 05:09:07 +00:00
|
|
|
proto_tree_add_int(mip_tree, hf_mip_type, tvb, 0, 1, type);
|
2000-05-27 13:53:26 +00:00
|
|
|
|
|
|
|
code = tvb_get_guint8(tvb, 1);
|
2000-05-31 05:09:07 +00:00
|
|
|
proto_tree_add_boolean(mip_tree, hf_mip_s, tvb, 1, 1, code);
|
|
|
|
proto_tree_add_boolean(mip_tree, hf_mip_b, tvb, 1, 1, code);
|
|
|
|
proto_tree_add_boolean(mip_tree, hf_mip_d, tvb, 1, 1, code);
|
|
|
|
proto_tree_add_boolean(mip_tree, hf_mip_m, tvb, 1, 1, code);
|
|
|
|
proto_tree_add_boolean(mip_tree, hf_mip_g, tvb, 1, 1, code);
|
|
|
|
proto_tree_add_boolean(mip_tree, hf_mip_v, tvb, 1, 1, code);
|
|
|
|
|
|
|
|
proto_tree_add_int(mip_tree, hf_mip_life, tvb, 2, 2, tvb_get_ntohs(tvb, 2));
|
|
|
|
proto_tree_add_ipv4(mip_tree, hf_mip_homeaddr, tvb, 4, 4, tvb_get_letohl(tvb, 4));
|
|
|
|
proto_tree_add_ipv4(mip_tree, hf_mip_haaddr, tvb, 8, 4, tvb_get_letohl(tvb, 8));
|
|
|
|
proto_tree_add_ipv4(mip_tree, hf_mip_coa, tvb, 12, 4, tvb_get_letohl(tvb, 12));
|
|
|
|
proto_tree_add_bytes(mip_tree, hf_mip_ident, tvb, 16, 8, tvb_get_ptr(tvb, 16, 8));
|
2000-05-27 13:53:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (type==3){
|
|
|
|
if (check_col(fd, COL_INFO))
|
2000-11-19 08:54:37 +00:00
|
|
|
col_set_str(fd, COL_INFO, "Mobile IP Registration Reply");
|
2000-05-27 13:53:26 +00:00
|
|
|
|
|
|
|
if (tree) {
|
2000-05-31 05:09:07 +00:00
|
|
|
ti = proto_tree_add_item(tree, proto_mip, tvb, 0, tvb_length(tvb), FALSE);
|
2000-05-27 13:53:26 +00:00
|
|
|
mip_tree = proto_item_add_subtree(ti, ett_mip);
|
2000-05-31 05:09:07 +00:00
|
|
|
proto_tree_add_int(mip_tree, hf_mip_type, tvb, 0, 1, type);
|
2000-05-27 13:53:26 +00:00
|
|
|
|
|
|
|
code = tvb_get_guint8(tvb, 1);
|
2000-05-31 05:09:07 +00:00
|
|
|
proto_tree_add_uint(mip_tree, hf_mip_code, tvb, 1, 1, code);
|
|
|
|
proto_tree_add_int(mip_tree, hf_mip_life, tvb, 2, 2, tvb_get_ntohs(tvb, 2));
|
|
|
|
proto_tree_add_ipv4(mip_tree, hf_mip_homeaddr, tvb, 4, 4, tvb_get_letohl(tvb, 4));
|
|
|
|
proto_tree_add_ipv4(mip_tree, hf_mip_haaddr, tvb, 8, 4, tvb_get_letohl(tvb, 8));
|
|
|
|
proto_tree_add_bytes(mip_tree, hf_mip_ident, tvb, 12, 8, tvb_get_ptr(tvb, 12, 8));
|
2000-05-27 13:53:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Register the protocol with Ethereal */
|
|
|
|
void proto_register_mip(void)
|
|
|
|
{
|
|
|
|
|
|
|
|
/* Setup list of header fields */
|
|
|
|
static hf_register_info hf[] = {
|
|
|
|
{ &hf_mip_type,
|
|
|
|
{ "Message Type", "mip.type",
|
|
|
|
FT_INT8, BASE_DEC, VALS(mip_types), 0,
|
|
|
|
"Mobile IP Message type." }
|
|
|
|
},
|
|
|
|
{ &hf_mip_s,
|
|
|
|
{"Simultaneous Bindings", "mip.s",
|
|
|
|
FT_BOOLEAN, 8, NULL, 128,
|
|
|
|
"Simultaneous Bindings Allowed" }
|
|
|
|
},
|
2000-05-27 17:51:15 +00:00
|
|
|
{ &hf_mip_b,
|
2000-05-27 13:53:26 +00:00
|
|
|
{"Broadcast Datagrams", "mip.b",
|
|
|
|
FT_BOOLEAN, 8, NULL, 64,
|
|
|
|
"Broadcast Datagrams requested" }
|
|
|
|
},
|
|
|
|
{ &hf_mip_d,
|
|
|
|
{ "Co-lcated Care-of Address", "mip.d",
|
|
|
|
FT_BOOLEAN, 8, NULL, 32,
|
|
|
|
"MN using Co-located Care-of address" }
|
|
|
|
},
|
|
|
|
{ &hf_mip_m,
|
|
|
|
{"Minimal Encapsulation", "mip.m",
|
|
|
|
FT_BOOLEAN, 8, NULL, 16,
|
|
|
|
"MN wants Minimal encapsulation" }
|
|
|
|
},
|
|
|
|
{ &hf_mip_g,
|
|
|
|
{"GRE", "mip.g",
|
|
|
|
FT_BOOLEAN, 8, NULL, 8,
|
|
|
|
"MN wants GRE encapsulation" }
|
|
|
|
},
|
|
|
|
{ &hf_mip_v,
|
|
|
|
{ "Van Jacobson", "mip.v",
|
|
|
|
FT_BOOLEAN, 8, NULL, 4,
|
2000-05-27 17:51:15 +00:00
|
|
|
"Van Jacobson" }
|
2000-05-27 13:53:26 +00:00
|
|
|
},
|
|
|
|
{ &hf_mip_code,
|
|
|
|
{ "Reply Code", "mip.code",
|
|
|
|
FT_UINT8, BASE_DEC, VALS(mip_reply_codes), 0,
|
|
|
|
"Mobile IP Reply code." }
|
|
|
|
},
|
|
|
|
{ &hf_mip_life,
|
|
|
|
{ "Lifetime", "mip.life",
|
|
|
|
FT_INT16, BASE_DEC, NULL, 0,
|
|
|
|
"Mobile IP Lifetime." }
|
|
|
|
},
|
|
|
|
{ &hf_mip_homeaddr,
|
|
|
|
{ "Home Address", "mip.homeaddr",
|
|
|
|
FT_IPv4, BASE_NONE, NULL, 0,
|
2000-05-27 17:51:15 +00:00
|
|
|
"Mobile Node's home address." }
|
2000-05-27 13:53:26 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
{ &hf_mip_haaddr,
|
|
|
|
{ "Home Agent", "mip.haaddr",
|
|
|
|
FT_IPv4, BASE_NONE, NULL, 0,
|
2000-05-27 17:51:15 +00:00
|
|
|
"Home agent IP Address." }
|
2000-05-27 13:53:26 +00:00
|
|
|
},
|
|
|
|
{ &hf_mip_coa,
|
|
|
|
{ "Care of Address", "mip.coa",
|
|
|
|
FT_IPv4, BASE_NONE, NULL, 0,
|
|
|
|
"Care of Address." }
|
|
|
|
},
|
|
|
|
{ &hf_mip_ident,
|
|
|
|
{ "Identification", "mip.ident",
|
|
|
|
FT_BYTES, BASE_NONE, NULL, 0,
|
|
|
|
"MN Identification." }
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Setup protocol subtree array */
|
|
|
|
static gint *ett[] = {
|
|
|
|
&ett_mip,
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Register the protocol name and description */
|
2001-01-03 06:56:03 +00:00
|
|
|
proto_mip = proto_register_protocol("Mobile IP", "Mobile IP", "mip");
|
2000-05-27 13:53:26 +00:00
|
|
|
|
|
|
|
/* Required function calls to register the header fields and subtrees used */
|
|
|
|
proto_register_field_array(proto_mip, hf, array_length(hf));
|
|
|
|
proto_register_subtree_array(ett, array_length(ett));
|
|
|
|
};
|
|
|
|
|
|
|
|
void
|
|
|
|
proto_reg_handoff_mip(void)
|
|
|
|
{
|
2001-01-09 06:32:10 +00:00
|
|
|
old_dissector_add("udp.port", UDP_PORT_MIP, dissect_mip, proto_mip);
|
2000-05-27 13:53:26 +00:00
|
|
|
}
|