diff options
author | Charles-François Natali <neologix@free.fr> | 2011-10-06 17:47:44 (GMT) |
---|---|---|
committer | Charles-François Natali <neologix@free.fr> | 2011-10-06 17:47:44 (GMT) |
commit | 47413c117145c3da7cdb0ded5c05d0d540a26a4a (patch) | |
tree | 8b216bb9a929129d5a9a457c3e0943f551d7b4a4 /Modules/socketmodule.c | |
parent | 90c30e87be7df19604c920ee24b6888afa91a093 (diff) | |
download | cpython-47413c117145c3da7cdb0ded5c05d0d540a26a4a.zip cpython-47413c117145c3da7cdb0ded5c05d0d540a26a4a.tar.gz cpython-47413c117145c3da7cdb0ded5c05d0d540a26a4a.tar.bz2 |
Issue #10141: socket: add SocketCAN (PF_CAN) support. Initial patch by Matthias
Fuchs, updated by Tiago Gonçalves.
Diffstat (limited to 'Modules/socketmodule.c')
-rw-r--r-- | Modules/socketmodule.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 62b3fe9..aac1b72 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -1220,6 +1220,25 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto) } #endif +#ifdef HAVE_LINUX_CAN_H + case AF_CAN: + { + struct sockaddr_can *a = (struct sockaddr_can *)addr; + char *ifname = ""; + struct ifreq ifr; + /* need to look up interface name given index */ + if (a->can_ifindex) { + ifr.ifr_ifindex = a->can_ifindex; + if (ioctl(sockfd, SIOCGIFNAME, &ifr) == 0) + ifname = ifr.ifr_name; + } + + return Py_BuildValue("O&h", PyUnicode_DecodeFSDefault, + ifname, + a->can_family); + } +#endif + /* More cases here... */ default: @@ -1587,6 +1606,53 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, } #endif +#ifdef HAVE_LINUX_CAN_H + case AF_CAN: + switch (s->sock_proto) { + case CAN_RAW: + { + struct sockaddr_can *addr; + PyObject *interfaceName; + struct ifreq ifr; + addr = (struct sockaddr_can *)addr_ret; + Py_ssize_t len; + + if (!PyArg_ParseTuple(args, "O&", PyUnicode_FSConverter, + &interfaceName)) + return 0; + + len = PyBytes_GET_SIZE(interfaceName); + + if (len == 0) { + ifr.ifr_ifindex = 0; + } else if (len < sizeof(ifr.ifr_name)) { + strcpy(ifr.ifr_name, PyBytes_AS_STRING(interfaceName)); + if (ioctl(s->sock_fd, SIOCGIFINDEX, &ifr) < 0) { + s->errorhandler(); + Py_DECREF(interfaceName); + return 0; + } + } else { + PyErr_SetString(socket_error, + "AF_CAN interface name too long"); + Py_DECREF(interfaceName); + return 0; + } + + addr->can_family = AF_CAN; + addr->can_ifindex = ifr.ifr_ifindex; + + *len_ret = sizeof(*addr); + Py_DECREF(interfaceName); + return 1; + } + default: + PyErr_SetString(socket_error, + "getsockaddrarg: unsupported CAN protocol"); + return 0; + } +#endif + /* More cases here... */ default: @@ -1680,6 +1746,14 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret) } #endif +#ifdef HAVE_LINUX_CAN_H + case AF_CAN: + { + *len_ret = sizeof (struct sockaddr_can); + return 1; + } +#endif + /* More cases here... */ default: @@ -5533,6 +5607,15 @@ PyInit__socket(void) PyModule_AddStringConstant(m, "BDADDR_LOCAL", "00:00:00:FF:FF:FF"); #endif +#ifdef AF_CAN + /* Controller Area Network */ + PyModule_AddIntConstant(m, "AF_CAN", AF_CAN); +#endif +#ifdef PF_CAN + /* Controller Area Network */ + PyModule_AddIntConstant(m, "PF_CAN", PF_CAN); +#endif + #ifdef AF_PACKET PyModule_AddIntMacro(m, AF_PACKET); #endif @@ -5803,6 +5886,28 @@ PyInit__socket(void) #else PyModule_AddIntConstant(m, "SOL_UDP", 17); #endif +#ifdef SOL_CAN_BASE + PyModule_AddIntConstant(m, "SOL_CAN_BASE", SOL_CAN_BASE); +#endif +#ifdef SOL_CAN_RAW + PyModule_AddIntConstant(m, "SOL_CAN_RAW", SOL_CAN_RAW); + PyModule_AddIntConstant(m, "CAN_RAW", CAN_RAW); +#endif +#ifdef HAVE_LINUX_CAN_H + PyModule_AddIntConstant(m, "CAN_EFF_FLAG", CAN_EFF_FLAG); + PyModule_AddIntConstant(m, "CAN_RTR_FLAG", CAN_RTR_FLAG); + PyModule_AddIntConstant(m, "CAN_ERR_FLAG", CAN_ERR_FLAG); + + PyModule_AddIntConstant(m, "CAN_SFF_MASK", CAN_SFF_MASK); + PyModule_AddIntConstant(m, "CAN_EFF_MASK", CAN_EFF_MASK); + PyModule_AddIntConstant(m, "CAN_ERR_MASK", CAN_ERR_MASK); +#endif +#ifdef HAVE_LINUX_CAN_RAW_H + PyModule_AddIntConstant(m, "CAN_RAW_FILTER", CAN_RAW_FILTER); + PyModule_AddIntConstant(m, "CAN_RAW_ERR_FILTER", CAN_RAW_ERR_FILTER); + PyModule_AddIntConstant(m, "CAN_RAW_LOOPBACK", CAN_RAW_LOOPBACK); + PyModule_AddIntConstant(m, "CAN_RAW_RECV_OWN_MSGS", CAN_RAW_RECV_OWN_MSGS); +#endif #ifdef IPPROTO_IP PyModule_AddIntConstant(m, "IPPROTO_IP", IPPROTO_IP); #else |