ipv4.py's parse() grabs the IP headers and passes the rest of its input on to 
some next layer (which may be TCP, UDP, ICMP, or just raw data, depending).  
Sounds good, but… there are times when the rest of its input isn't actually all 
IP payload.  Specifically, when the ethernet frame has been padded to meet the 
minimum frame size.  Then when tcp.py parses itself, for example, it thinks the 
padding is TCP payload, which is really annoying.

Since IP knows how much of the rest of the data it's actually encapsulating, it 
seems like the right thing to do is just to not pass the ethernet frame padding 
forward and throw it away instead.  I can't think of any reason you'd want to 
do otherwise.  Here's a patch:

--- /home/user/nox3/src/nox/lib/packet/ipv4.py  2010-03-31 23:49:59.000000000 
-0700
+++ ipv4.py     2010-04-13 19:29:50.000000000 -0700
@@ -137,19 +137,22 @@
         # packet
         self.parsed = True
 
+        length = self.iplen
+        if length > dlen: length = dlen # Clamp to what we've got
+        
         if self.protocol == ipv4.UDP_PROTOCOL:
-            self.next = udp(arr=self.arr[self.hl*4:], prev=self)
+            self.next = udp(arr=self.arr[self.hl*4:length], prev=self)
         elif self.protocol == ipv4.TCP_PROTOCOL:
-            self.next = tcp(arr=self.arr[self.hl*4:], prev=self)
+            self.next = tcp(arr=self.arr[self.hl*4:length], prev=self)
         elif self.protocol == ipv4.ICMP_PROTOCOL:
-            self.next = icmp(arr=self.arr[self.hl*4:], prev=self)
+            self.next = icmp(arr=self.arr[self.hl*4:length], prev=self)
         elif dlen < self.iplen:
             self.msg('(ip parse) warning IP packet data shorter than IP len: 
%u < %u' % (dlen, self.iplen))
         else:    
-            self.next =  self.arr[self.hl*4:].tostring()
+            self.next =  self.arr[self.hl*4:length].tostring()
 
         if isinstance(self.next, packet_base) and not self.next.parsed:
-            self.next =  self.arr[self.hl*4:].tostring()
+            self.next =  self.arr[self.hl*4:length].tostring()
 
     def checksum(self):    
         data = struct.pack('!BBHHHBBHII', (self.v << 4) + self.hl, self.tos, \

-- Murphy
_______________________________________________
nox-dev mailing list
nox-dev@noxrepo.org
http://noxrepo.org/mailman/listinfo/nox-dev_noxrepo.org

Reply via email to