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