1 From 4e7af9f022996cb0a03b30f6af265b757807dfa2 Mon Sep 17 00:00:00 2001
2 From: Paul Fertser <fercerpav@gmail.com>
3 Date: Wed, 27 Jun 2012 17:44:55 +0400
4 Subject: [PATCH 1/3] wpscrack: big-endian fixes
6 This should fix access to the radiotap, 802.11, LLC/SNAP and WFA
7 headers' fields. Run-time tested on an ar71xx BE system.
9 Signed-off-by: Paul Fertser <fercerpav@gmail.com>
11 src/80211.c | 65 +++++++++++++++++++------------
12 src/builder.c | 23 +++++------
13 src/defs.h | 116 +++++++++++++++++++++++++++++++++++++++-----------------
14 src/exchange.c | 23 ++++++-----
15 src/wpsmon.c | 13 ++++--
16 5 files changed, 151 insertions(+), 89 deletions(-)
18 diff --git a/src/80211.c b/src/80211.c
19 index c2aff59..19f1e92 100644
22 @@ -90,17 +90,19 @@ void read_ap_beacon()
23 if(header.len >= MIN_BEACON_SIZE)
25 rt_header = (struct radio_tap_header *) radio_header(packet, header.len);
26 - frame_header = (struct dot11_frame_header *) (packet + rt_header->len);
28 + size_t rt_header_len = __le16_to_cpu(rt_header->len);
29 + frame_header = (struct dot11_frame_header *) (packet + rt_header_len);
31 if(is_target(frame_header))
33 - if(frame_header->fc.type == MANAGEMENT_FRAME && frame_header->fc.sub_type == SUBTYPE_BEACON)
34 + if((frame_header->fc & __cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
35 + __cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON))
37 - beacon = (struct beacon_management_frame *) (packet + rt_header->len + sizeof(struct dot11_frame_header));
38 + beacon = (struct beacon_management_frame *) (packet + rt_header_len + sizeof(struct dot11_frame_header));
39 set_ap_capability(beacon->capability);
41 /* Obtain the SSID and channel number from the beacon packet */
42 - tag_offset = rt_header->len + sizeof(struct dot11_frame_header) + sizeof(struct beacon_management_frame);
43 + tag_offset = rt_header_len + sizeof(struct dot11_frame_header) + sizeof(struct beacon_management_frame);
44 channel = parse_beacon_tags(packet, header.len);
46 /* If no channel was manually specified, switch to the AP's current channel */
47 @@ -135,29 +137,31 @@ int8_t signal_strength(const u_char *packet, size_t len)
49 header = (struct radio_tap_header *) packet;
51 - if((header->flags & SSI_FLAG) == SSI_FLAG)
52 + uint32_t flags = __le32_to_cpu(header->flags);
54 + if((flags & SSI_FLAG) == SSI_FLAG)
56 - if((header->flags & TSFT_FLAG) == TSFT_FLAG)
57 + if((flags & TSFT_FLAG) == TSFT_FLAG)
62 - if((header->flags & FLAGS_FLAG) == FLAGS_FLAG)
63 + if((flags & FLAGS_FLAG) == FLAGS_FLAG)
68 - if((header->flags & RATE_FLAG) == RATE_FLAG)
69 + if((flags & RATE_FLAG) == RATE_FLAG)
74 - if((header->flags & CHANNEL_FLAG) == CHANNEL_FLAG)
75 + if((flags & CHANNEL_FLAG) == CHANNEL_FLAG)
77 offset += CHANNEL_SIZE;
80 - if((header->flags & FHSS_FLAG) == FHSS_FLAG)
81 + if((flags & FHSS_FLAG) == FHSS_FLAG)
85 @@ -196,11 +200,13 @@ int is_wps_locked()
86 if(header.len >= MIN_BEACON_SIZE)
88 rt_header = (struct radio_tap_header *) radio_header(packet, header.len);
89 - frame_header = (struct dot11_frame_header *) (packet + rt_header->len);
90 + size_t rt_header_len = __le16_to_cpu(rt_header->len);
91 + frame_header = (struct dot11_frame_header *) (packet + rt_header_len);
93 if(memcmp(frame_header->addr3, get_bssid(), MAC_ADDR_LEN) == 0)
95 - if(frame_header->fc.type == MANAGEMENT_FRAME && frame_header->fc.sub_type == SUBTYPE_BEACON)
96 + if((frame_header->fc & __cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
97 + __cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON))
99 if(parse_wps_parameters(packet, header.len, &wps))
101 @@ -411,24 +417,30 @@ int associate_recv_loop()
102 if(header.len >= MIN_AUTH_SIZE)
104 rt_header = (struct radio_tap_header *) radio_header(packet, header.len);
105 - dot11_frame = (struct dot11_frame_header *) (packet + rt_header->len);
106 + size_t rt_header_len = __le16_to_cpu(rt_header->len);
107 + dot11_frame = (struct dot11_frame_header *) (packet + rt_header_len);
109 if((memcmp(dot11_frame->addr3, get_bssid(), MAC_ADDR_LEN) == 0) &&
110 (memcmp(dot11_frame->addr1, get_mac(), MAC_ADDR_LEN) == 0))
112 - if(dot11_frame->fc.type == MANAGEMENT_FRAME)
113 + if((dot11_frame->fc & __cpu_to_le16(IEEE80211_FCTL_FTYPE)) ==
114 + __cpu_to_le16(IEEE80211_FTYPE_MGMT))
116 - auth_frame = (struct authentication_management_frame *) (packet + sizeof(struct dot11_frame_header) + rt_header->len);
117 - assoc_frame = (struct association_response_management_frame *) (packet + sizeof(struct dot11_frame_header) + rt_header->len);
118 + auth_frame = (struct authentication_management_frame *) (packet + sizeof(struct dot11_frame_header) + rt_header_len);
119 + assoc_frame = (struct association_response_management_frame *) (packet + sizeof(struct dot11_frame_header) + rt_header_len);
121 /* Did we get an authentication packet with a successful status? */
122 - if((dot11_frame->fc.sub_type == SUBTYPE_AUTHENTICATION) && (auth_frame->status == AUTHENTICATION_SUCCESS))
123 + if((dot11_frame->fc & __cpu_to_le16(IEEE80211_FCTL_STYPE)) ==
124 + __cpu_to_le16(IEEE80211_STYPE_AUTH)
125 + && (auth_frame->status == __cpu_to_le16(AUTHENTICATION_SUCCESS)))
130 /* Did we get an association packet with a successful status? */
131 - else if((dot11_frame->fc.sub_type == SUBTYPE_ASSOCIATION) && (assoc_frame->status == ASSOCIATION_SUCCESS))
132 + else if((dot11_frame->fc & __cpu_to_le16(IEEE80211_FCTL_STYPE)) ==
133 + __cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP)
134 + && (assoc_frame->status == __cpu_to_le16(ASSOCIATION_SUCCESS)))
136 ret_val = ASSOCIATE_OK;
138 @@ -455,13 +467,14 @@ enum encryption_type supported_encryption(const u_char *packet, size_t len)
139 if(len > MIN_BEACON_SIZE)
141 rt_header = (struct radio_tap_header *) radio_header(packet, len);
142 - beacon = (struct beacon_management_frame *) (packet + rt_header->len + sizeof(struct dot11_frame_header));
143 - offset = tag_offset = rt_header->len + sizeof(struct dot11_frame_header) + sizeof(struct beacon_management_frame);
144 + size_t rt_header_len = __le16_to_cpu(rt_header->len);
145 + beacon = (struct beacon_management_frame *) (packet + rt_header_len + sizeof(struct dot11_frame_header));
146 + offset = tag_offset = rt_header_len + sizeof(struct dot11_frame_header) + sizeof(struct beacon_management_frame);
148 tag_len = len - tag_offset;
149 tag_data = (const u_char *) (packet + tag_offset);
151 - if((beacon->capability & CAPABILITY_WEP) == CAPABILITY_WEP)
152 + if((__le16_to_cpu(beacon->capability) & CAPABILITY_WEP) == CAPABILITY_WEP)
156 @@ -509,7 +522,7 @@ int parse_beacon_tags(const u_char *packet, size_t len)
157 struct radio_tap_header *rt_header = NULL;
159 rt_header = (struct radio_tap_header *) radio_header(packet, len);
160 - tag_offset = rt_header->len + sizeof(struct dot11_frame_header) + sizeof(struct beacon_management_frame);
161 + tag_offset = __le16_to_cpu(rt_header->len) + sizeof(struct dot11_frame_header) + sizeof(struct beacon_management_frame);
165 @@ -548,7 +561,7 @@ int parse_beacon_tags(const u_char *packet, size_t len)
169 - memcpy((int *) &channel, channel_data, ie_len);
170 + channel = *(uint8_t*)channel_data;
174 @@ -603,13 +616,13 @@ int check_fcs(const u_char *packet, size_t len)
177 /* Get the packet's reported FCS (last 4 bytes of the packet) */
178 - memcpy((uint32_t *) &fcs, (packet + (len-4)), 4);
179 + fcs = __le32_to_cpu(*(uint32_t*)(packet + (len-4)));
181 /* FCS is not calculated over the radio tap header */
184 rt_header = (struct radio_tap_header *) packet;
185 - offset += rt_header->len;
186 + offset += __le16_to_cpu(rt_header->len);
190 diff --git a/src/builder.c b/src/builder.c
191 index 37f2de7..6bf89e7 100644
194 @@ -44,9 +44,8 @@ const void *build_radio_tap_header(size_t *len)
195 memset((void *) buf, 0, sizeof(struct radio_tap_header));
196 rt_header = (struct radio_tap_header *) buf;
198 - rt_header->len = sizeof(struct radio_tap_header);
200 - *len = rt_header->len;
201 + *len = sizeof(struct radio_tap_header);
202 + rt_header->len = __cpu_to_le16(*len);
206 @@ -67,9 +66,9 @@ const void *build_dot11_frame_header(uint16_t fc, size_t *len)
208 frag_seq += SEQ_MASK;
210 - header->duration = DEFAULT_DURATION;
211 - memcpy((void *) &header->fc, (void *) &fc, sizeof(struct frame_control));
212 - header->frag_seq = frag_seq;
213 + header->duration = __cpu_to_le16(DEFAULT_DURATION);
214 + header->fc = __cpu_to_le16(fc);
215 + header->frag_seq = __cpu_to_le16(frag_seq);
217 memcpy((void *) header->addr1, get_bssid(), MAC_ADDR_LEN);
218 memcpy((void *) header->addr2, get_mac(), MAC_ADDR_LEN);
219 @@ -91,8 +90,8 @@ const void *build_authentication_management_frame(size_t *len)
220 memset((void *) buf, 0, *len);
221 frame = (struct authentication_management_frame *) buf;
223 - frame->algorithm = OPEN_SYSTEM;
224 - frame->sequence = 1;
225 + frame->algorithm = __cpu_to_le16(OPEN_SYSTEM);
226 + frame->sequence = __cpu_to_le16(1);
230 @@ -111,8 +110,8 @@ const void *build_association_management_frame(size_t *len)
231 memset((void *) buf, 0, *len);
232 frame = (struct association_request_management_frame *) buf;
234 - frame->capability = get_ap_capability();
235 - frame->listen_interval = LISTEN_INTERVAL;
236 + frame->capability = __cpu_to_le16(get_ap_capability());
237 + frame->listen_interval = __cpu_to_le16(LISTEN_INTERVAL);
241 @@ -133,7 +132,7 @@ const void *build_llc_header(size_t *len)
242 header->dsap = LLC_SNAP;
243 header->ssap = LLC_SNAP;
244 header->control_field = UNNUMBERED_FRAME;
245 - header->type = DOT1X_AUTHENTICATION;
246 + header->type = __cpu_to_be16(DOT1X_AUTHENTICATION);
250 @@ -279,7 +278,7 @@ const void *build_wfa_header(uint8_t op_code, size_t *len)
251 header = (struct wfa_expanded_header *) buf;
253 memcpy(header->id, WFA_VENDOR_ID, sizeof(header->id));
254 - header->type = SIMPLE_CONFIG;
255 + header->type = __cpu_to_be32(SIMPLE_CONFIG);
256 header->opcode = op_code;
259 diff --git a/src/defs.h b/src/defs.h
260 index b2f45ea..0c628e7 100644
267 +#include <asm/byteorder.h>
272 #define MANAGEMENT_FRAME 0x00
273 #define SUBTYPE_BEACON 0x08
275 -#define DOT1X_AUTHENTICATION 0x8E88
276 +#define DOT1X_AUTHENTICATION 0x888E
277 #define DOT1X_EAP_PACKET 0x00
279 -#define SIMPLE_CONFIG 0x01000000
280 +#define SIMPLE_CONFIG 0x00000001
282 #define P1_SIZE 10000
284 @@ -282,66 +283,111 @@ enum wfa_elements
285 WEP_TRANSMIT_KEY = 0x10064
288 +#define IEEE80211_FCTL_VERS 0x0003
289 +#define IEEE80211_FCTL_FTYPE 0x000c
290 +#define IEEE80211_FCTL_STYPE 0x00f0
291 +#define IEEE80211_FCTL_TODS 0x0100
292 +#define IEEE80211_FCTL_FROMDS 0x0200
293 +#define IEEE80211_FCTL_MOREFRAGS 0x0400
294 +#define IEEE80211_FCTL_RETRY 0x0800
295 +#define IEEE80211_FCTL_PM 0x1000
296 +#define IEEE80211_FCTL_MOREDATA 0x2000
297 +#define IEEE80211_FCTL_PROTECTED 0x4000
298 +#define IEEE80211_FCTL_ORDER 0x8000
300 +#define IEEE80211_SCTL_FRAG 0x000F
301 +#define IEEE80211_SCTL_SEQ 0xFFF0
303 +#define IEEE80211_FTYPE_MGMT 0x0000
304 +#define IEEE80211_FTYPE_CTL 0x0004
305 +#define IEEE80211_FTYPE_DATA 0x0008
308 +#define IEEE80211_STYPE_ASSOC_REQ 0x0000
309 +#define IEEE80211_STYPE_ASSOC_RESP 0x0010
310 +#define IEEE80211_STYPE_REASSOC_REQ 0x0020
311 +#define IEEE80211_STYPE_REASSOC_RESP 0x0030
312 +#define IEEE80211_STYPE_PROBE_REQ 0x0040
313 +#define IEEE80211_STYPE_PROBE_RESP 0x0050
314 +#define IEEE80211_STYPE_BEACON 0x0080
315 +#define IEEE80211_STYPE_ATIM 0x0090
316 +#define IEEE80211_STYPE_DISASSOC 0x00A0
317 +#define IEEE80211_STYPE_AUTH 0x00B0
318 +#define IEEE80211_STYPE_DEAUTH 0x00C0
319 +#define IEEE80211_STYPE_ACTION 0x00D0
322 +#define IEEE80211_STYPE_BACK_REQ 0x0080
323 +#define IEEE80211_STYPE_BACK 0x0090
324 +#define IEEE80211_STYPE_PSPOLL 0x00A0
325 +#define IEEE80211_STYPE_RTS 0x00B0
326 +#define IEEE80211_STYPE_CTS 0x00C0
327 +#define IEEE80211_STYPE_ACK 0x00D0
328 +#define IEEE80211_STYPE_CFEND 0x00E0
329 +#define IEEE80211_STYPE_CFENDACK 0x00F0
332 +#define IEEE80211_STYPE_DATA 0x0000
333 +#define IEEE80211_STYPE_DATA_CFACK 0x0010
334 +#define IEEE80211_STYPE_DATA_CFPOLL 0x0020
335 +#define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030
336 +#define IEEE80211_STYPE_NULLFUNC 0x0040
337 +#define IEEE80211_STYPE_CFACK 0x0050
338 +#define IEEE80211_STYPE_CFPOLL 0x0060
339 +#define IEEE80211_STYPE_CFACKPOLL 0x0070
340 +#define IEEE80211_STYPE_QOS_DATA 0x0080
341 +#define IEEE80211_STYPE_QOS_DATA_CFACK 0x0090
342 +#define IEEE80211_STYPE_QOS_DATA_CFPOLL 0x00A0
343 +#define IEEE80211_STYPE_QOS_DATA_CFACKPOLL 0x00B0
344 +#define IEEE80211_STYPE_QOS_NULLFUNC 0x00C0
345 +#define IEEE80211_STYPE_QOS_CFACK 0x00D0
346 +#define IEEE80211_STYPE_QOS_CFPOLL 0x00E0
347 +#define IEEE80211_STYPE_QOS_CFACKPOLL 0x00F0
350 struct radio_tap_header
358 -struct frame_control
360 - unsigned version : 2;
362 - unsigned sub_type : 4;
364 - unsigned to_ds : 1;
365 - unsigned from_ds : 1;
366 - unsigned more_frag : 1;
367 - unsigned retry : 1;
368 - unsigned pwr_mgt : 1;
369 - unsigned more_data : 1;
370 - unsigned protected_frame : 1;
371 - unsigned order : 1;
376 struct dot11_frame_header
378 - struct frame_control fc;
382 unsigned char addr1[MAC_ADDR_LEN];
383 unsigned char addr2[MAC_ADDR_LEN];
384 unsigned char addr3[MAC_ADDR_LEN];
389 struct authentication_management_frame
391 - uint16_t algorithm;
399 struct association_request_management_frame
401 - uint16_t capability;
402 - uint16_t listen_interval;
404 + __le16 listen_interval;
407 struct association_response_management_frame
409 - uint16_t capability;
417 struct beacon_management_frame
419 unsigned char timestamp[TIMESTAMP_LEN];
420 - uint16_t beacon_interval;
421 - uint16_t capability;
422 + __le16 beacon_interval;
427 @@ -350,7 +396,7 @@ struct llc_header
429 uint8_t control_field;
430 unsigned char org_code[3];
436 @@ -371,7 +417,7 @@ struct eap_header
437 struct wfa_expanded_header
445 diff --git a/src/exchange.c b/src/exchange.c
446 index 23c87e9..4f9a82b 100644
449 @@ -306,26 +306,27 @@ enum wps_type process_packet(const u_char *packet, struct pcap_pkthdr *header)
451 /* Cast the radio tap and 802.11 frame headers and parse out the Frame Control field */
452 rt_header = (struct radio_tap_header *) packet;
453 - frame_header = (struct dot11_frame_header *) (packet+rt_header->len);
454 + size_t rt_header_len = __le16_to_cpu(rt_header->len);
455 + frame_header = (struct dot11_frame_header *) (packet+rt_header_len);
457 /* Does the BSSID/source address match our target BSSID? */
458 if(memcmp(frame_header->addr3, get_bssid(), MAC_ADDR_LEN) == 0)
460 /* Is this a data packet sent to our MAC address? */
461 - if(frame_header->fc.type == DATA_FRAME &&
462 - frame_header->fc.sub_type == SUBTYPE_DATA &&
463 - (memcmp(frame_header->addr1, get_mac(), MAC_ADDR_LEN) == 0))
464 + if (((frame_header->fc & __cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
465 + __cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA)) &&
466 + (memcmp(frame_header->addr1, get_mac(), MAC_ADDR_LEN) == 0))
468 llc = (struct llc_header *) (packet +
471 sizeof(struct dot11_frame_header)
474 /* All packets in our exchanges will be 802.1x */
475 - if(llc->type == DOT1X_AUTHENTICATION)
476 + if(llc->type == __cpu_to_be16(DOT1X_AUTHENTICATION))
478 dot1x = (struct dot1X_header *) (packet +
481 sizeof(struct dot11_frame_header) +
482 sizeof(struct llc_header)
484 @@ -334,7 +335,7 @@ enum wps_type process_packet(const u_char *packet, struct pcap_pkthdr *header)
485 if(dot1x->type == DOT1X_EAP_PACKET && (header->len >= EAP_PACKET_SIZE))
487 eap = (struct eap_header *) (packet +
490 sizeof(struct dot11_frame_header) +
491 sizeof(struct llc_header) +
492 sizeof(struct dot1X_header)
493 @@ -366,7 +367,7 @@ enum wps_type process_packet(const u_char *packet, struct pcap_pkthdr *header)
494 else if((eap->type == EAP_EXPANDED) && (header->len > WFA_PACKET_SIZE))
496 wfa = (struct wfa_expanded_header *) (packet +
499 sizeof(struct dot11_frame_header) +
500 sizeof(struct llc_header) +
501 sizeof(struct dot1X_header) +
502 @@ -374,14 +375,14 @@ enum wps_type process_packet(const u_char *packet, struct pcap_pkthdr *header)
505 /* Verify that this is a WPS message */
506 - if(wfa->type == SIMPLE_CONFIG)
507 + if(wfa->type == __cpu_to_be32(SIMPLE_CONFIG))
509 wps_msg_len = (size_t) ntohs(eap->len) -
510 sizeof(struct eap_header) -
511 sizeof(struct wfa_expanded_header);
513 wps_msg = (const void *) (packet +
516 sizeof(struct dot11_frame_header) +
517 sizeof(struct llc_header) +
518 sizeof(struct dot1X_header) +
519 diff --git a/src/wpsmon.c b/src/wpsmon.c
520 index d976924..22a394f 100644
523 @@ -295,7 +295,8 @@ void parse_wps_settings(const u_char *packet, struct pcap_pkthdr *header, char *
526 rt_header = (struct radio_tap_header *) radio_header(packet, header->len);
527 - frame_header = (struct dot11_frame_header *) (packet + rt_header->len);
528 + size_t rt_header_len = __le16_to_cpu(rt_header->len);
529 + frame_header = (struct dot11_frame_header *) (packet + rt_header_len);
531 /* If a specific BSSID was specified, only parse packets from that BSSID */
532 if(!is_target(frame_header))
533 @@ -323,15 +324,17 @@ void parse_wps_settings(const u_char *packet, struct pcap_pkthdr *header, char *
537 - if(frame_header->fc.sub_type == PROBE_RESPONSE ||
538 - frame_header->fc.sub_type == SUBTYPE_BEACON)
539 + unsigned fsub_type = frame_header->fc & __cpu_to_le16(IEEE80211_FCTL_STYPE);
541 + if(fsub_type == __cpu_to_le16(IEEE80211_STYPE_PROBE_RESP) ||
542 + fsub_type == __cpu_to_le16(IEEE80211_STYPE_BEACON))
544 wps_parsed = parse_wps_parameters(packet, header->len, wps);
547 if(!is_done(bssid) && (get_channel() == channel || source == PCAP_FILE))
549 - if(frame_header->fc.sub_type == SUBTYPE_BEACON &&
550 + if(fsub_type == __cpu_to_le16(IEEE80211_STYPE_BEACON) &&
554 @@ -369,7 +372,7 @@ void parse_wps_settings(const u_char *packet, struct pcap_pkthdr *header, char *
555 * If there was no WPS information, then the AP does not support WPS and we should ignore it from here on.
556 * If this was a probe response, then we've gotten all WPS info we can get from this AP and should ignore it from here on.
558 - if(!wps_parsed || frame_header->fc.sub_type == PROBE_RESPONSE)
559 + if(!wps_parsed || fsub_type == __cpu_to_le16(IEEE80211_STYPE_PROBE_RESP))
561 mark_ap_complete(bssid);