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: src/tools/tools/net80211/w00t/libw00t/w00t.c,v 1.2 2006/08/06 23:50:56 sam Exp $ 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 <netproto/802_11/ieee80211_radiotap.h> 42 #include <netproto/802_11/ieee80211.h> 43 #include <openssl/rc4.h> 44 #include <zlib.h> 45 #include "w00t.h" 46 47 int 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 63 void 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 70 short 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 81 unsigned 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 88 int 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 127 int open_tx(char *iface) 128 { 129 return open_bpf(iface, DLT_IEEE802_11_RADIO); 130 } 131 132 int open_rx(char *iface) 133 { 134 return open_bpf(iface, DLT_IEEE802_11_RADIO); 135 } 136 137 int 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 145 int inject(int fd, void *buf, int len) 146 { 147 return inject_params(fd, buf, len, NULL); 148 } 149 150 int 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 181 int sniff(int fd, void *buf, int len) 182 { 183 return read(fd, buf, len); 184 } 185 186 void *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 228 int 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 246 int 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 254 int 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 277 int 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 305 int 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 333 void 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 356 int 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 367 void 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 376 int 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 393 static 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 402 char *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