2 * Copyright (c) 2006, Andrea Bittau <a.bittau@cs.ucl.ac.uk>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
32 #include <sys/socket.h>
33 #include <sys/types.h>
34 #include <sys/endian.h>
39 #include <sys/ioctl.h>
41 #include <net80211/ieee80211_radiotap.h>
42 #include <net80211/ieee80211.h>
43 #include <openssl/rc4.h>
47 int str2mac(char *mac, char *str)
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)
57 for (i = 0; i < 6; i++)
58 *mac++ = (char) macf[i];
63 void mac2str(char *str, char* m)
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]);
70 short seqfn(unsigned short seq, unsigned short fn)
77 r |= ( (seq % 4096) << IEEE80211_SEQ_SEQ_SHIFT);
81 unsigned short seqno(struct ieee80211_frame *wh)
83 unsigned short *s = (unsigned short*) wh->i_seq;
85 return (*s & IEEE80211_SEQ_SEQ_MASK) >> IEEE80211_SEQ_SEQ_SHIFT;
88 int open_bpf(char *dev, int dlt)
95 for(i = 0;i < 16; i++) {
96 sprintf(buf, "/dev/bpf%d", i);
98 fd = open(buf, O_RDWR);
111 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)-1);
112 ifr.ifr_name[sizeof(ifr.ifr_name)-1] = 0;
114 if(ioctl(fd, BIOCSETIF, &ifr) < 0)
117 if (ioctl(fd, BIOCSDLT, &dlt) < 0)
121 if (ioctl(fd, BIOCIMMEDIATE, &i) < 0)
127 int open_tx(char *iface)
129 return open_bpf(iface, DLT_IEEE802_11_RADIO);
132 int open_rx(char *iface)
134 return open_bpf(iface, DLT_IEEE802_11_RADIO);
137 int open_rxtx(char *iface, int *rx, int *tx)
139 *rx = open_bpf(iface, DLT_IEEE802_11_RADIO);
145 int inject(int fd, void *buf, int len)
147 return inject_params(fd, buf, len, NULL);
150 int inject_params(int fd, void *buf, int len,
151 struct ieee80211_bpf_params *params)
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 */
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;
173 rc = writev(fd, iov, 2);
177 rc -= iov[0].iov_len; /* XXX could be negative */
181 int sniff(int fd, void *buf, int len)
183 return read(fd, buf, len);
186 void *get_wifi(void *buf, int *len)
188 #define BIT(n) (1<<(n))
189 struct bpf_hdr* bpfh = (struct bpf_hdr*) buf;
190 struct ieee80211_radiotap_header* rth;
196 *len -= bpfh->bh_hdrlen;
198 if (bpfh->bh_caplen != *len) {
199 assert(bpfh->bh_caplen < *len);
200 *len = bpfh->bh_caplen;
202 assert(bpfh->bh_caplen == *len);
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];
214 rflags = ((const uint8_t *)rth)[0];
220 if (rflags & IEEE80211_RADIOTAP_F_FCS)
221 *len -= IEEE80211_CRC_LEN;
223 ptr = (char*)rth + rth->it_len;
228 int send_ack(int fd, char *mac)
230 static char buf[2+2+6];
235 memset(buf, 0, sizeof(buf));
236 buf[0] |= IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_ACK;
242 rc = inject(fd, buf, sizeof(buf));
246 int open_tap(char *iface)
250 snprintf(buf, sizeof(buf), "/dev/%s", iface);
251 return open(buf, O_RDWR);
254 int set_iface_mac(char *iface, char *mac)
259 s = socket(PF_INET, SOCK_DGRAM, 0);
263 memset(&ifr, 0, sizeof(ifr));
264 strcpy(ifr.ifr_name, iface);
266 ifr.ifr_addr.sa_family = AF_LINK;
267 ifr.ifr_addr.sa_len = 6;
268 memcpy(ifr.ifr_addr.sa_data, mac, 6);
270 rc = ioctl(s, SIOCSIFLLADDR, &ifr);
277 int str2wep(char *wep, int *len, char *str)
286 if (klen != 5 && klen != 13)
294 if (sscanf(str, "%2x", &x) != 1)
297 *wep = (unsigned char) x;
305 int wep_decrypt(struct ieee80211_frame *wh, int len, char *key, int klen)
309 char *p = (char*) (wh+1);
310 uLong crc = crc32(0L, Z_NULL, 0);
313 assert(sizeof(seed) >= klen + 3);
315 memcpy(&seed[3], key, klen);
317 RC4_set_key(&k, klen+3, seed);
324 crc = crc32(crc, p, len - 4);
325 pcrc = (uLong*) (p+len-4);
333 void wep_encrypt(struct ieee80211_frame *wh, int len, char *key, int klen)
337 char *p = (char*) (wh+1);
338 uLong crc = crc32(0L, Z_NULL, 0);
341 assert(sizeof(seed) >= klen + 3);
343 memcpy(&seed[3], key, klen);
345 RC4_set_key(&k, klen+3, seed);
349 crc = crc32(crc, p, len - 4);
350 pcrc = (uLong*) (p+len-4);
356 int frame_type(struct ieee80211_frame *wh, int type, int stype)
358 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != type)
361 if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) != stype)
367 void hexdump(void *b, int len)
369 unsigned char *p = (unsigned char*) b;
372 printf("%.2X ", *p++);
376 int elapsed(struct timeval *past, struct timeval *now)
380 el = now->tv_sec - past->tv_sec;
383 el = now->tv_usec - past->tv_usec;
385 el = (el - 1)*1000*1000;
386 el += 1000*1000-past->tv_usec;
393 static int is_arp(struct ieee80211_frame *wh, int len)
396 if (len > (sizeof(*wh) + 4 + 4 + 39))
402 char *known_pt(struct ieee80211_frame *wh, int *len)
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";
408 arp = is_arp(wh, *len);