From: Michael Olbrich Date: Tue, 5 May 2009 15:17:20 +0200 Subject: [PATCH] Add support for socketcan to the python socket module This patch add support for the protocol family AF_CAN. It contains all the necessary code to use the python socket module for socketcan. Signed-off-by: Michael Olbrich Signed-off-by: Marc Kleine-Budde --- Lib/plat-linux2/IN.py | 2 ++ Modules/socketmodule.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++ Modules/socketmodule.h | 11 +++++++ configure.ac | 13 ++++++++ 4 files changed, 115 insertions(+) diff --git a/Lib/plat-linux2/IN.py b/Lib/plat-linux2/IN.py index ad307f65398b..f72ae886cad8 100644 --- a/Lib/plat-linux2/IN.py +++ b/Lib/plat-linux2/IN.py @@ -384,6 +384,7 @@ PF_SNA = 22 PF_IRDA = 23 PF_PPPOX = 24 PF_WANPIPE = 25 +PF_CAN = 29 PF_BLUETOOTH = 31 PF_MAX = 32 AF_UNSPEC = PF_UNSPEC @@ -414,6 +415,7 @@ AF_SNA = PF_SNA AF_IRDA = PF_IRDA AF_PPPOX = PF_PPPOX AF_WANPIPE = PF_WANPIPE +AF_CAN = PF_CAN AF_BLUETOOTH = PF_BLUETOOTH AF_MAX = PF_MAX SOL_RAW = 255 diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 8d3670529e85..f1c0bab247b0 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -448,6 +448,10 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); #define SAS2SA(x) ((struct sockaddr *)(x)) +#ifdef ENABLE_CAN +#include +#endif + /* * Constants for getnameinfo() */ @@ -1125,6 +1129,22 @@ makesockaddr(int sockfd, struct sockaddr *addr, int addrlen, int proto) } #endif /* ENABLE_IPV6 */ +#ifdef ENABLE_CAN + case AF_CAN: + { + struct sockaddr_can *a = (struct sockaddr_can *)addr; + char *ifname = ""; + struct ifreq ifr; + /* need to look up interface name give index */ + if (a->can_ifindex) { + ifr.ifr_ifindex = a->can_ifindex; + if (ioctl(sockfd, SIOCGIFNAME, &ifr) == 0) + ifname = ifr.ifr_name; + } + return Py_BuildValue("s", ifname); + } +#endif + #ifdef USE_BLUETOOTH case AF_BLUETOOTH: switch (proto) { @@ -1411,6 +1431,28 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, } #endif /* ENABLE_IPV6 */ +#ifdef ENABLE_CAN + case AF_CAN: + { + struct sockaddr_can* addr; + struct ifreq ifr; + char *interfaceName; + addr = (struct sockaddr_can*)addr_ret; + if (!PyArg_Parse(args, "s", &interfaceName)) + return 0; + strncpy(ifr.ifr_name, interfaceName, sizeof(ifr.ifr_name)); + ifr.ifr_name[(sizeof(ifr.ifr_name))-1] = '\0'; + if (ioctl(s->sock_fd, SIOCGIFINDEX, &ifr) < 0) { + s->errorhandler(); + return 0; + } + addr->can_family = AF_CAN; + addr->can_ifindex = ifr.ifr_ifindex; + *len_ret = sizeof *addr; + return 1; + } +#endif + #ifdef USE_BLUETOOTH case AF_BLUETOOTH: { @@ -1662,6 +1704,14 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret) } #endif /* ENABLE_IPV6 */ +#ifdef ENABLE_CAN + case AF_CAN: + { + *len_ret = sizeof (struct sockaddr_can); + return 1; + } +#endif + #ifdef USE_BLUETOOTH case AF_BLUETOOTH: { @@ -4798,6 +4848,10 @@ init_socket(void) PyModule_AddIntConstant(m, "AF_LLC", AF_LLC); #endif +#ifdef ENABLE_CAN + PyModule_AddIntConstant(m, "AF_CAN", AF_CAN); +#endif + #ifdef USE_BLUETOOTH PyModule_AddIntConstant(m, "AF_BLUETOOTH", AF_BLUETOOTH); PyModule_AddIntConstant(m, "BTPROTO_L2CAP", BTPROTO_L2CAP); @@ -5154,6 +5208,41 @@ init_socket(void) PyModule_AddIntConstant(m, "IPPROTO_MAX", IPPROTO_MAX); #endif +#ifdef CAN_RAW + PyModule_AddIntConstant(m, "CAN_RAW", CAN_RAW); +#endif +#ifdef CAN_BCM + PyModule_AddIntConstant(m, "CAN_BCM", CAN_BCM); +#endif +#ifdef CAN_TP16 + PyModule_AddIntConstant(m, "CAN_TP16", CAN_TP16); +#endif +#ifdef CAN_TP20 + PyModule_AddIntConstant(m, "CAN_TP20", CAN_TP20); +#endif +#ifdef CAN_MCNET + PyModule_AddIntConstant(m, "CAN_MCNET", CAN_MCNET); +#endif +#ifdef CAN_ISOTP + PyModule_AddIntConstant(m, "CAN_ISOTP", CAN_ISOTP); +#endif +#ifdef CAN_NPROTO + PyModule_AddIntConstant(m, "CAN_NPROTO", CAN_NPROTO); +#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); +#endif +#ifdef ENABLE_CAN + 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 + /* Some port configuration */ #ifdef IPPORT_RESERVED PyModule_AddIntConstant(m, "IPPORT_RESERVED", IPPORT_RESERVED); diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h index d98e00e88d27..3b6e22e29d3a 100644 --- a/Modules/socketmodule.h +++ b/Modules/socketmodule.h @@ -55,6 +55,14 @@ typedef int socklen_t; #include #endif +#define AF_CAN 29 +#define PF_CAN AF_CAN + +#ifdef HAVE_LINUX_CAN_H +#define ENABLE_CAN 1 +#include +#endif + #ifdef HAVE_BLUETOOTH_H #include #endif @@ -106,6 +114,9 @@ typedef union sock_addr { struct sockaddr_in6 in6; struct sockaddr_storage storage; #endif +#ifdef ENABLE_CAN + struct sockaddr_can can; +#endif #ifdef HAVE_BLUETOOTH_BLUETOOTH_H struct sockaddr_l2 bt_l2; struct sockaddr_rc bt_rc; diff --git a/configure.ac b/configure.ac index 913d5469d06e..675f56835e59 100644 --- a/configure.ac +++ b/configure.ac @@ -1746,6 +1746,19 @@ AC_CHECK_HEADERS(linux/netlink.h,,,[ #endif ]) +AC_CHECK_HEADERS(linux/can.h,[],[],[#include ]) +# check for AF_CAN +AC_TRY_COMPILE( + [[#include + int domain = AF_CAN;]], + [[socket(domain, 0, 0);]], + [], + [ + AC_DEFINE(AF_CAN, 29, [Define AF_CAN if not defined by sys/socket.h]) + AC_DEFINE(PF_CAN, 29, [Define PF_CAN if not defined by sys/socket.h]) + ] +) + # checks for typedefs was_it_defined=no AC_MSG_CHECKING(for clock_t in time.h)