def CheckRecvfrom(self, family, addr): s = self._BuildSocket(family, addr) addr = s.getsockname() sockaddr = csocket.Sockaddr(addr) s.sendto("foo", addr) data, addr = csocket.Recvfrom(s, 4096, 0) self.assertEqual("foo", data) self.assertEqual(sockaddr, addr) s.close()
def testPacketCount(self): self.map_fd = CreateMap(BPF_MAP_TYPE_HASH, 4, 4, 10) key = 0xf0f0 bpf_prog = BpfMov64Reg(BPF_REG_6, BPF_REG_1) bpf_prog += BpfLoadMapFd(self.map_fd, BPF_REG_1) bpf_prog += BpfMov64Imm(BPF_REG_7, key) bpf_prog += BpfStxMem(BPF_W, BPF_REG_10, BPF_REG_7, -4) bpf_prog += BpfMov64Reg(BPF_REG_8, BPF_REG_10) bpf_prog += BpfAlu64Imm(BPF_ADD, BPF_REG_8, -4) bpf_prog += BpfMov64Reg(BPF_REG_2, BPF_REG_8) bpf_prog += BpfFuncLookupMap() bpf_prog += BpfJumpImm(BPF_AND, BPF_REG_0, 0, 10) bpf_prog += BpfLoadMapFd(self.map_fd, BPF_REG_1) bpf_prog += BpfMov64Reg(BPF_REG_2, BPF_REG_8) bpf_prog += BpfStMem(BPF_W, BPF_REG_10, -8, 1) bpf_prog += BpfMov64Reg(BPF_REG_3, BPF_REG_10) bpf_prog += BpfAlu64Imm(BPF_ADD, BPF_REG_3, -8) bpf_prog += BpfMov64Imm(BPF_REG_4, 0) bpf_prog += BpfFuncUpdateMap() bpf_prog += BpfLdxMem(BPF_W, BPF_REG_0, BPF_REG_6, 0) bpf_prog += BpfExitInsn() bpf_prog += BpfMov64Reg(BPF_REG_2, BPF_REG_0) bpf_prog += BpfMov64Imm(BPF_REG_1, 1) bpf_prog += BpfRawInsn(BPF_STX | BPF_XADD | BPF_W, BPF_REG_2, BPF_REG_1, 0, 0) bpf_prog += BpfLdxMem(BPF_W, BPF_REG_0, BPF_REG_6, 0) bpf_prog += BpfExitInsn() insn_buff = ctypes.create_string_buffer(bpf_prog) # this program loaded is used to counting the packet transmitted through # a target socket. It will store the packet count into the eBPF map and we # will verify if the counting result is correct. self.prog_fd = BpfProgLoad(BPF_PROG_TYPE_SOCKET_FILTER, ctypes.addressof(insn_buff), len(insn_buff), BpfInsn._length) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0) sock.settimeout(1) BpfProgAttachSocket(sock.fileno(), self.prog_fd) addr = "127.0.0.1" sock.bind((addr, 0)) addr = sock.getsockname() sockaddr = csocket.Sockaddr(addr) packet_count = 100 for i in xrange(packet_count): sock.sendto("foo", addr) data, retaddr = csocket.Recvfrom(sock, 4096, 0) self.assertEqual("foo", data) self.assertEqual(sockaddr, retaddr) self.assertEquals(LookupMap(self.map_fd, key).value, packet_count)
def SocketUDPLoopBack(packet_count, version, prog_fd): family = {4: socket.AF_INET, 6: socket.AF_INET6}[version] sock = socket.socket(family, socket.SOCK_DGRAM, 0) if prog_fd is not None: BpfProgAttachSocket(sock.fileno(), prog_fd) net_test.SetNonBlocking(sock) addr = {4: "127.0.0.1", 6: "::1"}[version] sock.bind((addr, 0)) addr = sock.getsockname() sockaddr = csocket.Sockaddr(addr) for i in xrange(packet_count): sock.sendto("foo", addr) data, retaddr = csocket.Recvfrom(sock, 4096, 0) assert "foo" == data assert sockaddr == retaddr return sock
def testRecvfromLeak(self): s = socket(AF_INET6, SOCK_DGRAM, 0) s.bind(("::1", 0)) # Call shutdown on another thread while a recvfrom is in progress. net_test.SetSocketTimeout(s, 2000) def ShutdownSocket(): time.sleep(0.5) self.assertRaisesErrno(ENOTCONN, s.shutdown, SHUT_RDWR) t = threading.Thread(target=ShutdownSocket) t.start() # This could have been written with just "s.recvfrom", but because we're # testing for a bug where the kernel returns garbage, it's probably safer # to call the syscall directly. data, addr = csocket.Recvfrom(s, 4096) self.assertEqual("", data) self.assertEqual(None, addr)
def testProgLoad(self): bpf_prog = BpfMov64Reg(BPF_REG_6, BPF_REG_1) bpf_prog += BpfLdxMem(BPF_W, BPF_REG_0, BPF_REG_6, 0) bpf_prog += BpfExitInsn() insn_buff = ctypes.create_string_buffer(bpf_prog) # Load a program that does nothing except pass every packet it receives # It should not block the packet transmission otherwise the test fails. self.prog_fd = BpfProgLoad(BPF_PROG_TYPE_SOCKET_FILTER, ctypes.addressof(insn_buff), len(insn_buff), BpfInsn._length) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0) sock.settimeout(1) BpfProgAttachSocket(sock.fileno(), self.prog_fd) addr = "127.0.0.1" sock.bind((addr, 0)) addr = sock.getsockname() sockaddr = csocket.Sockaddr(addr) sock.sendto("foo", addr) data, addr = csocket.Recvfrom(sock, 4096, 0) self.assertEqual("foo", data) self.assertEqual(sockaddr, addr)