The ONL Tutorial

Tutorial >> More Plugins TOC

Modify Packets

The proper plugin action after you modify a packet is to recompute checksums. Since the checksum in the IP header only covers the header itself, it does not need to be recomputed if the header is not changed. But in the case of TCP, you will have to recompute the checksum field in the TCP header if you change the TCP payload. Since the checksum in a UDP header is optional, it should be examined for a non-zero value to see if it needs to be recomputed (a 0 checksum indicates that the sender did not compute the checksum).

The stringSub plugin changes any occurrence of the string "HELLO" to "adieu" found in either the header or payload of a TCP packet. (Note this behavior is really a but since the plugin should really scan only the payload portion, not the TCP header.) The assign_tcpCksums(...) function in line 24 below recomputes both the checksum in the IP header and the TCP header. First, it computes a 16-bit checksum by adding 16-bit words (adjusting for an odd number of bytes) which include a 12-byte pseudo-header and the TCP payload using the calc_cksums(...) utility. Then, it computes the checksum over the IP header using the wunet_cksum16(...) utility. These are two of several helper functions defined in ~onl/wu_arl/msr/rp/plugins/include/ipnet.h (included as <plugins/include/ipnet.h>).

 1	void stringSub_handle_packet(
 2	  struct rp_instance *this,		// points to instance structure
 3	  void *bufferList)			// points to list of pkt buffers
 4	{
 5	  struct stringSub_instance *inst = (struct stringSub_instance *)this;
 6	  msr_bufhdr_t	*buffer	= msr_firstBuffer(bufferList);
 7	  struct ip	*iph	= msr_pkt_iph(buffer);
 8	  int		len	= msr_iplen(iph);
 9	  char		*p, *end;
10	
11	  p = ((char *) iph) + msr_iphlen(iph);	// point to 1st byte of IP payload
12	  end = ((char *) iph) + len - 5;	// point to 5th byte from end of payload
13	  inst->pktCount++;
14	
15	  while (p < end) {	// replace "HELLO" with "adieu" everywhere
16	    if (prefix("HELLO",p)) {
17	      copy("adieu",p);
18	      inst->count++;
19	      p += 5;
20	    } else {
21	      p++;
22	    }
23	  }
24	  assign_tcpCksums((iphdr_t *) iph);	// recompute TCP checksum
25	}

Recomputing the IP header check sum was not really necessary here but the assign_tcpCksums was convenient to use. Alternatively, the user could have called the calc_cksums function to recompute only the TCP header checksum. But that function requires that the user zero the checksum field first. This, in turn, means that the user would have also had to find the location of the TCP header. None of this is particularly difficult, but again, the assign_tcpCksums was convenient to use here.

Note that the packet passed into the sringSub_handle_packet function is never removed from bufferList. So, when the function returns, the SPC kernel forwards the packet.

  

Tutorial >> More Plugins TOC