def test_addr_raw_packet(): if not hasattr(rsocket._c, 'sockaddr_ll'): py.test.skip("posix specific test") c_addr_ll = lltype.malloc(rsocket._c.sockaddr_ll, flavor='raw') addrlen = rffi.sizeof(rsocket._c.sockaddr_ll) c_addr = rffi.cast(lltype.Ptr(rsocket._c.sockaddr), c_addr_ll) rffi.setintfield(c_addr_ll, 'c_sll_ifindex', 1) rffi.setintfield(c_addr_ll, 'c_sll_protocol', 8) rffi.setintfield(c_addr_ll, 'c_sll_pkttype', 13) rffi.setintfield(c_addr_ll, 'c_sll_hatype', 0) rffi.setintfield(c_addr_ll, 'c_sll_halen', 3) c_addr_ll.c_sll_addr[0] = 'a' c_addr_ll.c_sll_addr[1] = 'b' c_addr_ll.c_sll_addr[2] = 'c' rffi.setintfield(c_addr, 'c_sa_family', socket.AF_PACKET) # fd needs to be somehow valid s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) fd = s.fileno() w_obj = rsocket.make_address(c_addr, addrlen).as_object(fd, space) lltype.free(c_addr_ll, flavor='raw') assert space.is_true( space.eq( w_obj, space.newtuple([ space.wrap('lo'), space.wrap(socket.ntohs(8)), space.wrap(13), space.wrap(False), space.wrap("abc"), ])))
def test_addr_raw_packet(): if not hasattr(rsocket._c, 'sockaddr_ll'): py.test.skip("posix specific test") c_addr_ll = lltype.malloc(rsocket._c.sockaddr_ll, flavor='raw') addrlen = rffi.sizeof(rsocket._c.sockaddr_ll) c_addr = rffi.cast(lltype.Ptr(rsocket._c.sockaddr), c_addr_ll) rffi.setintfield(c_addr_ll, 'c_sll_ifindex', 1) rffi.setintfield(c_addr_ll, 'c_sll_protocol', 8) rffi.setintfield(c_addr_ll, 'c_sll_pkttype', 13) rffi.setintfield(c_addr_ll, 'c_sll_hatype', 0) rffi.setintfield(c_addr_ll, 'c_sll_halen', 3) c_addr_ll.c_sll_addr[0] = 'a' c_addr_ll.c_sll_addr[1] = 'b' c_addr_ll.c_sll_addr[2] = 'c' rffi.setintfield(c_addr, 'c_sa_family', socket.AF_PACKET) # fd needs to be somehow valid s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) fd = s.fileno() w_obj = rsocket.make_address(c_addr, addrlen).as_object(fd, space) lltype.free(c_addr_ll, flavor='raw') assert space.is_true(space.eq(w_obj, space.newtuple([ space.wrap('lo'), space.wrap(socket.ntohs(8)), space.wrap(13), space.wrap(False), space.wrap("abc"), ])))
def get_addr(hostname, socktype, protocol, port, address_to_fill): hostent = _c.gethostbyname(hostname) if not hostent: raise GAIError(EAI_FAIL) hname, aliases, address_list = gethost_common("", hostent) result = [] for address in address_list: if address.family == _c.AF_INET: a = address.lock(_c.sockaddr_in) rffi.setintfield(a, 'c_sin_port', port & 0xffff) address.unlock() a = address.lock() addr = make_address(a, address.addrlen, address_to_fill) address.unlock() result.append(( address.family, socktype, protocol, "", # XXX canonname? addr)) return result
def get_addr(hostname, socktype, protocol, port, address_to_fill): hostent = _c.gethostbyname(hostname) if not hostent: raise GAIError(EAI_FAIL) hname, aliases, address_list = gethost_common("", hostent) result = [] for address in address_list: if address.family == _c.AF_INET: a = address.lock(_c.sockaddr_in) rffi.setintfield(a, 'c_sin_port', r_uint(port) & 0xffff) address.unlock() a = address.lock() addr = make_address(a, address.addrlen, address_to_fill) address.unlock() result.append((address.family, socktype, protocol, "", # XXX canonname? addr)) return result
def get_addr(hostname, socktype, protocol, port, address_to_fill): hostent = _c.gethostbyname(hostname) if not hostent: raise GAIError(EAI_FAIL) hname, aliases, address_list = gethost_common("", hostent) result = [] for address in address_list: if address.addr.sa_family == _c.AF_INET: a = cast(pointer(address.addr), POINTER(_c.sockaddr_in)).contents a.sin_port = port & 0xffff addr = make_address(pointer(address.addr),address.addrlen,address_to_fill) result.append((address.addr.sa_family, socktype, protocol, "", # XXX canonname? addr)) return result
def getaddrinfo(hostname, servname, family=_c.AF_UNSPEC, socktype=0, protocol=0, flags=0, address_to_fill=None): if not hostname and not servname: raise GAIError(EAI_NONAME) # error checks for hints if flags & ~AI_MASK: raise GAIError(EAI_BADFLAGS) if family not in (_c.AF_UNSPEC, _c.AF_INET): raise GAIError(EAI_FAMILY) if socktype == GAI_ANY: if protocol == GAI_ANY: pass elif protocol == _c.IPPROTO_UDP: socktype = _c.SOCK_DGRAM elif protocol == _c.IPPROTO_TCP: socktype = _c.SOCK_STREAM else: socktype = _c.SOCK_RAW elif socktype == _c.SOCK_RAW: pass elif socktype == _c.SOCK_DGRAM: if protocol not in (_c.IPPROTO_UDP, GAI_ANY): raise GAIError(EAI_BADHINTS) protocol = _c.IPPROTO_UDP elif socktype == _c.SOCK_STREAM: if protocol not in (_c.IPPROTO_TCP, GAI_ANY): raise GAIError(EAI_BADHINTS) protocol = _c.IPPROTO_TCP else: raise GAIError(EAI_SOCKTYPE) port = GAI_ANY # service port if servname: if str_isdigit(servname): port = _c.htons(int(servname)) # On windows, python2.3 uses getattrinfo.c, # python2.4 uses VC2003 implementation of getaddrinfo(). # if sys.version < (2, 4) # socktype = _c.SOCK_DGRAM # protocol = _c.IPPROTO_UDP else: if socktype == _c.SOCK_DGRAM: proto = "udp" elif socktype == _c.SOCK_STREAM: proto = "tcp" else: proto = None sp = _c.getservbyname(servname, proto) if not sp: raise GAIError(EAI_SERVICE) port = sp.c_s_port if socktype == GAI_ANY: s_proto = rffi.charp2str(sp.c_s_proto) if s_proto == "udp": socktype = _c.SOCK_DGRAM protocol = _c.IPPROTO_UDP elif s_proto == "tcp": socktype = _c.SOCK_STREAM protocol = _c.IPPROTO_TCP else: raise GAIError(EAI_PROTOCOL) # hostname == NULL # passive socket -> anyaddr (0.0.0.0 or ::) # non-passive socket -> localhost (127.0.0.1 or ::1) if not hostname: result = [] if family in (_c.AF_UNSPEC, _c.AF_INET): sin = rffi.make(_c.sockaddr_in) try: rffi.setintfield(sin, 'c_sin_family', _c.AF_INET) rffi.setintfield(sin, 'c_sin_port', port) if flags & _c.AI_PASSIVE: s_addr = 0x0 # addrany else: s_addr = 0x0100007f # loopback rffi.setintfield(sin.c_sin_addr, 'c_s_addr', s_addr) addr = make_address(rffi.cast(_c.sockaddr_ptr, sin), rffi.sizeof(_c.sockaddr_in), address_to_fill) result.append(( _c.AF_INET, socktype, protocol, "", # xxx canonname meaningless? "anyaddr" addr)) finally: lltype.free(sin, flavor='raw') if not result: raise GAIError(EAI_FAMILY) return result # hostname as numeric name if family in (_c.AF_UNSPEC, _c.AF_INET): packedaddr = _c.inet_addr(hostname) if packedaddr != rffi.cast(rffi.UINT, INADDR_NONE): v4a = rffi.cast(lltype.Unsigned, _c.ntohl(packedaddr)) if (v4a & r_uint(0xf0000000) == r_uint(0xe0000000) or # IN_MULTICAST() v4a & r_uint(0xe0000000) == r_uint(0xe0000000)): # IN_EXPERIMENTAL() flags &= ~_c.AI_CANONNAME v4a >>= 24 # = IN_CLASSA_NSHIFT if v4a == r_uint(0) or v4a == r_uint(127): # = IN_LOOPBACKNET flags &= ~_c.AI_CANONNAME sin = rffi.make(_c.sockaddr_in) try: rffi.setintfield(sin, 'c_sin_family', _c.AF_INET) rffi.setintfield(sin, 'c_sin_port', port) rffi.setintfield(sin.c_sin_addr, 'c_s_addr', packedaddr) addr = make_address(rffi.cast(_c.sockaddr_ptr, sin), rffi.sizeof(_c.sockaddr_in), address_to_fill) finally: lltype.free(sin, flavor='raw') if not flags & _c.AI_CANONNAME: canonname = "" else: # getaddrinfo() is a name->address translation function, # and it looks strange that we do addr->name translation # here. # This is what python2.3 did on Windows: # if sys.version < (2, 4): # canonname = get_name(hostname, sin.sin_addr, # sizeof(_c.in_addr)) canonname = hostname return [(_c.AF_INET, socktype, protocol, canonname, addr)] if flags & _c.AI_NUMERICHOST: raise GAIError(EAI_NONAME) # hostname as alphabetical name result = get_addr(hostname, socktype, protocol, port, address_to_fill) if result: return result raise GAIError(EAI_FAIL)
def getaddrinfo(hostname, servname, family=_c.AF_UNSPEC, socktype=0, protocol=0, flags=0, address_to_fill=None): if not hostname and not servname: raise GAIError(EAI_NONAME) # error checks for hints if flags & ~AI_MASK: raise GAIError(EAI_BADFLAGS) if family not in (_c.AF_UNSPEC, _c.AF_INET): raise GAIError(EAI_FAMILY) if socktype == GAI_ANY: if protocol == GAI_ANY: pass elif protocol == _c.IPPROTO_UDP: socktype = _c.SOCK_DGRAM elif protocol == _c.IPPROTO_TCP: socktype = _c.SOCK_STREAM else: socktype = _c.SOCK_RAW elif socktype == _c.SOCK_RAW: pass elif socktype == _c.SOCK_DGRAM: if protocol not in (_c.IPPROTO_UDP, GAI_ANY): raise GAIError(EAI_BADHINTS) protocol = _c.IPPROTO_UDP elif socktype == _c.SOCK_STREAM: if protocol not in (_c.IPPROTO_TCP, GAI_ANY): raise GAIError(EAI_BADHINTS) protocol = _c.IPPROTO_TCP else: raise GAIError(EAI_SOCKTYPE) port = GAI_ANY # service port if servname: if str_isdigit(servname): port = _c.htons(int(servname)) # On windows, python2.3 uses getattrinfo.c, # python2.4 uses VC2003 implementation of getaddrinfo(). # if sys.version < (2, 4) # socktype = _c.SOCK_DGRAM # protocol = _c.IPPROTO_UDP else: if socktype == _c.SOCK_DGRAM: proto = "udp" elif socktype == _c.SOCK_STREAM: proto = "tcp" else: proto = None sp = _c.getservbyname(servname, proto) if not sp: raise GAIError(EAI_SERVICE) port = sp.c_s_port if socktype == GAI_ANY: s_proto = rffi.charp2str(sp.c_s_proto) if s_proto == "udp": socktype = _c.SOCK_DGRAM protocol = _c.IPPROTO_UDP elif s_proto == "tcp": socktype = _c.SOCK_STREAM protocol = _c.IPPROTO_TCP else: raise GAIError(EAI_PROTOCOL) # hostname == NULL # passive socket -> anyaddr (0.0.0.0 or ::) # non-passive socket -> localhost (127.0.0.1 or ::1) if not hostname: result = [] if family in (_c.AF_UNSPEC, _c.AF_INET): sin = rffi.make(_c.sockaddr_in) try: rffi.setintfield(sin, 'c_sin_family', _c.AF_INET) rffi.setintfield(sin, 'c_sin_port', port) if flags & _c.AI_PASSIVE: s_addr = 0x0 # addrany else: s_addr = 0x0100007f # loopback rffi.setintfield(sin.c_sin_addr, 'c_s_addr', s_addr) addr = make_address(rffi.cast(_c.sockaddr_ptr, sin), rffi.sizeof(_c.sockaddr_in), address_to_fill) result.append((_c.AF_INET, socktype, protocol, "", # xxx canonname meaningless? "anyaddr" addr)) finally: lltype.free(sin, flavor='raw') if not result: raise GAIError(EAI_FAMILY) return result # hostname as numeric name if family in (_c.AF_UNSPEC, _c.AF_INET): packedaddr = _c.inet_addr(hostname) if packedaddr != rffi.cast(rffi.UINT, INADDR_NONE): v4a = rffi.cast(lltype.Unsigned, _c.ntohl(packedaddr)) if (v4a & r_uint(0xf0000000) == r_uint(0xe0000000) or # IN_MULTICAST() v4a & r_uint(0xe0000000) == r_uint(0xe0000000)): # IN_EXPERIMENTAL() flags &= ~_c.AI_CANONNAME v4a >>= 24 # = IN_CLASSA_NSHIFT if v4a == r_uint(0) or v4a == r_uint(127): # = IN_LOOPBACKNET flags &= ~_c.AI_CANONNAME sin = rffi.make(_c.sockaddr_in) try: rffi.setintfield(sin, 'c_sin_family', _c.AF_INET) rffi.setintfield(sin, 'c_sin_port', port) rffi.setintfield(sin.c_sin_addr, 'c_s_addr', packedaddr) addr = make_address(rffi.cast(_c.sockaddr_ptr, sin), rffi.sizeof(_c.sockaddr_in), address_to_fill) finally: lltype.free(sin, flavor='raw') if not flags & _c.AI_CANONNAME: canonname = "" else: # getaddrinfo() is a name->address translation function, # and it looks strange that we do addr->name translation # here. # This is what python2.3 did on Windows: # if sys.version < (2, 4): # canonname = get_name(hostname, sin.sin_addr, # sizeof(_c.in_addr)) canonname = hostname return [(_c.AF_INET, socktype, protocol, canonname, addr)] if flags & _c.AI_NUMERICHOST: raise GAIError(EAI_NONAME) # hostname as alphabetical name result = get_addr(hostname, socktype, protocol, port, address_to_fill) if result: return result raise GAIError(EAI_FAIL)