Skip to main content
Tweeted twitter.com/StackCodeReview/status/754594503063957504
deleted 29 characters in body
Source Link

Note: No scapy tag?! How?

Note: No scapy tag?! How?

edited tags
Link
200_success
  • 144.2k
  • 22
  • 188
  • 473
Source Link

Buffer for TCP data

For an assignment (not school), I was supposed to make a "web browser" using Scapy.

While storing the response, I initially thought of

# got an array of packets using sniff() named responses
ans = ""
for pack in responses:
    ans += pack[Raw].load

But that clearly doesn't work if one of the ACKs gets lost or with any of that kind of edge cases where I receive more than one of the same packet or where I receive them in the wrong order. So I wrote a "buffer" class to help handle that.

Code:

class MessageBuffer:
    """
    Used to store a buffer or message
    """
    def __init__(self, init_key):
        """
        Creates a MessageBuffer object that will hold a buffer
        containing all the message that will be received.
        :param init_key: Initial sequence number
        """
        self._buffer = []
        self._init_key = init_key
        self.unsafe = False # Can be set to be able to convert incomplete buffer

    def __setitem__(self, key, value):
        """
        Adds a message into the buffer, automatically extending the storage if needed.
        :param key: the starting point
        :param value: the string to insert
        """
        key -= self._init_key

        if key < 0:
            raise KeyError("Key cannot be less than initial key")

        if key > len(self._buffer): # Missing values
            while key > len(self._buffer):
                self._buffer.append("") # Extend till Ok

            self._buffer.extend(value) # Add all string at the end.

        else:
            try:
                while value:
                    self._buffer[key] = value[0]
                    key += 1
                    value = value[1:]
            except IndexError: # End of self._buffer
                self._buffer.extend(value)

    def is_complete(self):
        """
        :return: True if buffer is complete, otherwise False
        """
        return "" not in self._buffer


    def __str__(self):
        """
        Converts the buffer into a string.
        """
        if not self.unsafe and not self.is_complete():
            raise Exception("Buffer isn't complete")

        return "".join(self._buffer)

I don't have particular concerns, but maybe I have some kind of bad practice or something like that in the code? Also, no usage of the class but in pseudo-python-code (since copying the whole code is pretty long and not what I'm asking about)

def handler_for_packet(packet):
    buffer[packet[TCP].seq] = packet[Raw].load
    if buffer.is_complete():
        send_ack_for_packet(packet)

Note: No scapy tag?! How?