xref: /freebsd/tools/tools/net80211/w00t/libw00t/w00t.c (revision b3e7694832e81d7a904a10f525f8797b753bf0d3)
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