]> git.ipfire.org Git - thirdparty/hostap.git/blame - wlantest/rx_ip.c
tests: Unsupported WNM Action
[thirdparty/hostap.git] / wlantest / rx_ip.c
CommitLineData
ee3b84be
JM
1/*
2 * Received Data frame processing for IPv4 packets
3 * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
4 *
0f3d578e
JM
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
ee3b84be
JM
7 */
8
9#include "utils/includes.h"
10#include <netinet/ip.h>
11#include <netinet/ip_icmp.h>
12
13#include "utils/common.h"
14#include "wlantest.h"
15
16
e4d99217
JM
17static void ping_update(struct wlantest *wt, struct wlantest_sta *sta, int req,
18 u32 src, u32 dst, u16 id, u16 seq)
244c9303
JM
19{
20 if (req) {
21 sta->icmp_echo_req_src = src;
22 sta->icmp_echo_req_dst = dst;
23 sta->icmp_echo_req_id = id;
24 sta->icmp_echo_req_seq = seq;
25 return;
26 }
27
28 if (sta->icmp_echo_req_src == dst &&
29 sta->icmp_echo_req_dst == src &&
30 sta->icmp_echo_req_id == id &&
31 sta->icmp_echo_req_seq == seq) {
32 sta->counters[WLANTEST_STA_COUNTER_PING_OK]++;
33 if (sta->counters[WLANTEST_STA_COUNTER_ASSOCREQ_TX] == 0 &&
34 sta->counters[WLANTEST_STA_COUNTER_REASSOCREQ_TX] == 0)
35 sta->counters[
36 WLANTEST_STA_COUNTER_PING_OK_FIRST_ASSOC]++;
e4d99217
JM
37 add_note(wt, MSG_DEBUG, "ICMP echo (ping) match for STA "
38 MACSTR, MAC2STR(sta->addr));
244c9303
JM
39 }
40}
41
42
ee3b84be
JM
43static void rx_data_icmp(struct wlantest *wt, const u8 *bssid,
44 const u8 *sta_addr, u32 dst, u32 src,
244c9303 45 const u8 *data, size_t len, const u8 *peer_addr)
ee3b84be
JM
46{
47 struct in_addr addr;
48 char buf[20];
49 const struct icmphdr *hdr;
50 u16 id, seq;
51 struct wlantest_bss *bss;
52 struct wlantest_sta *sta;
53
54 hdr = (const struct icmphdr *) data;
55 if (len < 4)
56 return;
57
58 /* TODO: check hdr->checksum */
59
60 if (hdr->type != ICMP_ECHOREPLY && hdr->type != ICMP_ECHO)
61 return;
62 if (len < 8)
63 return;
64
65 id = ntohs(hdr->un.echo.id);
66 seq = ntohs(hdr->un.echo.sequence);
67
68 addr.s_addr = dst;
69 snprintf(buf, sizeof(buf), "%s", inet_ntoa(addr));
70 addr.s_addr = src;
e4d99217
JM
71 add_note(wt, MSG_DEBUG, "ICMP echo %s %s -> %s id=%04x seq=%u len=%u%s",
72 hdr->type == ICMP_ECHO ? "request" : "response",
73 inet_ntoa(addr), buf, id, seq, (unsigned) len - 8,
74 peer_addr ? " [DL]" : "");
ee3b84be
JM
75
76 bss = bss_find(wt, bssid);
77 if (bss == NULL) {
e4d99217
JM
78 add_note(wt, MSG_INFO, "No BSS " MACSTR
79 " known for ICMP packet", MAC2STR(bssid));
ee3b84be
JM
80 return;
81 }
82
83 if (sta_addr == NULL)
84 return; /* FromDS broadcast ping */
85
86 sta = sta_find(bss, sta_addr);
87 if (sta == NULL) {
e4d99217
JM
88 add_note(wt, MSG_INFO, "No STA " MACSTR
89 " known for ICMP packet", MAC2STR(sta_addr));
ee3b84be
JM
90 return;
91 }
92
e4d99217 93 ping_update(wt, sta, hdr->type == ICMP_ECHO, src, dst, id, seq);
244c9303 94 if (peer_addr && (sta = sta_find(bss, peer_addr)))
e4d99217 95 ping_update(wt, sta, hdr->type == ICMP_ECHO, src, dst, id, seq);
ee3b84be
JM
96}
97
98
3b5a1a77
JM
99static int hwsim_test_packet(const u8 *data, size_t len)
100{
101 size_t i;
102
103 if (len != 1500 - 14)
104 return 0;
105
106 for (i = 0; i < len; i++) {
107 if (data[i] != (i & 0xff))
108 return 0;
109 }
110
111 return 1;
112}
113
114
ee3b84be 115void rx_data_ip(struct wlantest *wt, const u8 *bssid, const u8 *sta_addr,
244c9303
JM
116 const u8 *dst, const u8 *src, const u8 *data, size_t len,
117 const u8 *peer_addr)
ee3b84be
JM
118{
119 const struct iphdr *ip;
120 const u8 *payload;
121 size_t plen;
122 u16 frag_off, tot_len;
123
124 ip = (const struct iphdr *) data;
125 if (len < sizeof(*ip))
126 return;
127 if (ip->version != 4) {
3b5a1a77
JM
128 if (hwsim_test_packet(data, len)) {
129 add_note(wt, MSG_INFO, "hwsim_test package");
130 return;
131 }
e4d99217
JM
132 add_note(wt, MSG_DEBUG, "Unexpected IP protocol version %u in "
133 "IPv4 packet (bssid=" MACSTR " str=" MACSTR
134 " dst=" MACSTR ")", ip->version, MAC2STR(bssid),
135 MAC2STR(src), MAC2STR(dst));
ee3b84be
JM
136 return;
137 }
138 if (ip->ihl * 4 < sizeof(*ip)) {
e4d99217
JM
139 add_note(wt, MSG_DEBUG, "Unexpected IP header length %u in "
140 "IPv4 packet (bssid=" MACSTR " str=" MACSTR
141 " dst=" MACSTR ")", ip->ihl, MAC2STR(bssid),
142 MAC2STR(src), MAC2STR(dst));
ee3b84be
JM
143 return;
144 }
145 if (ip->ihl * 4 > len) {
e4d99217
JM
146 add_note(wt, MSG_DEBUG, "Truncated IP header (ihl=%u len=%u) "
147 "in IPv4 packet (bssid=" MACSTR " str=" MACSTR
148 " dst=" MACSTR ")", ip->ihl, (unsigned) len,
149 MAC2STR(bssid), MAC2STR(src), MAC2STR(dst));
ee3b84be
JM
150 return;
151 }
152
153 /* TODO: check header checksum in ip->check */
154
155 frag_off = be_to_host16(ip->frag_off);
156 if (frag_off & 0x1fff) {
157 wpa_printf(MSG_EXCESSIVE, "IP fragment reassembly not yet "
158 "supported");
159 return;
160 }
161
162 tot_len = be_to_host16(ip->tot_len);
163 if (tot_len > len)
164 return;
165 if (tot_len < len)
166 len = tot_len;
167
168 payload = data + 4 * ip->ihl;
169 plen = len - 4 * ip->ihl;
170
171 switch (ip->protocol) {
172 case IPPROTO_ICMP:
173 rx_data_icmp(wt, bssid, sta_addr, ip->daddr, ip->saddr,
244c9303 174 payload, plen, peer_addr);
ee3b84be
JM
175 break;
176 }
177}