From 9264555cddb7cac93e41f08c70a8932bceffcfaa Mon Sep 17 00:00:00 2001 From: Stefan Reither <stefan.reither@kit.edu> Date: Thu, 9 Jul 2020 17:00:13 +0200 Subject: [PATCH] adds raw_socket --- etc/raw_socket/Makefile | 18 ++++++ etc/raw_socket/raw_socket.c | 115 ++++++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 etc/raw_socket/Makefile create mode 100644 etc/raw_socket/raw_socket.c diff --git a/etc/raw_socket/Makefile b/etc/raw_socket/Makefile new file mode 100644 index 000000000..af261855d --- /dev/null +++ b/etc/raw_socket/Makefile @@ -0,0 +1,18 @@ +# raw_socket + +PREFIX = /usr/local +BDIR = $(DESTDIR)/$(PREFIX) + +.PHONY: all clean install + +all: raw_socket + +raw_socket: raw_socket.c + $(CC) -o $@ raw_socket.c + +install: raw_socket + install -D raw_socket $(BDIR)/bin/raw_socket + setcap cap_net_raw,cap_ipc_lock,cap_sys_nice+ep $(BDIR)/bin/raw_socket + +clean: + rm -f raw_socket diff --git a/etc/raw_socket/raw_socket.c b/etc/raw_socket/raw_socket.c new file mode 100644 index 000000000..32322d9be --- /dev/null +++ b/etc/raw_socket/raw_socket.c @@ -0,0 +1,115 @@ +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <sysexits.h> +#include <unistd.h> + +#include <arpa/inet.h> +#include <net/ethernet.h> +#include <net/if.h> +#include <linux/if_packet.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <sys/un.h> + +#define ETH_P_ECAT 0x88A4 + +extern char **environ; + +int main(int argc, char *argv[]) +{ + fprintf(stderr, "raw_socket was build: %s\n", __TIMESTAMP__); + int i, ret, ifindex, psock; + struct ifreq ifr; + struct sockaddr_ll sll; + struct timeval timeout; + int argssize = argc + 1; + char *args[argssize]; + char sock[5]; + + if (argc < 3) { + fprintf(stderr, "usage: %s [ifname] [binary] <args>\n", argv[0]); + return EX_USAGE; + } + + /* we use RAW packet socket, with packet type ETH_P_ECAT */ + psock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ECAT)); + if (psock < 0) { + perror("socket"); + fprintf(stderr, "raw_socket error: socket SOCK_RAW\n"); + return EX_OSERR; + } + + timeout.tv_sec = 0; + timeout.tv_usec = 1; + fprintf(stderr, "raw_socket: setsockopt SO_RCVTIMEO\n"); + ret = setsockopt(psock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); + if (ret != 0) { + perror("setsockopt"); + fprintf(stderr, "raw_socket error: setsockopt SO_RCVTIMEO\n"); + return EX_OSERR; + } + + fprintf(stderr, "raw_socket: setsockopt SO_SNDTIMEO\n"); + ret = setsockopt(psock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); + if (ret != 0) { + perror("setsockopt"); + fprintf(stderr, "raw_socket error: setsockopt SO_SNDTIMEO\n"); + return EX_OSERR; + } + + i = 1; + fprintf(stderr, "raw_socket: setsockopt SO_DONTROUTE\n"); + ret = setsockopt(psock, SOL_SOCKET, SO_DONTROUTE, &i, sizeof(i)); + if (ret != 0) { + perror("setsockopt"); + fprintf(stderr, "raw_socket error: setsockopt SO_DONTROUTE\n"); + return EX_OSERR; + } + /* connect socket to NIC by name */ + strcpy(ifr.ifr_name, argv[1]); + ret = ioctl(psock, SIOCGIFINDEX, &ifr); + ifindex = ifr.ifr_ifindex; + strcpy(ifr.ifr_name, argv[1]); + ifr.ifr_flags = 0; + /* reset flags of NIC interface */ + ret = ioctl(psock, SIOCGIFFLAGS, &ifr); + /* set flags of NIC interface, here promiscuous and broadcast */ + ifr.ifr_flags = ifr.ifr_flags | IFF_PROMISC | IFF_BROADCAST; + ret = ioctl(psock, SIOCGIFFLAGS, &ifr); + /* bind socket to protocol, in this case RAW EtherCAT */ + sll.sll_family = AF_PACKET; + sll.sll_ifindex = ifindex; + sll.sll_protocol = htons(ETH_P_ECAT); + ret = bind(psock, (struct sockaddr *)&sll, sizeof(sll)); + /* setup ethernet headers in tx buffers so we don't have to repeat it */ + + fprintf(stderr, "raw_socket: setenv ARMARX_LD_LIBRARY_PATH\n"); + ret = setenv("LD_LIBRARY_PATH", getenv("ARMARX_LD_LIBRARY_PATH"), 1); + if (ret != 0) { + perror("setenv"); + fprintf(stderr, "raw_socket error: setenv ARMARX_LD_LIBRARY_PATH\n"); + return EX_OSERR; + } + + i=0; + fprintf(stderr, "ARGUMENT %d/%d: %s\n", i+1, argssize, strrchr(argv[2], '/')); + args[i++] = strrchr(argv[2], '/'); + + snprintf(sock, 5, "%d", psock); + + fprintf(stderr, "ARGUMENT %d/%d: %s\n", i+1, argssize, sock); + args[i++] = sock; + for (i = 2; argv[i] != NULL; i++) { + fprintf(stderr, "ARGUMENT %d/%d: %s\n", i+1, argssize, argv[i]); + args[i] = argv[i]; + } + fprintf(stderr, "ARGUMENT %d/%d: NULL\n", i+1, argssize); + args[i] = NULL; + fprintf(stderr, "executing %s\n", argv[2]); + execve(argv[2], args, environ); + fprintf(stderr, "executing %s...done!\n", argv[2]); + perror("execv"); + + return EX_OSERR; +} -- GitLab