Clean include statements
[qemu/ar7.git] / hw / net / atheros_wlan_packet.c
blob3416553aa147546ff425690b8e85dd1d6dba8e7d
1 /**
2 * QEMU WLAN access point emulation
4 * Copyright (c) 2008 Clemens Kolbitsch
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
24 * Modifications:
25 * 2008-February-24 Clemens Kolbitsch :
26 * New implementation based on ne2000.c
30 #include "qemu/osdep.h"
32 #if defined(CONFIG_WIN32)
33 #warning("not compiled for Windows host")
34 #else
36 #include "hw.h"
37 #include "pci/pci.h"
38 #include "pc.h"
39 #include "net/net.h"
41 #include <sys/shm.h>
42 #include <sys/socket.h>
43 #include <sys/ipc.h>
44 #include <sys/sem.h>
45 #include <sys/mman.h>
46 #include <netinet/in.h>
47 #include <netdb.h>
50 #include "hw/atheros_wlan.h"
51 #include "hw/atheros_wlan_crc32.h"
52 #include "hw/atheros_wlan_packet.h"
54 #define FRAME_INSERT(_8bit_data) buf[i++] = _8bit_data
57 static int insertCRC(mac80211_frame *frame, uint32_t frame_length)
59 unsigned long crc;
60 unsigned char *fcs = (unsigned char *)frame;
62 crc = crc32_ccitt(fcs, frame_length);
63 memcpy(&fcs[frame_length], &crc, 4);
65 return frame_length + 4;
69 void Atheros_WLAN_init_frame(Atheros_WLANState *s, mac80211_frame *frame)
71 if (!frame) {
72 return;
75 frame->sequence_control.sequence_number = s->inject_sequence_number++;
76 memcpy(frame->source_address, s->ap_macaddr, 6);
77 memcpy(frame->bssid_address, s->ap_macaddr, 6);
79 frame->frame_length = insertCRC(frame, frame->frame_length);
83 mac80211_frame *Atheros_WLAN_create_beacon_frame(void)
85 unsigned int i;
86 unsigned char *buf;
87 mac80211_frame *frame;
89 frame = (mac80211_frame *)malloc(sizeof(mac80211_frame));
90 if (!frame) {
91 return NULL;
94 frame->next_frame = NULL;
95 frame->frame_control.protocol_version = 0;
96 frame->frame_control.type = IEEE80211_TYPE_MGT;
97 frame->frame_control.sub_type = IEEE80211_TYPE_MGT_SUBTYPE_BEACON;
98 frame->frame_control.flags = 0;
99 frame->duration_id = 0;
100 frame->sequence_control.fragment_number = 0;
102 for (i = 0; i < 6; frame->destination_address[i] = 0xff, i++) {
105 i = 0;
106 buf = (unsigned char *)frame->data_and_fcs;
109 * Fixed params... typical AP params (12 byte)
111 * They include
112 * - Timestamp
113 * - Beacon Interval
114 * - Capability Information
116 FRAME_INSERT(0x8d);
117 FRAME_INSERT(0x61);
118 FRAME_INSERT(0xa5);
119 FRAME_INSERT(0x18);
120 FRAME_INSERT(0x00);
121 FRAME_INSERT(0x00);
122 FRAME_INSERT(0x00);
123 FRAME_INSERT(0x00);
124 FRAME_INSERT(0x64);
125 FRAME_INSERT(0x00);
126 FRAME_INSERT(0x01);
127 FRAME_INSERT(0x00);
129 FRAME_INSERT(IEEE80211_BEACON_PARAM_SSID);
130 FRAME_INSERT(4); /* length */
131 FRAME_INSERT('Q'); /* SSID */
132 FRAME_INSERT('L'); /* SSID */
133 FRAME_INSERT('a'); /* SSID */
134 FRAME_INSERT('n'); /* SSID */
136 FRAME_INSERT(IEEE80211_BEACON_PARAM_RATES);
137 FRAME_INSERT(8); /* length */
138 FRAME_INSERT(0x82);
139 FRAME_INSERT(0x84);
140 FRAME_INSERT(0x8b);
141 FRAME_INSERT(0x96);
142 FRAME_INSERT(0x24);
143 FRAME_INSERT(0x30);
144 FRAME_INSERT(0x48);
145 FRAME_INSERT(0x6c);
147 FRAME_INSERT(IEEE80211_BEACON_PARAM_CHANNEL);
148 FRAME_INSERT(1); /* length */
149 FRAME_INSERT(0x09);
151 frame->frame_length = IEEE80211_HEADER_SIZE + i;
152 return frame;
155 mac80211_frame *Atheros_WLAN_create_probe_response(void)
157 unsigned int i;
158 unsigned char *buf;
159 mac80211_frame *frame;
161 frame = (mac80211_frame *)malloc(sizeof(mac80211_frame));
162 if (!frame) {
163 return NULL;
166 frame->next_frame = NULL;
167 frame->frame_control.protocol_version = 0;
168 frame->frame_control.type = IEEE80211_TYPE_MGT;
169 frame->frame_control.sub_type = IEEE80211_TYPE_MGT_SUBTYPE_PROBE_RESP;
170 frame->frame_control.flags = 0;
171 frame->duration_id = 314;
172 frame->sequence_control.fragment_number = 0;
174 i = 0;
175 buf = (unsigned char *)frame->data_and_fcs;
178 * Fixed params... typical AP params (12 byte)
180 * They include
181 * - Timestamp
182 * - Beacon Interval
183 * - Capability Information
185 buf[i++] = 0x8d;
186 buf[i++] = 0x61;
187 buf[i++] = 0xa5;
188 buf[i++] = 0x18;
189 buf[i++] = 0x00;
190 buf[i++] = 0x00;
191 buf[i++] = 0x00;
192 buf[i++] = 0x00;
193 buf[i++] = 0x64;
194 buf[i++] = 0x00;
195 buf[i++] = 0x01;
196 buf[i++] = 0x00;
198 FRAME_INSERT(IEEE80211_BEACON_PARAM_SSID);
199 FRAME_INSERT(4); /* length */
200 FRAME_INSERT('Q'); /* SSID */
201 FRAME_INSERT('L'); /* SSID */
202 FRAME_INSERT('a'); /* SSID */
203 FRAME_INSERT('n'); /* SSID */
205 FRAME_INSERT(IEEE80211_BEACON_PARAM_RATES);
206 FRAME_INSERT(8); /* length */
207 FRAME_INSERT(0x82);
208 FRAME_INSERT(0x84);
209 FRAME_INSERT(0x8b);
210 FRAME_INSERT(0x96);
211 FRAME_INSERT(0x24);
212 FRAME_INSERT(0x30);
213 FRAME_INSERT(0x48);
214 FRAME_INSERT(0x6c);
216 FRAME_INSERT(IEEE80211_BEACON_PARAM_CHANNEL);
217 FRAME_INSERT(1); /* length */
218 FRAME_INSERT(0x09);
220 frame->frame_length = IEEE80211_HEADER_SIZE + i;
221 return frame;
224 mac80211_frame *Atheros_WLAN_create_authentication(void)
226 unsigned int i;
227 unsigned char *buf;
228 mac80211_frame *frame;
230 frame = (mac80211_frame *)malloc(sizeof(mac80211_frame));
231 if (!frame) {
232 return NULL;
235 frame->next_frame = NULL;
236 frame->frame_control.protocol_version = 0;
237 frame->frame_control.type = IEEE80211_TYPE_MGT;
238 frame->frame_control.sub_type = IEEE80211_TYPE_MGT_SUBTYPE_AUTHENTICATION;
239 frame->frame_control.flags = 0;
240 frame->duration_id = 314;
241 frame->sequence_control.fragment_number = 0;
243 i = 0;
244 buf = (unsigned char *)frame->data_and_fcs;
247 * Fixed params... typical AP params (6 byte)
249 * They include
250 * - Authentication Algorithm (here: Open System)
251 * - Authentication SEQ
252 * - Status code (successful 0x0)
254 FRAME_INSERT(0x00);
255 FRAME_INSERT(0x00);
256 FRAME_INSERT(0x02);
257 FRAME_INSERT(0x00);
258 FRAME_INSERT(0x00);
259 FRAME_INSERT(0x00);
261 FRAME_INSERT(IEEE80211_BEACON_PARAM_SSID);
262 FRAME_INSERT(4); /* length */
263 FRAME_INSERT('Q'); /* SSID */
264 FRAME_INSERT('L'); /* SSID */
265 FRAME_INSERT('a'); /* SSID */
266 FRAME_INSERT('n'); /* SSID */
268 frame->frame_length = IEEE80211_HEADER_SIZE + i;
269 return frame;
272 mac80211_frame *Atheros_WLAN_create_deauthentication(void)
274 unsigned int i;
275 unsigned char *buf;
276 mac80211_frame *frame;
278 frame = (mac80211_frame *)malloc(sizeof(mac80211_frame));
279 if (!frame) {
280 return NULL;
283 frame->next_frame = NULL;
284 frame->frame_control.protocol_version = 0;
285 frame->frame_control.type = IEEE80211_TYPE_MGT;
286 frame->frame_control.sub_type = IEEE80211_TYPE_MGT_SUBTYPE_DEAUTHENTICATION;
287 frame->frame_control.flags = 0;
288 frame->duration_id = 314;
289 frame->sequence_control.fragment_number = 0;
291 i = 0;
292 buf = (unsigned char *)frame->data_and_fcs;
295 * Insert reason code:
296 * "Deauthentication because sending STA is leaving"
298 FRAME_INSERT(0x03);
299 FRAME_INSERT(0x00);
301 frame->frame_length = IEEE80211_HEADER_SIZE + i;
302 return frame;
305 mac80211_frame *Atheros_WLAN_create_association_response(void)
307 unsigned int i;
308 unsigned char *buf;
309 mac80211_frame *frame;
311 frame = (mac80211_frame *)malloc(sizeof(mac80211_frame));
312 if (!frame) {
313 return NULL;
316 frame->next_frame = NULL;
317 frame->frame_control.protocol_version = 0;
318 frame->frame_control.type = IEEE80211_TYPE_MGT;
319 frame->frame_control.sub_type = IEEE80211_TYPE_MGT_SUBTYPE_ASSOCIATION_RESP;
320 frame->frame_control.flags = 0;
321 #if 0
322 frame->duration_id = 314;
323 #endif
324 frame->sequence_control.fragment_number = 0;
326 i = 0;
327 buf = (unsigned char *)frame->data_and_fcs;
330 * Fixed params... typical AP params (6 byte)
332 * They include
333 * - Capability Information
334 * - Status code (successful 0x0)
335 * - Association ID
337 FRAME_INSERT(0x01);
338 FRAME_INSERT(0x00);
339 FRAME_INSERT(0x00);
340 FRAME_INSERT(0x00);
341 FRAME_INSERT(0x01);
342 FRAME_INSERT(0xc0);
344 FRAME_INSERT(IEEE80211_BEACON_PARAM_SSID);
345 FRAME_INSERT(4); /* length */
346 FRAME_INSERT('Q'); /* SSID */
347 FRAME_INSERT('L'); /* SSID */
348 FRAME_INSERT('a'); /* SSID */
349 FRAME_INSERT('n'); /* SSID */
351 FRAME_INSERT(IEEE80211_BEACON_PARAM_RATES);
352 FRAME_INSERT(8); /* length */
353 FRAME_INSERT(0x82);
354 FRAME_INSERT(0x84);
355 FRAME_INSERT(0x8b);
356 FRAME_INSERT(0x96);
357 FRAME_INSERT(0x24);
358 FRAME_INSERT(0x30);
359 FRAME_INSERT(0x48);
360 FRAME_INSERT(0x6c);
362 FRAME_INSERT(IEEE80211_BEACON_PARAM_EXTENDED_RATES);
363 FRAME_INSERT(4); /* length */
364 FRAME_INSERT(0x0c);
365 FRAME_INSERT(0x12);
366 FRAME_INSERT(0x18);
367 FRAME_INSERT(0x60);
369 frame->frame_length = IEEE80211_HEADER_SIZE + i;
370 return frame;
373 mac80211_frame *Atheros_WLAN_create_disassociation(void)
375 unsigned int i;
376 unsigned char *buf;
377 mac80211_frame *frame;
379 frame = (mac80211_frame *)malloc(sizeof(mac80211_frame));
380 if (!frame) {
381 return NULL;
384 frame->next_frame = NULL;
385 frame->frame_control.protocol_version = 0;
386 frame->frame_control.type = IEEE80211_TYPE_MGT;
387 frame->frame_control.sub_type = IEEE80211_TYPE_MGT_SUBTYPE_DISASSOCIATION;
388 frame->frame_control.flags = 0;
389 frame->duration_id = 314;
390 frame->sequence_control.fragment_number = 0;
392 i = 0;
393 buf = (unsigned char *)frame->data_and_fcs;
396 * Insert reason code:
397 * "Disassociation because sending STA is leaving"
399 FRAME_INSERT(0x03);
400 FRAME_INSERT(0x00);
402 frame->frame_length = IEEE80211_HEADER_SIZE + i;
403 return frame;
406 mac80211_frame *Atheros_WLAN_create_data_packet(Atheros_WLANState *s,
407 const uint8_t *buf, int size)
409 mac80211_frame *frame;
411 frame = (mac80211_frame *)malloc(sizeof(mac80211_frame));
412 if (!frame) {
413 return NULL;
416 frame->next_frame = NULL;
417 frame->frame_control.protocol_version = 0;
418 frame->frame_control.type = IEEE80211_TYPE_DATA;
419 frame->frame_control.sub_type = IEEE80211_TYPE_DATA_SUBTYPE_DATA;
420 frame->frame_control.flags = 0x2; /* from station back to station via AP */
421 frame->duration_id = 44;
422 frame->sequence_control.fragment_number = 0;
424 /* send message to wlan-device */
425 memcpy(frame->destination_address, s->macaddr, 6);
427 size -= 12; /* remove old 803.2 header */
428 size += 6; /* add new 803.11 header */
429 if (size > sizeof(frame->data_and_fcs)) {
430 /* sanitize memcpy */
431 size = sizeof(frame->data_and_fcs);
434 /* LLC */
435 frame->data_and_fcs[0] = 0xaa;
436 frame->data_and_fcs[1] = 0xaa;
437 frame->data_and_fcs[2] = 0x03;
438 frame->data_and_fcs[3] = 0x00;
439 frame->data_and_fcs[4] = 0x00;
440 frame->data_and_fcs[5] = 0x00;
442 memcpy(&frame->data_and_fcs[6], &buf[12], size);
443 frame->frame_length = IEEE80211_HEADER_SIZE + size;
445 return frame;
448 int Atheros_WLAN_dumpFrame(mac80211_frame *frame, int frame_len, char *filename)
450 int result = 1;
451 int i = 0, j;
452 unsigned char buf[56];
453 unsigned int frame_total_length = frame_len + 16;
454 unsigned char *l = (unsigned char *)&frame_total_length;
456 /* Wireshark header */
457 buf[i++] = 0xd4;
458 buf[i++] = 0xc3;
459 buf[i++] = 0xb2;
460 buf[i++] = 0xa1;
461 buf[i++] = 0x02;
462 buf[i++] = 0x00;
463 buf[i++] = 0x04;
464 buf[i++] = 0x00;
465 buf[i++] = 0x00;
466 buf[i++] = 0x00;
467 buf[i++] = 0x00;
468 buf[i++] = 0x00;
469 buf[i++] = 0x00;
470 buf[i++] = 0x00;
471 buf[i++] = 0x00;
472 buf[i++] = 0x00;
473 buf[i++] = 0x60;
474 buf[i++] = 0x00;
475 buf[i++] = 0x00;
476 buf[i++] = 0x00;
477 buf[i++] = 0x7f;
478 buf[i++] = 0x00;
479 buf[i++] = 0x00;
480 buf[i++] = 0x00;
481 buf[i++] = 0xd1;
482 buf[i++] = 0x75;
483 buf[i++] = 0x5d;
484 buf[i++] = 0x46;
485 buf[i++] = 0x76;
486 buf[i++] = 0x8b;
487 buf[i++] = 0x06;
488 buf[i++] = 0x00;
490 /* total frame length */
491 for (j = 0; j < 4; buf[i++] = l[j++]) {
493 /* captured frame length */
494 for (j = 0; j < 4; buf[i++] = l[j++]) {
497 /* Radiotap header */
498 buf[i++] = 0x00;
499 buf[i++] = 0x00;
500 buf[i++] = 0x10;
501 buf[i++] = 0x00;
502 buf[i++] = 0x0e;
503 buf[i++] = 0x18;
504 buf[i++] = 0x00;
505 buf[i++] = 0x00;
506 buf[i++] = 0x10;
507 buf[i++] = 0x02;
508 buf[i++] = 0x94;
509 buf[i++] = 0x09;
510 buf[i++] = 0xa0;
511 buf[i++] = 0x00;
512 buf[i++] = 0x00;
513 buf[i++] = 0x26;
515 FILE *fp;
516 fp = fopen(filename, "w");
517 if (fp) {
518 result = 0;
519 if (fwrite(buf, 1, sizeof(buf), fp) != sizeof(buf)) {
520 result = 1;
522 if (fwrite(frame, 1, frame_len, fp) != frame_len) {
523 result = 1;
525 fclose(fp);
528 return result;
531 #endif /* CONFIG_WIN32 */