summaryrefslogtreecommitdiffstats
path: root/Modules/socketmodule.c
diff options
context:
space:
mode:
authorCharles-François Natali <neologix@free.fr>2011-10-06 17:47:44 (GMT)
committerCharles-François Natali <neologix@free.fr>2011-10-06 17:47:44 (GMT)
commit47413c117145c3da7cdb0ded5c05d0d540a26a4a (patch)
tree8b216bb9a929129d5a9a457c3e0943f551d7b4a4 /Modules/socketmodule.c
parent90c30e87be7df19604c920ee24b6888afa91a093 (diff)
downloadcpython-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.c105
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