Ethereal-dev: Re: [Ethereal-dev] IP defragment
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Guy Harris <guy@xxxxxxxxxx>
Date: Mon, 16 Apr 2001 16:56:19 -0700 (PDT)
> please consider for cvs The code that does ipfk->srcip = *((guint32 *)pinfo->src.data); ipfk->dstip = *((guint32 *)pinfo->dst.data); may crash on platforms with strict memory alignment requirements (and, in fact, *did* crash on my SPARC/Solaris/GCC platform at work on at least one capture file); do memcpy(&ipfk->srcip, pinfo->src.data, sizeof ipfk->srcip); memcpy(&ipfk->dstip, pinfo->dst.data, sizeof ipfk->dstip); instead. Note also that "g_malloc()" is defined to abort the application if you run out of memory: http://developer.gnome.org/doc/API/glib/glib-memory-allocation.html "Note: If any call to allocate memory fails, the application is terminated. This also means that there is no need to check if the call succeeded." so it shouldn't check for "g_malloc()" returning NULL - it never returns NULL. You also need to save and restore some of the members of "pi" before calling a subdissector, so that old-style (non-tvbuffified) dissectors work correctly. In addition, given that the reassembly code checks the IP checksum, you have to compute it *regardless* of whether the "tree" argument is null or not. I've attached a patch to the "packet-ip.c" you sent out, which includes those fixes. Another thing you'll need to do is to arrange that if not all the data in a fragment is present - i.e., if "tvb_reported_length(tvb)" is creater than "tvb_length(tvb)" - you don't add it to the fragment hash table. This can happen if the capture was done with a snapshot length less than the MTU of the network; Ethereal/Tethereal, snoop, and Microsoft Network Monitor default to a large or "infinite" snapshot length, so, at least with those programs, it'll happen only if the user explicitly specifies a smaller snapshot length, but the default snapshot length in tcpdump is 68 bytes, so it'll happen with tcpdump *unless* the user specifies a larger snapshot length. > * multiple-tails, overlap-conflict and too-long-fragmnet will also set > "ip.fragments.error" which is easier to use in a > display-filter. Perhaps what we need here is either 1) a generic "error" flag that can be set on a frame, with an expression such as "error" checking it or 2) a way of marking a protocol tree item as an error indication, which could not only be filtered for with a special expression such as "error" but could perhaps also be made a different color (defaulting, perhaps, to the standard color, but allowing the user to specify a different color).
*** /tmp/packet-ip.c Mon Apr 16 16:48:25 2001 --- ./packet-ip.c Mon Apr 16 16:46:30 2001 *************** *** 448,459 **** /* create key to search hash with */ ! if ( (ipfk=g_malloc(sizeof(ip_fragment_key))) == NULL ){ ! fprintf(stderr,"packet-ip.c:ip_fragment_add() g_malloc() failed\n"); ! exit(10); ! } ! ipfk->srcip = *((guint32 *)pinfo->src.data); ! ipfk->dstip = *((guint32 *)pinfo->dst.data); ipfk->id = id; ipfd_head=g_hash_table_lookup(ip_fragment_table, ipfk); --- 448,456 ---- /* create key to search hash with */ ! ipfk=g_malloc(sizeof(ip_fragment_key)); ! memcpy(&ipfk->srcip, pinfo->src.data, sizeof ipfk->srcip); ! memcpy(&ipfk->dstip, pinfo->dst.data, sizeof ipfk->dstip); ipfk->id = id; ipfd_head=g_hash_table_lookup(ip_fragment_table, ipfk); *************** *** 1128,1133 **** --- 1125,1132 ---- guint16 ipsum; ip_fragment_data *ipfd_head; tvbuff_t *next_tvb; + packet_info save_pi; + gboolean must_restore_pi = FALSE; if (check_col(pinfo->fd, COL_PROTOCOL)) col_set_str(pinfo->fd, COL_PROTOCOL, "IP"); *************** *** 1188,1193 **** --- 1187,1197 ---- return; } + /* + * Compute the checksum of the IP header. + */ + ipsum = ip_checksum(tvb_get_ptr(tvb, offset, hlen), hlen); + if (tree) { proto_tree_add_uint(ip_tree, hf_ip_version, tvb, offset, 1, hi_nibble(iph.ip_v_hl)); proto_tree_add_uint_format(ip_tree, hf_ip_hdr_len, tvb, offset, 1, hlen, *************** *** 1231,1237 **** proto_tree_add_uint_format(ip_tree, hf_ip_proto, tvb, offset + 9, 1, iph.ip_p, "Protocol: %s (0x%02x)", ipprotostr(iph.ip_p), iph.ip_p); - ipsum = ip_checksum(tvb_get_ptr(tvb, offset, hlen), hlen); if (ipsum == 0) { proto_tree_add_uint_format(ip_tree, hf_ip_checksum, tvb, offset + 10, 2, iph.ip_sum, "Header checksum: 0x%04x (correct)", iph.ip_sum); --- 1235,1240 ---- *************** *** 1345,1350 **** --- 1348,1361 ---- /* It's not fragmented. */ pinfo->fragmented = FALSE; + + /* Save the current value of "pi", and adjust certain fields to + reflect the new tvbuff. */ + save_pi = pi; + pi.compat_top_tvb = next_tvb; + pi.len = tvb_reported_length(next_tvb); + pi.captured_len = tvb_length(next_tvb); + must_restore_pi = TRUE; } else { /* We don't have the complete reassembled payload. */ next_tvb = NULL; *************** *** 1381,1386 **** --- 1392,1400 ---- col_add_fstr(pinfo->fd, COL_INFO, "Fragmented IP protocol (proto=%s 0x%02x, off=%u)", ipprotostr(iph.ip_p), iph.ip_p, (iph.ip_off & IP_OFFSET) * 8); dissect_data(tvb, offset, pinfo, tree); + + /* As we haven't reassembled anything, we haven't changed "pi", so + we don't have to restore it. */ return; } *************** *** 1397,1402 **** --- 1411,1419 ---- col_add_fstr(pinfo->fd, COL_INFO, "%s (0x%02x)", ipprotostr(iph.ip_p), iph.ip_p); dissect_data(next_tvb, 0, pinfo, tree); } + + if (must_restore_pi) + pi = save_pi; }
- Follow-Ups:
- Re: [Ethereal-dev] IP defragment
- From: Ronnie Sahlberg
- Re: [Ethereal-dev] IP defragment
- References:
- [Ethereal-dev] IP defragment
- From: Ronnie Sahlberg
- [Ethereal-dev] IP defragment
- Prev by Date: Re: [Ethereal-dev] On hook, MGCP
- Next by Date: [Ethereal-dev] WCP decode not working?
- Previous by thread: [Ethereal-dev] IP defragment
- Next by thread: Re: [Ethereal-dev] IP defragment
- Index(es):