diff options
author | Atsuo Ishimoto <ishimoto@gembook.org> | 2012-07-16 06:16:54 (GMT) |
---|---|---|
committer | Atsuo Ishimoto <ishimoto@gembook.org> | 2012-07-16 06:16:54 (GMT) |
commit | da0fc14d46a174b921ea0f68e7996bf1cda9b95d (patch) | |
tree | 86bd82e21bbe4bd0fc68ea5bc8b14d1a0a51fcf6 /Modules/socketmodule.c | |
parent | 29828a6fa9a7d42b1f2383860d37cdf7d9e74d49 (diff) | |
download | cpython-da0fc14d46a174b921ea0f68e7996bf1cda9b95d.zip cpython-da0fc14d46a174b921ea0f68e7996bf1cda9b95d.tar.gz cpython-da0fc14d46a174b921ea0f68e7996bf1cda9b95d.tar.bz2 |
Issue #7171: Add Windows implementation of ``inet_ntop`` and ``inet_pton`` to socket module.
Diffstat (limited to 'Modules/socketmodule.c')
-rw-r--r-- | Modules/socketmodule.c | 108 |
1 files changed, 106 insertions, 2 deletions
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 0396bf4..6c4b050 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -5023,7 +5023,7 @@ socket_inet_ntoa(PyObject *self, PyObject *args) return PyUnicode_FromString(inet_ntoa(packed_addr)); } -#ifdef HAVE_INET_PTON +#if defined(HAVE_INET_PTON) || defined(MS_WINDOWS) PyDoc_STRVAR(inet_pton_doc, "inet_pton(af, ip) -> packed IP address string\n\ @@ -5031,6 +5031,10 @@ PyDoc_STRVAR(inet_pton_doc, Convert an IP address from string format to a packed string suitable\n\ for use with low-level network functions."); +#endif + +#ifdef HAVE_INET_PTON + static PyObject * socket_inet_pton(PyObject *self, PyObject *args) { @@ -5075,12 +5079,52 @@ socket_inet_pton(PyObject *self, PyObject *args) return NULL; } } +#elif defined(MS_WINDOWS) + +static PyObject * +socket_inet_pton(PyObject *self, PyObject *args) +{ + int af; + char* ip; + struct sockaddr_in6 addr; + INT ret, size; + + if (!PyArg_ParseTuple(args, "is:inet_pton", &af, &ip)) { + return NULL; + } + + size = sizeof(addr); + ret = WSAStringToAddressA(ip, af, NULL, (LPSOCKADDR)&addr, &size); + + if (ret) { + PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError()); + return NULL; + } else if(af == AF_INET) { + struct sockaddr_in *addr4 = (struct sockaddr_in*)&addr; + return PyBytes_FromStringAndSize((const char *)&(addr4->sin_addr), + sizeof(addr4->sin_addr)); + } else if (af == AF_INET6) { + return PyBytes_FromStringAndSize((const char *)&(addr.sin6_addr), + sizeof(addr.sin6_addr)); + } else { + PyErr_SetString(PyExc_OSError, "unknown address family"); + return NULL; + } +} + +#endif + +#if defined(HAVE_INET_PTON) || defined(MS_WINDOWS) PyDoc_STRVAR(inet_ntop_doc, "inet_ntop(af, packed_ip) -> string formatted IP address\n\ \n\ Convert a packed IP address of the given family to string format."); +#endif + + +#ifdef HAVE_INET_PTON static PyObject * socket_inet_ntop(PyObject *self, PyObject *args) { @@ -5134,6 +5178,66 @@ socket_inet_ntop(PyObject *self, PyObject *args) return NULL; } +#elif defined(MS_WINDOWS) + +static PyObject * +socket_inet_ntop(PyObject *self, PyObject *args) +{ + int af; + char* packed; + int len; + struct sockaddr_in6 addr; + DWORD addrlen, ret, retlen; + char ip[MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) + 1]; + + /* Guarantee NUL-termination for PyUnicode_FromString() below */ + memset((void *) &ip[0], '\0', sizeof(ip)); + + if (!PyArg_ParseTuple(args, "iy#:inet_ntop", &af, &packed, &len)) { + return NULL; + } + + if (af == AF_INET) { + struct sockaddr_in * addr4 = (struct sockaddr_in *)&addr; + + if (len != sizeof(struct in_addr)) { + PyErr_SetString(PyExc_ValueError, + "invalid length of packed IP address string"); + return NULL; + } + memset(addr4, 0, sizeof(struct sockaddr_in)); + addr4->sin_family = AF_INET; + memcpy(&(addr4->sin_addr), packed, sizeof(addr4->sin_addr)); + addrlen = sizeof(struct sockaddr_in); + } else if (af == AF_INET6) { + if (len != sizeof(struct in6_addr)) { + PyErr_SetString(PyExc_ValueError, + "invalid length of packed IP address string"); + return NULL; + } + + memset(&addr, 0, sizeof(addr)); + addr.sin6_family = AF_INET6; + memcpy(&(addr.sin6_addr), packed, sizeof(addr.sin6_addr)); + addrlen = sizeof(addr); + } else { + PyErr_Format(PyExc_ValueError, + "unknown address family %d", af); + return NULL; + } + + retlen = sizeof(ip); + ret = WSAAddressToStringA((struct sockaddr*)&addr, addrlen, NULL, + ip, &retlen); + + if (ret) { + PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError()); + return NULL; + } else { + return PyUnicode_FromString(ip); + } +} + #endif /* HAVE_INET_PTON */ /* Python interface to getaddrinfo(host, port). */ @@ -5600,7 +5704,7 @@ static PyMethodDef socket_methods[] = { METH_VARARGS, inet_aton_doc}, {"inet_ntoa", socket_inet_ntoa, METH_VARARGS, inet_ntoa_doc}, -#ifdef HAVE_INET_PTON +#if defined(HAVE_INET_PTON) || defined(MS_WINDOWS) {"inet_pton", socket_inet_pton, METH_VARARGS, inet_pton_doc}, {"inet_ntop", socket_inet_ntop, |