aboutsummaryrefslogtreecommitdiffstats
path: root/src/fnettrace-sni/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fnettrace-sni/main.c')
-rw-r--r--src/fnettrace-sni/main.c57
1 files changed, 40 insertions, 17 deletions
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;