From 9d6c66933a30d938bd883039b778266123500adf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Fri, 3 Feb 2012 17:44:58 +0100 Subject: Issue #13777: Add PF_SYSTEM sockets on OS X. Patch by Michael Goderbauer. --- Doc/library/socket.rst | 8 ++++ Misc/ACKS | 1 + Misc/NEWS | 3 ++ Modules/socketmodule.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++ Modules/socketmodule.h | 10 +++++ configure | 6 +-- configure.in | 6 +-- pyconfig.h.in | 6 +++ 8 files changed, 141 insertions(+), 6 deletions(-) diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index cb2ab23..6b7728f 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -99,6 +99,14 @@ created. Socket addresses are represented as follows: ``'can0'``. The network interface name ``''`` can be used to receive packets from all network interfaces of this family. +- A string or a tuple ``(id, unit)`` is used for the :const:`SYSPROTO_CONTROL` + protocol of the :const:`PF_SYSTEM` family. The string is the name of a + kernel control using a dynamically-assigned ID. The tuple can be used if ID + and unit number of the kernel control are known or if a registered ID is + used. + + .. versionadded:: 3.3 + - Certain other address families (:const:`AF_BLUETOOTH`, :const:`AF_PACKET`) support specific representations. diff --git a/Misc/ACKS b/Misc/ACKS index aafb51f..9f66255 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -366,6 +366,7 @@ Jonathan Giddy Johannes Gijsbers Michael Gilfix Yannick Gingras +Michael Goderbauer Christoph Gohlke Tim Golden Tiago Gonçalves diff --git a/Misc/NEWS b/Misc/NEWS index 68998e3..72a943d 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ What's New in Python 3.3 Alpha 1? Core and Builtins ----------------- +- Issue #13777: Add PF_SYSTEM sockets on OS X. + Patch by Michael Goderbauer. + - Issue #13908: Ready types returned from PyType_FromSpec. - Issue #11235: Fix OverflowError when trying to import a source file whose diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index b2ab5e9..d0b89c6 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -218,6 +218,11 @@ if_indextoname(index) -- return the corresponding interface name\n\ # include #endif +#ifdef __APPLE__ +# include +#endif + + #if defined(PYOS_OS2) # define INCL_DOS # define INCL_DOSERRORS @@ -1239,6 +1244,23 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto) } #endif +#ifdef PF_SYSTEM + case PF_SYSTEM: + switch(proto) { +#ifdef SYSPROTO_CONTROL + case SYSPROTO_CONTROL: + { + struct sockaddr_ctl *a = (struct sockaddr_ctl *)addr; + return Py_BuildValue("(II)", a->sc_id, a->sc_unit); + } +#endif + default: + PyErr_SetString(PyExc_ValueError, + "Invalid address type"); + return 0; + } +#endif + /* More cases here... */ default: @@ -1677,6 +1699,64 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, return 0; } #endif + +#ifdef PF_SYSTEM + case PF_SYSTEM: + switch (s->sock_proto) { +#ifdef SYSPROTO_CONTROL + case SYSPROTO_CONTROL: + { + struct sockaddr_ctl *addr; + + addr = (struct sockaddr_ctl *)addr_ret; + addr->sc_family = AF_SYSTEM; + addr->ss_sysaddr = AF_SYS_CONTROL; + + if (PyUnicode_Check(args)) { + struct ctl_info info; + PyObject *ctl_name; + + if (!PyArg_Parse(args, "O&", + PyUnicode_FSConverter, &ctl_name)) { + return 0; + } + + if (PyBytes_GET_SIZE(ctl_name) > sizeof(info.ctl_name)) { + PyErr_SetString(PyExc_ValueError, + "provided string is too long"); + Py_DECREF(ctl_name); + return 0; + } + strncpy(info.ctl_name, PyBytes_AS_STRING(ctl_name), + sizeof(info.ctl_name)); + Py_DECREF(ctl_name); + + if (ioctl(s->sock_fd, CTLIOCGINFO, &info)) { + PyErr_SetString(PyExc_OSError, + "cannot find kernel control with provided name"); + return 0; + } + + addr->sc_id = info.ctl_id; + addr->sc_unit = 0; + } else if (!PyArg_ParseTuple(args, "II", + &(addr->sc_id), &(addr->sc_unit))) { + PyErr_SetString(PyExc_TypeError, "getsockaddrarg: " + "expected str or tuple of two ints"); + + return 0; + } + + *len_ret = sizeof(*addr); + return 1; + } +#endif + default: + PyErr_SetString(PyExc_OSError, + "getsockaddrarg: unsupported PF_SYSTEM protocol"); + return 0; + } +#endif /* More cases here... */ @@ -1783,6 +1863,21 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret) return 1; } #endif + +#ifdef PF_SYSTEM + case PF_SYSTEM: + switch(s->sock_proto) { +#ifdef SYSPROTO_CONTROL + case SYSPROTO_CONTROL: + *len_ret = sizeof (struct sockaddr_ctl); + return 1; +#endif + default: + PyErr_SetString(PyExc_OSError, "getsockaddrlen: " + "unknown PF_SYSTEM protocol"); + return 0; + } +#endif /* More cases here... */ @@ -5660,6 +5755,14 @@ PyInit__socket(void) PyModule_AddIntConstant(m, "PF_RDS", PF_RDS); #endif +/* Kernel event messages */ +#ifdef PF_SYSTEM + PyModule_AddIntConstant(m, "PF_SYSTEM", PF_SYSTEM); +#endif +#ifdef AF_SYSTEM + PyModule_AddIntConstant(m, "AF_SYSTEM", AF_SYSTEM); +#endif + #ifdef AF_PACKET PyModule_AddIntMacro(m, AF_PACKET); #endif @@ -6096,6 +6199,10 @@ PyInit__socket(void) PyModule_AddIntConstant(m, "IPPROTO_MAX", IPPROTO_MAX); #endif +#ifdef SYSPROTO_CONTROL + PyModule_AddIntConstant(m, "SYSPROTO_CONTROL", SYSPROTO_CONTROL); +#endif + /* Some port configuration */ #ifdef IPPORT_RESERVED PyModule_AddIntConstant(m, "IPPORT_RESERVED", IPPORT_RESERVED); diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h index 59d4cb1..0435878 100644 --- a/Modules/socketmodule.h +++ b/Modules/socketmodule.h @@ -80,6 +80,13 @@ typedef int socklen_t; #include #endif +#ifdef HAVE_SYS_SYS_DOMAIN_H +#include +#endif +#ifdef HAVE_SYS_KERN_CONTROL_H +#include +#endif + #ifndef Py__SOCKET_H #define Py__SOCKET_H #ifdef __cplusplus @@ -138,6 +145,9 @@ typedef union sock_addr { #ifdef HAVE_LINUX_CAN_H struct sockaddr_can can; #endif +#ifdef HAVE_SYS_KERN_CONTROL_H + struct sockaddr_ctl ctl; +#endif } sock_addr_t; /* The object holding a socket. It holds some extra information, diff --git a/configure b/configure index ebae8f5..5ddb7046 100755 --- a/configure +++ b/configure @@ -6144,10 +6144,10 @@ ieeefp.h io.h langinfo.h libintl.h ncurses.h process.h pthread.h \ sched.h shadow.h signal.h stdint.h stropts.h termios.h \ unistd.h utime.h \ poll.h sys/devpoll.h sys/epoll.h sys/poll.h \ -sys/audioio.h sys/xattr.h sys/bsdtty.h sys/event.h sys/file.h sys/loadavg.h \ -sys/lock.h sys/mkdev.h sys/modem.h \ +sys/audioio.h sys/xattr.h sys/bsdtty.h sys/event.h sys/file.h \ +sys/kern_control.h sys/loadavg.h sys/lock.h sys/mkdev.h sys/modem.h \ sys/param.h sys/select.h sys/sendfile.h sys/socket.h sys/statvfs.h \ -sys/stat.h sys/syscall.h sys/termio.h sys/time.h \ +sys/stat.h sys/syscall.h sys/sys_domain.h sys/termio.h sys/time.h \ sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \ libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \ bluetooth/bluetooth.h linux/tipc.h spawn.h util.h diff --git a/configure.in b/configure.in index f0beb6b..ed7f0ad 100644 --- a/configure.in +++ b/configure.in @@ -1334,10 +1334,10 @@ ieeefp.h io.h langinfo.h libintl.h ncurses.h process.h pthread.h \ sched.h shadow.h signal.h stdint.h stropts.h termios.h \ unistd.h utime.h \ poll.h sys/devpoll.h sys/epoll.h sys/poll.h \ -sys/audioio.h sys/xattr.h sys/bsdtty.h sys/event.h sys/file.h sys/loadavg.h \ -sys/lock.h sys/mkdev.h sys/modem.h \ +sys/audioio.h sys/xattr.h sys/bsdtty.h sys/event.h sys/file.h \ +sys/kern_control.h sys/loadavg.h sys/lock.h sys/mkdev.h sys/modem.h \ sys/param.h sys/select.h sys/sendfile.h sys/socket.h sys/statvfs.h \ -sys/stat.h sys/syscall.h sys/termio.h sys/time.h \ +sys/stat.h sys/syscall.h sys/sys_domain.h sys/termio.h sys/time.h \ sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \ libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \ bluetooth/bluetooth.h linux/tipc.h spawn.h util.h) diff --git a/pyconfig.h.in b/pyconfig.h.in index fd4cfc7..5dd9878 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -908,6 +908,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_FILE_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_KERN_CONTROL_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_LOADAVG_H @@ -951,6 +954,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SYSCALL_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SYS_DOMAIN_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TERMIO_H -- cgit v0.12