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
35 #include <net80211/ieee80211.h>
36 #include <sys/endian.h>
71 void usage(char *pname)
73 printf("Usage: %s <opts>\n"
85 void fill_basic(struct ieee80211_frame *wh, struct params *p)
92 memcpy(wh->i_addr1, p->ap, 6);
93 memcpy(wh->i_addr2, p->mac, 6);
94 memcpy(wh->i_addr3, p->bssid, 6);
96 seq = (short*)wh->i_seq;
97 *seq = seqfn(p->seq, 0);
100 void send_frame(struct params *p, void *buf, int len)
104 rc = inject(p->tx, buf, len);
106 if (errno == EMSGSIZE)
107 warnx("inject(len %d)", len);
109 err(1, "inject(len %d)", len);
110 } else if (rc != len)
111 errx(1, "injected %d but only %d sent", rc, len);
115 void send_probe_request(struct params *p)
118 struct ieee80211_frame *wh;
122 memset(buf, 0, sizeof(buf));
124 wh = (struct ieee80211_frame*) buf;
126 wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_REQ;
128 memset(wh->i_addr1, 0xFF, 6);
129 memset(wh->i_addr3, 0xFF, 6);
131 data = (char*) (wh + 1);
132 *data++ = 0; /* SSID */
133 *data++ = strlen(p->ssid);
134 strcpy(data, p->ssid);
135 data += strlen(p->ssid);
137 *data++ = 1; /* rates */
144 len = data - (char*)wh;
146 send_frame(p, buf, len);
149 void send_auth(struct params *p)
152 struct ieee80211_frame *wh;
156 memset(buf, 0, sizeof(buf));
158 wh = (struct ieee80211_frame*) buf;
160 wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_AUTH;
162 data = (char*) (wh + 1);
168 /* transaction no. */
176 len = data - (char*)wh;
178 send_frame(p, buf, len);
182 * Add an ssid element to a frame.
185 ieee80211_add_ssid(u_int8_t *frm, const u_int8_t *ssid, u_int len)
187 *frm++ = IEEE80211_ELEMID_SSID;
189 memcpy(frm, ssid, len);
193 void send_assoc(struct params *p)
196 struct ieee80211_frame w;
199 struct ieee80211_frame *wh;
201 int len, capinfo, lintval;
203 memset(&u, 0, sizeof(u));
205 wh = (struct ieee80211_frame*) &u.w;
207 wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_ASSOC_REQ;
209 data = (char*) (wh + 1);
212 capinfo = IEEE80211_CAPINFO_ESS;
214 capinfo |= IEEE80211_CAPINFO_PRIVACY;
215 *(uint16_t *)data = htole16(capinfo);
218 /* listen interval */
219 *(uint16_t *)data = htole16(100);
222 data = ieee80211_add_ssid(data, p->ssid, strlen(p->ssid));
224 *data++ = 1; /* rates */
231 len = data - (char*)wh;
233 send_frame(p, u.buf, len);
236 int for_me(struct ieee80211_frame *wh, char *mac)
238 return memcmp(wh->i_addr1, mac, 6) == 0;
241 int from_ap(struct ieee80211_frame *wh, char *mac)
243 return memcmp(wh->i_addr2, mac, 6) == 0;
246 void ack(struct params *p, struct ieee80211_frame *wh)
248 if (memcmp(wh->i_addr1, p->mac, 6) != 0)
251 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL)
254 send_ack(p->tx, wh->i_addr2);
257 void generic_process(struct ieee80211_frame *wh, struct params *p, int len)
267 if (!for_me(wh, p->mac))
270 /* ignore my own shit */
271 if (memcmp(wh->i_addr2, p->mac, 6) == 0) {
275 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
276 stype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
278 if (for_me(wh, p->mac) && type == IEEE80211_FC0_TYPE_DATA) {
279 /* sequence number & dups */
281 p->seq_rx = seqno(wh);
287 if (p->seq_rx + 1 == s) {
295 printf("Got seq %d, prev %d\n",
300 } else { /* we got pas stuff... */
301 if (p->seq_rx - s > 1000) {
303 printf("Seqno wrap seq %d, last %d\n",
306 /* seqno wrapping ? */
312 printf("Got dup seq %d, last %d\n",
320 if (wh->i_fc[1] & IEEE80211_FC1_RETRY) {
321 printf("Got retry\n");
325 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_CTL) {
326 int rc = send_ack(p->tx, wh->i_addr2);
328 err(1, "send_ack()");
330 printf("Wrote ACK %d/%d\n", rc, 10);
337 if (type == IEEE80211_FC0_TYPE_DATA && !dup) {
342 if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) {
343 if (memcmp(wh->i_addr2, p->ap, 6) != 0)
346 if (memcmp(wh->i_addr1, p->ap, 6) != 0)
351 if (p->state < S_ASSOCIATED) {
352 printf("Got data when not associated!\n");
355 if (stype != IEEE80211_FC0_SUBTYPE_DATA) {
356 printf("Got weird data frame stype=%d\n",
357 stype >> IEEE80211_FC0_SUBTYPE_SHIFT);
361 if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) {
362 memcpy(src, wh->i_addr3, 6);
363 memcpy(dst, wh->i_addr1, 6);
365 memcpy(src, wh->i_addr2, 6);
366 memcpy(dst, wh->i_addr3, 6);
369 ptr = (char*) (wh + 1);
371 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
378 printf("Got wep but i aint wep %s->%s %d\n",
379 srca, dsta, len-sizeof(*wh)-8);
383 if (wep_decrypt(wh, len, p->wep_key, p->wep_len) == -1){
389 printf("Can't decrypt %s->%s %d\n", srca, dsta,
410 rc = write(p->tap, ptr, len);
414 printf("Wrote %d/%d\n", rc, len);
420 int get_probe_response(struct params *p)
424 struct ieee80211_frame *wh;
432 rc = sniff(p->rx, buf, sizeof(buf));
436 wh = get_wifi(buf, &rc);
440 generic_process(wh, p, rc);
442 if (!for_me(wh, p->mac))
445 if (!frame_type(wh, IEEE80211_FC0_TYPE_MGT,
446 IEEE80211_FC0_SUBTYPE_PROBE_RESP))
449 data = (char*) (wh+1);
450 data += 8; /* Timestamp */
451 data += 2; /* Beacon Interval */
453 wep = (*data & IEEE80211_CAPINFO_PRIVACY) ? 1 : 0;
454 data += 2; /* capability */
458 printf("Warning, expecting SSID got %x\n", *data);
465 printf("Warning, expected rates got %x\n", *data);
473 mac2str(from, wh->i_addr2);
474 mac2str(bssid, wh->i_addr3);
475 printf("Got response from %s [%s] [%s] ESS=%d WEP=%d\n",
476 from, bssid, ssid, ess, wep);
478 if (strcmp(ssid, p->ssid) != 0)
481 memcpy(p->ap, wh->i_addr2, 6);
482 memcpy(p->bssid, wh->i_addr3, 6);
486 int get_auth(struct params *p)
490 struct ieee80211_frame *wh;
493 rc = sniff(p->rx, buf, sizeof(buf));
497 wh = get_wifi(buf, &rc);
501 generic_process(wh, p, rc);
503 if (!for_me(wh, p->mac))
506 if (!from_ap(wh, p->ap))
509 if (!frame_type(wh, IEEE80211_FC0_TYPE_MGT,
510 IEEE80211_FC0_SUBTYPE_AUTH))
513 data = (short*) (wh+1);
516 if (le16toh(*data) != 0) {
517 printf("Not open-system %d!\n", le16toh(*data));
522 /* transaction no. */
523 if (le16toh(*data) != 2) {
524 printf("Got transaction %d!\n", le16toh(*data));
532 printf("Authenticated\n");
536 printf("Authentication failed code=%d\n", rc);
540 int get_assoc(struct params *p)
544 struct ieee80211_frame *wh;
545 unsigned short *data;
547 rc = sniff(p->rx, buf, sizeof(buf));
551 wh = get_wifi(buf, &rc);
555 generic_process(wh, p, rc);
557 if (!for_me(wh, p->mac))
560 if (!from_ap(wh, p->ap))
563 if (!frame_type(wh, IEEE80211_FC0_TYPE_MGT,
564 IEEE80211_FC0_SUBTYPE_ASSOC_RESP))
568 data = (unsigned short*) (wh+1);
573 rc = le16toh(*data++);
575 printf("Assoc failed code %d\n", rc);
580 p->aid = le16toh(*data & ~( (1 << 15) | (1 << 14)));
581 printf("Association ID=%d\n", p->aid);
586 void read_wifi(struct params *p)
590 struct ieee80211_frame *wh;
593 rc = sniff(p->rx, buf, sizeof(buf));
597 wh = get_wifi(buf, &rc);
601 generic_process(wh, p, rc);
603 if (!for_me(wh, p->mac))
606 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
607 stype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
610 if (type == IEEE80211_FC0_TYPE_CTL) {
612 case IEEE80211_FC0_SUBTYPE_ACK:
613 if (p->state == S_WAIT_ACK)
614 p->state = S_ASSOCIATED;
617 case IEEE80211_FC0_SUBTYPE_RTS:
624 printf("Unknown CTL frame %d\n",
625 stype >> IEEE80211_FC0_SUBTYPE_SHIFT);
632 if (!from_ap(wh, p->ap))
635 if (type != IEEE80211_FC0_TYPE_MGT)
638 if (stype == IEEE80211_FC0_SUBTYPE_DEAUTH ||
639 stype == IEEE80211_FC0_SUBTYPE_DISASSOC) {
640 printf("Got management! %d\n",
641 stype >> IEEE80211_FC0_SUBTYPE_SHIFT);
649 void read_tap(struct params *p)
652 int len = sizeof(p->packet);
655 struct ieee80211_frame *wh;
658 offset = sizeof(struct ieee80211_frame) + 8 - 14;
666 memset(p->packet, 0, sizeof(p->packet));
667 p->packet_len = read(p->tap, ptr, len);
668 if (p->packet_len == -1)
672 wh = (struct ieee80211_frame*) p->packet;
673 memcpy(mac, ptr, sizeof(mac));
675 memcpy(wh->i_addr3, mac, sizeof(wh->i_addr3));
676 wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
677 wh->i_fc[1] |= IEEE80211_FC1_DIR_TODS;
679 wh->i_fc[1] |= IEEE80211_FC1_WEP;
682 ptr = (char*) (wh+1);
691 /* ether type overlaps w00t */
693 p->packet_len += offset;
697 ptr = (char*) (wh+1);
698 memcpy(ptr, &p->wep_iv, 3);
702 wep_encrypt(wh, p->packet_len, p->wep_key, p->wep_len);
703 p->packet_len += 4; /* ICV */
707 int main(int argc, char *argv[])
710 char mac[] = { 0x00, 0x00, 0xde, 0xfa, 0xce, 0xd };
713 char *iface = "wlan0";
715 int timeout = 50*1000;
716 struct timeval start;
718 memset(&p, 0, sizeof(p));
723 while ((ch = getopt(argc, argv, "hm:s:i:w:t:b:")) != -1) {
726 if (str2mac(p.bssid, optarg)) {
727 printf("Error parsing BSSID\n");
730 memcpy(p.ap, p.bssid, sizeof(p.ap));
731 p.state = S_SEND_AUTH;
739 if (str2mac(mac, optarg)) {
740 printf("Error parsing MAC\n");
750 if (str2wep(p.wep_key, &p.wep_len, optarg)) {
751 printf("Error parsing WEP key\n");
774 if (open_rxtx(iface, &p.rx, &p.tx) == -1)
775 err(1, "open_rxtx()");
776 p.tap = open_tap(tap);
778 err(1, "open_tap()");
779 if (set_iface_mac(tap, mac) == -1)
780 err(1, "set_iface_mac()");
783 /* check for timeouts */
785 case S_WAIT_PROBE_RES:
795 if (gettimeofday(&tv, NULL) == -1)
796 err(1, "gettimeofday()");
797 elapsed = tv.tv_sec - start.tv_sec;
799 elapsed = tv.tv_usec - start.tv_usec;
801 elapsed *= (elapsed-1)*1000*1000;
802 elapsed += 1000*1000 - start.tv_usec;
803 elapsed += tv.tv_usec;
805 if (elapsed >= timeout)
813 elapsed = timeout - elapsed;
814 tv.tv_sec = elapsed/1000/1000;
815 elapsed -= tv.tv_sec*1000*1000;
816 tv.tv_usec = elapsed;
818 rc = select(p.rx+1, &fds, NULL,
838 p.state = S_SEND_PROBE_REQ;
841 case S_SEND_PROBE_REQ:
842 printf("Sending probe request for %s\n", ssid);
843 send_probe_request(&p);
844 p.state = S_WAIT_PROBE_RES;
845 if (gettimeofday(&start, NULL) == -1)
846 err(1, "gettimeofday()");
849 case S_WAIT_PROBE_RES:
850 if (get_probe_response(&p)) {
851 p.state = S_SEND_AUTH;
859 mac2str(apmac, p.ap);
860 printf("Sending auth to %s\n", apmac);
862 p.state = S_WAIT_AUTH;
863 if (gettimeofday(&start, NULL) == -1)
864 err(1, "gettimeofday()");
870 p.state = S_SEND_ASSOC;
875 printf("Sending assoc\n");
877 p.state = S_WAIT_ASSOC;
878 if (gettimeofday(&start, NULL) == -1)
879 err(1, "gettimeofday()");
884 printf("Associated\n");
885 p.state = S_ASSOCIATED;
897 max = (p.rx > p.tap) ? p.rx : p.tap;
899 max = select(max+1, &fds, NULL, NULL, NULL);
903 if (FD_ISSET(p.tap, &fds)) {
905 p.state = S_SEND_DATA;
907 if (FD_ISSET(p.rx, &fds)) {
914 send_frame(&p, p.packet, p.packet_len);
916 struct ieee80211_frame *wh;
918 wh = (struct ieee80211_frame*) p.packet;
919 wh->i_fc[1] |= IEEE80211_FC1_RETRY;
921 p.state = S_WAIT_ACK;
922 if (gettimeofday(&start, NULL) == -1)
923 err(1, "gettimeofday()");
931 printf("Unknown state %d\n", p.state);