aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/fnettrace-dns/main.c33
-rw-r--r--src/fnettrace-icmp/main.c35
-rw-r--r--src/fnettrace-sni/main.c57
-rw-r--r--src/fnettrace/main.c5
4 files changed, 100 insertions, 30 deletions
diff --git a/src/fnettrace-dns/main.c b/src/fnettrace-dns/main.c
index eb2eb7238..32122754f 100644
--- a/src/fnettrace-dns/main.c
+++ b/src/fnettrace-dns/main.c
@@ -22,6 +22,8 @@
22#include <time.h> 22#include <time.h>
23#include <linux/filter.h> 23#include <linux/filter.h>
24#include <linux/if_ether.h> 24#include <linux/if_ether.h>
25#include <sys/prctl.h>
26#include <signal.h>
25#define MAX_BUF_SIZE (64 * 1024) 27#define MAX_BUF_SIZE (64 * 1024)
26 28
27static char last[512] = {'\0'}; 29static char last[512] = {'\0'};
@@ -106,6 +108,18 @@ static void custom_bpf(int sock) {
106 } 108 }
107} 109}
108 110
111static void print_date(void) {
112 static int day = -1;
113 time_t now = time(NULL);
114 struct tm *t = localtime(&now);
115
116 if (day != t->tm_yday) {
117 printf("\nDNS trace for %s", ctime(&now));
118 day = t->tm_yday;
119 }
120 fflush(0);
121}
122
109static void run_trace(void) { 123static void run_trace(void) {
110 // grab all Ethernet packets and use a custom BPF filter to get only UDP from source port 53 124 // grab all Ethernet packets and use a custom BPF filter to get only UDP from source port 53
111 int s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); 125 int s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
@@ -113,19 +127,24 @@ static void run_trace(void) {
113 errExit("socket"); 127 errExit("socket");
114 custom_bpf(s); 128 custom_bpf(s);
115 129
130 struct timeval tv;
131 tv.tv_sec = 10;
132 tv.tv_usec = 0;
116 unsigned char buf[MAX_BUF_SIZE]; 133 unsigned char buf[MAX_BUF_SIZE];
117 while (1) { 134 while (1) {
118 fd_set rfds; 135 fd_set rfds;
119 FD_ZERO(&rfds); 136 FD_ZERO(&rfds);
120 FD_SET(s, &rfds); 137 FD_SET(s, &rfds);
121 struct timeval tv;
122 tv.tv_sec = 1;
123 tv.tv_usec = 0;
124 int rv = select(s + 1, &rfds, NULL, NULL, &tv); 138 int rv = select(s + 1, &rfds, NULL, NULL, &tv);
125 if (rv < 0) 139 if (rv < 0)
126 errExit("select"); 140 errExit("select");
127 else if (rv == 0) 141 else if (rv == 0) {
142 print_date();
143 tv.tv_sec = 10;
144 tv.tv_usec = 0;
128 continue; 145 continue;
146 }
147
129 unsigned bytes = recvfrom(s, buf, MAX_BUF_SIZE, 0, NULL, NULL); 148 unsigned bytes = recvfrom(s, buf, MAX_BUF_SIZE, 0, NULL, NULL);
130 149
131 if (bytes >= (14 + 20 + 8)) { // size of MAC + IP + UDP headers 150 if (bytes >= (14 + 20 + 8)) { // size of MAC + IP + UDP headers
@@ -174,8 +193,10 @@ int main(int argc, char **argv) {
174 return 1; 193 return 1;
175 } 194 }
176 195
177 time_t now = time(NULL); 196 // kill the process if the parent died
178 printf("DNS trace for %s\n", ctime(&now)); 197 prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
198
199 print_date();
179 run_trace(); 200 run_trace();
180 201
181 return 0; 202 return 0;
diff --git a/src/fnettrace-icmp/main.c b/src/fnettrace-icmp/main.c
index 47d61a326..e1e5daa48 100644
--- a/src/fnettrace-icmp/main.c
+++ b/src/fnettrace-icmp/main.c
@@ -22,6 +22,8 @@
22#include <time.h> 22#include <time.h>
23#include <linux/filter.h> 23#include <linux/filter.h>
24#include <linux/if_ether.h> 24#include <linux/if_ether.h>
25#include <sys/prctl.h>
26#include <signal.h>
25#define MAX_BUF_SIZE (64 * 1024) 27#define MAX_BUF_SIZE (64 * 1024)
26 28
27char *type_description[19] = { 29char *type_description[19] = {
@@ -139,6 +141,19 @@ static void custom_bpf(int sock) {
139 } 141 }
140} 142}
141 143
144static void print_date(void) {
145 static int day = -1;
146 time_t now = time(NULL);
147 struct tm *t = localtime(&now);
148
149 if (day != t->tm_yday) {
150 printf("\nICMP trace for %s", ctime(&now));
151 day = t->tm_yday;
152 }
153
154 fflush(0);
155}
156
142static void run_trace(void) { 157static void run_trace(void) {
143 // grab all Ethernet packets and use a custom BPF filter to get TLS/SNI packets 158 // grab all Ethernet packets and use a custom BPF filter to get TLS/SNI packets
144 int s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); 159 int s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
@@ -146,19 +161,24 @@ static void run_trace(void) {
146 errExit("socket"); 161 errExit("socket");
147 custom_bpf(s); 162 custom_bpf(s);
148 163
164 struct timeval tv;
165 tv.tv_sec = 10;
166 tv.tv_usec = 0;
149 unsigned char buf[MAX_BUF_SIZE]; 167 unsigned char buf[MAX_BUF_SIZE];
150 while (1) { 168 while (1) {
151 fd_set rfds; 169 fd_set rfds;
152 FD_ZERO(&rfds); 170 FD_ZERO(&rfds);
153 FD_SET(s, &rfds); 171 FD_SET(s, &rfds);
154 struct timeval tv;
155 tv.tv_sec = 1;
156 tv.tv_usec = 0;
157 int rv = select(s + 1, &rfds, NULL, NULL, &tv); 172 int rv = select(s + 1, &rfds, NULL, NULL, &tv);
158 if (rv < 0) 173 if (rv < 0)
159 errExit("select"); 174 errExit("select");
160 else if (rv == 0) 175 else if (rv == 0) {
176 print_date();
177 tv.tv_sec = 10;
178 tv.tv_usec = 0;
161 continue; 179 continue;
180 }
181
162 unsigned bytes = recvfrom(s, buf, MAX_BUF_SIZE, 0, NULL, NULL); 182 unsigned bytes = recvfrom(s, buf, MAX_BUF_SIZE, 0, NULL, NULL);
163 183
164 if (bytes >= (14 + 20 + 2)) { // size of MAC + IP + ICMP code and type fields 184 if (bytes >= (14 + 20 + 2)) { // size of MAC + IP + ICMP code and type fields
@@ -180,7 +200,6 @@ static void run_trace(void) {
180 close(s); 200 close(s);
181} 201}
182 202
183
184static void usage(void) { 203static void usage(void) {
185 printf("Usage: fnettrace-icmp [OPTIONS]\n"); 204 printf("Usage: fnettrace-icmp [OPTIONS]\n");
186 printf("Options:\n"); 205 printf("Options:\n");
@@ -207,8 +226,10 @@ int main(int argc, char **argv) {
207 return 1; 226 return 1;
208 } 227 }
209 228
210 time_t now = time(NULL); 229 // kill the process if the parent died
211 printf("ICMP trace for %s\n", ctime(&now)); 230 prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
231
232 print_date();
212 run_trace(); 233 run_trace();
213 234
214 return 0; 235 return 0;
diff --git a/src/fnettrace-sni/main.c b/src/fnettrace-sni/main.c
index 571089e29..71793a560 100644
--- a/src/fnettrace-sni/main.c
+++ b/src/fnettrace-sni/main.c
@@ -22,6 +22,8 @@
22#include <time.h> 22#include <time.h>
23#include <linux/filter.h> 23#include <linux/filter.h>
24#include <linux/if_ether.h> 24#include <linux/if_ether.h>
25#include <sys/prctl.h>
26#include <signal.h>
25#define MAX_BUF_SIZE (64 * 1024) 27#define MAX_BUF_SIZE (64 * 1024)
26 28
27static char last[512] = {'\0'}; 29static char last[512] = {'\0'};
@@ -94,19 +96,22 @@ nosni:
94// https://www.kernel.org/doc/html/latest/networking/filter.html 96// https://www.kernel.org/doc/html/latest/networking/filter.html
95static void custom_bpf(int sock) { 97static void custom_bpf(int sock) {
96 struct sock_filter code[] = { 98 struct sock_filter code[] = {
97 // sudo tcpdump "tcp port 443 and (tcp[((tcp[12] & 0xf0) >>2)] = 0x16) && (tcp[((tcp[12] & 0xf0) >>2)+5] = 0x01)" -dd 99 // ports: 443 (regular TLS), 853 (DoT)
100 // sudo tcpdump "tcp port (443 or 853) and (tcp[((tcp[12] & 0xf0) >>2)] = 0x16) && (tcp[((tcp[12] & 0xf0) >>2)+5] = 0x01)" -dd
98 { 0x28, 0, 0, 0x0000000c }, 101 { 0x28, 0, 0, 0x0000000c },
99 { 0x15, 27, 0, 0x000086dd }, 102 { 0x15, 29, 0, 0x000086dd },
100 { 0x15, 0, 26, 0x00000800 }, 103 { 0x15, 0, 28, 0x00000800 },
101 { 0x30, 0, 0, 0x00000017 }, 104 { 0x30, 0, 0, 0x00000017 },
102 { 0x15, 0, 24, 0x00000006 }, 105 { 0x15, 0, 26, 0x00000006 },
103 { 0x28, 0, 0, 0x00000014 }, 106 { 0x28, 0, 0, 0x00000014 },
104 { 0x45, 22, 0, 0x00001fff }, 107 { 0x45, 24, 0, 0x00001fff },
105 { 0xb1, 0, 0, 0x0000000e }, 108 { 0xb1, 0, 0, 0x0000000e },
106 { 0x48, 0, 0, 0x0000000e }, 109 { 0x48, 0, 0, 0x0000000e },
107 { 0x15, 2, 0, 0x000001bb }, 110 { 0x15, 4, 0, 0x000001bb },
111 { 0x15, 3, 0, 0x00000355 },
108 { 0x48, 0, 0, 0x00000010 }, 112 { 0x48, 0, 0, 0x00000010 },
109 { 0x15, 0, 17, 0x000001bb }, 113 { 0x15, 1, 0, 0x000001bb },
114 { 0x15, 0, 17, 0x00000355 },
110 { 0x50, 0, 0, 0x0000001a }, 115 { 0x50, 0, 0, 0x0000001a },
111 { 0x54, 0, 0, 0x000000f0 }, 116 { 0x54, 0, 0, 0x000000f0 },
112 { 0x74, 0, 0, 0x00000002 }, 117 { 0x74, 0, 0, 0x00000002 },
@@ -139,6 +144,19 @@ static void custom_bpf(int sock) {
139 } 144 }
140} 145}
141 146
147static void print_date(void) {
148 static int day = -1;
149 time_t now = time(NULL);
150 struct tm *t = localtime(&now);
151
152 if (day != t->tm_yday) {
153 printf("\nSNI trace for %s", ctime(&now));
154 day = t->tm_yday;
155 }
156
157 fflush(0);
158}
159
142static void run_trace(void) { 160static void run_trace(void) {
143 // grab all Ethernet packets and use a custom BPF filter to get TLS/SNI packets 161 // grab all Ethernet packets and use a custom BPF filter to get TLS/SNI packets
144 int s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); 162 int s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
@@ -146,19 +164,24 @@ static void run_trace(void) {
146 errExit("socket"); 164 errExit("socket");
147 custom_bpf(s); 165 custom_bpf(s);
148 166
167 struct timeval tv;
168 tv.tv_sec = 10;
169 tv.tv_usec = 0;
149 unsigned char buf[MAX_BUF_SIZE]; 170 unsigned char buf[MAX_BUF_SIZE];
150 while (1) { 171 while (1) {
151 fd_set rfds; 172 fd_set rfds;
152 FD_ZERO(&rfds); 173 FD_ZERO(&rfds);
153 FD_SET(s, &rfds); 174 FD_SET(s, &rfds);
154 struct timeval tv;
155 tv.tv_sec = 1;
156 tv.tv_usec = 0;
157 int rv = select(s + 1, &rfds, NULL, NULL, &tv); 175 int rv = select(s + 1, &rfds, NULL, NULL, &tv);
158 if (rv < 0) 176 if (rv < 0)
159 errExit("select"); 177 errExit("select");
160 else if (rv == 0) 178 else if (rv == 0) {
179 print_date();
180 tv.tv_sec = 10;
181 tv.tv_usec = 0;
161 continue; 182 continue;
183 }
184
162 unsigned bytes = recvfrom(s, buf, MAX_BUF_SIZE, 0, NULL, NULL); 185 unsigned bytes = recvfrom(s, buf, MAX_BUF_SIZE, 0, NULL, NULL);
163 186
164 if (bytes >= (14 + 20 + 20)) { // size of MAC + IP + TCP headers 187 if (bytes >= (14 + 20 + 20)) { // size of MAC + IP + TCP headers
@@ -166,15 +189,13 @@ static void run_trace(void) {
166 uint16_t port_dest; 189 uint16_t port_dest;
167 memcpy(&port_dest, buf + 14 + ip_hlen + 2, 2); 190 memcpy(&port_dest, buf + 14 + ip_hlen + 2, 2);
168 port_dest = ntohs(port_dest); 191 port_dest = ntohs(port_dest);
169 uint8_t protocol = buf[14 + 9];
170 uint32_t ip_dest; 192 uint32_t ip_dest;
171 memcpy(&ip_dest, buf + 14 + 16, 4); 193 memcpy(&ip_dest, buf + 14 + 16, 4);
172 ip_dest = ntohl(ip_dest); 194 ip_dest = ntohl(ip_dest);
173 uint8_t tcp_hlen = (buf[14 + ip_hlen + 12] & 0xf0) >> 2; 195 uint8_t tcp_hlen = (buf[14 + ip_hlen + 12] & 0xf0) >> 2;
174 196
175 // if TLS packet, extract SNI 197 // extract SNI
176 if (port_dest == 443 && protocol == 6) // TCP protocol 198 print_tls(ip_dest, buf + 14 + ip_hlen + tcp_hlen, bytes - 14 - ip_hlen - tcp_hlen); // IP and TCP header len
177 print_tls(ip_dest, buf + 14 + ip_hlen + tcp_hlen, bytes - 14 - ip_hlen - tcp_hlen); // IP and TCP header len
178 } 199 }
179 } 200 }
180 201
@@ -208,8 +229,10 @@ int main(int argc, char **argv) {
208 return 1; 229 return 1;
209 } 230 }
210 231
211 time_t now = time(NULL); 232 // kill the process if the parent died
212 printf("SNI trace for %s\n", ctime(&now)); 233 prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
234
235 print_date();
213 run_trace(); 236 run_trace();
214 237
215 return 0; 238 return 0;
diff --git a/src/fnettrace/main.c b/src/fnettrace/main.c
index 56974e79c..f57aa6c87 100644
--- a/src/fnettrace/main.c
+++ b/src/fnettrace/main.c
@@ -21,6 +21,8 @@
21#include "radix.h" 21#include "radix.h"
22#include <limits.h> 22#include <limits.h>
23#include <sys/ioctl.h> 23#include <sys/ioctl.h>
24#include <sys/prctl.h>
25#include <signal.h>
24#define MAX_BUF_SIZE (64 * 1024) 26#define MAX_BUF_SIZE (64 * 1024)
25 27
26static int arg_netfilter = 0; 28static int arg_netfilter = 0;
@@ -732,6 +734,9 @@ int main(int argc, char **argv) {
732 return 1; 734 return 1;
733 } 735 }
734 736
737 // kill the process if the parent died
738 prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
739
735 ansi_clrscr(); 740 ansi_clrscr();
736 if (arg_netfilter) 741 if (arg_netfilter)
737 logprintf("starting network lockdown\n"); 742 logprintf("starting network lockdown\n");