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
45int 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
61void 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
68short 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
79unsigned 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
86int 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
125int open_tx(char *iface)
126{
127	return open_bpf(iface, DLT_IEEE802_11_RADIO);
128}
129
130int open_rx(char *iface)
131{
132	return open_bpf(iface, DLT_IEEE802_11_RADIO);
133}
134
135int 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
143int inject(int fd, void *buf, int len)
144{
145	return inject_params(fd, buf, len, NULL);
146}
147
148int 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
179int sniff(int fd, void *buf, int len)
180{
181	return read(fd, buf, len);
182}
183
184void *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
226int 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
244int 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
252int 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
275int 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
303int 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
331void 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
354int 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
365void 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
374int 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
391static 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
400char *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