1#define _GNU_SOURCE
2
3#include <arpa/inet.h>
4#include <errno.h>
5#include <fcntl.h>
6#include <linux/if_tun.h>
7#include <net/if.h>
8#include <netinet/in.h>
9#include <netinet/ip.h>
10#include <netinet/tcp.h>
11#include <sched.h>
12#include <stdarg.h>
13#include <stdint.h>
14#include <stdio.h>
15#include <stdlib.h>
16#include <string.h>
17#include <sys/ioctl.h>
18#include <sys/socket.h>
19#include <sys/stat.h>
20#include <sys/types.h>
21#include <sys/uio.h>
22#include <unistd.h>
23
24void HF_ITER(uint8_t**, size_t*);
25
26void fatal(const char* fmt, ...)
27{
28    fprintf(stdout, "[-] ");
29
30    va_list args;
31    va_start(args, fmt);
32    vfprintf(stdout, fmt, args);
33    va_end(args);
34
35    fprintf(stdout, "\n");
36
37    exit(1);
38}
39
40void pfatal(const char* fmt, ...)
41{
42    fprintf(stdout, "[-] ");
43
44    va_list args;
45    va_start(args, fmt);
46    vfprintf(stdout, fmt, args);
47    va_end(args);
48
49    fprintf(stdout, ": %s\n", strerror(errno));
50
51    exit(1);
52}
53
54void mlog(const char* fmt, ...)
55{
56    fprintf(stdout, "[+] ");
57
58    va_list args;
59    va_start(args, fmt);
60    vfprintf(stdout, fmt, args);
61    va_end(args);
62
63    fprintf(stdout, "\n");
64}
65
66int main(void)
67{
68    if (unshare(CLONE_NEWUSER | CLONE_NEWNET) == -1) {
69        pfatal("unshare()");
70    }
71
72    struct ifreq ifr;
73    memset(&ifr, '\0', sizeof(ifr));
74    ifr.ifr_flags = IFF_TUN | IFF_NO_PI | IFF_NOFILTER;
75    strcpy(ifr.ifr_name, "FUZZ0");
76
77    int fd = open("/dev/net/tun", O_RDWR);
78    if (fd == -1) {
79        pfatal("open('/dev/net/tun')");
80    }
81    if (ioctl(fd, TUNSETIFF, (void*)&ifr) != 0) {
82        pfatal("ioctl(TUNSETIFF)");
83    }
84    if (ioctl(fd, TUNSETOFFLOAD, TUN_F_CSUM | TUN_F_TSO_ECN | TUN_F_TSO4 | TUN_F_TSO6 | TUN_F_UFO) == -1) {
85        pfatal("ioctl(fd, TUNSETOFFLOAD)");
86    }
87
88    int udp_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
89    if (udp_sock == -1) {
90        pfatal("socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)");
91    }
92    int tcp_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
93    if (tcp_sock == -1) {
94        pfatal("socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)");
95    }
96    int sctp_sock = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
97    if (sctp_sock == -1) {
98        pfatal("socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP)");
99    }
100    int udp_lite_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDPLITE);
101    if (udp_lite_sock == -1) {
102        pfatal("socket(AF_INET, SOCK_DGRAM, IPPROTO_UDPLITE)");
103    }
104
105    int disable = 1;
106    if (setsockopt(udp_sock, SOL_SOCKET, SO_NO_CHECK, (void*)&disable, sizeof(disable)) == -1) {
107        pfatal("setsockopt(udp_sock, SOL_SOCKET, SO_NO_CHECK)");
108    }
109    if (setsockopt(tcp_sock, SOL_SOCKET, SO_NO_CHECK, (void*)&disable, sizeof(disable)) == -1) {
110        pfatal("setsockopt(tcp_sock, SOL_SOCKET, SO_NO_CHECK)");
111    }
112    const uint8_t md5s[TCP_MD5SIG_MAXKEYLEN] = { 0 };
113    setsockopt(tcp_sock, SOL_TCP, TCP_MD5SIG, (void*)md5s, sizeof(md5s));
114    if (setsockopt(sctp_sock, SOL_SOCKET, SO_NO_CHECK, (void*)&disable, sizeof(disable)) == -1) {
115        pfatal("setsockopt(sctp_sock, SOL_SOCKET, SO_NO_CHECK)");
116    }
117    if (setsockopt(udp_lite_sock, SOL_SOCKET, SO_NO_CHECK, (void*)&disable, sizeof(disable)) == -1) {
118        pfatal("setsockopt(udp_lite_sock, SOL_SOCKET, SO_NO_CHECK)");
119    }
120
121    struct sockaddr_in* sa = (struct sockaddr_in*)(&ifr.ifr_addr);
122    sa->sin_family = AF_INET;
123    sa->sin_addr.s_addr = inet_addr("192.168.255.1");
124    if (ioctl(tcp_sock, SIOCSIFADDR, &ifr) == -1) {
125        pfatal("ioctl(tcp_sock, SIOCSIFADDR, &ifr)");
126    }
127    sa->sin_addr.s_addr = inet_addr("192.168.255.2");
128    if (ioctl(tcp_sock, SIOCSIFDSTADDR, &ifr) == -1) {
129        pfatal("ioctl(tcp_sock, SIOCSIFDSTADDR, &ifr)");
130    }
131
132    if (ioctl(tcp_sock, SIOCGIFFLAGS, &ifr) == -1) {
133        pfatal("ioctl(tcp_sock, SIOCGIFFLAGS, &ifr)");
134    }
135    ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
136    if (ioctl(tcp_sock, SIOCSIFFLAGS, &ifr) == -1) {
137        pfatal("ioctl(tcp_sock, SIOCSIFFLAGS, &ifr)");
138    }
139
140    struct sockaddr_in addr = {
141        .sin_family = AF_INET,
142        .sin_port = htons(1337),
143        .sin_addr.s_addr = INADDR_ANY,
144    };
145
146    if (bind(tcp_sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
147        pfatal("bind(tcp)");
148    }
149    if (bind(udp_sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
150        pfatal("bind(udp)");
151    }
152    if (bind(sctp_sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
153        pfatal("bind(sctp)");
154    }
155    if (bind(udp_lite_sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
156        pfatal("bind(udp_lite)");
157    }
158    if (fcntl(fd, F_SETFL, O_NONBLOCK | O_RDWR) == -1) {
159        pfatal("fcntl(fd, F_SETFL, O_NONBLOCK|O_RDWR)");
160    }
161    if (fcntl(tcp_sock, F_SETFL, O_NONBLOCK | O_RDWR) == -1) {
162        pfatal("fcntl(tcp_sock, F_SETFL, O_NONBLOCK|O_RDWR)");
163    }
164    if (fcntl(udp_sock, F_SETFL, O_NONBLOCK | O_RDWR) == -1) {
165        pfatal("fcntl(udp_sock, F_SETFL, O_NONBLOCK|O_RDWR)");
166    }
167    if (fcntl(sctp_sock, F_SETFL, O_NONBLOCK | O_RDWR) == -1) {
168        pfatal("fcntl(sctp_sock, F_SETFL, O_NONBLOCK|O_RDWR)");
169    }
170    if (fcntl(udp_lite_sock, F_SETFL, O_NONBLOCK | O_RDWR) == -1) {
171        pfatal("fcntl(udp_lite_sock, F_SETFL, O_NONBLOCK|O_RDWR)");
172    }
173
174    if (listen(tcp_sock, SOMAXCONN) == -1) {
175        pfatal("listen(tcp_sock)");
176    }
177    if (listen(sctp_sock, SOMAXCONN) == -1) {
178        pfatal("listen(sctp_sock)");
179    }
180
181    int tcp_acc_sock = -1;
182
183    for (;;) {
184        char b[1024 * 128];
185        for (;;) {
186            if (read(fd, b, sizeof(b)) <= 0) {
187                break;
188            }
189        }
190
191        uint8_t* buf;
192        size_t len;
193
194        HF_ITER(&buf, &len);
195
196        const size_t pkt_size = 1400UL;
197        size_t num_iov = 0;
198        if (len > 0) {
199            num_iov = ((len - 1) / pkt_size) + 1;
200        }
201        for (size_t i = 0; i < num_iov; i++) {
202            size_t off = pkt_size * i;
203            size_t sz = ((len - off) > pkt_size) ? pkt_size : (len - off);
204            write(fd, &buf[off], sz);
205
206            char b[1024 * 128];
207            for (;;) {
208                if (read(fd, b, sizeof(b)) <= 0) {
209                    break;
210                }
211            }
212
213            if (tcp_acc_sock == -1) {
214                struct sockaddr_in nsock;
215                socklen_t slen = sizeof(nsock);
216                tcp_acc_sock = accept4(tcp_sock, (struct sockaddr*)&nsock, &slen, SOCK_NONBLOCK);
217            }
218            if (tcp_acc_sock != -1) {
219                if (recv(tcp_acc_sock, b, sizeof(b), MSG_DONTWAIT) == 0) {
220                    close(tcp_acc_sock);
221                    tcp_acc_sock = -1;
222                }
223                send(tcp_acc_sock, b, 1, MSG_NOSIGNAL | MSG_DONTWAIT);
224            }
225
226            struct sockaddr_in addr;
227            socklen_t slen = sizeof(addr);
228            if (recvfrom(udp_sock, b, sizeof(b), MSG_DONTWAIT, (struct sockaddr*)&addr, &slen) > 0) {
229                sendto(udp_sock, b, 1, MSG_NOSIGNAL | MSG_DONTWAIT, (struct sockaddr*)&addr, slen);
230            }
231
232            slen = sizeof(addr);
233            if (recvfrom(sctp_sock, b, sizeof(b), MSG_DONTWAIT, (struct sockaddr*)&addr, &slen) > 0) {
234                sendto(sctp_sock, b, 1, MSG_NOSIGNAL | MSG_DONTWAIT, (struct sockaddr*)&addr, slen);
235            }
236
237            slen = sizeof(addr);
238            if (recvfrom(udp_lite_sock, b, sizeof(b), MSG_DONTWAIT, (struct sockaddr*)&addr, &slen) > 0) {
239                sendto(udp_lite_sock, b, 1, MSG_NOSIGNAL | MSG_DONTWAIT, (struct sockaddr*)&addr, slen);
240            }
241        }
242    }
243}
244