#include #include #include #include #include #include #include #include #include #include #include #include #include unsigned short checksum(unsigned short* buff, int _16bitword) { unsigned long sum; for(sum=0;_16bitword>0;_16bitword--) sum+=htons(*(buff)++); sum = ((sum >> 16) + (sum & 0xFFFF)); sum += (sum>>16); return (unsigned short)(~sum); } void die(char * msg) { perror(msg); exit(1); } void _recv(unsigned char * buffer, int rx, int if_idx, int tx) { int n; n = recvfrom(rx , buffer, 65536, 0 , NULL, NULL); if (n == -1) die("Failed to get packets\n"); // even though this is a AF_PACKET socket, // since we are on a wireguard interface, there are no layer 2 headers // AF_INET/IPPROTO_RAW did not work, i don't know why struct iphdr *ip_packet = (struct iphdr *)(buffer); if (ntohl(ip_packet->daddr) != 0x0a6300ff) return; struct sockaddr_in addr = {0}; addr.sin_family=AF_INET; // unicast to everyone because wireguard for (int32_t daddr = 0x0a630081; daddr < 0x0a6300ff; daddr++) { addr.sin_addr.s_addr = htonl(daddr); ip_packet->daddr = htonl(daddr); ip_packet->check = checksum((unsigned short *)ip_packet, sizeof(struct iphdr) / 2); int res = sendto(tx, ip_packet, ntohs(ip_packet->tot_len), 0, (struct sockaddr *) &addr, sizeof(addr)); if (res == -1) { //perror("aaah shit"); // it's ok if this fails, since we spam a lot of adresses, that don't exist } } } int main() { unsigned char *buffer = (unsigned char *)malloc(65536); int rx = socket (AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if(rx == -1) die("Failed to create rx socket"); struct sockaddr_ll addr = {0}; addr.sll_family=AF_PACKET; addr.sll_protocol=htons(ETH_P_ALL); char * if_name = "wg-spielwiese"; struct ifreq ifr; size_t if_name_len=strlen(if_name); memcpy(ifr.ifr_name,if_name,if_name_len + 1); if (ioctl(rx,SIOCGIFINDEX,&ifr)==-1) { printf("%s",strerror(errno)); exit(2); } int if_idx=ifr.ifr_ifindex; addr.sll_ifindex=if_idx; bind(rx, (struct sockaddr *)&addr, sizeof(addr)); int tx = socket (AF_INET, SOCK_RAW, IPPROTO_RAW); if(tx == -1) die("Failed to create tx socket"); while(1) { _recv(buffer, rx, if_idx, tx); } return 0; }