2 * Received Data frame processing for IPv4 packets
3 * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
9 #include "utils/includes.h"
10 #include <netinet/ip.h>
11 #include <netinet/ip_icmp.h>
13 #include "utils/common.h"
17 static void ping_update(struct wlantest
*wt
, struct wlantest_sta
*sta
, int req
,
18 u32 src
, u32 dst
, u16 id
, u16 seq
)
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
;
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)
36 WLANTEST_STA_COUNTER_PING_OK_FIRST_ASSOC
]++;
37 add_note(wt
, MSG_DEBUG
, "ICMP echo (ping) match for STA "
38 MACSTR
, MAC2STR(sta
->addr
));
43 static void rx_data_icmp(struct wlantest
*wt
, const u8
*bssid
,
44 const u8
*sta_addr
, u32 dst
, u32 src
,
45 const u8
*data
, size_t len
, const u8
*peer_addr
)
49 const struct icmphdr
*hdr
;
51 struct wlantest_bss
*bss
;
52 struct wlantest_sta
*sta
;
54 hdr
= (const struct icmphdr
*) data
;
58 /* TODO: check hdr->checksum */
60 if (hdr
->type
!= ICMP_ECHOREPLY
&& hdr
->type
!= ICMP_ECHO
)
65 id
= ntohs(hdr
->un
.echo
.id
);
66 seq
= ntohs(hdr
->un
.echo
.sequence
);
69 snprintf(buf
, sizeof(buf
), "%s", inet_ntoa(addr
));
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]" : "");
76 bss
= bss_find(wt
, bssid
);
78 add_note(wt
, MSG_INFO
, "No BSS " MACSTR
79 " known for ICMP packet", MAC2STR(bssid
));
84 return; /* FromDS broadcast ping */
86 sta
= sta_find(bss
, sta_addr
);
88 add_note(wt
, MSG_INFO
, "No STA " MACSTR
89 " known for ICMP packet", MAC2STR(sta_addr
));
93 ping_update(wt
, sta
, hdr
->type
== ICMP_ECHO
, src
, dst
, id
, seq
);
94 if (peer_addr
&& (sta
= sta_find(bss
, peer_addr
)))
95 ping_update(wt
, sta
, hdr
->type
== ICMP_ECHO
, src
, dst
, id
, seq
);
99 static int hwsim_test_packet(const u8
*data
, size_t len
)
103 if (len
!= 1500 - 14)
106 for (i
= 0; i
< len
; i
++) {
107 if (data
[i
] != (i
& 0xff))
115 void rx_data_ip(struct wlantest
*wt
, const u8
*bssid
, const u8
*sta_addr
,
116 const u8
*dst
, const u8
*src
, const u8
*data
, size_t len
,
119 const struct iphdr
*ip
;
122 u16 frag_off
, tot_len
;
124 ip
= (const struct iphdr
*) data
;
125 if (len
< sizeof(*ip
))
127 if (ip
->version
!= 4) {
128 if (hwsim_test_packet(data
, len
)) {
129 add_note(wt
, MSG_INFO
, "hwsim_test package");
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
));
138 if (ip
->ihl
* 4 < sizeof(*ip
)) {
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
));
145 if (ip
->ihl
* 4 > len
) {
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
));
153 /* TODO: check header checksum in ip->check */
155 frag_off
= be_to_host16(ip
->frag_off
);
156 if (frag_off
& 0x1fff) {
157 wpa_printf(MSG_EXCESSIVE
, "IP fragment reassembly not yet "
162 tot_len
= be_to_host16(ip
->tot_len
);
168 payload
= data
+ 4 * ip
->ihl
;
169 plen
= len
- 4 * ip
->ihl
;
171 switch (ip
->protocol
) {
173 rx_data_icmp(wt
, bssid
, sta_addr
, ip
->daddr
, ip
->saddr
,
174 payload
, plen
, peer_addr
);