diff options
author | Guy Harris <guy@alum.mit.edu> | 2001-02-06 06:46:10 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2001-02-06 06:46:10 +0000 |
commit | d9ee8bec536d8eac9177deef04f4d90d96d2e390 (patch) | |
tree | 7a89cb2573f7ae92f6d3acbf562079f2a4144834 /packet-portmap.c | |
parent | 60ce2f6158217e56240d20e765a497b9e3dffdb5 (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.c | 277 |
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); } |