Text   |  XML   |  ReML   |   Visible Warnings:

Null Test After Dereference  at packet-rpc.c:2694

No properties have been set. | edit properties
Jump to warning location ↓ warning details...
Show Events | Options

dissect_rpc_message

(/home/sate/Testcases/c/cve/wireshark-1.2.0/epan/dissectors/packet-rpc.c)expand/collapse
Show more  
 1687  dissect_rpc_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 1688      tvbuff_t *frag_tvb, fragment_data *ipfd_head, gboolean is_tcp,
 1689      guint32 rpc_rm, gboolean first_pdu)
 1690  {
 1691          guint32 msg_type;
 1692          rpc_call_info_value *rpc_call = NULL;
 1693          rpc_prog_info_value *rpc_prog = NULL;
 1694          rpc_prog_info_key rpc_prog_key;
 1695   
 1696          unsigned int xid;
 1697          unsigned int rpcvers;
 1698          unsigned int prog = 0;
 1699          unsigned int vers = 0;
 1700          unsigned int proc = 0;
 1701          flavor_t flavor = FLAVOR_UNKNOWN;
 1702          unsigned int gss_proc = 0;
 1703          unsigned int gss_svc = 0;
 1704          protocol_t *proto = NULL;
 1705          int     proto_id = 0;
 1706          int     ett = 0;
 1707          int     procedure_hf;
 1708   
 1709          unsigned int reply_state;
 1710          unsigned int accept_state;
 1711          unsigned int reject_state;
 1712   
 1713          const char *msg_type_name = NULL;
 1714          const char *progname = NULL;
 1715          char *procname = NULL;
 1716   
 1717          unsigned int vers_low;
 1718          unsigned int vers_high;
 1719   
 1720          unsigned int auth_state;
 1721   
 1722          proto_item *rpc_item = NULL;
 1723          proto_tree *rpc_tree = NULL;
 1724   
 1725          proto_item *pitem = NULL;
 1726          proto_tree *ptree = NULL;
 1727          int offset = (is_tcp && tvb == frag_tvb) ? 4 : 0;
 1728   
 1729          rpc_proc_info_key       key;
 1730          rpc_proc_info_value     *value = NULL;
 1731          conversation_t* conversation;
 1732          static address null_address = { AT_NONE, 0, NULL };
 1733          nstime_t ns;
 1734   
 1735          dissect_function_t *dissect_function = NULL;
 1736          gboolean dissect_rpc = TRUE;
 1737   
 1738          rpc_conv_info_t *rpc_conv_info=NULL;
 1739   
 1740   
 1741          /*
 1742           * Check to see whether this looks like an RPC call or reply.
 1743           */
 1744          if (!tvb_bytes_exist(tvb, offset, 8)) {
 1745                  /* Captured data in packet isn't enough to let us tell. */
 1746                  return FALSE;
 1747          }
 1748   
 1749          /* both directions need at least this */
 1750          msg_type = tvb_get_ntohl(tvb, offset + 4);
 1751   
 1752          switch (msg_type) {
 1753   
 1754          case RPC_CALL:
 1755                  /* check for RPC call */
 1756                  if (!tvb_bytes_exist(tvb, offset, 16)) {
 1757                          /* Captured data in packet isn't enough to let us
 1758                             tell. */
 1759                          return FALSE;
 1760                  }
 1761   
 1762                  /* XID can be anything, so dont check it.
 1763                     We already have the message type.
 1764                     Check whether an RPC version number of 2 is in the
 1765                     location where it would be, and that an RPC program 
 1766                     number we know about is in the location where it would be.
 1767   
 1768                     XXX - Sun's snoop appears to recognize as RPC even calls
 1769                     to stuff it doesn't dissect; does it just look for a 2 
 1770                     at that location, which seems far to weak a heuristic 
 1771                     (too many false positives), or does it have some additional
 1772                     checks it does?
 1773   
 1774                     We could conceivably check for any of the program numbers 
 1775                     in the list at 
 1776   
 1777                          ftp://ftp.tau.ac.il/pub/users/eilon/rpc/rpc
 1778   
 1779                     and report it as RPC (but not dissect the payload if 
 1780                     we don't have a subdissector) if it matches. */
 1781                  rpc_prog_key.prog = tvb_get_ntohl(tvb, offset + 12);
 1782   
 1783                  /* we only dissect version 2 */
 1784                  if (tvb_get_ntohl(tvb, offset + 8) != 2 ){
 1785                          return FALSE;
 1786                  }
 1787                  /* let the user be able to weaken the heuristics if he need
 1788                   * to look at proprietary protocols not known 
 1789                   * to wireshark.
 1790                   */
 1791                  if(rpc_dissect_unknown_programs){
 1792                          guint32 version;
 1793   
 1794                          /* if the user has specified that he wants to try to 
 1795                           * dissect even completely unknown RPC program numbers 
 1796                           * then let him do that.
 1797                           * In this case we only check that the program number
 1798                           * is neither 0 nor -1 which is better than nothing.
 1799                           */
 1800                          if(rpc_prog_key.prog==0 || rpc_prog_key.prog==0xffffffff){
 1801                                  return FALSE;
 1802                          }
 1803                          version=tvb_get_ntohl(tvb, offset+16);
 1804                          make_fake_rpc_prog_if_needed (&rpc_prog_key, version);
 1805                  }
 1806                  if( (rpc_prog = g_hash_table_lookup(rpc_progs, &rpc_prog_key)) == NULL) {
 1807                          /* They're not, so it's probably not an RPC call. */
 1808                          return FALSE;
 1809                  }
 1810                  break;
 1811   
 1812          case RPC_REPLY:
 1813                  /* Check for RPC reply.  A reply must match a call that
 1814                     we've seen, and the reply must be sent to the same 
 1815                     address that the call came from, and must come from
 1816                     the port to which the call was sent.
 1817   
 1818                     If the transport is connection-oriented (we check, for 
 1819                     now, only for "pinfo->ptype" of PT_TCP), we take
 1820                     into  the port from which the call was sent 
 1821                     and the address to which the call was sent, because 
 1822                     the addresses and ports of the two endpoints should be 
 1823                     the same for all calls and replies.
 1824   
 1825                     If the transport is connectionless, we don't worry 
 1826                     about the address to which the call was sent and from
 1827                     which the reply was sent, because there's no 
 1828                     guarantee that the reply will come from the address
 1829                     to which the call was sent.  We also don't worry about
 1830                     the port *from* which the call was sent and *to* which 
 1831                     the reply was sent, because some clients (*cough* OS X
 1832                     NFS client *cough) might send retransmissions from a 
 1833                     different port from the original request. */
 1834                  if (pinfo->ptype == PT_TCP) {
 1835                          conversation = find_conversation(pinfo->fd->num, &pinfo->src,
 1836                              &pinfo->dst, pinfo->ptype, pinfo->srcport,
 1837                              pinfo->destport, 0);
 1838                  } else {
 1839                          /*
 1840                           * XXX - you currently still have to pass a non-null
 1841                           * pointer for the second address argument even 
 1842                           * if you use NO_ADDR_B.
 1843                           */
 1844                          conversation = find_conversation(pinfo->fd->num, &pinfo->dst,
 1845                              &null_address, pinfo->ptype, pinfo->srcport,
 1846                              0, NO_ADDR_B|NO_PORT_B);
 1847                  }
 1848                  if (conversation == NULL) {
 1849                          /* We haven't seen an RPC call for that conversation,
 1850                             so we can't check for a reply to that call. */
 1851                          return FALSE;
 1852                  }
 1853                  /*
 1854                   * Do we already have a state structure for this conv
 1855                   */
 1856                  rpc_conv_info = conversation_get_proto_data(conversation, proto_rpc);
 1857                  if (!rpc_conv_info) {
 1858                          /* No.  Attach that information to the conversation, and add
 1859                           * it to the list of information structures.
 1860                           */
 1861                          rpc_conv_info = se_alloc(sizeof(rpc_conv_info_t));
 1862                          rpc_conv_info->xids=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "rpc_xids");
 1863   
 1864                          conversation_add_proto_data(conversation, proto_rpc, rpc_conv_info);
 1865                  }
 1866   
 1867                  /* The XIDs of the call and reply must match. */
 1868                  xid = tvb_get_ntohl(tvb, offset + 0);
 1869                  rpc_call = se_tree_lookup32(rpc_conv_info->xids, xid);
 1870                  if (rpc_call == NULL) {
 1871                          /* The XID doesn't match a call from that 
 1872                             conversation, so it's probably not an RPC reply. */
 1873   
 1874                          /* unless we're permitted to scan for embedded records
 1875                           * and this is a connection-oriented transport, give up */
 1876                          if ((! rpc_find_fragment_start) || (pinfo->ptype != PT_TCP)) {
 1877                                  return FALSE;
 1878                          }
 1879   
 1880                          /* in parse-partials, so define a dummy conversation for this reply */
 1881                          rpc_call = se_alloc(sizeof(rpc_call_info_value));
 1882                          rpc_call->req_num = 0;
 1883                          rpc_call->rep_num = pinfo->fd->num;
 1884                          rpc_call->prog = 0;
 1885                          rpc_call->vers = 0;
 1886                          rpc_call->proc = 0;
 1887                          rpc_call->private_data = NULL;
 1888                          rpc_call->xid = xid;
 1889                          rpc_call->flavor = FLAVOR_NOT_GSSAPI;  /* total punt */
 1890                          rpc_call->gss_proc = 0;
 1891                          rpc_call->gss_svc = 0;
 1892                          rpc_call->proc_info = value;
 1893                          rpc_call->req_time = pinfo->fd->abs_ts;
 1894   
 1895                          /* store it */
 1896                          se_tree_insert32(rpc_conv_info->xids, xid, (void *)rpc_call);
 1897   
 1898                          /* and fake up a matching program */
 1899                          rpc_prog_key.prog = rpc_call->prog;
 1900                  }
 1901   
 1902                  /* pass rpc_info to subdissectors */
 1903                  rpc_call->request=FALSE;
 1904                  pinfo->private_data=rpc_call;
 1905                  break;
 1906   
 1907          default:
 1908                  /* The putative message type field contains neither 
 1909                     RPC_CALL nor RPC_REPLY, so it's not an RPC call or 
 1910                     reply. */
 1911                  return FALSE;
 1912          }
 1913   
 1914          if (is_tcp) {
 1915                  /*
 1916                   * This is RPC-over-TCP; check if this is the last
 1917                   * fragment.
 1918                   */
 1919                  if (!(rpc_rm & RPC_RM_LASTFRAG)) {
 1920                          /*
 1921                           * This isn't the last fragment.
 1922                           * If we're doing reassembly, just return
 1923                           * TRUE to indicate that this looks like 
 1924                           * the beginning of an RPC message,
 1925                           * and let them do fragment reassembly.
 1926                           */
 1927                          if (rpc_defragment)
 1928                                  return TRUE;
 1929                  }
 1930          }
 1931   
 1932          if (check_col(pinfo->cinfo, COL_PROTOCOL))
 1933                  col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPC");
 1934   
 1935          if (tree) {
 1936                  rpc_item = proto_tree_add_item(tree, proto_rpc, tvb, 0, -1,
 1937                      FALSE);
 1938                  rpc_tree = proto_item_add_subtree(rpc_item, ett_rpc);
 1939   
 1940                  if (is_tcp) {
 1941                          show_rpc_fraginfo(tvb, frag_tvb, rpc_tree, rpc_rm,
 1942                              ipfd_head, pinfo);
 1943                  }
 1944          }
 1945   
 1946          xid      = tvb_get_ntohl(tvb, offset + 0);
 1947          if (rpc_tree) {
 1948                  proto_tree_add_uint_format(rpc_tree,hf_rpc_xid, tvb,
 1949                          offset+0, 4, xid, "XID: 0x%x (%u)", xid, xid);
 1950          }
 1951   
 1952          msg_type_name = val_to_str(msg_type,rpc_msg_type,"%u");
 1953          if (rpc_tree) {
 1954                  proto_tree_add_uint(rpc_tree, hf_rpc_msgtype, tvb,
 1955                          offset+4, 4, msg_type);
 1956                  proto_item_append_text(rpc_item, ", Type:%s XID:0x%08x", msg_type_name, xid);
 1957          }
 1958   
 1959          offset += 8;
 1960   
 1961          switch (msg_type) {
 1962   
 1963          case RPC_CALL:
 1964                  /* we know already the proto-entry, the ETT-const,
 1965                     and "rpc_prog" */
 1966                  proto = rpc_prog->proto;
 1967                  proto_id = rpc_prog->proto_id;
 1968                  ett = rpc_prog->ett;
 1969                  progname = rpc_prog->progname;
 1970   
 1971                  rpcvers = tvb_get_ntohl(tvb, offset + 0);
 1972                  if (rpc_tree) {
 1973                          proto_tree_add_uint(rpc_tree,
 1974                                  hf_rpc_version, tvb, offset+0, 4, rpcvers);
 1975                  }
 1976   
 1977                  prog = tvb_get_ntohl(tvb, offset + 4);
 1978   
 1979                  if (rpc_tree) {
 1980                          proto_tree_add_uint_format(rpc_tree,
 1981                                  hf_rpc_program, tvb, offset+4, 4, prog,
 1982                                  "Program: %s (%u)", progname, prog);
 1983                  }
 1984   
 1985                  if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
 1986                          /* Set the protocol name to the underlying 
 1987                             program name. */
 1988                          col_set_str(pinfo->cinfo, COL_PROTOCOL, progname);
 1989                  }
 1990   
 1991                  vers = tvb_get_ntohl(tvb, offset+8);
 1992                  if (rpc_tree) {
 1993                          proto_tree_add_uint(rpc_tree,
 1994                                  hf_rpc_programversion, tvb, offset+8, 4, vers);
 1995                  }
 1996   
 1997                  proc = tvb_get_ntohl(tvb, offset+12);
 1998   
 1999                  key.prog = prog;
 2000                  key.vers = vers;
 2001                  key.proc = proc;
 2002   
 2003                  if ((value = g_hash_table_lookup(rpc_procs,&key)) != NULL) {
 2004                          dissect_function = value->dissect_call;
 2005                          procname = (char *)value->name;
 2006                  }
 2007                  else {
 2008                          /* happens only with strange program versions or 
 2009                             non-existing dissectors */
 2010  #if 0 
 2011                          dissect_function = NULL;
 2012  #endif
 2013                          procname=ep_alloc(20);
 2014                          g_snprintf(procname, 20, "proc-%u", proc);
 2015                  }
 2016   
 2017                  /* Check for RPCSEC_GSS and AUTH_GSSAPI */
 2018                  if (tvb_bytes_exist(tvb, offset+16, 4)) {
 2019                          switch (tvb_get_ntohl(tvb, offset+16)) {
 2020   
 2021                          case RPCSEC_GSS:
 2022                                  /*
 2023                                   * It's GSS-API authentication...
 2024                                   */
 2025                                  if (tvb_bytes_exist(tvb, offset+28, 8)) {
 2026                                          /*
 2027                                           * ...and we have the procedure
 2028                                           * and service information for it.
 2029                                           */
 2030                                          flavor = FLAVOR_GSSAPI;
 2031                                          gss_proc = tvb_get_ntohl(tvb, offset+28);
 2032                                          gss_svc = tvb_get_ntohl(tvb, offset+36);
 2033                                  } else {
 2034                                          /*
 2035                                           * ...but the procedure and service
 2036                                           * information isn't available.
 2037                                           */
 2038                                          flavor = FLAVOR_GSSAPI_NO_INFO;
 2039                                  }
 2040                                  break;
 2041   
 2042                          case AUTH_GSSAPI:
 2043                                  /*
 2044                                   * AUTH_GSSAPI flavor.  If auth_msg is TRUE,
 2045                                   * then this is an AUTH_GSSAPI message and 
 2046                                   * not an application level message.
 2047                                   */
 2048                                  if (tvb_bytes_exist(tvb, offset+28, 4)) {
 2049                                          if (tvb_get_ntohl(tvb, offset+28)) {
 2050                                                  flavor = FLAVOR_AUTHGSSAPI_MSG;
 2051                                                  gss_proc = proc;
 2052                                                  procname = (char *)
 2053                                                      val_to_str(gss_proc,
 2054                                                      rpc_authgssapi_proc, "Unknown (%d)");
 2055                                          } else {
 2056                                                  flavor = FLAVOR_AUTHGSSAPI;
 2057                                          }
 2058                                  }
 2059                                  break;
 2060   
 2061                          default:
 2062                                  /*
 2063                                   * It's not GSS-API authentication.
 2064                                   */
 2065                                  flavor = FLAVOR_NOT_GSSAPI;
 2066                                  break;
 2067                          }
 2068                  }
 2069   
 2070                  if (rpc_tree) {
 2071                          proto_tree_add_uint_format(rpc_tree,
 2072                                  hf_rpc_procedure, tvb, offset+12, 4, proc,
 2073                                  "Procedure: %s (%u)", procname, proc);
 2074                  }
 2075   
 2076                  if (check_col(pinfo->cinfo, COL_INFO)) {
 2077                          if (first_pdu)
 2078                                  col_clear(pinfo->cinfo, COL_INFO);
 2079                          else 
 2080                                  col_append_str(pinfo->cinfo, COL_INFO, "  ; ");
 2081                          col_append_fstr(pinfo->cinfo, COL_INFO,"V%u %s %s",
 2082                                  vers,
 2083                                  procname,
 2084                                  msg_type_name);
 2085                  }
 2086   
 2087                  /* Keep track of the address whence the call came, and the
 2088                     port to which the call is being sent, so that we can
 2089                     match up calls with replies.
 2090   
 2091                     If the transport is connection-oriented (we check, for 
 2092                     now, only for "pinfo->ptype" of PT_TCP), we also take 
 2093                     into  the port from which the call was sent 
 2094                     and the address to which the call was sent, because 
 2095                     the addresses and ports of the two endpoints should be 
 2096                     the same for all calls and replies.  (XXX - what if
 2097                     the connection is broken and re-established?)
 2098   
 2099                     If the transport is connectionless, we don't worry 
 2100                     about the address to which the call was sent and from
 2101                     which the reply was sent, because there's no 
 2102                     guarantee that the reply will come from the address
 2103                     to which the call was sent.  We also don't worry about
 2104                     the port *from* which the call was sent and *to* which 
 2105                     the reply was sent, because some clients (*cough* OS X
 2106                     NFS client *cough) might send retransmissions from a 
 2107                     different port from the original request. */
 2108                  if (pinfo->ptype == PT_TCP) {
 2109                          conversation = find_conversation(pinfo->fd->num, &pinfo->src,
 2110                              &pinfo->dst, pinfo->ptype, pinfo->srcport,
 2111                              pinfo->destport, 0);
 2112                  } else {
 2113                          /*
 2114                           * XXX - you currently still have to pass a non-null
 2115                           * pointer for the second address argument even 
 2116                           * if you use NO_ADDR_B.
 2117                           */
 2118                          conversation = find_conversation(pinfo->fd->num, &pinfo->src,
 2119                              &null_address, pinfo->ptype, pinfo->destport,
 2120                              0, NO_ADDR_B|NO_PORT_B);
 2121                  }
 2122                  if (conversation == NULL) {
 2123                          /* It's not part of any conversation - create a new 
 2124                             one. */
 2125                          if (pinfo->ptype == PT_TCP) {
 2126                                  conversation = conversation_new(pinfo->fd->num, &pinfo->src,
 2127                                      &pinfo->dst, pinfo->ptype, pinfo->srcport,
 2128                                      pinfo->destport, 0);
 2129                          } else {
 2130                                  conversation = conversation_new(pinfo->fd->num, &pinfo->src,
 2131                                      &null_address, pinfo->ptype, pinfo->destport,
 2132                                      0, NO_ADDR2|NO_PORT2);
 2133                          }
 2134                  }
 2135                  /*
 2136                   * Do we already have a state structure for this conv
 2137                   */
 2138                  rpc_conv_info = conversation_get_proto_data(conversation, proto_rpc);
 2139                  if (!rpc_conv_info) {
 2140                          /* No.  Attach that information to the conversation, and add
 2141                           * it to the list of information structures.
 2142                           */
 2143                          rpc_conv_info = se_alloc(sizeof(rpc_conv_info_t));
 2144                          rpc_conv_info->xids=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "rpc_xids");
 2145   
 2146                          conversation_add_proto_data(conversation, proto_rpc, rpc_conv_info);
 2147                  }
 2148   
 2149   
 2150                  /* Make the dissector for this conversation the non-heuristic
 2151                     RPC dissector. */
 2152                  conversation_set_dissector(conversation,
 2153                          (pinfo->ptype == PT_TCP) ? rpc_tcp_handle : rpc_handle);
 2154   
 2155                  /* look up the request */
 2156                  rpc_call = se_tree_lookup32(rpc_conv_info->xids, xid);
 2157                  if (rpc_call) {
 2158                          /* We've seen a request with this XID, with the same 
 2159                             source and destination, before - but was it 
 2160                             *this* request? */
 2161                          if (pinfo->fd->num != rpc_call->req_num) {
 2162                                  /* No, so it's a duplicate request.
 2163                                     Mark it as such. */
 2164                                  if (check_col(pinfo->cinfo, COL_INFO)) {
 2165                                          col_prepend_fstr(pinfo->cinfo, COL_INFO,
 2166                                                  "[RPC retransmission of #%d]", rpc_call->req_num);
 2167                                  }
 2168                                  proto_tree_add_item(rpc_tree,
 2169                                          hf_rpc_dup, tvb, 0,0, TRUE);
 2170                                  proto_tree_add_uint(rpc_tree,
 2171                                          hf_rpc_call_dup, tvb, 0,0, rpc_call->req_num);
 2172                          }
 2173                          if(rpc_call->rep_num){
 2174                                  if (check_col(pinfo->cinfo, COL_INFO)) {
 2175                                          col_append_fstr(pinfo->cinfo, COL_INFO," (Reply In %d)", rpc_call->rep_num);
 2176                                  }
 2177                          }
 2178                  } else {
 2179                          /* Prepare the value data.
 2180                             "req_num" and "rep_num" are frame numbers;
 2181                             frame numbers are 1-origin, so we use 0
 2182                             to mean "we don't yet know in which frame 
 2183                             the reply for this call appears". */
 2184                          rpc_call = se_alloc(sizeof(rpc_call_info_value));
 2185                          rpc_call->req_num = pinfo->fd->num;
 2186                          rpc_call->rep_num = 0;
 2187                          rpc_call->prog = prog;
 2188                          rpc_call->vers = vers;
 2189                          rpc_call->proc = proc;
 2190                          rpc_call->private_data = NULL;
 2191                          rpc_call->xid = xid;
 2192                          rpc_call->flavor = flavor;
 2193                          rpc_call->gss_proc = gss_proc;
 2194                          rpc_call->gss_svc = gss_svc;
 2195                          rpc_call->proc_info = value;
 2196                          rpc_call->req_time = pinfo->fd->abs_ts;
 2197   
 2198                          /* store it */
 2199                          se_tree_insert32(rpc_conv_info->xids, xid, (void *)rpc_call);
 2200                  }
 2201   
 2202                  if(rpc_call && rpc_call->rep_num){
 2203                          proto_item *tmp_item;
 2204   
 2205                          tmp_item=proto_tree_add_uint_format(rpc_tree, hf_rpc_reqframe,
 2206                              tvb, 0, 0, rpc_call->rep_num,
 2207                              "The reply to this request is in frame %u",
 2208                              rpc_call->rep_num);
 2209                          PROTO_ITEM_SET_GENERATED(tmp_item);
 2210                  }
 2211   
 2212                  offset += 16;
 2213   
 2214                  offset = dissect_rpc_cred(tvb, rpc_tree, offset);
 2215                  offset = dissect_rpc_verf(tvb, rpc_tree, offset, msg_type, pinfo);
 2216   
 2217                  /* pass rpc_info to subdissectors */
 2218                  rpc_call->request=TRUE;
 2219                  pinfo->private_data=rpc_call;
 2220   
 2221                  /* go to the next dissector */
 2222   
 2223                  break;  /* end of RPC call */
 2224   
 2225          case RPC_REPLY:
 2226                  /* we know already the type from the calling routine,
 2227                     and we already have "rpc_call" set above. */
 2228                  prog = rpc_call->prog;
 2229                  vers = rpc_call->vers;
 2230                  proc = rpc_call->proc;
 2231                  flavor = rpc_call->flavor;
 2232                  gss_proc = rpc_call->gss_proc;
 2233                  gss_svc = rpc_call->gss_svc;
 2234   
 2235                  if (rpc_call->proc_info != NULL) {
 2236                          dissect_function = rpc_call->proc_info->dissect_reply;
 2237                          if (rpc_call->proc_info->name != NULL) {
 2238                                  procname = (char *)rpc_call->proc_info->name;
 2239                          }
 2240                          else {
 2241                                  procname=ep_alloc(20);
 2242                                  g_snprintf(procname, 20, "proc-%u", proc);
 2243                          }
 2244                  }
 2245                  else {
 2246  #if 0 
 2247                          dissect_function = NULL;
 2248  #endif
 2249                          procname=ep_alloc(20);
 2250                          g_snprintf(procname, 20, "proc-%u", proc);
 2251                  }
 2252   
 2253                  /*
 2254                   * If this is an AUTH_GSSAPI message, then the RPC procedure
 2255                   * is not an application procedure, but rather an auth level 
 2256                   * procedure, so it would be misleading to print the RPC 
 2257                   * procname.  Replace the RPC procname with the corresponding
 2258                   * AUTH_GSSAPI procname.
 2259                   */
 2260                  if (flavor == FLAVOR_AUTHGSSAPI_MSG) {
 2261                          procname = (char *)match_strval(gss_proc, rpc_authgssapi_proc);
 2262                  }
 2263   
 2264                  rpc_prog_key.prog = prog;
 2265                  if ((rpc_prog = g_hash_table_lookup(rpc_progs,&rpc_prog_key)) == NULL) {
 2266                          proto = NULL;
 2267                          proto_id = 0;
 2268                          ett = 0;
 2269                          progname = "Unknown";
 2270                  }
 2271                  else {
 2272                          proto = rpc_prog->proto;
 2273                          proto_id = rpc_prog->proto_id;
 2274                          ett = rpc_prog->ett;
 2275                          progname = rpc_prog->progname;
 2276   
 2277                          if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
 2278                                  /* Set the protocol name to the underlying 
 2279                                     program name. */
 2280                                  col_set_str(pinfo->cinfo, COL_PROTOCOL, progname);
 2281                          }
 2282                  }
 2283   
 2284                  if (check_col(pinfo->cinfo, COL_INFO)) {
 2285                          if (first_pdu)
 2286                                  col_clear(pinfo->cinfo, COL_INFO);
 2287                          else 
 2288                                  col_append_str(pinfo->cinfo, COL_INFO, "  ; ");
 2289                          col_append_fstr(pinfo->cinfo, COL_INFO,"V%u %s %s",
 2290                                  vers,
 2291                                  procname,
 2292                                  msg_type_name);
 2293                  }
 2294   
 2295                  if (rpc_tree) {
 2296                          proto_item *tmp_item;
 2297                          tmp_item=proto_tree_add_uint_format(rpc_tree,
 2298                                  hf_rpc_program, tvb, 0, 0, prog,
 2299                                  "Program: %s (%u)", progname, prog);
 2300                          PROTO_ITEM_SET_GENERATED(tmp_item);
 2301                          tmp_item=proto_tree_add_uint(rpc_tree,
 2302                                  hf_rpc_programversion, tvb, 0, 0, vers);
 2303                          PROTO_ITEM_SET_GENERATED(tmp_item);
 2304                          tmp_item=proto_tree_add_uint_format(rpc_tree,
 2305                                  hf_rpc_procedure, tvb, 0, 0, proc,
 2306                                  "Procedure: %s (%u)", procname, proc);
 2307                          PROTO_ITEM_SET_GENERATED(tmp_item);
 2308                  }
 2309   
 2310                  reply_state = tvb_get_ntohl(tvb,offset+0);
 2311                  if (rpc_tree) {
 2312                          proto_tree_add_uint(rpc_tree, hf_rpc_state_reply, tvb,
 2313                                  offset+0, 4, reply_state);
 2314                  }
 2315                  offset += 4;
 2316   
 2317                  /* Indicate the frame to which this is a reply. */
 2318                  if(rpc_call && rpc_call->req_num){
 2319                          proto_item *tmp_item;
 2320   
 2321                          tmp_item=proto_tree_add_uint_format(rpc_tree, hf_rpc_repframe,
 2322                              tvb, 0, 0, rpc_call->req_num,
 2323                              "This is a reply to a request in frame %u",
 2324                              rpc_call->req_num);
 2325                          PROTO_ITEM_SET_GENERATED(tmp_item);
 2326   
 2327                          nstime_delta(&ns, &pinfo->fd->abs_ts, &rpc_call->req_time);
 2328                          tmp_item=proto_tree_add_time(rpc_tree, hf_rpc_time, tvb, offset, 0,
 2329                                  &ns);
 2330                          PROTO_ITEM_SET_GENERATED(tmp_item);
 2331   
 2332                          if (check_col(pinfo->cinfo, COL_INFO)) {
 2333                                  col_append_fstr(pinfo->cinfo, COL_INFO," (Call In %d)", rpc_call->req_num);
 2334                          }
 2335                  }
 2336   
 2337   
 2338                  if ((!rpc_call) || (rpc_call->rep_num == 0)) {
 2339                          /* We have not yet seen a reply to that call, so 
 2340                             this must be the first reply; remember its
 2341                             frame number. */
 2342                          rpc_call->rep_num = pinfo->fd->num;
 2343                  } else {
 2344                          /* We have seen a reply to this call - but was it 
 2345                             *this* reply? */
 2346                          if (rpc_call->rep_num != pinfo->fd->num) {
 2347                                  proto_item *tmp_item;
 2348   
 2349                                  /* No, so it's a duplicate reply.
 2350                                     Mark it as such. */
 2351                                  if (check_col(pinfo->cinfo, COL_INFO)) {
 2352                                          col_prepend_fstr(pinfo->cinfo, COL_INFO,
 2353                                                  "[RPC duplicate of #%d]", rpc_call->rep_num);
 2354                                  }
 2355                                  tmp_item=proto_tree_add_item(rpc_tree,
 2356                                          hf_rpc_dup, tvb, 0,0, TRUE);
 2357                                  PROTO_ITEM_SET_GENERATED(tmp_item);
 2358   
 2359                                  tmp_item=proto_tree_add_uint(rpc_tree,
 2360                                          hf_rpc_reply_dup, tvb, 0,0, rpc_call->rep_num);
 2361                                  PROTO_ITEM_SET_GENERATED(tmp_item);
 2362                          }
 2363                  }
 2364   
 2365                  switch (reply_state) {
 2366   
 2367                  case MSG_ACCEPTED:
 2368                          offset = dissect_rpc_verf(tvb, rpc_tree, offset, msg_type, pinfo);
 2369                          accept_state = tvb_get_ntohl(tvb,offset+0);
 2370                          if (rpc_tree) {
 2371                                  proto_tree_add_uint(rpc_tree, hf_rpc_state_accept, tvb,
 2372                                          offset+0, 4, accept_state);
 2373                          }
 2374                          offset += 4;
 2375                          switch (accept_state) {
 2376   
 2377                          case SUCCESS:
 2378                                  /* go to the next dissector */
 2379                                  break;
 2380   
 2381                          case PROG_MISMATCH:
 2382                                  vers_low = tvb_get_ntohl(tvb,offset+0);
 2383                                  vers_high = tvb_get_ntohl(tvb,offset+4);
 2384                                  if (rpc_tree) {
 2385                                          proto_tree_add_uint(rpc_tree,
 2386                                                  hf_rpc_programversion_min,
 2387                                                  tvb, offset+0, 4, vers_low);
 2388                                          proto_tree_add_uint(rpc_tree,
 2389                                                  hf_rpc_programversion_max,
 2390                                                  tvb, offset+4, 4, vers_high);
 2391                                  }
 2392                                  offset += 8;
 2393   
 2394                                  /*
 2395                                   * There's no protocol reply, so don't
 2396                                   * try to dissect it.
 2397                                   */
 2398                                  dissect_rpc = FALSE;
 2399                                  break;
 2400   
 2401                          default:
 2402                                  /*
 2403                                   * There's no protocol reply, so don't
 2404                                   * try to dissect it.
 2405                                   */
 2406                                  dissect_rpc = FALSE;
 2407                                  break;
 2408                          }
 2409                          break;
 2410   
 2411                  case MSG_DENIED:
 2412                          reject_state = tvb_get_ntohl(tvb,offset+0);
 2413                          if (rpc_tree) {
 2414                                  proto_tree_add_uint(rpc_tree,
 2415                                          hf_rpc_state_reject, tvb, offset+0, 4,
 2416                                          reject_state);
 2417                          }
 2418                          offset += 4;
 2419   
 2420                          if (reject_state==RPC_MISMATCH) {
 2421                                  vers_low = tvb_get_ntohl(tvb,offset+0);
 2422                                  vers_high = tvb_get_ntohl(tvb,offset+4);
 2423                                  if (rpc_tree) {
 2424                                          proto_tree_add_uint(rpc_tree,
 2425                                                  hf_rpc_version_min,
 2426                                                  tvb, offset+0, 4, vers_low);
 2427                                          proto_tree_add_uint(rpc_tree,
 2428                                                  hf_rpc_version_max,
 2429                                                  tvb, offset+4, 4, vers_high);
 2430                                  }
 2431                                  offset += 8;
 2432                          } else if (reject_state==AUTH_ERROR) {
 2433                                  auth_state = tvb_get_ntohl(tvb,offset+0);
 2434                                  if (rpc_tree) {
 2435                                          proto_tree_add_uint(rpc_tree,
 2436                                                  hf_rpc_state_auth, tvb, offset+0, 4,
 2437                                                  auth_state);
 2438                                  }
 2439                                  offset += 4;
 2440                          }
 2441   
 2442                          /*
 2443                           * There's no protocol reply, so don't
 2444                           * try to dissect it.
 2445                           */
 2446                          dissect_rpc = FALSE;
 2447                          break;
 2448   
 2449                  default:
 2450                          /*
 2451                           * This isn't a valid reply state, so we have 
 2452                           * no clue what's going on; don't try to dissect 
 2453                           * the protocol reply.
 2454                           */
 2455                          dissect_rpc = FALSE;
 2456                          break;
 2457                  }
 2458                  break; /* end of RPC reply */
 2459   
 2460          default:
 2461                  /*
 2462                   * The switch statement at the top returned if
 2463                   * this was neither an RPC call nor a reply.
 2464                   */
 2465                  DISSECTOR_ASSERT_NOT_REACHED();
 2466          }
 2467   
 2468          /* now we know, that RPC was shorter */
 2469          if (rpc_item) {
 2470                  if (offset < 0)
 2471                          THROW(ReportedBoundsError);
 2472                  tvb_ensure_bytes_exist(tvb, offset, 0);
 2473                  proto_item_set_end(rpc_item, tvb, offset);
 2474          }
 2475   
 2476          if (!dissect_rpc) {
 2477                  /*
 2478                   * There's no RPC call or reply here; just dissect
 2479                   * whatever's left as data.
 2480                   */
 2481                  call_dissector(data_handle,
 2482                      tvb_new_subset(tvb, offset, -1, -1), pinfo, rpc_tree);
 2483                  return TRUE;
 2484          }
 2485   
 2486          /* we must queue this packet to the tap system before we actually
 2487             call the subdissectors since short packets (i.e. nfs read reply)
 2488             will cause an exception and execution would never reach the call
 2489             to tap_queue_packet() in that case 
 2490          */
 2491          tap_queue_packet(rpc_tap, pinfo, rpc_call);
 2492   
 2493          /* create here the program specific sub-tree */
 2494          if (tree && (flavor != FLAVOR_AUTHGSSAPI_MSG)) {
 2495                  pitem = proto_tree_add_item(tree, proto_id, tvb, offset, -1,
 2496                      FALSE);
 2497                  if (pitem) {
 2498                          ptree = proto_item_add_subtree(pitem, ett);
 2499                  }
 2500   
 2501                  if (ptree) {
 2502                          proto_item *tmp_item;
 2503   
 2504                          tmp_item=proto_tree_add_uint(ptree,
 2505                                  hf_rpc_programversion, tvb, 0, 0, vers);
 2506                          PROTO_ITEM_SET_GENERATED(tmp_item);
 2507                          if (rpc_prog && (rpc_prog->procedure_hfs->len > vers) )
 2508                                  procedure_hf = g_array_index(rpc_prog->procedure_hfs, int, vers);
 2509                          else {
 2510                                  /*
 2511                                   * No such element in the GArray.
 2512                                   */
 2513                                  procedure_hf = 0;
 2514                          }
 2515                          if (procedure_hf != 0 && procedure_hf != -1) {
 2516                                  tmp_item=proto_tree_add_uint(ptree,
 2517                                          procedure_hf, tvb, 0, 0, proc);
 2518                                  PROTO_ITEM_SET_GENERATED(tmp_item);
 2519                          } else {
 2520                                  tmp_item=proto_tree_add_uint_format(ptree,
 2521                                          hf_rpc_procedure, tvb, 0, 0, proc,
 2522                                          "Procedure: %s (%u)", procname, proc);
 2523                                  PROTO_ITEM_SET_GENERATED(tmp_item);
 2524                          }
 2525                  }
 2526          }
 2527   
 2528          /* proto==0 if this is an unknown program */
 2529          if( (proto==0) || !proto_is_protocol_enabled(proto)){
 2530                  dissect_function = NULL;
 2531          }
 2532   
 2533          /*
 2534           * Don't call any subdissector if we have no more date to dissect.
 2535           */
 2536          if (tvb_length_remaining(tvb, offset) == 0) {
 2537                  return TRUE;
 2538          }
 2539   
 2540          /*
 2541           * Handle RPCSEC_GSS and AUTH_GSSAPI specially.
 2542           */
 2543          switch (flavor) {
 2544   
 2545          case FLAVOR_UNKNOWN:
 2546                  /*
 2547                   * We don't know the authentication flavor, so we can't
 2548                   * dissect the payload.
 2549                   */
 2550                  proto_tree_add_text(ptree, tvb, offset, -1,
 2551                      "Unknown authentication flavor - cannot dissect");
 2552                  return TRUE;
 2553   
 2554          case FLAVOR_NOT_GSSAPI:
 2555                  /*
 2556                   * It's not GSS-API authentication.  Just dissect the
 2557                   * payload.
 2558                   */
 2559                  offset = call_dissect_function(tvb, pinfo, ptree, offset,
 2560                                  dissect_function, progname);
 2561                  break;
 2562   
 2563          case FLAVOR_GSSAPI_NO_INFO:
 2564                  /*
 2565                   * It's GSS-API authentication, but we don't have the
 2566                   * procedure and service information, so we can't dissect 
 2567                   * the payload.
 2568                   */
 2569                  proto_tree_add_text(ptree, tvb, offset, -1,
 2570                      "GSS-API authentication, but procedure and service unknown - cannot dissect");
 2571                  return TRUE;
 2572   
 2573          case FLAVOR_GSSAPI:
 2574                  /*
 2575                   * It's GSS-API authentication, and we have the procedure 
 2576                   * and service information; process the GSS-API stuff,
 2577                   * and process the payload if there is any.
 2578                   */
 2579                  switch (gss_proc) {
 2580   
 2581                  case RPCSEC_GSS_INIT:
 2582                  case RPCSEC_GSS_CONTINUE_INIT:
 2583                          if (msg_type == RPC_CALL) {
 2584                                  offset = dissect_rpc_authgss_initarg(tvb,
 2585                                          ptree, offset, pinfo);
 2586                          }
 2587                          else {
 2588                                  offset = dissect_rpc_authgss_initres(tvb,
 2589                                          ptree, offset, pinfo);
 2590                          }
 2591                          break;
 2592   
 2593                  case RPCSEC_GSS_DATA:
 2594                          if (gss_svc == RPCSEC_GSS_SVC_NONE) {
 2595                                  offset = call_dissect_function(tvb,
 2596                                                  pinfo, ptree, offset,
 2597                                                  dissect_function,
 2598                                                  progname);
 2599                          }
 2600                          else if (gss_svc == RPCSEC_GSS_SVC_INTEGRITY) {
 2601                                  offset = dissect_rpc_authgss_integ_data(tvb,
 2602                                                  pinfo, ptree, offset,
 2603                                                  dissect_function,
 2604                                                  progname);
 2605                          }
 2606                          else if (gss_svc == RPCSEC_GSS_SVC_PRIVACY) {
 2607                                  offset = dissect_rpc_authgss_priv_data(tvb,
 2608                                                  ptree, offset);
 2609                          }
 2610                          break;
 2611   
 2612                  default:
 2613                          break;
 2614                  }
 2615                  break;
 2616   
 2617          case FLAVOR_AUTHGSSAPI_MSG:
 2618                  /*
 2619                   * This is an AUTH_GSSAPI message.  It contains data
 2620                   * only for the authentication procedure and not for the 
 2621                   * application level RPC procedure.  Reset the column
 2622                   * protocol and info fields to indicate that this is 
 2623                   * an RPC auth level message, then process the args.
 2624                   */
 2625                  if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
 2626                          col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPC");
 2627                  }
 2628                  if (check_col(pinfo->cinfo, COL_INFO)) {
 2629                          col_clear(pinfo->cinfo, COL_INFO);
 2630                          col_append_fstr(pinfo->cinfo, COL_INFO,
 2631                              "%s %s XID 0x%x",
 2632                              val_to_str(gss_proc, rpc_authgssapi_proc, "Unknown (%d)"),
 2633                              msg_type_name, xid);
 2634                  }
 2635   
 2636                  switch (gss_proc) {
 2637   
 2638                  case AUTH_GSSAPI_INIT:
 2639                  case AUTH_GSSAPI_CONTINUE_INIT:
 2640                  case AUTH_GSSAPI_MSG:
 2641                          if (msg_type == RPC_CALL) {
 2642                              offset = dissect_rpc_authgssapi_initarg(tvb,
 2643                                  rpc_tree, offset, pinfo);
 2644                          } else {
 2645                              offset = dissect_rpc_authgssapi_initres(tvb,
 2646                                  rpc_tree, offset, pinfo);
 2647                          }
 2648                          break;
 2649   
 2650                  case AUTH_GSSAPI_DESTROY:
 2651                          offset = dissect_rpc_data(tvb, rpc_tree,
 2652                              hf_rpc_authgss_data, offset);
 2653                          break;
 2654   
 2655                  case AUTH_GSSAPI_EXIT:
 2656                          break;
 2657                  }
 2658   
 2659                  /* Adjust the length to  for the auth message. */
 2660                  if (rpc_item) {
 2661                          proto_item_set_end(rpc_item, tvb, offset);
 2662                  }
 2663                  break;
 2664   
 2665          case FLAVOR_AUTHGSSAPI:
 2666                  /*
 2667                   * An RPC with AUTH_GSSAPI authentication.  The data 
 2668                   * portion is always private, so don't call the dissector.
 2669                   */
 2670                  offset = dissect_auth_gssapi_data(tvb, ptree, offset);
 2671                  break;
 2672          }
 2673   
 2674          if (tvb_length_remaining(tvb, offset) > 0) {
 2675            /*
 2676             * dissect any remaining bytes (incomplete dissection) as pure
 2677             * data in the ptree
 2678             */
 2679   
 2680            call_dissector(data_handle,
 2681                tvb_new_subset(tvb, offset, -1, -1), pinfo, ptree);
 2682          }
 2683   
 2684          /* XXX this should really loop over all fhandles registred for the frame */
 2685          if(nfs_fhandle_reqrep_matching){
 2686                  switch (msg_type) {
 2687                  case RPC_CALL:
 2688                          if(rpc_call && rpc_call->rep_num){
 2689                                  dissect_fhandle_hidden(pinfo,
 2690                                                  ptree, rpc_call->rep_num);
 2691                          }
 2692                          break;
 2693                  case RPC_REPLY:
 2694                          if(rpc_call && rpc_call->req_num){
 2695                                  dissect_fhandle_hidden(pinfo,
 2696                                                  ptree, rpc_call->req_num);
 2697                          }
 2698                          break;
 2699                  }
 2700          }
 2701   
 2702          return TRUE;
 2703  }
Show more  




Change Warning 2918.34440 : Null Test After Dereference

Because they are very similar, this warning shares annotations with warning 2918.34441.

Priority:
State:
Finding:
Owner:
Note: