Skip to content
Snippets Groups Projects
Verified Commit a285b988 authored by Christian Dreher's avatar Christian Dreher
Browse files

chore: Move raw_socket to own repo.

parent 9c03603d
No related branches found
No related tags found
No related merge requests found
raw_socket
# 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
#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;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment