diff options
author | Guy Harris <guy@alum.mit.edu> | 1999-11-14 20:44:52 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 1999-11-14 20:44:52 +0000 |
commit | 1f31ab9cbbebc2d652dbb1c0149ee7c8b27e88db (patch) | |
tree | 3ce095d4e462ff7446fd48a198bf49e8f7924c4c | |
parent | 7d5804a8222381a4b86938c9e460cad0ccf798e0 (diff) |
Move the test to see if something looks like an ONC RPC request or reply
into "dissect_rpc()" itself; it returns TRUE if it is, FALSE if it
isn't.
svn path=/trunk/; revision=1030
-rw-r--r-- | packet-rpc.c | 115 | ||||
-rw-r--r-- | packet-udp.c | 55 | ||||
-rw-r--r-- | packet.h | 12 |
3 files changed, 107 insertions, 75 deletions
diff --git a/packet-rpc.c b/packet-rpc.c index e9b703a098..44eb236116 100644 --- a/packet-rpc.c +++ b/packet-rpc.c @@ -2,7 +2,7 @@ * Routines for rpc dissection * Copyright 1999, Uwe Girlich <Uwe.Girlich@philosys.de> * - * $Id: packet-rpc.c,v 1.9 1999/11/12 15:12:23 nneul Exp $ + * $Id: packet-rpc.c,v 1.10 1999/11/14 20:44:52 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@unicom.net> @@ -593,10 +593,15 @@ dissect_rpc_verf( const u_char *pd, int offset, frame_data *fd, proto_tree *tree } -void -dissect_rpc( const u_char *pd, int offset, frame_data *fd, proto_tree *tree, - guint32 msg_type, void* info) +gboolean +dissect_rpc( const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { + guint32 msg_type; + rpc_call_info rpc_key; + rpc_call_info *rpc_call = NULL; + rpc_prog_info_value *rpc_prog = NULL; + rpc_prog_info_key rpc_prog_key; + unsigned int xid; unsigned int rpcvers; unsigned int prog; @@ -631,13 +636,68 @@ dissect_rpc( const u_char *pd, int offset, frame_data *fd, proto_tree *tree, rpc_proc_info_value *value = NULL; conversation_t* conversation; - /* the last parameter can be either of these two types */ - rpc_call_info *rpc_call; - rpc_prog_info_key rpc_prog_key; - rpc_prog_info_value *rpc_prog; - dissect_function_t *dissect_function = NULL; + /* + * Check to see whether this looks like an RPC call or reply. + */ + if (!BYTES_ARE_IN_FRAME(offset,8)) { + /* Captured data in packet isn't enough to let us tell. */ + return FALSE; + } + + /* both directions need at least this */ + msg_type = EXTRACT_UINT(pd,offset+4); + + switch (msg_type) { + + case RPC_CALL: + /* check for RPC call */ + if (!BYTES_ARE_IN_FRAME(offset,16)) { + /* Captured data in packet isn't enough to let us + tell. */ + return FALSE; + } + + /* XID can be anything, we don't check it. + We already have the message type. + Check whether an RPC version number of 2 is in the + location where it would be, and that an RPC program + number we know about is in the locaton where it would be. */ + rpc_prog_key.prog = EXTRACT_UINT(pd,offset+12); + if (EXTRACT_UINT(pd,offset+8) != 2 || + ((rpc_prog = g_hash_table_lookup(rpc_progs, &rpc_prog_key)) + == NULL)) { + /* They're not, so it's probably not an RPC call. */ + return FALSE; + } + break; + + case RPC_REPLY: + /* check for RPC reply */ + conversation = find_conversation(&pi.src, &pi.dst, + pi.ptype, pi.srcport, pi.destport); + if (conversation == NULL) { + /* We haven't seen an RPC call for that conversation, + so we can't check for a reply to that call. */ + return FALSE; + } + rpc_key.xid = EXTRACT_UINT(pd,offset+0); + rpc_key.conversation = conversation; + if ((rpc_call = rpc_call_lookup(&rpc_key)) == NULL) { + /* The XID doesn't match a call from that + conversation, so it's probably not an RPC reply. */ + return FALSE; + } + break; + + default: + /* The putative message type field contains neither + RPC_CALL nor RPC_REPLY, so it's not an RPC call or + reply. */ + return FALSE; + } + if (check_col(fd, COL_PROTOCOL)) col_add_str(fd, COL_PROTOCOL, "RPC"); @@ -654,8 +714,6 @@ dissect_rpc( const u_char *pd, int offset, frame_data *fd, proto_tree *tree, "XID: 0x%x (%u)", xid, xid); } - /* we should better compare this with the argument?! */ - msg_type = EXTRACT_UINT(pd,offset+4); msg_type_name = val_to_str(msg_type,rpc_msg_type,"%u"); if (rpc_tree) { proto_tree_add_text(rpc_tree,offset+4,4, @@ -666,8 +724,8 @@ dissect_rpc( const u_char *pd, int offset, frame_data *fd, proto_tree *tree, offset += 8; if (msg_type==RPC_CALL) { - /* we know already the proto-entry and the ETT-const */ - rpc_prog = (rpc_prog_info_value*)info; + /* we know already the proto-entry, the ETT-const, + and "rpc_prog" */ proto = rpc_prog->proto; ett = rpc_prog->ett; progname = rpc_prog->progname; @@ -691,14 +749,16 @@ dissect_rpc( const u_char *pd, int offset, frame_data *fd, proto_tree *tree, col_add_fstr(fd, COL_PROTOCOL, "%s", progname); } - if (!BYTES_ARE_IN_FRAME(offset+8,4)) return; + if (!BYTES_ARE_IN_FRAME(offset+8,4)) + return TRUE; vers = EXTRACT_UINT(pd,offset+8); if (rpc_tree) { proto_tree_add_text(rpc_tree,offset+8,4, "Program Version: %u",vers); } - if (!BYTES_ARE_IN_FRAME(offset+12,4)) return; + if (!BYTES_ARE_IN_FRAME(offset+12,4)) + return TRUE; proc = EXTRACT_UINT(pd,offset+12); key.prog = prog; @@ -771,8 +831,8 @@ dissect_rpc( const u_char *pd, int offset, frame_data *fd, proto_tree *tree, } /* end of RPC call */ else if (msg_type == RPC_REPLY) { - /* we know already the type from the calling routine */ - rpc_call = (rpc_call_info*)info; + /* we know already the type from the calling routine, + and we already have "rpc_call" set above. */ prog = rpc_call->prog; vers = rpc_call->vers; proc = rpc_call->proc; @@ -836,7 +896,8 @@ dissect_rpc( const u_char *pd, int offset, frame_data *fd, proto_tree *tree, } } - if (!BYTES_ARE_IN_FRAME(offset,4)) return; + if (!BYTES_ARE_IN_FRAME(offset,4)) + return TRUE; reply_state = EXTRACT_UINT(pd,offset+0); if (rpc_tree) { proto_tree_add_text(rpc_tree,offset+0, 4, @@ -848,7 +909,8 @@ dissect_rpc( const u_char *pd, int offset, frame_data *fd, proto_tree *tree, if (reply_state == MSG_ACCEPTED) { offset = dissect_rpc_verf(pd, offset, fd, rpc_tree); - if (!BYTES_ARE_IN_FRAME(offset,4)) return; + if (!BYTES_ARE_IN_FRAME(offset,4)) + return TRUE; accept_state = EXTRACT_UINT(pd,offset+0); if (rpc_tree) { proto_tree_add_text(rpc_tree,offset+0, 4, @@ -863,7 +925,8 @@ dissect_rpc( const u_char *pd, int offset, frame_data *fd, proto_tree *tree, goto dissect_rpc_prog; break; case PROG_MISMATCH: - if (!BYTES_ARE_IN_FRAME(offset,8)) return; + if (!BYTES_ARE_IN_FRAME(offset,8)) + return TRUE; vers_low = EXTRACT_UINT(pd,offset+0); vers_high = EXTRACT_UINT(pd,offset+4); if (rpc_tree) { @@ -883,7 +946,8 @@ dissect_rpc( const u_char *pd, int offset, frame_data *fd, proto_tree *tree, break; } } else if (reply_state == MSG_DENIED) { - if (!BYTES_ARE_IN_FRAME(offset,4)) return; + if (!BYTES_ARE_IN_FRAME(offset,4)) + return TRUE; reject_state = EXTRACT_UINT(pd,offset+0); if (rpc_tree) { proto_tree_add_text(rpc_tree, offset+0, 4, @@ -894,7 +958,8 @@ dissect_rpc( const u_char *pd, int offset, frame_data *fd, proto_tree *tree, offset += 4; if (reject_state==RPC_MISMATCH) { - if (!BYTES_ARE_IN_FRAME(offset,8)) return; + if (!BYTES_ARE_IN_FRAME(offset,8)) + return TRUE; vers_low = EXTRACT_UINT(pd,offset+0); vers_high = EXTRACT_UINT(pd,offset+4); if (rpc_tree) { @@ -909,7 +974,8 @@ dissect_rpc( const u_char *pd, int offset, frame_data *fd, proto_tree *tree, } offset += 8; } else if (reject_state==AUTH_ERROR) { - if (!BYTES_ARE_IN_FRAME(offset,4)) return; + if (!BYTES_ARE_IN_FRAME(offset,4)) + return TRUE; auth_state = EXTRACT_UINT(pd,offset+0); if (rpc_tree) { proto_tree_add_text(rpc_tree, @@ -946,6 +1012,8 @@ dissect_rpc_prog: /* dissect any remaining bytes (incomplete dissection) as pure data in the ptree */ dissect_data(pd, offset, fd, ptree); + + return TRUE; } /* will be called from file.c on every new file open */ @@ -966,4 +1034,3 @@ proto_register_rpc(void) /* please remove this, if all specific dissectors are ready */ init_incomplete_dissect(); } - diff --git a/packet-udp.c b/packet-udp.c index 6a196aa5fd..c7a90df5af 100644 --- a/packet-udp.c +++ b/packet-udp.c @@ -1,7 +1,7 @@ /* packet-udp.c * Routines for UDP packet disassembly * - * $Id: packet-udp.c,v 1.33 1999/10/29 01:04:18 guy Exp $ + * $Id: packet-udp.c,v 1.34 1999/11/14 20:44:51 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -43,7 +43,6 @@ #include <glib.h> #include "packet.h" #include "resolv.h" -#include "packet-rpc.h" int proto_udp = -1; int hf_udp_srcport = -1; @@ -223,53 +222,11 @@ dissect_udp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { pi.srcport = uh_sport; pi.destport = uh_dport; - /* RPC */ - if (BYTES_ARE_IN_FRAME(offset,8)) { - guint32 rpc_msgtype; - - /* both directions need at least this */ - rpc_msgtype = EXTRACT_UINT(pd,offset+4); - - /* check for RPC reply */ - if (rpc_msgtype == RPC_REPLY) { - rpc_call_info rpc_key; - rpc_call_info *rpc_value; - conversation_t *conversation; - - conversation = find_conversation(&pi.src, &pi.dst, pi.ptype, - pi.srcport, pi.destport); - if (conversation) { - /* It makes only sense to look for the corresponding RPC request, - if there was a conversation. */ - rpc_key.xid = EXTRACT_UINT(pd,offset+0); - rpc_key.conversation = conversation; - if ((rpc_value=rpc_call_lookup(&rpc_key)) != NULL) { - dissect_rpc(pd,offset,fd,tree,rpc_msgtype,(void*)rpc_value); - return; - } - } - } - - /* check for RPC call */ - if (BYTES_ARE_IN_FRAME(offset,16)) { - guint32 rpc_vers; - rpc_prog_info_key rpc_prog_key; - rpc_prog_info_value *rpc_prog_info; - - /* xid can be anything, we dont check it */ - /* msgtype is already defined */ - rpc_vers = EXTRACT_UINT(pd,offset+8); - rpc_prog_key.prog = EXTRACT_UINT(pd,offset+12); - if (rpc_msgtype == RPC_CALL && - rpc_vers == 2 && - ((rpc_prog_info = g_hash_table_lookup(rpc_progs, &rpc_prog_key)) != NULL)) - { - dissect_rpc(pd,offset,fd,tree,rpc_msgtype,(void*)rpc_prog_info); - return; - } - } - } - /* end of RPC */ + /* ONC RPC. We can't base this on anything in the UDP header; we have + to look at the payload. If "dissect_rpc()" returns TRUE, it was + an RPC packet, otherwise it's some other type of packet. */ + if (dissect_rpc(pd, offset, fd, tree)) + return; /* XXX - we should do all of this through the table of ports. */ #define PORT_IS(port) (uh_sport == port || uh_dport == port) @@ -1,7 +1,7 @@ /* packet.h * Definitions for packet disassembly structures and routines * - * $Id: packet.h,v 1.139 1999/11/14 02:42:03 sharpe Exp $ + * $Id: packet.h,v 1.140 1999/11/14 20:44:52 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -654,7 +654,15 @@ void dissect_smb(const u_char *, int, frame_data *, proto_tree *, int); void dissect_pptp(const u_char *, int, frame_data *, proto_tree *); void dissect_gre(const u_char *, int, frame_data *, proto_tree *); -void dissect_rpc(const u_char *, int, frame_data *, proto_tree *, guint32, void*); +/* + * Routines in packet-*.c + * Routines should take four args: packet data *, offset, frame_data *, + * tree * + * They should never modify the packet data. + * They should return TRUE if the packet is of the type the routine would + * dissect, FALSE otherwise. + */ +gboolean dissect_rpc(const u_char *, int, frame_data *, proto_tree *); void init_dissect_rpc(void); void init_dissect_udp(void); |