aboutsummaryrefslogtreecommitdiffstats
path: root/packet-portmap.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2001-02-06 06:46:10 +0000
committerGuy Harris <guy@alum.mit.edu>2001-02-06 06:46:10 +0000
commitd9ee8bec536d8eac9177deef04f4d90d96d2e390 (patch)
tree7a89cb2573f7ae92f6d3acbf562079f2a4144834 /packet-portmap.c
parent60ce2f6158217e56240d20e765a497b9e3dffdb5 (diff)
Tvbuffify the portmap/rpcbind dissector, and implement part of CALLIT
dissection (dissection of V2 CALLIT calls; no V3/V4 stuff or reply handling yet). svn path=/trunk/; revision=2994
Diffstat (limited to 'packet-portmap.c')
-rw-r--r--packet-portmap.c277
1 files changed, 166 insertions, 111 deletions
diff --git a/packet-portmap.c b/packet-portmap.c
index f0add47dd1..372da8688f 100644
--- a/packet-portmap.c
+++ b/packet-portmap.c
@@ -1,7 +1,7 @@
/* packet-portmap.c
* Routines for portmap dissection
*
- * $Id: packet-portmap.c,v 1.24 2001/01/28 03:39:48 guy Exp $
+ * $Id: packet-portmap.c,v 1.25 2001/02/06 06:46:10 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -65,175 +65,233 @@ static gint ett_portmap_entry = -1;
/* Dissect a getport call */
-int dissect_getport_call(const u_char *pd, int offset, frame_data *fd,
+int dissect_getport_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree)
{
guint32 proto;
guint32 prog;
- if ( !BYTES_ARE_IN_FRAME(offset, 16)) return offset;
if ( tree )
{
- prog = pntohl(&pd[offset+0]);
- proto_tree_add_uint_format(tree, hf_portmap_prog, NullTVB,
+ prog = tvb_get_ntohl(tvb, offset+0);
+ proto_tree_add_uint_format(tree, hf_portmap_prog, tvb,
offset, 4, prog, "Program: %s (%u)",
rpc_prog_name(prog), prog);
- proto_tree_add_uint(tree, hf_portmap_version, NullTVB,
- offset+4, 4, pntohl(&pd[offset+4]));
+ proto_tree_add_item(tree, hf_portmap_version, tvb,
+ offset+4, 4, FALSE);
- proto = pntohl(&pd[offset+8]);
- proto_tree_add_uint_format(tree, hf_portmap_proto, NullTVB,
+ proto = tvb_get_ntohl(tvb, offset+8);
+ proto_tree_add_uint_format(tree, hf_portmap_proto, tvb,
offset+8, 4, proto, "Proto: %s (%u)", ipprotostr(proto), proto);
- proto_tree_add_uint(tree, hf_portmap_port, NullTVB,
- offset+12, 4, pntohl(&pd[offset+12]));
+ proto_tree_add_item(tree, hf_portmap_port, tvb,
+ offset+12, 4, FALSE);
}
return offset+16;
}
-int dissect_getport_reply(const u_char *pd, int offset, frame_data *fd,
+int dissect_getport_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree)
{
- if ( !BYTES_ARE_IN_FRAME(offset, 4)) return offset;
- if ( tree )
- {
- proto_tree_add_uint(tree, hf_portmap_port, NullTVB,
- offset, 4, pntohl(&pd[offset+0]));
- }
- return offset+=4;
+ offset = dissect_rpc_uint32_tvb(tvb, pinfo, tree, hf_portmap_port,
+ offset);
+ return offset;
}
/* Dissect a 'set' call */
-int dissect_set_call(const u_char *pd, int offset, frame_data *fd,
+int dissect_set_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree)
{
guint32 proto;
guint32 prog;
- if ( !BYTES_ARE_IN_FRAME(offset, 16)) return offset;
if ( tree )
{
- prog = pntohl(&pd[offset+0]);
- proto_tree_add_uint_format(tree, hf_portmap_prog, NullTVB,
+ prog = tvb_get_ntohl(tvb, offset+0);
+ proto_tree_add_uint_format(tree, hf_portmap_prog, tvb,
offset, 4, prog, "Program: %s (%d)",
rpc_prog_name(prog), prog);
- proto_tree_add_uint(tree, hf_portmap_version, NullTVB,
- offset+4, 4, pntohl(&pd[offset+4]));
+ proto_tree_add_item(tree, hf_portmap_version, tvb,
+ offset+4, 4, FALSE);
- proto = pntohl(&pd[offset+8]);
- proto_tree_add_uint_format(tree, hf_portmap_proto, NullTVB,
+ proto = tvb_get_ntohl(tvb, offset+8);
+ proto_tree_add_uint_format(tree, hf_portmap_proto,tvb,
offset+8, 4, proto, "Proto: %s (%d)", ipprotostr(proto), proto);
- proto_tree_add_uint(tree, hf_portmap_port, NullTVB,
- offset+12, 4, pntohl(&pd[offset+12]));
+ proto_tree_add_item(tree, hf_portmap_port, tvb,
+ offset+12, 4, FALSE);
}
return offset+16;
}
/* Dissect a 'unset' call */
-int dissect_unset_call(const u_char *pd, int offset, frame_data *fd,
+int dissect_unset_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree)
{
guint32 proto;
guint32 prog;
- if ( !BYTES_ARE_IN_FRAME(offset, 16)) return offset;
if ( tree )
{
- prog = pntohl(&pd[offset+0]);
- proto_tree_add_uint_format(tree, hf_portmap_prog, NullTVB,
+ prog = tvb_get_ntohl(tvb, offset+0);
+ proto_tree_add_uint_format(tree, hf_portmap_prog, tvb,
offset, 4, prog, "Program: %s (%d)",
rpc_prog_name(prog), prog);
- proto_tree_add_uint(tree, hf_portmap_version, NullTVB,
- offset+4, 4, pntohl(&pd[offset+4]));
+ proto_tree_add_item(tree, hf_portmap_version, tvb,
+ offset+4, 4, FALSE);
- proto = pntohl(&pd[offset+8]);
- proto_tree_add_uint(tree, hf_portmap_proto, NullTVB,
+ proto = tvb_get_ntohl(tvb, offset+8);
+ proto_tree_add_uint(tree, hf_portmap_proto, tvb,
offset+8, 4, proto);
- proto_tree_add_uint(tree, hf_portmap_port, NullTVB,
- offset+12, 4, pntohl(&pd[offset+12]));
+ proto_tree_add_item(tree, hf_portmap_port, tvb,
+ offset+12, 4, FALSE);
}
-
+
return offset+16;
}
-int dissect_set_reply(const u_char *pd, int offset, frame_data *fd,
+int dissect_set_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree)
{
- if ( tree )
- {
- if ( !BYTES_ARE_IN_FRAME(offset, 4)) return offset;
-
- proto_tree_add_boolean(tree, hf_portmap_answer, NullTVB,
- offset, 4, pntohl(&pd[offset+0]));
- offset += 4;
- }
- return offset;
+ offset = dissect_rpc_bool_tvb(tvb, pinfo, tree, hf_portmap_answer,
+ offset);
+ return offset;
}
static int
-dissect_dump_entry(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
+dissect_dump_entry(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree)
{
int prog, version, proto, port;
proto_item *ti, *subtree;
- if ( ! BYTES_ARE_IN_FRAME(offset, 16) )
- {
- if ( tree )
- {
- proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Map Entry: <TRUNCATED>");
- }
- return pi.captured_len;
- }
- prog = pntohl(&pd[offset+0]);
- version = pntohl(&pd[offset+4]);
- proto = pntohl(&pd[offset+8]);
- port = pntohl(&pd[offset+12]);
+ prog = tvb_get_ntohl(tvb, offset+0);
+ version = tvb_get_ntohl(tvb, offset+4);
+ proto = tvb_get_ntohl(tvb, offset+8);
+ port = tvb_get_ntohl(tvb, offset+12);
if ( tree )
{
- ti = proto_tree_add_text(tree, NullTVB, offset, 16, "Map Entry: %s (%u) V%d",
+ ti = proto_tree_add_text(tree, tvb, offset, 16,
+ "Map Entry: %s (%u) V%d",
rpc_prog_name(prog), prog, version);
subtree = proto_item_add_subtree(ti, ett_portmap_entry);
- proto_tree_add_uint_format(subtree, hf_portmap_prog, NullTVB,
+ proto_tree_add_uint_format(subtree, hf_portmap_prog, tvb,
offset+0, 4, prog,
"Program: %s (%u)", rpc_prog_name(prog), prog);
- proto_tree_add_uint(subtree, hf_portmap_version, NullTVB,
+ proto_tree_add_uint(subtree, hf_portmap_version, tvb,
offset+4, 4, version);
- proto_tree_add_uint_format(subtree, hf_portmap_proto, NullTVB,
+ proto_tree_add_uint_format(subtree, hf_portmap_proto, tvb,
offset+8, 4, proto,
"Protocol: %s (0x%02x)", ipprotostr(proto), proto);
- proto_tree_add_uint(subtree, hf_portmap_port, NullTVB,
+ proto_tree_add_uint(subtree, hf_portmap_port, tvb,
offset+12, 4, port);
}
offset += 16;
return offset;
}
-int dissect_dump_reply(const u_char *pd, int offset, frame_data *fd,
+int dissect_dump_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree)
{
- offset = dissect_rpc_list(pd, offset, fd, tree, dissect_dump_entry);
+ offset = dissect_rpc_list_tvb(tvb, pinfo, tree, offset,
+ dissect_dump_entry);
return offset;
}
+/* Dissect a callit call */
+int dissect_callit_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree)
+{
+ rpc_proc_info_key key;
+ rpc_proc_info_value *value;
+ char *procname = NULL;
+ char procname_static[20];
+ old_dissect_function_t *old_dissect_function = NULL;
+ dissect_function_t *dissect_function = NULL;
+
+ key.prog = tvb_get_ntohl(tvb, offset+0);
+ if ( tree )
+ {
+ proto_tree_add_uint_format(tree, hf_portmap_prog, tvb,
+ offset, 4, key.prog, "Program: %s (%u)",
+ rpc_prog_name(key.prog), key.prog);
+ }
+
+ key.vers = tvb_get_ntohl(tvb, offset+4);
+ if ( tree )
+ {
+ proto_tree_add_uint(tree, hf_portmap_version, tvb,
+ offset+4, 4, key.vers);
+ }
+
+ key.proc = tvb_get_ntohl(tvb, offset+8);
+ if ((value = g_hash_table_lookup(rpc_procs,&key)) != NULL) {
+ if (value->is_old_dissector)
+ old_dissect_function = value->dissect_call.old;
+ else
+ dissect_function = value->dissect_call.new;
+ procname = value->name;
+ }
+ else {
+ /* happens only with strange program versions or
+ non-existing dissectors */
+#if 0
+ dissect_function = NULL;
+#endif
+ sprintf(procname_static, "proc-%u", key.proc);
+ procname = procname_static;
+ }
+ if ( tree )
+ {
+ proto_tree_add_uint_format(tree, hf_portmap_proc, tvb,
+ offset+8, 4, key.proc, "Procedure: %s (%u)",
+ procname, key.proc);
+ }
+
+ if ( tree )
+ {
+ proto_tree_add_text(tree, tvb, offset+12, 4,
+ "Argument length: %u",
+ tvb_get_ntohl(tvb, offset+12));
+ }
+
+ offset += 16;
+
+ /* Call the call dissector to dissect the opaque arguments.
+ Make the columns non-writable, so it won't change them out
+ from under us. */
+ col_set_writable(pinfo->fd, FALSE);
+ offset = call_dissect_function(tvb, pinfo, tree, offset,
+ old_dissect_function, dissect_function, NULL);
+
+ return offset;
+}
+
+/*
+ * XXX - to dissect a CALLIT reply, we'd need to somehow associate
+ * the program/version/procedure information we get on a call with
+ * the RPC dissector's information about the call, and get that
+ * information from the reply dissector.
+ */
+
/* proc number, "proc name", dissect_request, dissect_reply */
/* NULL as function pointer means: type of arguments is "void". */
-static const old_vsff portmap1_proc[] = {
- { PORTMAPPROC_NULL, "NULL", NULL, NULL },
- { PORTMAPPROC_SET, "SET", NULL, NULL },
- { PORTMAPPROC_UNSET, "UNSET", NULL, NULL },
- { PORTMAPPROC_GETPORT, "GETPORT", NULL, NULL },
- { PORTMAPPROC_DUMP, "DUMP", NULL, NULL },
- { PORTMAPPROC_CALLIT, "CALLIT", NULL, NULL },
- { 0, NULL, NULL, NULL }
+static const vsff portmap1_proc[] = {
+ { PORTMAPPROC_NULL, "NULL", NULL, NULL },
+ { PORTMAPPROC_SET, "SET", NULL, NULL },
+ { PORTMAPPROC_UNSET, "UNSET", NULL, NULL },
+ { PORTMAPPROC_GETPORT, "GETPORT", NULL, NULL },
+ { PORTMAPPROC_DUMP, "DUMP", NULL, NULL },
+ { PORTMAPPROC_CALLIT, "CALLIT", NULL, NULL },
+ { 0, NULL, NULL, NULL }
};
/* end of Portmap version 1 */
-static const old_vsff portmap2_proc[] = {
+static const vsff portmap2_proc[] = {
{ PORTMAPPROC_NULL, "NULL",
NULL, NULL },
{ PORTMAPPROC_SET, "SET",
@@ -245,47 +303,43 @@ static const old_vsff portmap2_proc[] = {
{ PORTMAPPROC_DUMP, "DUMP",
NULL, dissect_dump_reply },
{ PORTMAPPROC_CALLIT, "CALLIT",
- NULL, NULL },
- { 0, NULL, NULL, NULL }
+ dissect_callit_call, NULL },
+ { 0, NULL, NULL, NULL }
};
/* end of Portmap version 2 */
/* RFC 1833, Page 3 */
static int
-dissect_rpcb(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
+dissect_rpcb(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
{
proto_item* rpcb_item = NULL;
proto_tree* rpcb_tree = NULL;
int old_offset = offset;
guint32 prog;
- guint32 version;
if (tree) {
- rpcb_item = proto_tree_add_item(tree, hf_portmap_rpcb, NullTVB,
- offset+0, END_OF_FRAME, FALSE);
+ rpcb_item = proto_tree_add_item(tree, hf_portmap_rpcb, tvb,
+ offset, tvb_length(tvb), FALSE);
if (rpcb_item)
rpcb_tree = proto_item_add_subtree(rpcb_item, ett_portmap_rpcb);
}
- if (!BYTES_ARE_IN_FRAME(offset, 4)) return offset;
- prog = EXTRACT_UINT(pd, offset + 0);
+ prog = tvb_get_ntohl(tvb, offset);
if (rpcb_tree)
- proto_tree_add_uint_format(rpcb_tree, hf_portmap_rpcb_prog, NullTVB,
- offset+0, 4, prog,
+ proto_tree_add_uint_format(rpcb_tree, hf_portmap_rpcb_prog, tvb,
+ offset, 4, prog,
"Program: %s (%u)", rpc_prog_name(prog), prog);
offset += 4;
- if (!BYTES_ARE_IN_FRAME(offset, 4)) return offset;
- version = EXTRACT_UINT(pd, offset + 0);
- if (rpcb_tree)
- proto_tree_add_uint(rpcb_tree, hf_portmap_rpcb_version, NullTVB,
- offset+0, 4, version);
- offset += 4;
-
- offset = dissect_rpc_string(pd, offset, fd, rpcb_tree, hf_portmap_rpcb_netid,NULL);
- offset = dissect_rpc_string(pd, offset, fd, rpcb_tree, hf_portmap_rpcb_addr,NULL);
- offset = dissect_rpc_string(pd, offset, fd, rpcb_tree, hf_portmap_rpcb_owner,NULL);
+ offset = dissect_rpc_uint32_tvb(tvb, pinfo, rpcb_tree,
+ hf_portmap_rpcb_version, offset);
+ offset = dissect_rpc_string_tvb(tvb, pinfo, rpcb_tree,
+ hf_portmap_rpcb_netid, offset, NULL);
+ offset = dissect_rpc_string_tvb(tvb, pinfo, rpcb_tree,
+ hf_portmap_rpcb_addr, offset, NULL);
+ offset = dissect_rpc_string_tvb(tvb, pinfo, rpcb_tree,
+ hf_portmap_rpcb_owner, offset, NULL);
/* now we know, that rpcb is shorter */
if (rpcb_item) {
@@ -298,36 +352,37 @@ dissect_rpcb(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
/* RFC 1833, Page 7 */
-int dissect_rpcb3_getaddr_call(const u_char *pd, int offset, frame_data *fd,
+int dissect_rpcb3_getaddr_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree)
{
- offset = dissect_rpcb(pd, offset, fd, tree);
+ offset = dissect_rpcb(tvb, offset, pinfo, tree);
return offset;
}
/* RFC 1833, Page 7 */
-int dissect_rpcb3_getaddr_reply(const u_char *pd, int offset, frame_data *fd,
+int dissect_rpcb3_getaddr_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree)
{
- offset = dissect_rpc_string(pd, offset, fd, tree, hf_portmap_uaddr,NULL);
+ offset = dissect_rpc_string_tvb(tvb, pinfo, tree,
+ hf_portmap_uaddr, offset, NULL);
return offset;
}
/* RFC 1833, Page 7 */
-int dissect_rpcb3_dump_reply(const u_char *pd, int offset, frame_data *fd,
+int dissect_rpcb3_dump_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree)
{
- offset = dissect_rpc_list(pd, offset, fd, tree, dissect_rpcb);
+ offset = dissect_rpc_list_tvb(tvb, pinfo, tree, offset, dissect_rpcb);
return offset;
}
/* Portmapper version 3, RFC 1833, Page 7 */
-static const old_vsff portmap3_proc[] = {
+static const vsff portmap3_proc[] = {
{ RPCBPROC_NULL, "NULL",
NULL, NULL },
{ RPCBPROC_SET, "SET",
@@ -352,7 +407,7 @@ static const old_vsff portmap3_proc[] = {
/* Portmapper version 4, RFC 1833, Page 8 */
-static const old_vsff portmap4_proc[] = {
+static const vsff portmap4_proc[] = {
{ RPCBPROC_NULL, "NULL",
NULL, NULL },
{ RPCBPROC_SET, "SET",
@@ -444,8 +499,8 @@ proto_reg_handoff_portmap(void)
/* Register the protocol as RPC */
rpc_init_prog(proto_portmap, PORTMAP_PROGRAM, ett_portmap);
/* Register the procedure tables */
- old_rpc_init_proc_table(PORTMAP_PROGRAM, 1, portmap1_proc);
- old_rpc_init_proc_table(PORTMAP_PROGRAM, 2, portmap2_proc);
- old_rpc_init_proc_table(PORTMAP_PROGRAM, 3, portmap3_proc);
- old_rpc_init_proc_table(PORTMAP_PROGRAM, 4, portmap4_proc);
+ rpc_init_proc_table(PORTMAP_PROGRAM, 1, portmap1_proc);
+ rpc_init_proc_table(PORTMAP_PROGRAM, 2, portmap2_proc);
+ rpc_init_proc_table(PORTMAP_PROGRAM, 3, portmap3_proc);
+ rpc_init_proc_table(PORTMAP_PROGRAM, 4, portmap4_proc);
}