Updated through tag hostap_2_5 from git://w1.fi/hostap.git
[mech_eap.git] / libeap / wlantest / rx_data.c
1 /*
2  * Received Data frame processing
3  * Copyright (c) 2010-2015, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8
9 #include "utils/includes.h"
10 #include <linux/if_ether.h>
11
12 #include "utils/common.h"
13 #include "common/defs.h"
14 #include "common/ieee802_11_defs.h"
15 #include "wlantest.h"
16
17
18 static const char * data_stype(u16 stype)
19 {
20         switch (stype) {
21         case WLAN_FC_STYPE_DATA:
22                 return "DATA";
23         case WLAN_FC_STYPE_DATA_CFACK:
24                 return "DATA-CFACK";
25         case WLAN_FC_STYPE_DATA_CFPOLL:
26                 return "DATA-CFPOLL";
27         case WLAN_FC_STYPE_DATA_CFACKPOLL:
28                 return "DATA-CFACKPOLL";
29         case WLAN_FC_STYPE_NULLFUNC:
30                 return "NULLFUNC";
31         case WLAN_FC_STYPE_CFACK:
32                 return "CFACK";
33         case WLAN_FC_STYPE_CFPOLL:
34                 return "CFPOLL";
35         case WLAN_FC_STYPE_CFACKPOLL:
36                 return "CFACKPOLL";
37         case WLAN_FC_STYPE_QOS_DATA:
38                 return "QOSDATA";
39         case WLAN_FC_STYPE_QOS_DATA_CFACK:
40                 return "QOSDATA-CFACK";
41         case WLAN_FC_STYPE_QOS_DATA_CFPOLL:
42                 return "QOSDATA-CFPOLL";
43         case WLAN_FC_STYPE_QOS_DATA_CFACKPOLL:
44                 return "QOSDATA-CFACKPOLL";
45         case WLAN_FC_STYPE_QOS_NULL:
46                 return "QOS-NULL";
47         case WLAN_FC_STYPE_QOS_CFPOLL:
48                 return "QOS-CFPOLL";
49         case WLAN_FC_STYPE_QOS_CFACKPOLL:
50                 return "QOS-CFACKPOLL";
51         }
52         return "??";
53 }
54
55
56 static void rx_data_eth(struct wlantest *wt, const u8 *bssid,
57                         const u8 *sta_addr, const u8 *dst, const u8 *src,
58                         u16 ethertype, const u8 *data, size_t len, int prot,
59                         const u8 *peer_addr)
60 {
61         switch (ethertype) {
62         case ETH_P_PAE:
63                 rx_data_eapol(wt, dst, src, data, len, prot);
64                 break;
65         case ETH_P_IP:
66                 rx_data_ip(wt, bssid, sta_addr, dst, src, data, len,
67                            peer_addr);
68                 break;
69         case 0x890d:
70                 rx_data_80211_encap(wt, bssid, sta_addr, dst, src, data, len);
71                 break;
72         }
73 }
74
75
76 static void rx_data_process(struct wlantest *wt, const u8 *bssid,
77                             const u8 *sta_addr,
78                             const u8 *dst, const u8 *src,
79                             const u8 *data, size_t len, int prot,
80                             const u8 *peer_addr)
81 {
82         if (len == 0)
83                 return;
84
85         if (len >= 8 && os_memcmp(data, "\xaa\xaa\x03\x00\x00\x00", 6) == 0) {
86                 rx_data_eth(wt, bssid, sta_addr, dst, src,
87                             WPA_GET_BE16(data + 6), data + 8, len - 8, prot,
88                             peer_addr);
89                 return;
90         }
91
92         wpa_hexdump(MSG_DEBUG, "Unrecognized LLC", data, len > 8 ? 8 : len);
93 }
94
95
96 static u8 * try_all_ptk(struct wlantest *wt, int pairwise_cipher,
97                         const struct ieee80211_hdr *hdr,
98                         const u8 *data, size_t data_len, size_t *decrypted_len)
99 {
100         struct wlantest_ptk *ptk;
101         u8 *decrypted;
102         int prev_level = wpa_debug_level;
103
104         wpa_debug_level = MSG_WARNING;
105         dl_list_for_each(ptk, &wt->ptk, struct wlantest_ptk, list) {
106                 unsigned int tk_len = ptk->ptk_len - 32;
107                 decrypted = NULL;
108                 if ((pairwise_cipher == WPA_CIPHER_CCMP ||
109                      pairwise_cipher == 0) && tk_len == 16) {
110                         decrypted = ccmp_decrypt(ptk->ptk.tk, hdr, data,
111                                                  data_len, decrypted_len);
112                 } else if ((pairwise_cipher == WPA_CIPHER_CCMP_256 ||
113                             pairwise_cipher == 0) && tk_len == 32) {
114                         decrypted = ccmp_256_decrypt(ptk->ptk.tk, hdr, data,
115                                                      data_len, decrypted_len);
116                 } else if ((pairwise_cipher == WPA_CIPHER_GCMP ||
117                             pairwise_cipher == WPA_CIPHER_GCMP_256 ||
118                             pairwise_cipher == 0) &&
119                            (tk_len == 16 || tk_len == 32)) {
120                         decrypted = gcmp_decrypt(ptk->ptk.tk, tk_len, hdr,
121                                                  data, data_len, decrypted_len);
122                 } else if ((pairwise_cipher == WPA_CIPHER_TKIP ||
123                             pairwise_cipher == 0) && tk_len == 32) {
124                         decrypted = tkip_decrypt(ptk->ptk.tk, hdr, data,
125                                                  data_len, decrypted_len);
126                 }
127                 if (decrypted) {
128                         wpa_debug_level = prev_level;
129                         add_note(wt, MSG_DEBUG, "Found PTK match from list of all known PTKs");
130                         return decrypted;
131                 }
132         }
133         wpa_debug_level = prev_level;
134
135         return NULL;
136 }
137
138
139 static void rx_data_bss_prot_group(struct wlantest *wt,
140                                    const struct ieee80211_hdr *hdr,
141                                    const u8 *qos, const u8 *dst, const u8 *src,
142                                    const u8 *data, size_t len)
143 {
144         struct wlantest_bss *bss;
145         int keyid;
146         u8 *decrypted = NULL;
147         size_t dlen;
148         u8 pn[6];
149
150         bss = bss_get(wt, hdr->addr2);
151         if (bss == NULL)
152                 return;
153         if (len < 4) {
154                 add_note(wt, MSG_INFO, "Too short group addressed data frame");
155                 return;
156         }
157
158         if (bss->group_cipher & (WPA_CIPHER_TKIP | WPA_CIPHER_CCMP) &&
159             !(data[3] & 0x20)) {
160                 add_note(wt, MSG_INFO, "Expected TKIP/CCMP frame from "
161                          MACSTR " did not have ExtIV bit set to 1",
162                          MAC2STR(bss->bssid));
163                 return;
164         }
165
166         if (bss->group_cipher == WPA_CIPHER_TKIP) {
167                 if (data[3] & 0x1f) {
168                         add_note(wt, MSG_INFO, "TKIP frame from " MACSTR
169                                  " used non-zero reserved bit",
170                                  MAC2STR(bss->bssid));
171                 }
172                 if (data[1] != ((data[0] | 0x20) & 0x7f)) {
173                         add_note(wt, MSG_INFO, "TKIP frame from " MACSTR
174                                  " used incorrect WEPSeed[1] (was 0x%x, "
175                                  "expected 0x%x)",
176                                  MAC2STR(bss->bssid), data[1],
177                                  (data[0] | 0x20) & 0x7f);
178                 }
179         } else if (bss->group_cipher == WPA_CIPHER_CCMP) {
180                 if (data[2] != 0 || (data[3] & 0x1f) != 0) {
181                         add_note(wt, MSG_INFO, "CCMP frame from " MACSTR
182                                  " used non-zero reserved bit",
183                                  MAC2STR(bss->bssid));
184                 }
185         }
186
187         keyid = data[3] >> 6;
188         if (bss->gtk_len[keyid] == 0 && bss->group_cipher != WPA_CIPHER_WEP40)
189         {
190                 add_note(wt, MSG_MSGDUMP, "No GTK known to decrypt the frame "
191                          "(A2=" MACSTR " KeyID=%d)",
192                          MAC2STR(hdr->addr2), keyid);
193                 return;
194         }
195
196         if (bss->group_cipher == WPA_CIPHER_TKIP)
197                 tkip_get_pn(pn, data);
198         else if (bss->group_cipher == WPA_CIPHER_WEP40)
199                 goto skip_replay_det;
200         else
201                 ccmp_get_pn(pn, data);
202         if (os_memcmp(pn, bss->rsc[keyid], 6) <= 0) {
203                 u16 seq_ctrl = le_to_host16(hdr->seq_ctrl);
204                 add_note(wt, MSG_INFO, "CCMP/TKIP replay detected: A1=" MACSTR
205                          " A2=" MACSTR " A3=" MACSTR " seq=%u frag=%u%s",
206                          MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
207                          MAC2STR(hdr->addr3),
208                          WLAN_GET_SEQ_SEQ(seq_ctrl),
209                          WLAN_GET_SEQ_FRAG(seq_ctrl),
210                          (le_to_host16(hdr->frame_control) & WLAN_FC_RETRY) ?
211                          " Retry" : "");
212                 wpa_hexdump(MSG_INFO, "RX PN", pn, 6);
213                 wpa_hexdump(MSG_INFO, "RSC", bss->rsc[keyid], 6);
214         }
215
216 skip_replay_det:
217         if (bss->group_cipher == WPA_CIPHER_TKIP)
218                 decrypted = tkip_decrypt(bss->gtk[keyid], hdr, data, len,
219                                          &dlen);
220         else if (bss->group_cipher == WPA_CIPHER_WEP40)
221                 decrypted = wep_decrypt(wt, hdr, data, len, &dlen);
222         else if (bss->group_cipher == WPA_CIPHER_CCMP)
223                 decrypted = ccmp_decrypt(bss->gtk[keyid], hdr, data, len,
224                                          &dlen);
225         else if (bss->group_cipher == WPA_CIPHER_CCMP_256)
226                 decrypted = ccmp_256_decrypt(bss->gtk[keyid], hdr, data, len,
227                                              &dlen);
228         else if (bss->group_cipher == WPA_CIPHER_GCMP ||
229                  bss->group_cipher == WPA_CIPHER_GCMP_256)
230                 decrypted = gcmp_decrypt(bss->gtk[keyid], bss->gtk_len[keyid],
231                                          hdr, data, len, &dlen);
232
233         if (decrypted) {
234                 rx_data_process(wt, bss->bssid, NULL, dst, src, decrypted,
235                                 dlen, 1, NULL);
236                 os_memcpy(bss->rsc[keyid], pn, 6);
237                 write_pcap_decrypted(wt, (const u8 *) hdr, 24 + (qos ? 2 : 0),
238                                      decrypted, dlen);
239         } else
240                 add_note(wt, MSG_DEBUG, "Failed to decrypt frame");
241         os_free(decrypted);
242 }
243
244
245 static void rx_data_bss_prot(struct wlantest *wt,
246                              const struct ieee80211_hdr *hdr, const u8 *qos,
247                              const u8 *dst, const u8 *src, const u8 *data,
248                              size_t len)
249 {
250         struct wlantest_bss *bss;
251         struct wlantest_sta *sta, *sta2;
252         int keyid;
253         u16 fc = le_to_host16(hdr->frame_control);
254         u8 *decrypted;
255         size_t dlen;
256         int tid;
257         u8 pn[6], *rsc;
258         struct wlantest_tdls *tdls = NULL, *found;
259         const u8 *tk = NULL;
260         int ptk_iter_done = 0;
261         int try_ptk_iter = 0;
262
263         if (hdr->addr1[0] & 0x01) {
264                 rx_data_bss_prot_group(wt, hdr, qos, dst, src, data, len);
265                 return;
266         }
267
268         if (fc & WLAN_FC_TODS) {
269                 bss = bss_get(wt, hdr->addr1);
270                 if (bss == NULL)
271                         return;
272                 sta = sta_get(bss, hdr->addr2);
273                 if (sta)
274                         sta->counters[WLANTEST_STA_COUNTER_PROT_DATA_TX]++;
275         } else if (fc & WLAN_FC_FROMDS) {
276                 bss = bss_get(wt, hdr->addr2);
277                 if (bss == NULL)
278                         return;
279                 sta = sta_get(bss, hdr->addr1);
280         } else {
281                 bss = bss_get(wt, hdr->addr3);
282                 if (bss == NULL)
283                         return;
284                 sta = sta_find(bss, hdr->addr2);
285                 sta2 = sta_find(bss, hdr->addr1);
286                 if (sta == NULL || sta2 == NULL)
287                         return;
288                 found = NULL;
289                 dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list)
290                 {
291                         if ((tdls->init == sta && tdls->resp == sta2) ||
292                             (tdls->init == sta2 && tdls->resp == sta)) {
293                                 found = tdls;
294                                 if (tdls->link_up)
295                                         break;
296                         }
297                 }
298                 if (found) {
299                         if (!found->link_up)
300                                 add_note(wt, MSG_DEBUG,
301                                          "TDLS: Link not up, but Data "
302                                          "frame seen");
303                         tk = found->tpk.tk;
304                         tdls = found;
305                 }
306         }
307         if ((sta == NULL ||
308              (!sta->ptk_set && sta->pairwise_cipher != WPA_CIPHER_WEP40)) &&
309             tk == NULL) {
310                 add_note(wt, MSG_MSGDUMP, "No PTK known to decrypt the frame");
311                 if (dl_list_empty(&wt->ptk))
312                         return;
313                 try_ptk_iter = 1;
314         }
315
316         if (len < 4) {
317                 add_note(wt, MSG_INFO, "Too short encrypted data frame");
318                 return;
319         }
320
321         if (sta == NULL)
322                 return;
323         if (sta->pairwise_cipher & (WPA_CIPHER_TKIP | WPA_CIPHER_CCMP) &&
324             !(data[3] & 0x20)) {
325                 add_note(wt, MSG_INFO, "Expected TKIP/CCMP frame from "
326                          MACSTR " did not have ExtIV bit set to 1",
327                          MAC2STR(src));
328                 return;
329         }
330
331         if (tk == NULL && sta->pairwise_cipher == WPA_CIPHER_TKIP) {
332                 if (data[3] & 0x1f) {
333                         add_note(wt, MSG_INFO, "TKIP frame from " MACSTR
334                                  " used non-zero reserved bit",
335                                  MAC2STR(hdr->addr2));
336                 }
337                 if (data[1] != ((data[0] | 0x20) & 0x7f)) {
338                         add_note(wt, MSG_INFO, "TKIP frame from " MACSTR
339                                  " used incorrect WEPSeed[1] (was 0x%x, "
340                                  "expected 0x%x)",
341                                  MAC2STR(hdr->addr2), data[1],
342                                  (data[0] | 0x20) & 0x7f);
343                 }
344         } else if (tk || sta->pairwise_cipher == WPA_CIPHER_CCMP) {
345                 if (data[2] != 0 || (data[3] & 0x1f) != 0) {
346                         add_note(wt, MSG_INFO, "CCMP frame from " MACSTR
347                                  " used non-zero reserved bit",
348                                  MAC2STR(hdr->addr2));
349                 }
350         }
351
352         keyid = data[3] >> 6;
353         if (keyid != 0) {
354                 add_note(wt, MSG_INFO, "Unexpected non-zero KeyID %d in "
355                          "individually addressed Data frame from " MACSTR,
356                          keyid, MAC2STR(hdr->addr2));
357         }
358
359         if (qos) {
360                 tid = qos[0] & 0x0f;
361                 if (fc & WLAN_FC_TODS)
362                         sta->tx_tid[tid]++;
363                 else
364                         sta->rx_tid[tid]++;
365         } else {
366                 tid = 0;
367                 if (fc & WLAN_FC_TODS)
368                         sta->tx_tid[16]++;
369                 else
370                         sta->rx_tid[16]++;
371         }
372         if (tk) {
373                 if (os_memcmp(hdr->addr2, tdls->init->addr, ETH_ALEN) == 0)
374                         rsc = tdls->rsc_init[tid];
375                 else
376                         rsc = tdls->rsc_resp[tid];
377         } else if (fc & WLAN_FC_TODS)
378                 rsc = sta->rsc_tods[tid];
379         else
380                 rsc = sta->rsc_fromds[tid];
381
382
383         if (tk == NULL && sta->pairwise_cipher == WPA_CIPHER_TKIP)
384                 tkip_get_pn(pn, data);
385         else if (sta->pairwise_cipher == WPA_CIPHER_WEP40)
386                 goto skip_replay_det;
387         else
388                 ccmp_get_pn(pn, data);
389         if (os_memcmp(pn, rsc, 6) <= 0) {
390                 u16 seq_ctrl = le_to_host16(hdr->seq_ctrl);
391                 add_note(wt, MSG_INFO, "CCMP/TKIP replay detected: A1=" MACSTR
392                          " A2=" MACSTR " A3=" MACSTR " seq=%u frag=%u%s",
393                          MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
394                          MAC2STR(hdr->addr3),
395                          WLAN_GET_SEQ_SEQ(seq_ctrl),
396                          WLAN_GET_SEQ_FRAG(seq_ctrl),
397                          (le_to_host16(hdr->frame_control) &  WLAN_FC_RETRY) ?
398                          " Retry" : "");
399                 wpa_hexdump(MSG_INFO, "RX PN", pn, 6);
400                 wpa_hexdump(MSG_INFO, "RSC", rsc, 6);
401         }
402
403 skip_replay_det:
404         if (tk) {
405                 if (sta->pairwise_cipher == WPA_CIPHER_CCMP_256)
406                         decrypted = ccmp_256_decrypt(tk, hdr, data, len, &dlen);
407                 else if (sta->pairwise_cipher == WPA_CIPHER_GCMP ||
408                          sta->pairwise_cipher == WPA_CIPHER_GCMP_256)
409                         decrypted = gcmp_decrypt(tk, sta->tk_len, hdr, data,
410                                                  len, &dlen);
411                 else
412                         decrypted = ccmp_decrypt(tk, hdr, data, len, &dlen);
413         } else if (sta->pairwise_cipher == WPA_CIPHER_TKIP) {
414                 decrypted = tkip_decrypt(sta->ptk.tk, hdr, data, len, &dlen);
415         } else if (sta->pairwise_cipher == WPA_CIPHER_WEP40) {
416                 decrypted = wep_decrypt(wt, hdr, data, len, &dlen);
417         } else if (sta->ptk_set) {
418                 if (sta->pairwise_cipher == WPA_CIPHER_CCMP_256)
419                         decrypted = ccmp_256_decrypt(sta->ptk.tk, hdr, data,
420                                                      len, &dlen);
421                 else if (sta->pairwise_cipher == WPA_CIPHER_GCMP ||
422                          sta->pairwise_cipher == WPA_CIPHER_GCMP_256)
423                         decrypted = gcmp_decrypt(sta->ptk.tk, sta->tk_len,
424                                                  hdr, data, len, &dlen);
425                 else
426                         decrypted = ccmp_decrypt(sta->ptk.tk, hdr, data, len,
427                                                  &dlen);
428         } else {
429                 decrypted = try_all_ptk(wt, sta->pairwise_cipher, hdr, data,
430                                         len, &dlen);
431                 ptk_iter_done = 1;
432         }
433         if (!decrypted && !ptk_iter_done) {
434                 decrypted = try_all_ptk(wt, sta->pairwise_cipher, hdr, data,
435                                         len, &dlen);
436                 if (decrypted) {
437                         add_note(wt, MSG_DEBUG, "Current PTK did not work, but found a match from all known PTKs");
438                 }
439         }
440         if (decrypted) {
441                 u16 fc = le_to_host16(hdr->frame_control);
442                 const u8 *peer_addr = NULL;
443                 if (!(fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)))
444                         peer_addr = hdr->addr1;
445                 os_memcpy(rsc, pn, 6);
446                 rx_data_process(wt, bss->bssid, sta->addr, dst, src, decrypted,
447                                 dlen, 1, peer_addr);
448                 write_pcap_decrypted(wt, (const u8 *) hdr, 24 + (qos ? 2 : 0),
449                                      decrypted, dlen);
450         } else if (!try_ptk_iter)
451                 add_note(wt, MSG_DEBUG, "Failed to decrypt frame");
452         os_free(decrypted);
453 }
454
455
456 static void rx_data_bss(struct wlantest *wt, const struct ieee80211_hdr *hdr,
457                         const u8 *qos, const u8 *dst, const u8 *src,
458                         const u8 *data, size_t len)
459 {
460         u16 fc = le_to_host16(hdr->frame_control);
461         int prot = !!(fc & WLAN_FC_ISWEP);
462
463         if (qos) {
464                 u8 ack = (qos[0] & 0x60) >> 5;
465                 wpa_printf(MSG_MSGDUMP, "BSS DATA: " MACSTR " -> " MACSTR
466                            " len=%u%s tid=%u%s%s",
467                            MAC2STR(src), MAC2STR(dst), (unsigned int) len,
468                            prot ? " Prot" : "", qos[0] & 0x0f,
469                            (qos[0] & 0x10) ? " EOSP" : "",
470                            ack == 0 ? "" :
471                            (ack == 1 ? " NoAck" :
472                             (ack == 2 ? " NoExpAck" : " BA")));
473         } else {
474                 wpa_printf(MSG_MSGDUMP, "BSS DATA: " MACSTR " -> " MACSTR
475                            " len=%u%s",
476                            MAC2STR(src), MAC2STR(dst), (unsigned int) len,
477                            prot ? " Prot" : "");
478         }
479
480         if (prot)
481                 rx_data_bss_prot(wt, hdr, qos, dst, src, data, len);
482         else {
483                 const u8 *bssid, *sta_addr, *peer_addr;
484                 struct wlantest_bss *bss;
485
486                 if (fc & WLAN_FC_TODS) {
487                         bssid = hdr->addr1;
488                         sta_addr = hdr->addr2;
489                         peer_addr = NULL;
490                 } else if (fc & WLAN_FC_FROMDS) {
491                         bssid = hdr->addr2;
492                         sta_addr = hdr->addr1;
493                         peer_addr = NULL;
494                 } else {
495                         bssid = hdr->addr3;
496                         sta_addr = hdr->addr2;
497                         peer_addr = hdr->addr1;
498                 }
499
500                 bss = bss_get(wt, bssid);
501                 if (bss) {
502                         struct wlantest_sta *sta = sta_get(bss, sta_addr);
503
504                         if (sta) {
505                                 if (qos) {
506                                         int tid = qos[0] & 0x0f;
507                                         if (fc & WLAN_FC_TODS)
508                                                 sta->tx_tid[tid]++;
509                                         else
510                                                 sta->rx_tid[tid]++;
511                                 } else {
512                                         if (fc & WLAN_FC_TODS)
513                                                 sta->tx_tid[16]++;
514                                         else
515                                                 sta->rx_tid[16]++;
516                                 }
517                         }
518                 }
519
520                 rx_data_process(wt, bssid, sta_addr, dst, src, data, len, 0,
521                                 peer_addr);
522         }
523 }
524
525
526 static struct wlantest_tdls * get_tdls(struct wlantest *wt, const u8 *bssid,
527                                        const u8 *sta1_addr,
528                                        const u8 *sta2_addr)
529 {
530         struct wlantest_bss *bss;
531         struct wlantest_sta *sta1, *sta2;
532         struct wlantest_tdls *tdls, *found = NULL;
533
534         bss = bss_find(wt, bssid);
535         if (bss == NULL)
536                 return NULL;
537         sta1 = sta_find(bss, sta1_addr);
538         if (sta1 == NULL)
539                 return NULL;
540         sta2 = sta_find(bss, sta2_addr);
541         if (sta2 == NULL)
542                 return NULL;
543
544         dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list) {
545                 if ((tdls->init == sta1 && tdls->resp == sta2) ||
546                     (tdls->init == sta2 && tdls->resp == sta1)) {
547                         found = tdls;
548                         if (tdls->link_up)
549                                 break;
550                 }
551         }
552
553         return found;
554 }
555
556
557 static void add_direct_link(struct wlantest *wt, const u8 *bssid,
558                             const u8 *sta1_addr, const u8 *sta2_addr)
559 {
560         struct wlantest_tdls *tdls;
561
562         tdls = get_tdls(wt, bssid, sta1_addr, sta2_addr);
563         if (tdls == NULL)
564                 return;
565
566         if (tdls->link_up)
567                 tdls->counters[WLANTEST_TDLS_COUNTER_VALID_DIRECT_LINK]++;
568         else
569                 tdls->counters[WLANTEST_TDLS_COUNTER_INVALID_DIRECT_LINK]++;
570 }
571
572
573 static void add_ap_path(struct wlantest *wt, const u8 *bssid,
574                         const u8 *sta1_addr, const u8 *sta2_addr)
575 {
576         struct wlantest_tdls *tdls;
577
578         tdls = get_tdls(wt, bssid, sta1_addr, sta2_addr);
579         if (tdls == NULL)
580                 return;
581
582         if (tdls->link_up)
583                 tdls->counters[WLANTEST_TDLS_COUNTER_INVALID_AP_PATH]++;
584         else
585                 tdls->counters[WLANTEST_TDLS_COUNTER_VALID_AP_PATH]++;
586 }
587
588
589 void rx_data(struct wlantest *wt, const u8 *data, size_t len)
590 {
591         const struct ieee80211_hdr *hdr;
592         u16 fc, stype;
593         size_t hdrlen;
594         const u8 *qos = NULL;
595
596         if (len < 24)
597                 return;
598
599         hdr = (const struct ieee80211_hdr *) data;
600         fc = le_to_host16(hdr->frame_control);
601         stype = WLAN_FC_GET_STYPE(fc);
602         hdrlen = 24;
603         if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) ==
604             (WLAN_FC_TODS | WLAN_FC_FROMDS))
605                 hdrlen += ETH_ALEN;
606         if (stype & 0x08) {
607                 qos = data + hdrlen;
608                 hdrlen += 2;
609         }
610         if (len < hdrlen)
611                 return;
612         wt->rx_data++;
613
614         switch (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) {
615         case 0:
616                 wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s IBSS DA=" MACSTR " SA="
617                            MACSTR " BSSID=" MACSTR,
618                            data_stype(WLAN_FC_GET_STYPE(fc)),
619                            fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
620                            fc & WLAN_FC_ISWEP ? " Prot" : "",
621                            MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
622                            MAC2STR(hdr->addr3));
623                 add_direct_link(wt, hdr->addr3, hdr->addr1, hdr->addr2);
624                 rx_data_bss(wt, hdr, qos, hdr->addr1, hdr->addr2,
625                             data + hdrlen, len - hdrlen);
626                 break;
627         case WLAN_FC_FROMDS:
628                 wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s FromDS DA=" MACSTR
629                            " BSSID=" MACSTR " SA=" MACSTR,
630                            data_stype(WLAN_FC_GET_STYPE(fc)),
631                            fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
632                            fc & WLAN_FC_ISWEP ? " Prot" : "",
633                            MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
634                            MAC2STR(hdr->addr3));
635                 add_ap_path(wt, hdr->addr2, hdr->addr1, hdr->addr3);
636                 rx_data_bss(wt, hdr, qos, hdr->addr1, hdr->addr3,
637                             data + hdrlen, len - hdrlen);
638                 break;
639         case WLAN_FC_TODS:
640                 wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s ToDS BSSID=" MACSTR
641                            " SA=" MACSTR " DA=" MACSTR,
642                            data_stype(WLAN_FC_GET_STYPE(fc)),
643                            fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
644                            fc & WLAN_FC_ISWEP ? " Prot" : "",
645                            MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
646                            MAC2STR(hdr->addr3));
647                 add_ap_path(wt, hdr->addr1, hdr->addr3, hdr->addr2);
648                 rx_data_bss(wt, hdr, qos, hdr->addr3, hdr->addr2,
649                             data + hdrlen, len - hdrlen);
650                 break;
651         case WLAN_FC_TODS | WLAN_FC_FROMDS:
652                 wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s WDS RA=" MACSTR " TA="
653                            MACSTR " DA=" MACSTR " SA=" MACSTR,
654                            data_stype(WLAN_FC_GET_STYPE(fc)),
655                            fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
656                            fc & WLAN_FC_ISWEP ? " Prot" : "",
657                            MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
658                            MAC2STR(hdr->addr3),
659                            MAC2STR((const u8 *) (hdr + 1)));
660                 break;
661         }
662 }