1 // SPDX-License-Identifier: GPL-2.0-only 2 #include <errno.h> 3 #include <stdbool.h> 4 #include <stdio.h> 5 #include <string.h> 6 #include <unistd.h> 7 #include <linux/err.h> 8 #include <linux/in.h> 9 #include <linux/in6.h> 10 11 #include "network_helpers.h" 12 13 #define clean_errno() (errno == 0 ? "None" : strerror(errno)) 14 #define log_err(MSG, ...) fprintf(stderr, "(%s:%d: errno: %s) " MSG "\n", \ 15 __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__) 16 17 struct ipv4_packet pkt_v4 = { 18 .eth.h_proto = __bpf_constant_htons(ETH_P_IP), 19 .iph.ihl = 5, 20 .iph.protocol = IPPROTO_TCP, 21 .iph.tot_len = __bpf_constant_htons(MAGIC_BYTES), 22 .tcp.urg_ptr = 123, 23 .tcp.doff = 5, 24 }; 25 26 struct ipv6_packet pkt_v6 = { 27 .eth.h_proto = __bpf_constant_htons(ETH_P_IPV6), 28 .iph.nexthdr = IPPROTO_TCP, 29 .iph.payload_len = __bpf_constant_htons(MAGIC_BYTES), 30 .tcp.urg_ptr = 123, 31 .tcp.doff = 5, 32 }; 33 34 int start_server(int family, int type) 35 { 36 struct sockaddr_storage addr = {}; 37 socklen_t len; 38 int fd; 39 40 if (family == AF_INET) { 41 struct sockaddr_in *sin = (void *)&addr; 42 43 sin->sin_family = AF_INET; 44 len = sizeof(*sin); 45 } else { 46 struct sockaddr_in6 *sin6 = (void *)&addr; 47 48 sin6->sin6_family = AF_INET6; 49 len = sizeof(*sin6); 50 } 51 52 fd = socket(family, type | SOCK_NONBLOCK, 0); 53 if (fd < 0) { 54 log_err("Failed to create server socket"); 55 return -1; 56 } 57 58 if (bind(fd, (const struct sockaddr *)&addr, len) < 0) { 59 log_err("Failed to bind socket"); 60 close(fd); 61 return -1; 62 } 63 64 if (type == SOCK_STREAM) { 65 if (listen(fd, 1) < 0) { 66 log_err("Failed to listed on socket"); 67 close(fd); 68 return -1; 69 } 70 } 71 72 return fd; 73 } 74 75 static const struct timeval timeo_sec = { .tv_sec = 3 }; 76 static const size_t timeo_optlen = sizeof(timeo_sec); 77 78 int connect_to_fd(int family, int type, int server_fd) 79 { 80 struct sockaddr_storage addr; 81 socklen_t len = sizeof(addr); 82 int fd; 83 84 fd = socket(family, type, 0); 85 if (fd < 0) { 86 log_err("Failed to create client socket"); 87 return -1; 88 } 89 90 if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeo_sec, timeo_optlen)) { 91 log_err("Failed to set SO_RCVTIMEO"); 92 goto out; 93 } 94 95 if (getsockname(server_fd, (struct sockaddr *)&addr, &len)) { 96 log_err("Failed to get server addr"); 97 goto out; 98 } 99 100 if (connect(fd, (const struct sockaddr *)&addr, len) < 0) { 101 log_err("Fail to connect to server with family %d", family); 102 goto out; 103 } 104 105 return fd; 106 107 out: 108 close(fd); 109 return -1; 110 } 111