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