|
|
|
@ -1094,25 +1094,33 @@ setipaddr(const char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Create a string object representing an IP address. |
|
|
|
This is always a string of the form 'dd.dd.dd.dd' (with variable |
|
|
|
size numbers). */ |
|
|
|
/* Convert IPv4 sockaddr to a Python str. */ |
|
|
|
|
|
|
|
static PyObject * |
|
|
|
makeipaddr(struct sockaddr *addr, int addrlen) |
|
|
|
make_ipv4_addr(const struct sockaddr_in *addr) |
|
|
|
{ |
|
|
|
char buf[NI_MAXHOST]; |
|
|
|
int error; |
|
|
|
|
|
|
|
error = getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0, |
|
|
|
NI_NUMERICHOST); |
|
|
|
if (error) { |
|
|
|
set_gaierror(error); |
|
|
|
char buf[INET_ADDRSTRLEN]; |
|
|
|
if (inet_ntop(AF_INET, &addr->sin_addr, buf, sizeof(buf)) == NULL) { |
|
|
|
PyErr_SetFromErrno(PyExc_OSError); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
return PyUnicode_FromString(buf); |
|
|
|
} |
|
|
|
|
|
|
|
#ifdef ENABLE_IPV6 |
|
|
|
/* Convert IPv6 sockaddr to a Python str. */ |
|
|
|
|
|
|
|
static PyObject * |
|
|
|
make_ipv6_addr(const struct sockaddr_in6 *addr) |
|
|
|
{ |
|
|
|
char buf[INET6_ADDRSTRLEN]; |
|
|
|
if (inet_ntop(AF_INET6, &addr->sin6_addr, buf, sizeof(buf)) == NULL) { |
|
|
|
PyErr_SetFromErrno(PyExc_OSError); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
return PyUnicode_FromString(buf); |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
#ifdef USE_BLUETOOTH |
|
|
|
/* Convert a string representation of a Bluetooth address into a numeric |
|
|
|
@ -1177,11 +1185,10 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto) |
|
|
|
|
|
|
|
case AF_INET: |
|
|
|
{ |
|
|
|
struct sockaddr_in *a; |
|
|
|
PyObject *addrobj = makeipaddr(addr, sizeof(*a)); |
|
|
|
const struct sockaddr_in *a = (const struct sockaddr_in *)addr; |
|
|
|
PyObject *addrobj = make_ipv4_addr(a); |
|
|
|
PyObject *ret = NULL; |
|
|
|
if (addrobj) { |
|
|
|
a = (struct sockaddr_in *)addr; |
|
|
|
ret = Py_BuildValue("Oi", addrobj, ntohs(a->sin_port)); |
|
|
|
Py_DECREF(addrobj); |
|
|
|
} |
|
|
|
@ -1225,11 +1232,10 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto) |
|
|
|
#ifdef ENABLE_IPV6 |
|
|
|
case AF_INET6: |
|
|
|
{ |
|
|
|
struct sockaddr_in6 *a; |
|
|
|
PyObject *addrobj = makeipaddr(addr, sizeof(*a)); |
|
|
|
const struct sockaddr_in6 *a = (const struct sockaddr_in6 *)addr; |
|
|
|
PyObject *addrobj = make_ipv6_addr(a); |
|
|
|
PyObject *ret = NULL; |
|
|
|
if (addrobj) { |
|
|
|
a = (struct sockaddr_in6 *)addr; |
|
|
|
ret = Py_BuildValue("OiII", |
|
|
|
addrobj, |
|
|
|
ntohs(a->sin6_port), |
|
|
|
@ -5036,14 +5042,14 @@ static PyObject * |
|
|
|
socket_gethostbyname(PyObject *self, PyObject *args) |
|
|
|
{ |
|
|
|
char *name; |
|
|
|
sock_addr_t addrbuf; |
|
|
|
struct sockaddr_in addrbuf; |
|
|
|
PyObject *ret = NULL; |
|
|
|
|
|
|
|
if (!PyArg_ParseTuple(args, "et:gethostbyname", "idna", &name)) |
|
|
|
return NULL; |
|
|
|
if (setipaddr(name, SAS2SA(&addrbuf), sizeof(addrbuf), AF_INET) < 0) |
|
|
|
if (setipaddr(name, (struct sockaddr *)&addrbuf, sizeof(addrbuf), AF_INET) < 0) |
|
|
|
goto finally; |
|
|
|
ret = makeipaddr(SAS2SA(&addrbuf), sizeof(struct sockaddr_in)); |
|
|
|
ret = make_ipv4_addr(&addrbuf); |
|
|
|
finally: |
|
|
|
PyMem_Free(name); |
|
|
|
return ret; |
|
|
|
@ -5145,7 +5151,7 @@ gethost_common(struct hostent *h, struct sockaddr *addr, size_t alen, int af) |
|
|
|
sin.sin_len = sizeof(sin); |
|
|
|
#endif |
|
|
|
memcpy(&sin.sin_addr, *pch, sizeof(sin.sin_addr)); |
|
|
|
tmp = makeipaddr((struct sockaddr *)&sin, sizeof(sin)); |
|
|
|
tmp = make_ipv4_addr(&sin); |
|
|
|
|
|
|
|
if (pch == h->h_addr_list && alen >= sizeof(sin)) |
|
|
|
memcpy((char *) addr, &sin, sizeof(sin)); |
|
|
|
@ -5162,8 +5168,7 @@ gethost_common(struct hostent *h, struct sockaddr *addr, size_t alen, int af) |
|
|
|
sin6.sin6_len = sizeof(sin6); |
|
|
|
#endif |
|
|
|
memcpy(&sin6.sin6_addr, *pch, sizeof(sin6.sin6_addr)); |
|
|
|
tmp = makeipaddr((struct sockaddr *)&sin6, |
|
|
|
sizeof(sin6)); |
|
|
|
tmp = make_ipv6_addr(&sin6); |
|
|
|
|
|
|
|
if (pch == h->h_addr_list && alen >= sizeof(sin6)) |
|
|
|
memcpy((char *) addr, &sin6, sizeof(sin6)); |
|
|
|
@ -5934,14 +5939,11 @@ socket_inet_ntop(PyObject *self, PyObject *args) |
|
|
|
Py_buffer packed_ip; |
|
|
|
const char* retval; |
|
|
|
#ifdef ENABLE_IPV6 |
|
|
|
char ip[Py_MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) + 1]; |
|
|
|
char ip[Py_MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN)]; |
|
|
|
#else |
|
|
|
char ip[INET_ADDRSTRLEN + 1]; |
|
|
|
char ip[INET_ADDRSTRLEN]; |
|
|
|
#endif |
|
|
|
|
|
|
|
/* Guarantee NUL-termination for PyUnicode_FromString() below */ |
|
|
|
memset((void *) &ip[0], '\0', sizeof(ip)); |
|
|
|
|
|
|
|
if (!PyArg_ParseTuple(args, "iy*:inet_ntop", &af, &packed_ip)) { |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
@ -5969,6 +5971,7 @@ socket_inet_ntop(PyObject *self, PyObject *args) |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
/* inet_ntop guarantee NUL-termination of resulting string. */ |
|
|
|
retval = inet_ntop(af, packed_ip.buf, ip, sizeof(ip)); |
|
|
|
PyBuffer_Release(&packed_ip); |
|
|
|
if (!retval) { |
|
|
|
|