diff --git a/__init__.py b/__init__.py index 3bd50cd..e821df5 100755 --- a/__init__.py +++ b/__init__.py @@ -115,16 +115,7 @@ def assert_in(a, *b): class BitVector: def __init__(self, i=0, length=None): - if type(i) == type(1): - self._val = i - if length is not None: - self._len = length - else: - self._len = 0 - while i > 0: - i >>= 1 - self._len += 1 - else: + try: self._val = 0 for c in i: self._val <<= 8 @@ -133,6 +124,15 @@ class BitVector: self._len = length else: self._len = len(i) * 8 + except TypeError: + self._val = i + if length is not None: + self._len = length + else: + self._len = 0 + while i > 0: + i >>= 1 + self._len += 1 def __len__(self): return self._len diff --git a/crypto.py b/crypto.py index 48c6b7c..c40da5e 100644 --- a/crypto.py +++ b/crypto.py @@ -163,7 +163,7 @@ def neighbors(txt): ## def rot(n, txt): - """Caesar cipher""" + """Caesar cipher only across letters""" out = "" for c in txt: @@ -178,8 +178,11 @@ def rot(n, txt): return out +def caesar(n, txt): + return [chr((ord(c) + n) % 256) for c in txt] + def caesars(txt): - return [rot(i, txt) for i in range(26)] + return [caesar(i, txt) for i in range(256)] # Tabula recta tabula_recta = caesars('ABCDEFGHIJKLMNOPQRSTUVWXYZ') diff --git a/gapstr.py b/gapstr.py index bff3e2b..e7303d8 100755 --- a/gapstr.py +++ b/gapstr.py @@ -30,26 +30,29 @@ class GapString: self.length += len(i) self.contents.append(i) except TypeError: - self.length += int(i) - self.contents.append(int(i)) + self.length += i + self.contents.append(long(i)) def __str__(self): ret = [] for i in self.contents: - if isinstance(i, int): + try: ret.append(self.drop * i) - else: + except TypeError: ret.append(i) return ''.join(ret) def __iter__(self): for i in self.contents: - if isinstance(i, int): - for j in range(i): - yield self.drop - else: + try: for c in i: yield c + except TypeError: + for j in range(i): + yield self.drop + + def __nonzero__(self): + return self.length > 0 def hasgaps(self): for i in self.contents: @@ -62,10 +65,10 @@ class GapString: d = __init__.HexDumper(fd) for i in self.contents: - if isinstance(i, int): + try: for j in range(i): d.dump_drop() - else: + except TypeError: for c in i: d.dump_chr(c) d.finish() @@ -90,11 +93,11 @@ class GapString: # Trim off the beginning while start >= 0: i = new.contents.pop(0) - if isinstance(i, int): + try: start -= i if start < 0: new.contents.insert(0, -start) - else: + except TypeError: start -= len(i) if start < 0: new.contents.insert(0, i[start:]) @@ -102,11 +105,11 @@ class GapString: # Trim off the end while l >= 0: i = new.contents.pop() - if isinstance(i, int): + try: l -= i if l < 0: new.contents.append(-l) - else: + except TypeError: l -= len(i) if l < 0: new.contents.append(i[:-l]) @@ -127,17 +130,15 @@ class GapString: return new def __xor__(self, mask): - if isinstance(mask, int): - mask = [mask] - if isinstance(mask, str) or isinstance(mask, GapString): + try: mask = [ord(c) for c in mask] + except TypeError: + mask = [mask] masklen = len(mask) new = self.__class__(drop=self.drop) for i in self.contents: - if isinstance(i, int): - new.append(i) - else: + try: r = [] offset = len(new) % masklen for c in i: @@ -145,8 +146,12 @@ class GapString: r.append(chr(o ^ mask[offset])) offset = (offset + 1) % masklen new.append(''.join(r)) + except TypeError: + new.append(i) return new + def startswith(self, what): + return (what == str(self[:len(what)])) if __name__ == '__main__': diff --git a/ip.py b/ip.py index 892742d..976b736 100755 --- a/ip.py +++ b/ip.py @@ -23,6 +23,7 @@ def unpack_nybbles(byte): IP = 0x0800 ARP = 0x0806 +VLAN = 0x8100 ICMP = 1 TCP = 6 @@ -42,6 +43,8 @@ class Frame: self.eth_shost, self.eth_type, p) = unpack('!6s6sH', frame) + if self.eth_type == VLAN: + _, self.eth_type, p = unpack('!HH', p) if self.eth_type == ARP: # ARP self.name, self.protocol = ('ARP', ARP) @@ -184,7 +187,7 @@ class TCP_Resequence: self.lastack = [None, None] self.first = None self.pending = [{}, {}] - self.closed = 0 + self.closed = [False, False] self.midstream = False self.hash = 0 @@ -198,7 +201,7 @@ class TCP_Resequence: by __init__. The current value of this function is the state. """ - pass + raise NotImplementedError() def handle_handshake(self, pkt): if not self.first: @@ -237,8 +240,12 @@ class TCP_Resequence: # Does this ACK after the last output sequence number? seq = self.lastack[idx] if pkt.ack > seq: + if self.closed[idx]: + # XXX: If the next thing happens, that means you need to + # return a gapstring to deal with dropped frames + assert (pkt.ack == seq + 1) + return pending = self.pending[xdi] - # Get a sorted list of sequence numbers keys = pending.keys() keys.sort() @@ -259,7 +266,11 @@ class TCP_Resequence: # Hopefully just a retransmit... del pending[key] continue + elif key == seq: + # Default + pass elif key > seq: + # Dropped frame(s) gs.append(key - seq) seq = key frame = pending[key] @@ -267,6 +278,7 @@ class TCP_Resequence: seq += len(frame.payload) del pending[key] if seq != pkt.ack: + # Drop at the end gs.append(pkt.ack - seq) self.lastack[idx] = pkt.ack @@ -276,14 +288,12 @@ class TCP_Resequence: # Is it a FIN or RST? if pkt.flags & (FIN | RST): - self.lastack[xdi] = pkt.seq + 1 - self.closed += 1 - if self.closed == 2: + self.closed[idx] = True + if self.closed == 3: # Warn about any unhandled packets if self.pending[0] or self.pending[1]: warnings.warn('Dropping unhandled frames after shutdown' % pkt) self.handle = self.handle_drop - ret = None return ret