def parser(self): """ Get a function for parsing a datagram read from a I{tun} device. @return: A function which accepts a datagram exactly as might be read from a I{tun} device. The datagram is expected to ultimately carry a UDP datagram. When called, it returns a L{list} of L{tuple}s. Each tuple has the UDP application data as the first element and the sender address as the second element. """ datagrams = [] receiver = DatagramProtocol() def capture(*args): datagrams.append(args) receiver.datagramReceived = capture udp = RawUDPProtocol() udp.addProto(12345, receiver) ip = IPProtocol() ip.addProto(17, udp) def parse(data): # TUN devices omit the ethernet framing so we can start parsing # right at the IP layer. ip.datagramReceived(data, False, None, None, None) return datagrams return parse
def main(reactor): startLogging(stdout, setStdout=False) udp = RawUDPProtocol() udp.addProto(42, MyProto()) ip = IPProtocol() ip.addProto(17, udp) eth = EthernetProtocol() eth.addProto(0x800, ip) port = TuntapPort(interface='tap0', proto=eth, reactor=reactor) port.startListening() # Run forever return Deferred()
def recv(self, nbytes): """ Receive a datagram sent to this port using the L{MemoryIOSystem} which created this object. This behaves like L{socket.socket.recv} but the data being I{sent} and I{received} only passes through various memory buffers managed by this object and L{MemoryIOSystem}. @see: L{socket.socket.recv} """ data = self._system._openFiles[self._fileno].writeBuffer.popleft() datagrams = [] receiver = DatagramProtocol() def capture(datagram, address): datagrams.append(datagram) receiver.datagramReceived = capture udp = RawUDPProtocol() udp.addProto(12345, receiver) ip = IPProtocol() ip.addProto(17, udp) mode = self._system._openFiles[self._fileno].tunnelMode if (mode & TunnelFlags.IFF_TAP.value): ether = EthernetProtocol() ether.addProto(0x800, ip) datagramReceived = ether.datagramReceived else: datagramReceived = lambda data: ip.datagramReceived( data, None, None, None, None) dataHasPI = not (mode & TunnelFlags.IFF_NO_PI.value) if dataHasPI: # datagramReceived can't handle the PI, get rid of it. data = data[_PI_SIZE:] datagramReceived(data) return datagrams[0][:nbytes]
def main(): # Unbuffered mode makes it possible to do things like tail the log and # get semi-realtime results. It should also prevent any lines from # being written non-atomically (if partial lines get written there will # be some mild corruption in the file). This depends on the code using # self._log writing complete lines, of course. log = fdopen(1, "at", 0) tcp = RawTCPProtocol(log) ipv4 = IPProtocol() ipv4.addProto(6, tcp) protocol = EthernetProtocol() protocol.addProto(0x800, ipv4) s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)) while True: data = s.recv(2 ** 16) protocol.datagramReceived(data)
def parser(self): """ Get a function for parsing a datagram read from a I{tap} device. @return: A function which accepts a datagram exactly as might be read from a I{tap} device. The datagram is expected to ultimately carry a UDP datagram. When called, it returns a L{list} of L{tuple}s. Each tuple has the UDP application data as the first element and the sender address as the second element. """ datagrams = [] receiver = DatagramProtocol() def capture(*args): datagrams.append(args) receiver.datagramReceived = capture udp = RawUDPProtocol() udp.addProto(12345, receiver) ip = IPProtocol() ip.addProto(17, udp) ether = EthernetProtocol() ether.addProto(0x800, ip) def parser(datagram): # TAP devices might include a PI header. Strip that off if we # expect it to be there. if self.pi: datagram = datagram[_PI_SIZE:] # TAP devices include ethernet framing so start parsing at the # ethernet layer. ether.datagramReceived(datagram) return datagrams return parser
def __init__(self, server): IPProtocol.__init__(self) protocol = NFLogLoggerProtocol() protocol.nflogServer = server # 6 = TCP self.addProto(6, protocol)