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
28 #include <sys/types.h>
29 #include <sys/select.h>
31 #include <sys/endian.h>
69 struct client *clients;
78 void usage(char *name)
80 printf("Usage: %s <opts>\n"
92 void fill_basic(struct ieee80211_frame *wh, struct params *p)
99 memcpy(wh->i_addr2, p->mac, 6);
101 seq = (short*)wh->i_seq;
102 *seq = seqfn(p->seq, 0);
105 void send_frame(struct params *p, void *buf, int len)
109 rc = inject(p->tx, buf, len);
113 printf("injected %d/%d\n", rc, len);
119 int fill_beacon(struct params *p, struct ieee80211_frame *wh)
124 ptr = (char*) (wh+1);
125 ptr += 8; /* timestamp */
127 *ptr |= IEEE80211_CAPINFO_ESS;
131 len = strlen(p->ssid);
134 memcpy(ptr, p->ssid, len);
150 return ptr - ((char*) wh);
153 void send_beacon(struct params *p)
156 struct ieee80211_frame *wh;
160 wh = (struct ieee80211_frame*) buf;
162 memset(buf, 0, sizeof(buf));
164 memset(wh->i_addr1, 0xff, 6);
165 memcpy(wh->i_addr3, p->mac, 6);
167 wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT;
168 wh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_BEACON;
170 len = fill_beacon(p, wh);
173 ptr = (char*)wh + len;
178 printf("sending beacon\n");
180 send_frame(p, wh, len);
182 if (gettimeofday(&p->blast, NULL) == -1)
183 err(1, "gettimeofday()");
187 void send_pres(struct params *p, char *mac)
190 struct ieee80211_frame *wh;
193 wh = (struct ieee80211_frame*) buf;
195 memset(buf, 0, sizeof(buf));
197 memcpy(wh->i_addr1, mac, 6);
198 memcpy(wh->i_addr3, p->mac, 6);
200 wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT;
201 wh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_PROBE_RESP;
203 len = fill_beacon(p, wh);
205 printf("sending probe response\n");
206 send_frame(p, wh, len);
209 void read_preq(struct params *p, struct ieee80211_frame *wh, int len)
213 unsigned char macs[6*3];
215 ptr = (unsigned char*) (wh+1);
219 printf("weird pr %x\n", *ptr);
224 end = ptr + (*ptr) + 1;
228 mac2str(macs, wh->i_addr2);
229 printf("Probe request for [%s] from %s\n", ptr, macs);
231 if ((strcmp(ptr, "") == 0) || (strcmp(ptr, p->ssid) == 0))
232 send_pres(p, wh->i_addr2);
235 void send_auth(struct params* p, char *mac)
238 struct ieee80211_frame *wh;
242 wh = (struct ieee80211_frame*) buf;
244 memset(buf, 0, sizeof(buf));
246 memcpy(wh->i_addr1, mac, 6);
247 memcpy(wh->i_addr3, p->mac, 6);
249 wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT;
250 wh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_AUTH;
252 ptr = (unsigned short*) (wh+1);
257 len = ((char*)ptr) - ((char*) wh);
258 printf("sending auth\n");
259 send_frame(p, wh, len);
262 void read_auth(struct params *p, struct ieee80211_frame *wh, int len)
267 if (memcmp(wh->i_addr1, p->mac, 6) != 0)
270 ptr = (unsigned short*) (wh+1);
271 if (le16toh(*ptr) != 0) {
272 printf("Unknown auth algo %d\n", le16toh(*ptr));
276 if (le16toh(*ptr) == 1) {
277 mac2str(mac, wh->i_addr2);
278 printf("Got auth from %s\n", mac);
279 send_auth(p, wh->i_addr2);
281 printf("Weird seq in auth %d\n", le16toh(*ptr));
285 void send_assoc(struct params *p, char *mac)
288 struct ieee80211_frame *wh;
292 wh = (struct ieee80211_frame*) buf;
294 memset(buf, 0, sizeof(buf));
296 memcpy(wh->i_addr1, mac, 6);
297 memcpy(wh->i_addr3, p->mac, 6);
299 wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT;
300 wh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_ASSOC_RESP;
302 ptr = (char*) (wh+1);
303 *ptr |= IEEE80211_CAPINFO_ESS;
305 ptr += 2; /* status */
316 len = ptr - ((char*) wh);
317 printf("sending assoc response\n");
318 send_frame(p, wh, len);
321 void read_assoc(struct params *p, struct ieee80211_frame *wh, int len)
325 unsigned char macs[6*3];
327 if (memcmp(wh->i_addr1, p->mac, 6) != 0)
330 ptr = (unsigned char*) (wh+1);
332 ptr += 2; /* list interval */
336 printf("weird pr %x\n", *ptr);
341 end = ptr + (*ptr) + 1;
345 mac2str(macs, wh->i_addr2);
346 printf("Assoc request for [%s] from %s\n", ptr, macs);
348 if (strcmp(ptr, p->ssid) == 0)
349 send_assoc(p, wh->i_addr2);
352 void read_mgt(struct params *p, struct ieee80211_frame *wh, int len)
354 switch (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) {
355 case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
356 read_preq(p, wh, len);
359 case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
362 case IEEE80211_FC0_SUBTYPE_AUTH:
363 read_auth(p, wh, len);
366 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
367 read_assoc(p, wh, len);
370 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
371 case IEEE80211_FC0_SUBTYPE_BEACON:
375 printf("wtf %d\n", (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) >>
376 IEEE80211_FC0_SUBTYPE_SHIFT);
382 void send_cts(struct params *p, char *mac)
385 struct ieee80211_frame *wh;
387 memset(buf, 0, sizeof(buf));
388 wh = (struct ieee80211_frame*) buf;
389 wh->i_fc[0] |= IEEE80211_FC0_TYPE_CTL;
390 wh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_CTS;
393 memcpy(wh->i_addr1, mac, 6);
395 send_frame(p, wh, 10);
398 void read_rts(struct params *p, struct ieee80211_frame *wh, int len)
400 if (memcmp(wh->i_addr1, p->mac, 6) != 0)
403 send_cts(p, wh->i_addr2);
406 void read_ack(struct params *p, struct ieee80211_frame *wh, int len)
408 if (memcmp(wh->i_addr1, p->mac, 6) == 0)
412 void read_ctl(struct params *p, struct ieee80211_frame *wh, int len)
414 switch (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) {
415 case IEEE80211_FC0_SUBTYPE_RTS:
416 read_rts(p, wh, len);
419 case IEEE80211_FC0_SUBTYPE_ACK:
420 read_ack(p, wh, len);
423 case IEEE80211_FC0_SUBTYPE_CTS:
427 printf("wtf %d\n", (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) >>
428 IEEE80211_FC0_SUBTYPE_SHIFT);
437 int broadcast(struct ieee80211_frame *wh)
441 if (memcmp(wh->i_addr1, "\xff\xff\xff\xff\xff\xff", 6) == 0)
447 void enque(struct params *p, struct ieee80211_frame *wh, int len)
452 assert(sizeof(p->packet) >= len);
454 memcpy(p->packet, wh, len);
458 wh = (struct ieee80211_frame*) p->packet;
459 wh->i_fc[1] |= IEEE80211_FC1_RETRY;
461 if (gettimeofday(&p->plast, NULL) == -1)
462 err(1, "gettimeofday()");
465 void relay_data(struct params *p, struct ieee80211_frame *wh, int len)
472 memcpy(fc, wh->i_fc, 2);
473 memcpy(seq, wh->i_seq, 2);
476 wh->i_fc[1] &= ~(IEEE80211_FC1_DIR_TODS | IEEE80211_FC1_RETRY);
477 wh->i_fc[1] |= IEEE80211_FC1_DIR_FROMDS;
478 memcpy(wh->i_addr1, wh->i_addr3, sizeof(wh->i_addr1));
479 memcpy(wh->i_addr3, wh->i_addr2, sizeof(wh->i_addr3));
480 memcpy(wh->i_addr2, p->mac, sizeof(wh->i_addr2));
481 ps = (unsigned short*)wh->i_seq;
482 *ps = seqfn(p->seq, 0);
484 send_frame(p, wh, len);
488 memcpy(wh->i_fc, fc, sizeof(fc));
489 memcpy(wh->i_addr2, wh->i_addr3, sizeof(wh->i_addr2));
490 memcpy(wh->i_addr3, wh->i_addr1, sizeof(wh->i_addr2));
491 memcpy(wh->i_addr1, p->mac, sizeof(wh->i_addr1));
492 memcpy(wh->i_seq, seq, sizeof(seq));
495 void read_real_data(struct params *p, struct ieee80211_frame *wh, int len)
499 char *ptr = (char*) (wh+1);
501 /* stuff not for this net */
502 if (memcmp(wh->i_addr1, p->mac, 6) != 0)
506 if (memcmp(wh->i_addr3, p->mac, 6) != 0)
507 relay_data(p, wh, len);
509 memcpy(dst, wh->i_addr3, 6);
512 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
514 printf("Got wep but i aint wep\n");
518 if (wep_decrypt(wh, len, p->wep_key, p->wep_len) == -1){
519 printf("Can't decrypt\n");
530 memcpy(ptr, wh->i_addr2, 6);
539 rc = write(p->tap, ptr, len);
543 printf("Wrote %d/%d\n", rc, len);
548 void read_data(struct params *p, struct ieee80211_frame *wh, int len)
550 switch (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) {
551 case IEEE80211_FC0_SUBTYPE_DATA:
552 read_real_data(p, wh, len);
555 case IEEE80211_FC0_SUBTYPE_NODATA:
559 printf("wtf %d\n", (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) >>
560 IEEE80211_FC0_SUBTYPE_SHIFT);
566 struct client* client_find(struct params *p, char *mac)
568 struct client* c = p->clients;
571 if (memcmp(c->mac, mac, 6) == 0)
580 void client_insert(struct params *p, struct client *c)
586 mac2str(mac, c->mac);
587 printf("Adding client %s\n", mac);
591 c->next = p->clients;
595 int duplicate(struct params *p, struct ieee80211_frame *wh, int rc)
600 if (!frame_type(wh, IEEE80211_FC0_TYPE_DATA,
601 IEEE80211_FC0_SUBTYPE_DATA))
606 c = client_find(p, wh->i_addr2);
608 c = malloc(sizeof(*c));
612 memset(c, 0, sizeof(*c));
613 memcpy(c->mac, wh->i_addr2, 6);
619 if (wh->i_fc[1] & IEEE80211_FC1_RETRY) {
620 if ( (s <= c->seq) && ((c->seq - s ) < 5)) {
622 printf("Dup seq %d prev %d\n",
633 mac2str(mac, c->mac);
634 printf("%s seq %d prev %d\n", mac, s, c->seq);
642 void ack(struct params *p, struct ieee80211_frame *wh)
644 if (memcmp(wh->i_addr1, p->mac, 6) != 0)
647 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL)
650 send_ack(p->tx, wh->i_addr2);
653 void read_wifi(struct params *p)
657 struct ieee80211_frame *wh;
659 rc = sniff(p->rx, buf, sizeof(buf));
663 wh = get_wifi(buf, &rc);
667 /* filter my own shit */
668 if (memcmp(wh->i_addr2, p->mac, 6) == 0) {
670 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) !=
671 IEEE80211_FC0_TYPE_CTL)
679 if (duplicate(p, wh, rc)) {
686 switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
687 case IEEE80211_FC0_TYPE_MGT:
691 case IEEE80211_FC0_TYPE_CTL:
695 case IEEE80211_FC0_TYPE_DATA:
696 read_data(p, wh, rc);
706 void read_tap(struct params *p)
710 int len = sizeof(buf);
713 struct ieee80211_frame *wh;
717 offset = sizeof(struct ieee80211_frame) + 8 - 14;
725 memset(buf, 0, sizeof(buf));
726 rd = read(p->tap, ptr, len);
731 wh = (struct ieee80211_frame*) buf;
732 memcpy(dst, ptr, sizeof(dst));
733 memcpy(src, ptr+6, sizeof(src));
735 memcpy(wh->i_addr3, src, sizeof(wh->i_addr3));
736 memcpy(wh->i_addr1, dst, sizeof(wh->i_addr1));
737 wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
738 wh->i_fc[1] |= IEEE80211_FC1_DIR_FROMDS;
740 wh->i_fc[1] |= IEEE80211_FC1_WEP;
743 ptr = (char*) (wh+1);
752 /* ether type overlaps w00t */
758 ptr = (char*) (wh+1);
759 memcpy(ptr, &p->wep_iv, 3);
763 wep_encrypt(wh, rd, p->wep_key, p->wep_len);
767 send_frame(p, wh, rd);
770 int retransmit(struct params *p)
773 printf("RETRANS %d\n", p->packet_try);
776 send_frame(p, p->packet, p->packet_len);
779 if (p->packet_try > 3)
782 if (gettimeofday(&p->plast, NULL) == -1)
783 err(1, "gettimeofday()");
786 return p->packet_try;
789 void next_event(struct params *p)
791 struct timeval to, now;
797 /* figure out select timeout */
798 if (gettimeofday(&now, NULL) == -1)
799 err(1, "gettimeofday()");
801 /* check beacon timeout */
802 el = elapsed(&p->blast, &now);
808 to.tv_sec = el/1000/1000;
809 to.tv_usec = el - to.tv_sec*1000*1000;
811 /* check tx timeout */
813 el = elapsed(&p->plast, &now);
815 /* check if we gotta retransmit more */
823 /* gotta retransmit in future */
826 if ((to.tv_sec*1000*1000 + to.tv_usec) > el) {
827 to.tv_sec = el/1000/1000;
828 to.tv_usec = el - to.tv_sec*1000*1000;
836 FD_SET(p->tap, &fds);
837 max = p->rx > p->tap ? p->rx : p->tap;
838 if (select(max+1, &fds, NULL, NULL, &to) == -1)
841 if (FD_ISSET(p->tap, &fds))
843 if (FD_ISSET(p->rx, &fds))
847 int main(int argc, char *argv[])
849 char *iface = "wlan0";
855 memset(&p, 0, sizeof(p));
856 memcpy(p.mac, "\x00\x00\xde\xfa\xce\x0d", 6);
857 strcpy(p.ssid, "sorbo");
860 if (gettimeofday(&p.blast, NULL) == -1)
861 err(1, "gettimeofday()");
864 while ((ch = getopt(argc, argv, "hi:s:m:w:c:t:")) != -1) {
874 p.chan = atoi(optarg);
878 strncpy(p.ssid, optarg, sizeof(p.ssid)-1);
879 p.ssid[sizeof(p.ssid)-1] = 0;
883 str2mac(p.mac, optarg);
887 if (str2wep(p.wep_key, &p.wep_len, optarg)) {
888 printf("Error parsing WEP key\n");
901 if ((p.tx = open_tx(iface)) == -1)
903 if ((p.rx = open_rx(iface)) == -1)
906 if ((p.tap = open_tap(tap)) == -1)
907 err(1, "open_tap()");
908 if (set_iface_mac(tap, p.mac) == -1)
909 err(1, "set_iface_mac()");