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