1 /*-
2 * Copyright (c) 2006, Andrea Bittau <a.bittau@cs.ucl.ac.uk>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26 #include <stdio.h>
27 #include <assert.h>
28 #include <fcntl.h>
29 #include <errno.h>
30 #include <sys/socket.h>
31 #include <sys/types.h>
32 #include <sys/endian.h>
33 #include <sys/uio.h>
34 #include <unistd.h>
35 #include <net/if.h>
36 #include <string.h>
37 #include <sys/ioctl.h>
38 #include <net/bpf.h>
39 #include <net80211/ieee80211_radiotap.h>
40 #include <net80211/ieee80211.h>
41 #include <openssl/rc4.h>
42 #include <zlib.h>
43 #include "w00t.h"
44
str2mac(char * mac,char * str)45 int str2mac(char *mac, char *str)
46 {
47 unsigned int macf[6];
48 int i;
49
50 if (sscanf(str, "%x:%x:%x:%x:%x:%x",
51 &macf[0], &macf[1], &macf[2],
52 &macf[3], &macf[4], &macf[5]) != 6)
53 return -1;
54
55 for (i = 0; i < 6; i++)
56 *mac++ = (char) macf[i];
57
58 return 0;
59 }
60
mac2str(char * str,char * m)61 void mac2str(char *str, char* m)
62 {
63 unsigned char *mac = m;
64 sprintf(str, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
65 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
66 }
67
seqfn(unsigned short seq,unsigned short fn)68 short seqfn(unsigned short seq, unsigned short fn)
69 {
70 unsigned short r = 0;
71
72 assert(fn < 16);
73
74 r = fn;
75 r |= ( (seq % 4096) << IEEE80211_SEQ_SEQ_SHIFT);
76 return r;
77 }
78
seqno(struct ieee80211_frame * wh)79 unsigned short seqno(struct ieee80211_frame *wh)
80 {
81 unsigned short *s = (unsigned short*) wh->i_seq;
82
83 return (*s & IEEE80211_SEQ_SEQ_MASK) >> IEEE80211_SEQ_SEQ_SHIFT;
84 }
85
open_bpf(char * dev,int dlt)86 int open_bpf(char *dev, int dlt)
87 {
88 int i;
89 char buf[64];
90 int fd = -1;
91 struct ifreq ifr;
92
93 for(i = 0;i < 16; i++) {
94 sprintf(buf, "/dev/bpf%d", i);
95
96 fd = open(buf, O_RDWR);
97 if(fd == -1) {
98 if(errno != EBUSY)
99 return -1;
100 continue;
101 }
102 else
103 break;
104 }
105
106 if(fd == -1)
107 return -1;
108
109 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)-1);
110 ifr.ifr_name[sizeof(ifr.ifr_name)-1] = 0;
111
112 if(ioctl(fd, BIOCSETIF, &ifr) < 0)
113 return -1;
114
115 if (ioctl(fd, BIOCSDLT, &dlt) < 0)
116 return -1;
117
118 i = 1;
119 if (ioctl(fd, BIOCIMMEDIATE, &i) < 0)
120 return -1;
121
122 return fd;
123 }
124
open_tx(char * iface)125 int open_tx(char *iface)
126 {
127 return open_bpf(iface, DLT_IEEE802_11_RADIO);
128 }
129
open_rx(char * iface)130 int open_rx(char *iface)
131 {
132 return open_bpf(iface, DLT_IEEE802_11_RADIO);
133 }
134
open_rxtx(char * iface,int * rx,int * tx)135 int open_rxtx(char *iface, int *rx, int *tx)
136 {
137 *rx = open_bpf(iface, DLT_IEEE802_11_RADIO);
138 *tx = *rx;
139
140 return *rx;
141 }
142
inject(int fd,void * buf,int len)143 int inject(int fd, void *buf, int len)
144 {
145 return inject_params(fd, buf, len, NULL);
146 }
147
inject_params(int fd,void * buf,int len,struct ieee80211_bpf_params * params)148 int inject_params(int fd, void *buf, int len,
149 struct ieee80211_bpf_params *params)
150 {
151 static struct ieee80211_bpf_params defaults = {
152 .ibp_vers = IEEE80211_BPF_VERSION,
153 /* NB: no need to pass series 2-4 rate+try */
154 .ibp_len = sizeof(struct ieee80211_bpf_params) - 6,
155 .ibp_rate0 = 2, /* 1 MB/s XXX */
156 .ibp_try0 = 1, /* no retransmits */
157 .ibp_flags = IEEE80211_BPF_NOACK,
158 .ibp_power = 100, /* nominal max */
159 .ibp_pri = WME_AC_VO, /* high priority */
160 };
161 struct iovec iov[2];
162 int rc;
163
164 if (params == NULL)
165 params = &defaults;
166 iov[0].iov_base = params;
167 iov[0].iov_len = params->ibp_len;
168 iov[1].iov_base = buf;
169 iov[1].iov_len = len;
170
171 rc = writev(fd, iov, 2);
172 if (rc == -1)
173 return rc;
174
175 rc -= iov[0].iov_len; /* XXX could be negative */
176 return rc;
177 }
178
sniff(int fd,void * buf,int len)179 int sniff(int fd, void *buf, int len)
180 {
181 return read(fd, buf, len);
182 }
183
get_wifi(void * buf,int * len)184 void *get_wifi(void *buf, int *len)
185 {
186 #define BIT(n) (1<<(n))
187 struct bpf_hdr* bpfh = (struct bpf_hdr*) buf;
188 struct ieee80211_radiotap_header* rth;
189 uint32_t present;
190 uint8_t rflags;
191 void *ptr;
192
193 /* bpf */
194 *len -= bpfh->bh_hdrlen;
195
196 if (bpfh->bh_caplen != *len) {
197 assert(bpfh->bh_caplen < *len);
198 *len = bpfh->bh_caplen;
199 }
200 assert(bpfh->bh_caplen == *len);
201
202 /* radiotap */
203 rth = (struct ieee80211_radiotap_header*)
204 ((char*)bpfh + bpfh->bh_hdrlen);
205 /* XXX cache; drivers won't change this per-packet */
206 /* check if FCS/CRC is included in packet */
207 present = le32toh(rth->it_present);
208 if (present & BIT(IEEE80211_RADIOTAP_FLAGS)) {
209 if (present & BIT(IEEE80211_RADIOTAP_TSFT))
210 rflags = ((const uint8_t *)rth)[8];
211 else
212 rflags = ((const uint8_t *)rth)[0];
213 } else
214 rflags = 0;
215 *len -= rth->it_len;
216
217 /* 802.11 CRC */
218 if (rflags & IEEE80211_RADIOTAP_F_FCS)
219 *len -= IEEE80211_CRC_LEN;
220
221 ptr = (char*)rth + rth->it_len;
222 return ptr;
223 #undef BIT
224 }
225
send_ack(int fd,char * mac)226 int send_ack(int fd, char *mac)
227 {
228 static char buf[2+2+6];
229 static char *p = 0;
230 int rc;
231
232 if (!p) {
233 memset(buf, 0, sizeof(buf));
234 buf[0] |= IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_ACK;
235 p = &buf[4];
236 }
237
238 memcpy(p, mac, 6);
239
240 rc = inject(fd, buf, sizeof(buf));
241 return rc;
242 }
243
open_tap(char * iface)244 int open_tap(char *iface)
245 {
246 char buf[64];
247
248 snprintf(buf, sizeof(buf), "/dev/%s", iface);
249 return open(buf, O_RDWR);
250 }
251
set_iface_mac(char * iface,char * mac)252 int set_iface_mac(char *iface, char *mac)
253 {
254 int s, rc;
255 struct ifreq ifr;
256
257 s = socket(PF_INET, SOCK_DGRAM, 0);
258 if (s == -1)
259 return -1;
260
261 memset(&ifr, 0, sizeof(ifr));
262 strcpy(ifr.ifr_name, iface);
263
264 ifr.ifr_addr.sa_family = AF_LINK;
265 ifr.ifr_addr.sa_len = 6;
266 memcpy(ifr.ifr_addr.sa_data, mac, 6);
267
268 rc = ioctl(s, SIOCSIFLLADDR, &ifr);
269
270 close(s);
271
272 return rc;
273 }
274
str2wep(char * wep,int * len,char * str)275 int str2wep(char *wep, int *len, char *str)
276 {
277 int klen;
278
279 klen = strlen(str);
280 if (klen % 2)
281 return -1;
282 klen /= 2;
283
284 if (klen != 5 && klen != 13)
285 return -1;
286
287 *len = klen;
288
289 while (klen--) {
290 unsigned int x;
291
292 if (sscanf(str, "%2x", &x) != 1)
293 return -1;
294
295 *wep = (unsigned char) x;
296 wep++;
297 str += 2;
298 }
299
300 return 0;
301 }
302
wep_decrypt(struct ieee80211_frame * wh,int len,char * key,int klen)303 int wep_decrypt(struct ieee80211_frame *wh, int len, char *key, int klen)
304 {
305 RC4_KEY k;
306 char seed[64];
307 char *p = (char*) (wh+1);
308 uLong crc = crc32(0L, Z_NULL, 0);
309 uLong *pcrc;
310
311 assert(sizeof(seed) >= klen + 3);
312 memcpy(seed, p, 3);
313 memcpy(&seed[3], key, klen);
314
315 RC4_set_key(&k, klen+3, seed);
316
317 len -= sizeof(*wh);
318 len -= 4;
319 p += 4;
320 RC4(&k, len, p, p);
321
322 crc = crc32(crc, p, len - 4);
323 pcrc = (uLong*) (p+len-4);
324
325 if (*pcrc == crc)
326 return 0;
327
328 return -1;
329 }
330
wep_encrypt(struct ieee80211_frame * wh,int len,char * key,int klen)331 void wep_encrypt(struct ieee80211_frame *wh, int len, char *key, int klen)
332 {
333 RC4_KEY k;
334 char seed[64];
335 char *p = (char*) (wh+1);
336 uLong crc = crc32(0L, Z_NULL, 0);
337 uLong *pcrc;
338
339 assert(sizeof(seed) >= klen + 3);
340 memcpy(seed, p, 3);
341 memcpy(&seed[3], key, klen);
342
343 RC4_set_key(&k, klen+3, seed);
344
345 len -= sizeof(*wh);
346 p += 4;
347 crc = crc32(crc, p, len - 4);
348 pcrc = (uLong*) (p+len-4);
349 *pcrc = crc;
350
351 RC4(&k, len, p, p);
352 }
353
frame_type(struct ieee80211_frame * wh,int type,int stype)354 int frame_type(struct ieee80211_frame *wh, int type, int stype)
355 {
356 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != type)
357 return 0;
358
359 if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) != stype)
360 return 0;
361
362 return 1;
363 }
364
hexdump(void * b,int len)365 void hexdump(void *b, int len)
366 {
367 unsigned char *p = (unsigned char*) b;
368
369 while (len--)
370 printf("%.2X ", *p++);
371 printf("\n");
372 }
373
elapsed(struct timeval * past,struct timeval * now)374 int elapsed(struct timeval *past, struct timeval *now)
375 {
376 int el;
377
378 el = now->tv_sec - past->tv_sec;
379 assert(el >= 0);
380 if (el == 0) {
381 el = now->tv_usec - past->tv_usec;
382 } else {
383 el = (el - 1)*1000*1000;
384 el += 1000*1000-past->tv_usec;
385 el += now->tv_usec;
386 }
387
388 return el;
389 }
390
is_arp(struct ieee80211_frame * wh,int len)391 static int is_arp(struct ieee80211_frame *wh, int len)
392 {
393 /* XXX */
394 if (len > (sizeof(*wh) + 4 + 4 + 39))
395 return 0;
396
397 return 1;
398 }
399
known_pt(struct ieee80211_frame * wh,int * len)400 char *known_pt(struct ieee80211_frame *wh, int *len)
401 {
402 static char *known_pt_arp = "\xAA\xAA\x03\x00\x00\x00\x08\x06";
403 static char *known_pt_ip = "\xAA\xAA\x03\x00\x00\x00\x08\x00";
404 int arp;
405
406 arp = is_arp(wh, *len);
407 *len = 8;
408 if (arp)
409 return known_pt_arp;
410 else
411 return known_pt_ip;
412 }
413