@@ -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
50285028PyDoc_STRVAR (inet_pton_doc ,
50295029"inet_pton(af, ip) -> packed IP address string\n\
50305030\n\
50315031Convert an IP address from string format to a packed string suitable\n\
50325032for use with low-level network functions." );
50335033
5034+ #endif
5035+
5036+ #ifdef HAVE_INET_PTON
5037+
50345038static PyObject *
50355039socket_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
50795119PyDoc_STRVAR (inet_ntop_doc ,
50805120"inet_ntop(af, packed_ip) -> string formatted IP address\n\
50815121\n\
50825122Convert a packed IP address of the given family to string format." );
50835123
5124+ #endif
5125+
5126+
5127+ #ifdef HAVE_INET_PTON
50845128static PyObject *
50855129socket_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