Move the test to see if something looks like an ONC RPC request or reply
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Sun, 14 Nov 1999 20:44:52 +0000 (20:44 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Sun, 14 Nov 1999 20:44:52 +0000 (20:44 +0000)
into "dissect_rpc()" itself; it returns TRUE if it is, FALSE if it
isn't.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@1030 f5534014-38df-0310-8fa8-9805f1628bb7

packet-rpc.c
packet-udp.c
packet.h

index e9b703a098b0634ffaf14f8c3e86cb5a8b1ba3be..44eb2361167a82e3d81f758c8f8a615904c6c822 100644 (file)
@@ -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();
 }
-
index 6a196aa5fd1f043dafa0107972ff16394b107669..c7a90df5af4a1b71fe1c8be39d73dd4e8ff30b39 100644 (file)
@@ -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)
index 6e7d4a4694ff73baf05a322905c54e723d2d632f..26d1d2ff5611dc09bee1517a8509e1b4b75c9f6a 100644 (file)
--- a/packet.h
+++ b/packet.h
@@ -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);