Imported Upstream version 12.1.0
[contrib/python-twisted.git] / twisted / pair / rawudp.py
1 # -*- test-case-name: twisted.pair.test.test_rawudp -*-
2 # Copyright (c) Twisted Matrix Laboratories.
3 # See LICENSE for details.
4
5 #
6
7 """Implementation of raw packet interfaces for UDP"""
8
9 import struct
10
11 from twisted.internet import protocol
12 from twisted.pair import raw
13 from zope.interface import implements
14
15 class UDPHeader:
16     def __init__(self, data):
17
18         (self.source, self.dest, self.len, self.check) \
19                  = struct.unpack("!HHHH", data[:8])
20
21 class RawUDPProtocol(protocol.AbstractDatagramProtocol):
22     implements(raw.IRawDatagramProtocol)
23     def __init__(self):
24         self.udpProtos = {}
25
26     def addProto(self, num, proto):
27         if not isinstance(proto, protocol.DatagramProtocol):
28             raise TypeError, 'Added protocol must be an instance of DatagramProtocol'
29         if num < 0:
30             raise TypeError, 'Added protocol must be positive or zero'
31         if num >= 2**16:
32             raise TypeError, 'Added protocol must fit in 16 bits'
33         if num not in self.udpProtos:
34             self.udpProtos[num] = []
35         self.udpProtos[num].append(proto)
36
37     def datagramReceived(self,
38                          data,
39                          partial,
40                          source,
41                          dest,
42                          protocol,
43                          version,
44                          ihl,
45                          tos,
46                          tot_len,
47                          fragment_id,
48                          fragment_offset,
49                          dont_fragment,
50                          more_fragments,
51                          ttl):
52         header = UDPHeader(data)
53         for proto in self.udpProtos.get(header.dest, ()):
54             proto.datagramReceived(data[8:],
55                                    (source, header.source))