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