OLD | NEW |
| (Empty) |
1 # -*- test-case-name: twisted.pair.test.test_ip -*- | |
2 # Copyright (c) 2001-2004 Twisted Matrix Laboratories. | |
3 # See LICENSE for details. | |
4 | |
5 # | |
6 | |
7 | |
8 """Support for working directly with IP packets""" | |
9 | |
10 import struct | |
11 import socket | |
12 | |
13 from twisted.internet import protocol | |
14 from twisted.pair import raw | |
15 from zope.interface import implements | |
16 | |
17 | |
18 class IPHeader: | |
19 def __init__(self, data): | |
20 | |
21 (ihlversion, self.tos, self.tot_len, self.fragment_id, frag_off, | |
22 self.ttl, self.protocol, self.check, saddr, daddr) \ | |
23 = struct.unpack("!BBHHHBBH4s4s", data[:20]) | |
24 self.saddr = socket.inet_ntoa(saddr) | |
25 self.daddr = socket.inet_ntoa(daddr) | |
26 self.version = ihlversion & 0x0F | |
27 self.ihl = ((ihlversion & 0xF0) >> 4) << 2 | |
28 self.fragment_offset = frag_off & 0x1FFF | |
29 self.dont_fragment = (frag_off & 0x4000 != 0) | |
30 self.more_fragments = (frag_off & 0x2000 != 0) | |
31 | |
32 MAX_SIZE = 2L**32 | |
33 | |
34 class IPProtocol(protocol.AbstractDatagramProtocol): | |
35 implements(raw.IRawPacketProtocol) | |
36 | |
37 def __init__(self): | |
38 self.ipProtos = {} | |
39 | |
40 def addProto(self, num, proto): | |
41 proto = raw.IRawDatagramProtocol(proto) | |
42 if num < 0: | |
43 raise TypeError, 'Added protocol must be positive or zero' | |
44 if num >= MAX_SIZE: | |
45 raise TypeError, 'Added protocol must fit in 32 bits' | |
46 if num not in self.ipProtos: | |
47 self.ipProtos[num] = [] | |
48 self.ipProtos[num].append(proto) | |
49 | |
50 def datagramReceived(self, | |
51 data, | |
52 partial, | |
53 dest, | |
54 source, | |
55 protocol): | |
56 header = IPHeader(data) | |
57 for proto in self.ipProtos.get(header.protocol, ()): | |
58 proto.datagramReceived(data=data[20:], | |
59 partial=partial, | |
60 source=header.saddr, | |
61 dest=header.daddr, | |
62 protocol=header.protocol, | |
63 version=header.version, | |
64 ihl=header.ihl, | |
65 tos=header.tos, | |
66 tot_len=header.tot_len, | |
67 fragment_id=header.fragment_id, | |
68 fragment_offset=header.fragment_offset, | |
69 dont_fragment=header.dont_fragment, | |
70 more_fragments=header.more_fragments, | |
71 ttl=header.ttl, | |
72 ) | |
OLD | NEW |