Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 3 Aug 2009 02:53:53 GMT
From:      Zachariah Riggle <zjriggl@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 166949 for review
Message-ID:  <200908030253.n732rrg5036111@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=166949

Change 166949 by zjriggl@zjriggl_tcpregression on 2009/08/03 02:53:10

	Periodic submit

Affected files ...

.. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/echoServer.py#5 edit
.. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/loggable.py#5 edit
.. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/logging.conf#5 edit
.. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/StringField.py#3 edit
.. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/__init__.py#8 edit
.. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/backup.tar#3 edit
.. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/checksum.py#2 edit
.. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/decorators.py#4 edit
.. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/field.py#2 edit
.. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/hwAddress.py#4 edit
.. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/ipAddress.py#5 edit
.. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/networkPort.py#4 edit
.. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/payload.py#4 edit
.. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/pseudoipv4.py#3 edit
.. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/segmentBuffer.py#3 edit
.. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/sniffLocalhost.py#5 edit
.. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/tcpConstructor.py#6 edit
.. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/tcpFilter.py#7 edit
.. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/tcprecvdaemon.py#3 edit
.. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/tcpstatemachine.py#8 edit
.. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/test.html#5 edit
.. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/testconfig.py#7 edit

Differences ...

==== //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/echoServer.py#5 (text+ko) ====


==== //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/loggable.py#5 (text+ko) ====

@@ -6,12 +6,13 @@
 logging.config.fileConfig( "logging.conf" )
 
 ( logging.FIELD_CHANGE,
- logging.RESPONSE_GENERATION,
- logging.PACKET_TRANSMIT,
+ logging.RESPONSE_GENERATION  ) = range( logging.DEBUG - 2, logging.DEBUG )
+ 
+( logging.PACKET_TRANSMIT,
  logging.PACKET_RECEIVED,
  logging.PACKET_SENT,
  logging.VALIDATE,
- logging.STATE_CHANGE ) = range( logging.INFO - 7, logging.INFO )
+ logging.STATE_CHANGE ) = range( logging.INFO - 5, logging.INFO )
 
 logging.addLevelName( logging.FIELD_CHANGE, "FIELD" )
 logging.addLevelName( logging.RESPONSE_GENERATION, "\033[1;36mGENERATE\033[1;m" )
@@ -19,7 +20,9 @@
 logging.addLevelName( logging.PACKET_RECEIVED, "\033[1;31mRECVD\033[1;m" )
 logging.addLevelName( logging.PACKET_SENT, "\033[1;31mSENT\033[1;m" )
 logging.addLevelName( logging.VALIDATE, "VALIDATE" )
-logging.addLevelName( logging.STATE_CHANGE, "STATE" )
+logging.addLevelName( logging.STATE_CHANGE, "\033[1;37;44mSTATE\033[1;m" )
+
+#  1;37;44
 
 # print '\033[1;36mGENERATE\033[1;m'
 # print '\033[1;36mCyan like Caribbean\033[1;m'

==== //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/logging.conf#5 (text+ko) ====


==== //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/StringField.py#3 (text+ko) ====


==== //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/__init__.py#8 (text+ko) ====

@@ -3,7 +3,7 @@
 import struct
 import socket
 import sys
-
+import re
 from pcs.packets.ipv4 import ipv4
 from pcs.packets.tcp import tcp
 from pcs.packets.tcpv6 import tcpv6
@@ -41,3 +41,14 @@
 
 def inet_atol( ipString ):
     return inet_ntol( socket.inet_aton( ipString ) )
+
+def wireSharkFormatBytes(x):
+    twoBits = r"(\w\w)"
+    octet = "((%s ){8})" % twoBits
+    twoBytes = "((%s   ){2})" % octet
+
+    x = re.sub(twoBits,r"\1 ",x)
+    x = re.sub(octet,r"\1   ",x)
+    x = re.sub(twoBytes,r"\1\n",x)
+    return x
+

==== //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/backup.tar#3 (binary) ====


==== //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/checksum.py#2 (text+ko) ====


==== //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/decorators.py#4 (text+ko) ====

@@ -186,7 +186,7 @@
       
     '''
     ops = func() or {}
-    name=ops.get('prefix','_')+func.__name__ # property name
+    name=ops.get('name') or ops.get('prefix','_')+func.__name__ # property name
     fget=ops.get('fget',lambda self:getattr(self, name))
     fset=ops.get('fset',lambda self,value:setattr(self,name,value))
     fdel=ops.get('fdel',lambda self:delattr(self,name))
@@ -241,7 +241,7 @@
     return property (fget, fset, fdel, func.__doc__)
 
 
-def uint(max=2**32):
+def uint(limit=2**32):
     '''
     >>> from pcsextension.decorators import *
     >>> lim = 5
@@ -272,4 +272,4 @@
         fset = lambda self,value: setattr(self, name, (value % max))
         fdel = lambda self: delattr(self, value)
         return property(fget, fset, fdel)
-    return unsignedInteger
+    return unsignedInteger
==== //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/field.py#2 (text+ko) ====

@@ -5,69 +5,118 @@
 '''
 
 class Field( object ):
+    '''
+    Base class for an extensible field class.  Allows the field to be represented
+    in various formats with ease, as needed by the developer.  This allows byte-
+    order and representation issues to be alleviated, as well as string-of-bytes
+    representation to be simplified for any byte order.
+    '''
 
     name = ""
     value = None
     width = 8
     networkByteOrder = False
 
-    def __init__( self, default = 0, width = None, networkByteOrder = False ):
+    def __init__( self, default = 0, width = 8, networkByteOrder = False ):
         self.width = width
         self.networkByteOrder = networkByteOrder
+        
         if isinstance( default, int ):
             self.setInteger( default )
         if isinstance( default, str ):
             self.setAscii( default )
+        if isinstance( default, Field):
+            self.setNetworkBytes(default.getNetworkBytes())
 
     def setAscii( self, x ):
+        '''
+        Set the value, given its textual representation, e.g. '12345' or '127.0.0.1'
+        '''
         pass
 
     def getAscii( self ):
+        '''
+        @see setAscii
+        '''
         return ""
 
     def setInteger( self, x ):
+        '''
+        Set the value, given its numeric representation in host-byte-order, e.g. 12345.
+        '''
         pass
 
     def getInteger( self ):
+        '''
+        @see setInteger
+        '''
         return 0
 
     def setNetworkInteger( self, x ):
+        '''
+        Set the value, given its numeric representation in network-byte-order, e.g. 14640
+        '''
         pass
 
     def getNetworkInteger( self ):
+        '''
+        @see setNetworkInteger
+        '''
         return 0
 
     def setBytes( self, x ):
+        '''
+        Set the value as a string of bytes in host-byte-order, e.g. '\x30\x39'
+        '''
         pass
 
     def getBytes( self ):
+        '''
+        @see setBytes
+        '''
         return ""
 
-    def getBytesShifted( self, shiftedBits ):
-        pass
-
     def setNetworkBytes( self, x ):
+        '''
+        Sets the value as a string of bytes in network-byte-order, e.g. '\x39\x30'
+        '''
         pass
 
     def getNetworkBytes( self ):
+        '''
+        @see setNetworkBytes
+        '''
         return ""
 
-    def getNetworkBytesShifted( self, shiftedBits ):
-        return getNetworkBytes()
-
     def setPCS( self, x ):
+        '''
+        Sets the value in the format native to the PCS (Packet Construction 
+        Set) library.  For example, network-byte-order integer for TCP ports,
+        or byte-string for Ethernet addresses.
+        '''
         pass
 
-    def getPCS( self, x ):
+    def getPCS( self ):
+        '''
+        @see setPCS
+        '''
         return self.getNetworkBytes()
 
     def encode( self ):
+        '''
+        Returns the same value as getBytes/getNetworkBytes as instructed by 
+        __init__ or the networkByteOrder property.
+        '''
         if self.networkByteOrder:
             return self.getNetworkBytes()
         else:
             return self.getBytes()
 
     def decode( self, bytes ):
+        '''
+        Calls setBytes/setNetworkBytes as instructed by __init__ or the 
+        networkByteOrder property.
+        '''
         if self.networkByteOrder:
             self.setNetworkBytes( bytes )
         else:
@@ -88,41 +137,15 @@
         return False
 
     def bound( self ):
-        if width == None:
+        '''
+        Ensures that the value returned by getBytes() is no longer than
+        self.width bits and that the value returned by getInteger is no
+        larger than an integer of self.width bits would allow.
+        '''
+        if self.width == None:
             return
 
-        elif width == 8:
-            if ( width == 8 and len( self.getBytes() ) > width * 8 ) or \
-                ( getInteger() > ( ( 2 ** self.width ) - 1 ) ):
-                raise Exception, "Value exceeds bit-width"
-
-    def __add__( self, x ):
-
-        if isinstance( x, Field ):
-            f = Field( width = self.width + x.width )
-            bytes = self.getNetworkBytes()
-            nextBytes = x.getNetworkBytes()
-
-            # If either of the widths are NOT even mod 8
-            # ord
-            # chr
-            if self.width % 8 != 0:
-
-                lastByte = bytes[:-1]
-
-                # Will the field fit in the remaining bits of the last byte
-                # In the below example 'X' = the appended bytes, 'O' = existing, current bytes
-                # Bit    1 2 3 4 5 6 7 8
-                #        O O O
-                #        X X X X X
-                #        O O O X X X X X
-                if x.width <= ( 8 - self.width ):
-                    nextBits = ord( nextBytes[0] ) >> self.width
-                    nextBits = nextBits | ord( lastByte )
-                    joined = struct.pack( "!B%d", nextBits )
-                    f.setNetworkBytes( self.getNetworkBytes()[:-1] + joined )
-
-                # The field will not fit in the remaining space
-
-            else:
-                f.setNetworkBytes( self.getNetworkBytes() + x.getNetworkBytes() )
+        elif self.width == 8:
+            if ( self.width == 8 and len( self.getBytes() ) > self.width * 8 ) or \
+                ( self.getInteger() > ( ( 2 ** self.width ) - 1 ) ):
+                raise Exception, "Value exceeds bit-width %i" % self.width
==== //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/hwAddress.py#4 (text+ko) ====


==== //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/ipAddress.py#5 (text+ko) ====

@@ -20,6 +20,12 @@
     def __init__( self, default = 0, width = None, networkByteOrder = False, version = AF_INET ):
         self.version = version
         Field.__init__( self, width = width, default = default, networkByteOrder = networkByteOrder )
+        
+        # Override the default Field.__init__ behavior.  If the string's length is 4, it is obviously
+        # a byte-string as opposed to an IP address.
+        if type(default) == str:
+            if len(default) == 4:
+                self.nbo = default
 
     def setAscii( self, x ):
         self.nbo = inet_pton( self.version, x )

==== //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/networkPort.py#4 (text+ko) ====

@@ -30,10 +30,10 @@
         return str( self.ho )
 
     def setBytes( self, bytes ):
-        self.ho = unpack( "H", bytes )
+        self.ho = unpack( "H", bytes )[0]
 
     def setNetworkBytes( self, bytes ):
-        self.ho = unpack( "!H", bytes )
+        self.ho = unpack( "!H", bytes )[0]
 
     def getBytes( self ):
         return pack( "H", self.ho )
@@ -51,7 +51,11 @@
         self.ho = ntohs( x )
 
     def getNetworkInteger( self ):
+        print "%s %s" % (type(self.ho), self.ho)
         return htons( self.ho )
+    
+    def getPCS(self):
+        return self.getInteger()
 
     def __eq__( self, x ):
         if isinstance( x, int ):

==== //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/payload.py#4 (text+ko) ====


==== //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/pseudoipv4.py#3 (text+ko) ====


==== //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/segmentBuffer.py#3 (text+ko) ====

@@ -4,7 +4,9 @@
 @author: zach
 '''
 
-class segmentBuffer(list):
+from pcsextension.decorators import prop
+
+class segmentBuffer(object):
     '''
     The segmentBuffer class allows pseudo-random access to a list, given an
     initial offset, and maximum offset.  The benefit of this is that we get
@@ -14,103 +16,219 @@
     using 4GB+ of memory, or use the segmentBuffer class.
     
     Example:
-    >>> x = segmentBuffer(base=100,max=110)
-    >>> x += ['a','b','c']
-    >>> len(x)
-    3
-    >>> x[100:102]
-    ['a','b','c']
-    
-    >>> y = segmentBuffer(base = 5, max=10)
-    >>> y += range(0,10)
-    >>> y
-    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
-    >>> y[5]
+    >>> from segmentBuffer import *
+    >>> sb = segmentBuffer(base=10, limit=15)
+    >>> sb += range(8)
+    >>> sb[10]    # The first item is at [10]
     0
-    >>> y[5:4]
-    [0, 1, 2, 3, 4, 5, 6, 7, 8]
-    >>> y[5:5]
-    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
-
-    
+    >>> sb[11]    # The second item is at [11]
+    1
+    >>> sb        # However, the items are in the proper order
+    [0, 1, 2, 3, 4, 5, 6, 7]
+    >>> sb[10:]   # And are properly sliced
+    [0, 1, 2, 3, 4, 5, 6, 7]
+    >>> sb[10:2]  # And the slices wrap-around at limit
+    [0, 1, 2, 3, 4, 5, 6]
+    >>> sb[2:10]  # And slices stop when it hits a gap.
+    [7]
+    >>> sb == sb[10:] # Truth works just fine.
+    True
+    >>> sb += 2   # The offset is incremented easily
+    >>> sb        # Notice that the first two items are deleted
+    [2, 3, 4, 5, 6, 7]
+    >>> len(sb)    # The length indeed goes down 8->2
+    6
+    >>> sb += range(100,200)
+    >>> len(sb)    # Adding 100 items keeps the correct length
+    15
+    >>> sb         # Only items up to the limit are added
+    [2, 3, 4, 5, 6, 7, 100, 101, 102, 103, 104, 105, 106, 107, 108]
+    >>> sb2 = sb + range(300,400)
+    >>> sb is sb2  # Addition operator returns a new object.
+    False
+    >>> sb2 += 3   # The other object can be incremented
+    >>> [i for i in sb if i not in sb2]
+    [2, 3, 4]      # Just an example to show the difference
+    >>> sb[12:15]  # This shows that the items were taken off the front
+    [2, 3, 4]
+    >>> sb[12:2]
+    [2, 3, 4, 5, 6]
+    >>> sb2[12:2]  # The indexes for the remaining items do not change
+    [5, 6]         # Although the deleted items are gone.
+    >>> sb
+    [2, 3, 4, 5, 6, 7, 100, 101, 102, 103, 104, 105, 106, 107, 108]
+    >>> sb2
+    [5, 6, 7, 100, 101, 102, 103, 104, 105, 106, 107, 108]
     '''
 
     __MAX = (2**31) - 1
+    limit = __MAX
+    buffer = []
+    
+    @prop
+    def base(): 
+        '''
+        Base index. Advancing the base index will remote items from the front of the list.
+        The base can only be incremented in value, and will be wrapped at 'limit'.
+        
+        '''
+        return {'fset': lambda self,x: self.setBase(x)}
     _base = 0
-    _max = __MAX
+    
+    @prop
+    def nextIndex():
+        return {'fget': lambda self: self.getNextIndex(),# (len(self) + self.base),
+                'fset': None}
+        
+    def getNextIndex(self):
+        return len(self)+self.base
+    
+    def setBase(self, x):
+        '''
+        Modifies the base.  Erases any existing items up to, but excluding, the
+        new base.
+        '''
+        # print "Setting base to %i" % x
+        # print "... %s if %s < %s else %s" % (self._getIndex(x), x, len(self), len(self))
+        # deleteUpToOffset = self._getIndex(x) if x < len(self) else len(self)
+        deleteUpToOffset = min(self._getIndex(x),len(self))
+        # print "Deleting up to offset %s" % deleteUpToOffset
+        self._base = x % self.limit
+        # print "_base is now %i" % self._base
+        # print "Buffer before delete: %s" % self.buffer 
+        del self.buffer[0:deleteUpToOffset]
+        # print "Buffer after delete: %s" % self.buffer
+
+    def __contains__(self,x):
+        return self.buffer.__contains__(x)
+    
+    def __iadd__(self,x):
+        '''
+        Adding an integer has the effect of advancing the 'base', and
+        deleting the leading elements.  'base' is modulo'd by 'limit' so
+        that it will properly wrap around to zero if needed, while retaining
+        the same indexes for items that are not deleted.
+        
+        NOTE: If the list is full, no more items can be 'added'.
+        '''
+        if type(x) in (int,long):
+            self.base += x
+        elif type(x) in (list,tuple,segmentBuffer):
+            
+            self.buffer += x
+            
+            # Prevent the list from being extended too long.
+            if len(self) > self.limit:
+                # Note that we are referring to the 'limit'th item directly, not
+                # its redirected index.  This is because we are actually deleting
+                # items beyond the boundary that should not exist.                
+                del self.buffer[self.limit:self.__MAX]
+                
+                
+        # retVal = segmentBuffer(base=self.base, limit=self.limit)
+        # retVal.buffer = self.buffer[:]
+        
+        return self
+
+    def __add__(self,x):
+        tmp = segmentBuffer(self)
+        tmp += x
+        return tmp
+
+    def __len__(self):
+        return self.buffer.__len__()
     
     def __eq__(self, x):
-        if not isinstance(x,list) and not isinstance(x,tuple):
+        '''
+        Compares to a list or tuple object.
+        For whatever reason, list.__eq__ doesn't evaluate properly.
+        '''
+        # Only compare to list, tuples, or the same class
+        if type(x) not in (list,tuple,type(self)):
             return False
         
+        # If we're not the same length, DEF not the same.
         if len(self) != len(x):
             return False
         
-        for i in range(0,len(self)):
-            if self[i] != x[i]:
+        # If we are comparing against a list or tuple, compare it to
+        # our internal buffer.
+        comparisonList = self.buffer
+        
+        # Otherwise, we are comparing against a segmentBuffer.  Compare
+        # it to ourself.
+        if type(x) == type(self):
+            
+            # Check the other fields
+            if x.limit != self.limit or x.base != self.base:
+                return False
+
+            comparisonList = self       
+        
+        # Iterate over each item
+        for i in range(len(self)):            
+            if comparisonList[i] != x[i]:
                 return False
-            
+                        
+        # Haven't found any differences.
         return True
     
-    def __init__(self, base=None, max=None):
-        list.__init__(self)
+    def __init__(self, copyList=None, base=0, limit=2**32):
+        if type(copyList) == segmentBuffer:
+            self.buffer = copyList.buffer[:]
+            self.base = copyList.base
+            self.limit = copyList.limit
+            
+            # Don't proceed to set other values below.  Just use the 
+            # copied values.
+            return
+        elif type(copyList) in (list,tuple):
+            self.buffer = copyList
+        else:
+            self.buffer = []
         
-        if base > 0:
-            self._base = base
-        if max > 0:
-            self._max = max
+        if base >= 0:
+            self.base = base
+        if limit >= 0:
+            self.limit = limit
 
     def __delslice__(self, i, j):
-        # print "delslice(%s,%s)" % (i,j)
-        for item in range(i,j):
-            del self[item]
+        for (ii,jj) in self._getIndices(i, j):
+            self.buffer.__delslice__(ii,jj)
             
     def __delitem__(self,i):
-        # print "delitem(%s)" % (i)
-        
         index = self._getIndex(i)
-        if index is None:
-            raise IndexError, "list index out of range"
-        
-        list.__delitem__(self, index)
+        self.buffer.__delitem__(index)
     
     def __getslice__(self, i, j):
-       # # print "getslice(%s,%s)" % (i,j)
        # return [list.__getitem__(self,item) for item in self._getIndices(i, j)]
        #  return [self[item] for item in range(i,j) ]
        
-       retVal = []
-       for (a,b) in self._getIndices(i, j):
-           retVal += list.__getslice__(self, a, b)
-       return retVal
+        retVal = []
+        for (a,b) in self._getIndices(i, j):
+            retVal += self.buffer.__getslice__(a, b)
+        return retVal
        
     def __getitem__(self,i):
         
         index = self._getIndex(i)
         if index is None: index = self.__MAX
-        return list.__getitem__(self,index)
+        return self.buffer.__getitem__(index)
     
     def __setslice__(self, i, j, k):
-        # print "setslice(%s,%s,%s)" % (i,j,k)
-        #for x,i in enumerate(self._getIndices(i, j)):
-        #    self.__setitem__(x,k[i])
-        
         indices = self._getIndices(i, j)
-        
         offset = 0
         
-        print indices
-        
         for (a,b) in indices:
             num = b-a
-            list.__setslice__(self, a, b, k[offset:offset+num])
+            self.buffer.__setslice__(a, b, k[offset:offset+num])
             offset += num  
         
     def __setitem__(self, i, x):
         
         index = self._getIndex(i)
         if index is None: index = self.__MAX
-        list.__setitem__(self, index, x)
+        self.buffer.__setitem__(index, x)
         
         
     def _getIndices(self, i, j):
@@ -133,7 +251,7 @@
 #        else:
 #            jj = self._getIndex(j)
 #            if jj is None:
-#                jj = self._max - self._base
+#                jj = self.limit - self.base
         
         retVal = ()
         
@@ -160,92 +278,70 @@
         Retrieves the actual index of an item.
         '''
         
-        # For this method, assume that base=5, max=10.
-        print "getIndex(%i)" % i
+        # For this method, assume that base=5, limit=10.
         retVal = None
         
         # Special cases defined for quickness.
         # The base is always at ZERO offset.
-        if i == self._base:
+        if i == self.base:
             return 0
-        # 'Max' is the "END" of the list, AND it is the 0th item.
+        # 'limit' is the "END" of the list, AND it is the 0th item.
         # '__MAX' is the absolute maximum value, and is the value provided
         # when we are given an empty-ended slice, i.e [3:]
-        elif i == self._max or i == self.__MAX:
-            return (self._max - self._base)
-        
+        elif i == self.limit:
+            return (self.limit - self.base)
+        elif  i == self.__MAX:
+            return len(self)
 #        elif i == self.__MAX:
-#            return self._getIndex(self._max) 
+#            return self._getIndex(self.limit) 
         
         # i.e. self[12], should refer to self[2].
         # i.e. self[10], should refer to self[0]
-        elif self._max < i:
-            return self._getIndex(i - self._max)
-            # retVal = self._getIndex(i - self._max)
+        elif self.limit < i:
+            return self._getIndex(i - self.limit)
+            # retVal = self._getIndex(i - self.limit)
             
         # i.e. self[6] is stored at [1], or i-base.
-        elif self._base < i < self._max:
-            retVal = i - self._base
+        elif self.base < i < self.limit:
+            retVal = i - self.base
             
-        # i.e. self[2] is stored at [10+2], or max+i 
-        elif 0 <= i < self._base:
-            retVal = self._getIndex(self._max) + i
+        # i.e. self[2] is stored at [10+2], or limit+i 
+        elif 0 <= i < self.base:
+            retVal = self._getIndex(self.limit) + i
         
         # i.e. self[-1] is stored at the real self[-1].
         elif i < 0:
-            retVal = self._getIndex(self._max + i) # Note we are adding a negative
+            retVal = len(self) + i
+            
+        if retVal > len(self):
+            return None
             
         return retVal 
-#
-#        if i == self.__MAX:
-#            # return self._getIndex(self._max - 1) + 1
-#            return len(self)
-#        
-#        if i == self._max:
-#            return self._max - self._base
-#        
-#        # Negative indices count from the back...
-#        if i < 0:
-#            # Make sure it's not TOO negative...
-#            if abs(i) > self._max:
-#                retVal = self._getIndex(i + self._max)
-#            else:
-#                retVal = len(self) + i # Note that we "add" a negative
-#            
-#        elif self._max <= i:
-#            # retVal = None # Still none...
-#            return 
-#            
-#        # If it's less than the base, then the index 0 is the max'th item, and
-#        # go from there.
-#        elif i < self._base:
-#            # Wrap...
-#            retVal = self._getIndex(self._max) + i
-#    
-#        # If it's over the max, decrement and re-do.
-#        # elif self._max <= i:
-#        #    retVal = self._getIndex(i - self._max)
-#        
-#        # The N'th item is offset from the base.
-#        elif self._base <= i < self._max:
-#            retVal = i - self._base
-#            
-#        else:
-#            print 'error: could not calculate index for %s' % i        
-#        # print "%s -> %s" % (i,retVal)
-#        
-#        # Don't return an out-of-bounds index...
-#        if retVal >= len(self):
-#            # print "OOB"
-#            return None
-#        
-#        return retVal
     
+    #def __repr__(self):
+    #    # return str( [self[i] for i in self._getIndices(0,len(self))] )
+    #    return str( self.buffer[:] )
+    #    # return self.__repr__()
+        
     def __repr__(self):
-        print 'repr!!'
-        # return str( [self[i] for i in self._getIndices(0,len(self))] )
-        return str( self[:] )
+        return '%s(limit=%i,base=%i,copyList=%s+%s)' % \
+            (self.__class__.__name__, self.limit, self.base, self[self.base:0], self[self.limit:] if self._getIndex(0) is not None else [])
+    
+    def __iter__(self):
+        return self.buffer.__iter__()
+    
+    def update(self, newBuffer):
+        
+        if newBuffer is self:
+            return self
+        
+        if type(newBuffer) == type(self):
+            # return '... is new buffer'
+            return newBuffer
         
-    def __str__(self):
-        print 'str!!'
-        return self.__repr__()+        if type(newBuffer) in (list,tuple):
+            # return '... is just a list or tuple'
+            self.buffer = newBuffer[:]
+             
+        return self
+            
==== //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/sniffLocalhost.py#5 (text+ko) ====


==== //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/tcpConstructor.py#6 (text+ko) ====


==== //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/tcpFilter.py#7 (text+ko) ====

@@ -10,23 +10,31 @@
 from pcs.packets.tcp import tcp
 from pcs.packets.tcpv6 import tcpv6
 from pcs.packets.ethernet import ethernet
+from pcsextension import wireSharkFormatBytes
 from pcsextension.ipAddress import IpAddress
 from pcsextension.networkPort import NetworkPort
 from pcsextension import findIpLayer, findTcpLayer
+from pcsextension.decorators import prop
 import pprint
+import binascii
+from threading import RLock
 class tcpFilter( object ):
 
     log = None
     pcapHandle = None
     doRead = False
-
+    lock = RLock()
+    
     @prop
     def interface():
-        return {'doc': 'Interface used with the TCP Filter.  If this interface is different from the'
-        ' current interface, the current one is closed, and the new one is opened automatically.',
-                'fset': lambda self, x: self.openInterface( x ) }
-    self._interface = None
-
+        '''
+        Interface used with the TCP Filter.  If this interface is different
+        from the current interface, the current one is closed, and the new 
+        one is opened automatically.
+        '''
+        return {'fset': lambda self, x: self.openInterface( x ) }
+    _interface = None
+    
     def __init__( self, interfaceName ):
         self.log = tcplog( self )
         self.interface = interfaceName
@@ -34,73 +42,143 @@
     def openInterface( self, interfaceName ):
         # Is it already opened with this interface?
         if self.interface is interfaceName:
-            log.info( 'Tried to re - open same interface: % s' % self.interface )
-            return
-        else:
-            self._interface = interfaceName
+            self.log.debug( 'Tried to re-open same interface: % s' % self.interface )
 
         # Open the interface
         try:
-            self.pcapHandle = PcapConnector( self.interface )
-            self.log.info( "Opened %s" % self.interface )
-            # self.pcapHandle = IP4Connector();
+            self.pcapHandle = PcapConnector( interfaceName )
+            self.log.info( "Opened %s" % interfaceName )
+            self._interface = interfaceName
         except:
-            self.log.error( "Could not open interface %s" % self.interface )
+            self.log.error( "Could not open interface %s" % interfaceName )
+
+    def getPcapConnector(self):
+        '''
+        Returns the PCAP handle.
+        '''
+        return self.pcapHandle
 
     def read( self ):
+        '''
+        Reads a packet in the form of a string of bytes from the PCAP handle.
+        '''
         return self.pcapHandle.readpkt()
 
     def write( self, bytes ):
-        self.log.pktsent( pprint.pformat( bytes ) )
-        self.pcapHandle.write( bytes, len( bytes ) )
+        '''
+        Writes a string of bytes to the PCAP handle.
+        '''
+        return self.pcapHandle.write( bytes, len( bytes ) )    
+    
+    def setBlocking(self, block=False):
+        '''
+        Sets the blocking mode on the PCAP handle.
+        '''
+        self.log.debug("Setting blocking mode to %s" % block) 
+        self.pcapHandle.file.setnonblock(block)
+    
+    def packetDestinedForIP(self, packet, ip):
+        '''
+        Returns True if the provided packet has a IP layer and its destination
+        is the provided IP address.
+        Returns False otherwise.
+        '''
+        # If the IP address is a string ("127.0.0.1") or byte array ('\x7f\x00\x00\x01')
+        # we need to convert it into an integer representation of the same.
+        ip = IpAddress(ip).getPCS()
+            
+        ipLayer = findIpLayer(packet)
+        if ipLayer is None:
+            return False
+        
+        if ip == ipLayer.dst:
+            return True
+        
+        return False
+    
+    def packetDestinedForPort(self, packet, port):
+        '''
+        Returns True if the provided packet has a TCP layer and its destination
+        is the provided port.
+        Returns False otherwise.
+        '''
+        port = NetworkPort( port ).getPCS()
+            
+        tcpLayer = findTcpLayer( packet )
+        if tcpLayer is None:
+            return False
+        
+        if port == tcpLayer.dport:
+            return True
+        
+        return False
+
 
-    def readFilteredByIP( self, ip ):
+    def readFilteredByIP( self, ip, block=True ):
         """
-        Reads packets until a packet is found going either to or from the specified IP address
-        is discovered.  Returns the first matching packet.
+        Reads packets until a packet is found that is destined to the specified
+        IP address is discovered.  Returns the first matching packet.
         @param ip IpAddress or dotted-quad string
-        @return A pcs.Packet object
+        @return A pcs.Packet object, or None if there are no packets on the
+        queue and non-blocking IO is used.
         """
-
-#        if isinstance(ipAddress,int):
-#            ipAddress = intToBytes(ipAddress)
-
-        # If the IP address is a string ("127.0.0.1") or byte array ('\x7f\x00\x00\x01')
-        # we need to convert it into an integer representation of the same.
-        if isinstance( ip, str ):
-            tmp = IpAddress()
-            tmp.setAscii( ip )
-            ip = tmp
-
+        
+        self.log.debug("Waiting on lock")
+        self.lock.acquire(blocking=True)
+        self.log.debug("Have lock")
+        self.setBlocking(block)
+        
+        packet = None
+        
         while True:
+            print "loop"
             packet = self.read()
+            
+            # None will only return [1] on error or [2] if using asynchronous 
+            # I/O and there are no waiting packets.
+            if packet is None or self.packetDestinedForIP(packet, ip):
+                break
+            
+        self.lock.release()
+        self.log.debug("Released lock")
+        
+        if packet is None:
+            self.log.debug("Returning NONE")
+            
+        return packet
 
-            ipLayer = findIpLayer( packet )
-
-            if ipLayer == None:
-                continue
-
-            # srcIP.setPCS( ipLayer.src )
-            # dstIP.setPCS( ipLayer.dst )
-
-            if ipLayer.src == ip.getPCS() or ipLayer.dst == ip.getPCS():
-                return packet
-
-    def readFilteredByTuple( self, ipAddress, port ):
+    def readFilteredByTuple( self, ipAddress, port, block=True ):
         """
-        Reads packets until a packet is found going either to or from [1] the specified
-        IP address and [2] the specified port.  Returns the first matching packet.
+        Reads packets until a packet is found that is destined to:
+            [1] the specified IP address 
+            [2] the specified port.  
+        Returns the first matching packet.
+        
         @param IpAddress object or dotted-quad string ('127.0.0.1')
         @param NetworkPort object or integer port number.
-        @return A pcs.Packet object.

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200908030253.n732rrg5036111>