[Python-checkins] python/dist/src/Modules socketmodule.c,1.259,1.260

gvanrossum@users.sourceforge.net gvanrossum@users.sourceforge.net
Thu, 24 Apr 2003 22:48:35 -0700


Update of /cvsroot/python/python/dist/src/Modules
In directory sc8-pr-cvs1:/tmp/cvs-serv26816/Modules

Modified Files:
	socketmodule.c 
Log Message:
Patch by Jp Calderone:

- The socket module now provides the functions inet_pton and inet_ntop
  for converting between string and packed representation of IP addresses.
  See SF patch #658327.

This still needs a bit of work in the doc area, because it is not
available on all platforms (especially not on Windows).


Index: socketmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v
retrieving revision 1.259
retrieving revision 1.260
diff -C2 -d -r1.259 -r1.260
*** socketmodule.c	18 Apr 2003 10:39:53 -0000	1.259
--- socketmodule.c	25 Apr 2003 05:48:32 -0000	1.260
***************
*** 36,39 ****
--- 36,40 ----
  - socket.getnameinfo(sockaddr, flags) --> (host, port)
  - socket.AF_INET, socket.SOCK_STREAM, etc.: constants from <socket.h>
+ - socket.has_ipv6: boolean value indicating if IPv6 is supported
  - socket.inet_aton(IP address) -> 32-bit packed IP representation
  - socket.inet_ntoa(packed IP) -> IP address string
***************
*** 63,66 ****
--- 64,70 ----
  #include "Python.h"
  
+ #undef MAX
+ #define MAX(x, y) ((x) < (y) ? (y) : (x))
+ 
  /* Socket object documentation */
  PyDoc_STRVAR(sock_doc,
***************
*** 2777,2780 ****
--- 2781,2878 ----
  }
  
+ #ifdef HAVE_INET_PTON
+ 
+ PyDoc_STRVAR(inet_pton_doc,
+ "inet_pton(af, ip) -> packed IP address string\n\
+ \n\
+ Convert an IP address from string format to a packed string suitable\n\
+ for use with low-level network functions.");
+ 
+ static PyObject *
+ socket_inet_pton(PyObject *self, PyObject *args)
+ {
+ 	int af;
+ 	char* ip;
+ 	int retval;
+ 	char packed[MAX(sizeof(struct in_addr), sizeof(struct in6_addr))];
+ 
+ 	if (!PyArg_ParseTuple(args, "is:inet_pton", &af, &ip)) {
+ 		return NULL;
+ 	}
+ 
+ 	retval = inet_pton(af, ip, packed);
+ 	if (retval < 0) {
+ 		PyErr_SetFromErrno(socket_error);
+ 		return NULL;
+ 	} else if (retval == 0) {
+ 		PyErr_SetString(socket_error,
+ 			"illegal IP address string passed to inet_pton");
+ 		return NULL;
+ 	} else if (af == AF_INET) {
+ 		return PyString_FromStringAndSize(packed,
+ 			sizeof(struct in_addr));
+ 	} else if (af == AF_INET6) {
+ 		return PyString_FromStringAndSize(packed,
+ 			sizeof(struct in6_addr));
+ 	} else {
+ 		PyErr_SetString(socket_error, "unknown address family");
+ 		return NULL;
+ 	}
+ }
+ 	
+ 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.");
+ 
+ static PyObject *
+ socket_inet_ntop(PyObject *self, PyObject *args)
+ {
+ 	int af;
+ 	char* packed;
+ 	int len;
+ 	const char* retval;
+ 	char ip[MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) + 1];
+ 	
+ 	/* Guarantee NUL-termination for PyString_FromString() below */
+ 	memset((void *) &ip[0], '\0', sizeof(ip) + 1);
+ 
+ 	if (!PyArg_ParseTuple(args, "is#:inet_ntop", &af, &packed, &len)) {
+ 		return NULL;
+ 	}
+ 
+ 	if (af == AF_INET) {
+ 		if (len != sizeof(struct in_addr)) {
+ 			PyErr_SetString(PyExc_ValueError,
+ 				"invalid length of packed IP address string");
+ 			return NULL;
+ 		}
+ 	} else if (af == AF_INET6) {
+ 		if (len != sizeof(struct in6_addr)) {
+ 			PyErr_SetString(PyExc_ValueError,
+ 				"invalid length of packed IP address string");
+ 			return NULL;
+ 		}
+ 	} else {
+ 		PyErr_Format(PyExc_ValueError,
+ 			"unknown address family %d", af);
+ 		return NULL;
+ 	}
+ 
+ 	retval = inet_ntop(af, packed, ip, sizeof(ip));
+ 	if (!retval) {
+ 		PyErr_SetFromErrno(socket_error);
+ 		return NULL;
+ 	} else {
+ 		return PyString_FromString(retval);
+ 	}
+ 
+ 	/* NOTREACHED */
+ 	PyErr_SetString(PyExc_RuntimeError, "invalid handling of inet_ntop");
+ 	return NULL;
+ }
+ 
+ #endif /* HAVE_INET_PTON */
+ 
  /* Python interface to getaddrinfo(host, port). */
  
***************
*** 3036,3039 ****
--- 3134,3143 ----
  	{"inet_ntoa",		socket_inet_ntoa,
  	 METH_VARARGS, inet_ntoa_doc},
+ #ifdef HAVE_INET_PTON
+ 	{"inet_pton",		socket_inet_pton,
+ 	 METH_VARARGS, inet_pton_doc},
+ 	{"inet_ntop",		socket_inet_ntop,
+ 	 METH_VARARGS, inet_ntop_doc},
+ #endif
  	{"getaddrinfo",		socket_getaddrinfo,
  	 METH_VARARGS, getaddrinfo_doc},
***************
*** 3179,3183 ****
  init_socket(void)
  {
! 	PyObject *m;
  
  	if (!os_init())
--- 3283,3287 ----
  init_socket(void)
  {
! 	PyObject *m, *has_ipv6;
  
  	if (!os_init())
***************
*** 3215,3218 ****
--- 3319,3330 ----
  		return;
  
+ #ifdef ENABLE_IPV6
+ 	has_ipv6 = Py_True;
+ #else
+ 	has_ipv6 = Py_False;
+ #endif
+ 	Py_INCREF(has_ipv6);
+ 	PyModule_AddObject(m, "has_ipv6", has_ipv6);
+ 
  	/* Export C API */
  	if (PyModule_AddObject(m, PySocket_CAPI_NAME,
***************
*** 3801,3804 ****
--- 3913,3917 ----
  
  /* Simplistic emulation code for inet_pton that only works for IPv4 */
+ /* These are not exposed because they do not set errno properly */
  
  int