Text   |  XML   |  ReML   |   Visible Warnings:

Cast Alters Value  at packet-iscsi.c:2307

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

dissect_iscsi

(/home/sate/Testcases/c/cve/wireshark-1.2.0/epan/dissectors/packet-iscsi.c)expand/collapse
Show more  
 1589  dissect_iscsi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean check_port) {
 1590      /* Set up structures needed to add the protocol subtree and manage it */
 1591      guint iSCSIPdusDissected = 0;
 1592      guint offset = 0;
 1593      guint32 available_bytes = tvb_length(tvb);
 1594      int digestsActive = 1;
 1595      conversation_t *conversation = NULL;
 1596      iscsi_session_t *iscsi_session=NULL;
 1597      guint8 opcode, tmpbyte;
 1598   
 1599      if (available_bytes < 48 ){
 1600          /* heuristic already rejected the packet if size < 48,
 1601            assume it's an iscsi packet with a segmented header */
 1602          pinfo->desegment_offset = offset;
 1603          pinfo->desegment_len = 48 - available_bytes;
 1604          return TRUE;
 1605      }
 1606   
 1607      opcode = tvb_get_guint8(tvb, offset + 0);
 1608      opcode &= OPCODE_MASK;
 1609   
 1610      /* heuristics to verify that the packet looks sane.   the heuristics
 1611       * are based on the RFC version of iscsi.
 1612       * (we should retire support for older iscsi versions in wireshark)
 1613       *      -- ronnie s
 1614       */
 1615      /* opcode must be any of the ones from the standard
 1616       * also check the header that it looks "sane"
 1617       * all reserved or undefined bits in iscsi must be set to zero.
 1618       */
 1619      switch(opcode){
 1620      case ISCSI_OPCODE_NOP_IN:
 1621          /* top two bits of byte 0 must be 0 */
 1622          if(tvb_get_guint8(tvb, offset+0)&0xc0){
 1623              return FALSE;
 1624          }
 1625          /* byte 1 must be 0x80 */
 1626          if(tvb_get_guint8(tvb, offset+1)!=0x80){
 1627              return FALSE;
 1628          }
 1629          /* bytes 2 and 3 must be 0 */
 1630
2111
Show [ Lines 1630 to 2111 omitted. ]
 2112          /* byte 2 must be reserved */
 2113          if(tvb_get_guint8(tvb,offset+2)){
 2114              return FALSE;
 2115          }
 2116          break;
 2117      case ISCSI_OPCODE_VENDOR_SPECIFIC_I0:
 2118      case ISCSI_OPCODE_VENDOR_SPECIFIC_I1:
 2119      case ISCSI_OPCODE_VENDOR_SPECIFIC_I2:
 2120      case ISCSI_OPCODE_VENDOR_SPECIFIC_T0:
 2121      case ISCSI_OPCODE_VENDOR_SPECIFIC_T1:
 2122      case ISCSI_OPCODE_VENDOR_SPECIFIC_T2:
 2123          break;
 2124      default:
 2125          return FALSE;
 2126      }
 2127   
 2128   
 2129      /* process multiple iSCSI PDUs per packet */
 2130      while(available_bytes >= 48 || (iscsi_desegment && available_bytes >= 8)) {
 2131          const char *opcode_str = NULL;
 2132          guint32 data_segment_len;
 2133          guint32 pduLen = 48;
 2134          guint8 secondPduByte = tvb_get_guint8(tvb, offset + 1);
 2135          int badPdu = FALSE;
 2136          guint8 ahsLen=0;
 2137   
 2138          /* mask out any extra bits in the opcode byte */
 2139          opcode = tvb_get_guint8(tvb, offset + 0);
 2140          opcode &= OPCODE_MASK;
 2141   
 2142          opcode_str = match_strval(opcode, iscsi_opcodes);
 2143          if(opcode == ISCSI_OPCODE_TASK_MANAGEMENT_FUNCTION ||
 2144             opcode == ISCSI_OPCODE_TASK_MANAGEMENT_FUNCTION_RESPONSE ||
 2145             opcode == ISCSI_OPCODE_R2T ||
 2146             opcode == ISCSI_OPCODE_LOGOUT_COMMAND ||
 2147             opcode == ISCSI_OPCODE_LOGOUT_RESPONSE ||
 2148             opcode == ISCSI_OPCODE_SNACK_REQUEST)
 2149              data_segment_len = 0;
 2150          else 
 2151              data_segment_len = tvb_get_ntohl(tvb, offset + 4) & 0x00ffffff;
 2152   
 2153          if(opcode_str == NULL) {
 2154              badPdu = TRUE;
 2155          }
 2156          else if(check_port && iscsi_port != 0 &&
 2157                  (((opcode & TARGET_OPCODE_BIT) && pinfo->srcport != iscsi_port) ||
 2158                   (!(opcode & TARGET_OPCODE_BIT) && pinfo->destport != iscsi_port))) {
 2159              badPdu = TRUE;
 2160          }
 2161          else if(enable_bogosity_filter) {
 2162              /* try and distinguish between data and real headers */
 2163              if(data_segment_len > bogus_pdu_data_length_threshold) {
 2164                  badPdu = TRUE;
 2165              }
 2166              else if(demand_good_f_bit &&
 2167                      !(secondPduByte & 0x80) &&
 2168                      (opcode == ISCSI_OPCODE_NOP_OUT ||
 2169                       opcode == ISCSI_OPCODE_NOP_IN ||
 2170                       opcode == ISCSI_OPCODE_LOGOUT_COMMAND ||
 2171                       opcode == ISCSI_OPCODE_LOGOUT_RESPONSE ||
 2172                       opcode == ISCSI_OPCODE_SCSI_RESPONSE ||
 2173                       opcode == ISCSI_OPCODE_TASK_MANAGEMENT_FUNCTION_RESPONSE ||
 2174                       opcode == ISCSI_OPCODE_R2T ||
 2175                       opcode == ISCSI_OPCODE_ASYNC_MESSAGE ||
 2176                       opcode == ISCSI_OPCODE_SNACK_REQUEST ||
 2177                       opcode == ISCSI_OPCODE_REJECT)) {
 2178                  badPdu = TRUE;
 2179              } else if(opcode==ISCSI_OPCODE_NOP_OUT) {
 2180                  /* TransferTag for NOP-Out should either be -1 or 
 2181                     the tag value we want for a response.  
 2182                     Assume 0 means we are just inside a big all zero
 2183                     datablock.
 2184                  */
 2185                  if(tvb_get_ntohl(tvb, offset+20)==0){
 2186                      badPdu = TRUE;
 2187                  }
 2188              }
 2189          }
 2190   
 2191          if(badPdu) {
 2192              return iSCSIPdusDissected > 0;
 2193          }
 2194   
 2195          if(opcode ==  ||
 2196              opcode == ) {
 2197              if(iscsi_protocol_version == ISCSI_PROTOCOL_DRAFT08) {
 2198                  if((secondPduByte & CSG_MASK) < ISCSI_CSG_OPERATIONAL_NEGOTIATION) {
 2199                      /* digests are not yet turned on */
 2200                      digestsActive = 0;
 2201                  }
 2202              } else {
 2203                  digestsActive = 0;
 2204              }
 2205          }
 2206   
 2207          if(opcode == ISCSI_OPCODE_SCSI_COMMAND) {
 2208              /* ahsLen */
 2209              ahsLen = tvb_get_guint8(tvb, offset + 4);
 2210              pduLen += ahsLen * 4;
 2211          }
 2212   
 2213          pduLen += data_segment_len;
 2214          if((pduLen & 3) != 0)
 2215              pduLen += 4 - (pduLen & 3);
 2216   
 2217   
 2218          if(digestsActive && data_segment_len > 0 && enableDataDigests) {
 2219              if(dataDigestIsCRC32)
 2220                  pduLen += 4;
 2221              else 
 2222                  pduLen += dataDigestSize;
 2223          }
 2224   
 2225          /* make sure we have a conversation for this session */
 2226          conversation = find_conversation (pinfo->fd->num, &pinfo->src, &pinfo->dst,
 2227                                            pinfo->ptype, pinfo->srcport,
 2228[+]                                           pinfo->destport, 0);
 2229          if (!conversation) {
 2230              conversation = conversation_new (pinfo->fd->num, &pinfo->src, &pinfo->dst,
 2231                                               pinfo->ptype, pinfo->srcport,
 2232                                               pinfo->destport, 0);
 2233          }
 2234[+]         iscsi_session=conversation_get_proto_data(conversation, proto_iscsi);
 2235          if(!iscsi_session){
 2236              iscsi_session=se_alloc(sizeof(iscsi_session_t));
 2237              iscsi_session->header_digest=ISCSI_HEADER_DIGEST_AUTO;
 2238              iscsi_session->itlq=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "iSCSI ITLQ");
 2239              iscsi_session->itl=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "iSCSI ITL");
 2240              conversation_add_proto_data(conversation, proto_iscsi, iscsi_session);
 2241   
 2242              /* DataOut PDUs are often mistaken by DCERPC heuristics to be
 2243               * that protocol. Now that we know this is iscsi, set a  
 2244               * dissector for this conversation to block other heuristic
 2245               * dissectors.  
 2246               */
 2247              conversation_set_dissector(conversation, iscsi_handle);
 2248          }
 2249          /* try to autodetect if header digest is used or not */
 2250          if(digestsActive && (available_bytes>=(guint32) (48+4+ahsLen*4)) && (iscsi_session->header_digest==ISCSI_HEADER_DIGEST_AUTO) ){
 2251              guint32 crc;
 2252                  /* we have enough data to test if HeaderDigest is enabled */
 2253              crc= ~calculate_crc32c(tvb_get_ptr(tvb, offset, 48+ahsLen*4), 48+ahsLen*4, CRC32C_PRELOAD);
 2254              if(crc==tvb_get_ntohl(tvb,48+ahsLen*4)){
 2255                  iscsi_session->header_digest=ISCSI_HEADER_DIGEST_CRC32;
 2256              } else {
 2257                  iscsi_session->header_digest=ISCSI_HEADER_DIGEST_NONE;
 2258              }
 2259          }
 2260   
 2261   
 2262          /* Add header digest length to pdulen */
 2263          if(digestsActive){
 2264                  switch(iscsi_session->header_digest){
 2265                  case ISCSI_HEADER_DIGEST_CRC32:
 2266                          pduLen += 4;
 2267                          break;
 2268                  case ISCSI_HEADER_DIGEST_NONE:
 2269                          break;
 2270                  case ISCSI_HEADER_DIGEST_AUTO:
 2271                          /* oops we didnt know what digest is used yet */
 2272                          /* here we should use some default */
 2273                          break;
 2274                  default:
 2275                          DISSECTOR_ASSERT_NOT_REACHED();
 2276                  }
 2277          }
 2278   
 2279          /*
 2280           * Desegmentation check.
 2281           */
 2282          if(iscsi_desegment && pinfo->can_desegment) {
 2283              if(pduLen > available_bytes) {
 2284                  /*
 2285                   * This frame doesn't have all of the data for
 2286                   * this message, but we can do reassembly on it.
 2287                   *
 2288                   * Tell the TCP dissector where the data for this 
 2289                   * message starts in the data it handed us, and 
 2290                   * how many more bytes we need, and return.
 2291                   */
 2292                  pinfo->desegment_offset = offset;
 2293                  pinfo->desegment_len = pduLen - available_bytes;
 2294                  return TRUE;
 2295              }
 2296          }
 2297   
 2298          /* This is to help TCP keep track of PDU boundaries
 2299             and allows it to find PDUs that are not aligned to  
 2300             the start of a TCP segments.
 2301             Since it also allows TCP to know what is in the middle 
 2302             of a large PDU, it reduces the probability of a segment 
 2303             in the middle of a large PDU transfer being misdissected as
 2304             a PDU.
 2305          */
 2306          if(!pinfo->fd->flags.visited){
 2307[+]             if(pduLen>(guint32)tvb_reported_length_remaining(tvb, offset)){
 2308                  pinfo->want_pdu_tracking=2;
 2309                  pinfo->bytes_until_next_pdu=pduLen-tvb_reported_length_remaining(tvb, offset);
 2310              }
 2311          }
 2312   
 2313          if(check_col(pinfo->cinfo, COL_INFO)) {
 2314              if(iSCSIPdusDissected == 0)
 2315                  col_set_str(pinfo->cinfo, COL_INFO, "");
 2316              else 
 2317                  col_append_str(pinfo->cinfo, COL_INFO, ", ");
 2318          }
 2319   
 2320          dissect_iscsi_pdu(tvb, pinfo, tree, offset, opcode, opcode_str, data_segment_len, iscsi_session, conversation);
 2321          if(pduLen > available_bytes)
 2322              pduLen = available_bytes;
 2323          offset += pduLen;
 2324          available_bytes -= pduLen;
 2325          ++iSCSIPdusDissected;
Show more  




Change Warning 2700.34928 : Cast Alters Value

Priority:
State:
Finding:
Owner:
Note: