Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 74af9d3

Browse files
Merge heads
2 parents 81895f8 + 72cd8b9 commit 74af9d3

3 files changed

Lines changed: 128 additions & 4 deletions

File tree

Doc/library/socket.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ The module :mod:`socket` exports the following constants and functions:
594594
both the value of *address_family* and the underlying implementation of
595595
:c:func:`inet_pton`.
596596

597-
Availability: Unix (maybe not all platforms).
597+
Availability: Unix (maybe not all platforms), Windows.
598598

599599

600600
.. function:: inet_ntop(address_family, packed_ip)
@@ -610,7 +610,7 @@ The module :mod:`socket` exports the following constants and functions:
610610
specified address family, :exc:`ValueError` will be raised. A
611611
:exc:`OSError` is raised for errors from the call to :func:`inet_ntop`.
612612

613-
Availability: Unix (maybe not all platforms).
613+
Availability: Unix (maybe not all platforms), Windows.
614614

615615

616616
..

Lib/test/test_socket.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,14 @@ def testIPv6toString(self):
980980
return
981981
except ImportError:
982982
return
983+
984+
if sys.platform == "win32":
985+
try:
986+
inet_pton(AF_INET6, '::')
987+
except OSError as e:
988+
if e.winerror == 10022:
989+
return # IPv6 might not be installed on this PC
990+
983991
f = lambda a: inet_pton(AF_INET6, a)
984992
assertInvalid = lambda a: self.assertRaises(
985993
(OSError, ValueError), f, a
@@ -1058,6 +1066,14 @@ def testStringToIPv6(self):
10581066
return
10591067
except ImportError:
10601068
return
1069+
1070+
if sys.platform == "win32":
1071+
try:
1072+
inet_ntop(AF_INET6, b'\x00' * 16)
1073+
except OSError as e:
1074+
if e.winerror == 10022:
1075+
return # IPv6 might not be installed on this PC
1076+
10611077
f = lambda a: inet_ntop(AF_INET6, a)
10621078
assertInvalid = lambda a: self.assertRaises(
10631079
(OSError, ValueError), f, a

Modules/socketmodule.c

Lines changed: 110 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5023,14 +5023,18 @@ socket_inet_ntoa(PyObject *self, PyObject *args)
50235023
return PyUnicode_FromString(inet_ntoa(packed_addr));
50245024
}
50255025

5026-
#ifdef HAVE_INET_PTON
5026+
#if defined(HAVE_INET_PTON) || defined(MS_WINDOWS)
50275027

50285028
PyDoc_STRVAR(inet_pton_doc,
50295029
"inet_pton(af, ip) -> packed IP address string\n\
50305030
\n\
50315031
Convert an IP address from string format to a packed string suitable\n\
50325032
for use with low-level network functions.");
50335033

5034+
#endif
5035+
5036+
#ifdef HAVE_INET_PTON
5037+
50345038
static PyObject *
50355039
socket_inet_pton(PyObject *self, PyObject *args)
50365040
{
@@ -5075,12 +5079,52 @@ socket_inet_pton(PyObject *self, PyObject *args)
50755079
return NULL;
50765080
}
50775081
}
5082+
#elif defined(MS_WINDOWS)
5083+
5084+
static PyObject *
5085+
socket_inet_pton(PyObject *self, PyObject *args)
5086+
{
5087+
int af;
5088+
char* ip;
5089+
struct sockaddr_in6 addr;
5090+
INT ret, size;
5091+
5092+
if (!PyArg_ParseTuple(args, "is:inet_pton", &af, &ip)) {
5093+
return NULL;
5094+
}
5095+
5096+
size = sizeof(addr);
5097+
ret = WSAStringToAddressA(ip, af, NULL, (LPSOCKADDR)&addr, &size);
5098+
5099+
if (ret) {
5100+
PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
5101+
return NULL;
5102+
} else if(af == AF_INET) {
5103+
struct sockaddr_in *addr4 = (struct sockaddr_in*)&addr;
5104+
return PyBytes_FromStringAndSize((const char *)&(addr4->sin_addr),
5105+
sizeof(addr4->sin_addr));
5106+
} else if (af == AF_INET6) {
5107+
return PyBytes_FromStringAndSize((const char *)&(addr.sin6_addr),
5108+
sizeof(addr.sin6_addr));
5109+
} else {
5110+
PyErr_SetString(PyExc_OSError, "unknown address family");
5111+
return NULL;
5112+
}
5113+
}
5114+
5115+
#endif
5116+
5117+
#if defined(HAVE_INET_PTON) || defined(MS_WINDOWS)
50785118

50795119
PyDoc_STRVAR(inet_ntop_doc,
50805120
"inet_ntop(af, packed_ip) -> string formatted IP address\n\
50815121
\n\
50825122
Convert a packed IP address of the given family to string format.");
50835123

5124+
#endif
5125+
5126+
5127+
#ifdef HAVE_INET_PTON
50845128
static PyObject *
50855129
socket_inet_ntop(PyObject *self, PyObject *args)
50865130
{
@@ -5134,6 +5178,70 @@ socket_inet_ntop(PyObject *self, PyObject *args)
51345178
return NULL;
51355179
}
51365180

5181+
#elif defined(MS_WINDOWS)
5182+
5183+
static PyObject *
5184+
socket_inet_ntop(PyObject *self, PyObject *args)
5185+
{
5186+
int af;
5187+
char* packed;
5188+
int len;
5189+
struct sockaddr_in6 addr;
5190+
DWORD addrlen, ret, retlen;
5191+
#ifdef ENABLE_IPV6
5192+
char ip[Py_MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) + 1];
5193+
#else
5194+
char ip[INET_ADDRSTRLEN + 1];
5195+
#endif
5196+
5197+
/* Guarantee NUL-termination for PyUnicode_FromString() below */
5198+
memset((void *) &ip[0], '\0', sizeof(ip));
5199+
5200+
if (!PyArg_ParseTuple(args, "iy#:inet_ntop", &af, &packed, &len)) {
5201+
return NULL;
5202+
}
5203+
5204+
if (af == AF_INET) {
5205+
struct sockaddr_in * addr4 = (struct sockaddr_in *)&addr;
5206+
5207+
if (len != sizeof(struct in_addr)) {
5208+
PyErr_SetString(PyExc_ValueError,
5209+
"invalid length of packed IP address string");
5210+
return NULL;
5211+
}
5212+
memset(addr4, 0, sizeof(struct sockaddr_in));
5213+
addr4->sin_family = AF_INET;
5214+
memcpy(&(addr4->sin_addr), packed, sizeof(addr4->sin_addr));
5215+
addrlen = sizeof(struct sockaddr_in);
5216+
} else if (af == AF_INET6) {
5217+
if (len != sizeof(struct in6_addr)) {
5218+
PyErr_SetString(PyExc_ValueError,
5219+
"invalid length of packed IP address string");
5220+
return NULL;
5221+
}
5222+
5223+
memset(&addr, 0, sizeof(addr));
5224+
addr.sin6_family = AF_INET6;
5225+
memcpy(&(addr.sin6_addr), packed, sizeof(addr.sin6_addr));
5226+
addrlen = sizeof(addr);
5227+
} else {
5228+
PyErr_Format(PyExc_ValueError,
5229+
"unknown address family %d", af);
5230+
return NULL;
5231+
}
5232+
5233+
retlen = sizeof(ip);
5234+
ret = WSAAddressToStringA((struct sockaddr*)&addr, addrlen, NULL,
5235+
ip, &retlen);
5236+
5237+
if (ret) {
5238+
PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
5239+
return NULL;
5240+
} else {
5241+
return PyUnicode_FromString(ip);
5242+
}
5243+
}
5244+
51375245
#endif /* HAVE_INET_PTON */
51385246

51395247
/* Python interface to getaddrinfo(host, port). */
@@ -5600,7 +5708,7 @@ static PyMethodDef socket_methods[] = {
56005708
METH_VARARGS, inet_aton_doc},
56015709
{"inet_ntoa", socket_inet_ntoa,
56025710
METH_VARARGS, inet_ntoa_doc},
5603-
#ifdef HAVE_INET_PTON
5711+
#if defined(HAVE_INET_PTON) || defined(MS_WINDOWS)
56045712
{"inet_pton", socket_inet_pton,
56055713
METH_VARARGS, inet_pton_doc},
56065714
{"inet_ntop", socket_inet_ntop,

0 commit comments

Comments
 (0)