rawudp.py 1.8 KB

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