ReactOS 0.4.16-dev-257-g6aa11ac
test_ip4.c
Go to the documentation of this file.
1#include "test_ip4.h"
2
3#include "lwip/icmp.h"
4#include "lwip/ip4.h"
5#include "lwip/etharp.h"
6#include "lwip/inet_chksum.h"
7#include "lwip/stats.h"
8#include "lwip/prot/ip.h"
9#include "lwip/prot/ip4.h"
10
11#include "lwip/tcpip.h"
12
13#if !LWIP_IPV4 || !IP_REASSEMBLY || !MIB2_STATS || !IPFRAG_STATS
14#error "This tests needs LWIP_IPV4, IP_REASSEMBLY; MIB2- and IPFRAG-statistics enabled"
15#endif
16
17static struct netif test_netif;
18static ip4_addr_t test_ipaddr, test_netmask, test_gw;
19static int linkoutput_ctr;
22static u8_t linkoutput_pkt[100];
23
24/* reference internal lwip variable in netif.c */
25
26static err_t
28{
29 fail_unless(netif == &test_netif);
30 fail_unless(p != NULL);
32 linkoutput_byte_ctr += p->tot_len;
33 /* Copy start of packet into buffer */
35 return ERR_OK;
36}
37
38static err_t
40{
41 fail_unless(netif != NULL);
43 netif->output = etharp_output;
44 netif->mtu = 1500;
47 return ERR_OK;
48}
49
50static void
52{
53 IP4_ADDR(&test_gw, 192,168,0,1);
54 IP4_ADDR(&test_ipaddr, 192,168,0,1);
55 IP4_ADDR(&test_netmask, 255,255,0,0);
56
57 fail_unless(netif_default == NULL);
62}
63
64static void
66{
67 if (netif_default == &test_netif) {
69 }
70}
71
72/* Helper functions */
73static void
75{
76 struct pbuf *p;
77 struct netif *input_netif = netif_list; /* just use any netif */
78 fail_unless((start & 7) == 0);
79 fail_unless(((len & 7) == 0) || last);
80 fail_unless(input_netif != NULL);
81
82 p = pbuf_alloc(PBUF_RAW, len + sizeof(struct ip_hdr), PBUF_RAM);
83 fail_unless(p != NULL);
84 if (p != NULL) {
85 err_t err;
86 struct ip_hdr *iphdr = (struct ip_hdr *)p->payload;
87 IPH_VHL_SET(iphdr, 4, sizeof(struct ip_hdr) / 4);
88 IPH_TOS_SET(iphdr, 0);
89 IPH_LEN_SET(iphdr, lwip_htons(p->tot_len));
90 IPH_ID_SET(iphdr, lwip_htons(ip_id));
91 if (last) {
92 IPH_OFFSET_SET(iphdr, lwip_htons(start / 8));
93 } else {
94 IPH_OFFSET_SET(iphdr, lwip_htons((start / 8) | IP_MF));
95 }
96 IPH_TTL_SET(iphdr, 5);
98 IPH_CHKSUM_SET(iphdr, 0);
99 ip4_addr_copy(iphdr->src, *netif_ip4_addr(input_netif));
100 iphdr->src.addr = lwip_htonl(lwip_htonl(iphdr->src.addr) + 1);
101 ip4_addr_copy(iphdr->dest, *netif_ip4_addr(input_netif));
102 IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, sizeof(struct ip_hdr)));
103
104 err = ip4_input(p, input_netif);
105 if (err != ERR_OK) {
106 pbuf_free(p);
107 }
108 fail_unless(err == ERR_OK);
109 }
110}
111
112static err_t arpless_output(struct netif *netif, struct pbuf *p,
113 const ip4_addr_t *ipaddr) {
114 LWIP_UNUSED_ARG(ipaddr);
115 return netif->linkoutput(netif, p);
116}
117
118/* Setups/teardown functions */
119
120static void
122{
123 lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
124}
125
126static void
128{
129 if (netif_list->loop_first != NULL) {
130 pbuf_free(netif_list->loop_first);
131 netif_list->loop_first = NULL;
132 }
133 netif_list->loop_last = NULL;
134 /* poll until all memory is released... */
135 tcpip_thread_poll_one();
136 lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
138 netif_set_up(netif_get_loopif());
139}
140
141/* Test functions */
142START_TEST(test_ip4_frag)
143{
144 struct pbuf *data = pbuf_alloc(PBUF_IP, 8000, PBUF_RAM);
145 ip_addr_t peer_ip = IPADDR4_INIT_BYTES(192,168,0,5);
146 err_t err;
147 LWIP_UNUSED_ARG(_i);
148
149 linkoutput_ctr = 0;
150
151 /* Verify that 8000 byte payload is split into six packets */
152 fail_unless(data != NULL);
154 test_netif.output = arpless_output;
155 err = ip4_output_if_src(data, &test_ipaddr, ip_2_ip4(&peer_ip),
156 16, 0, IP_PROTO_UDP, &test_netif);
157 fail_unless(err == ERR_OK);
158 fail_unless(linkoutput_ctr == 6);
159 fail_unless(linkoutput_byte_ctr == (8000 + (6 * IP_HLEN)));
162}
163END_TEST
164
165START_TEST(test_ip4_reass)
166{
167 const u16_t ip_id = 128;
168 LWIP_UNUSED_ARG(_i);
169
170 memset(&lwip_stats.mib2, 0, sizeof(lwip_stats.mib2));
171
172 create_ip4_input_fragment(ip_id, 8*200, 200, 1);
173 fail_unless(lwip_stats.ip_frag.recv == 1);
174 fail_unless(lwip_stats.ip_frag.err == 0);
175 fail_unless(lwip_stats.ip_frag.memerr == 0);
176 fail_unless(lwip_stats.ip_frag.drop == 0);
177 fail_unless(lwip_stats.mib2.ipreasmoks == 0);
178
179 create_ip4_input_fragment(ip_id, 0*200, 200, 0);
180 fail_unless(lwip_stats.ip_frag.recv == 2);
181 fail_unless(lwip_stats.ip_frag.err == 0);
182 fail_unless(lwip_stats.ip_frag.memerr == 0);
183 fail_unless(lwip_stats.ip_frag.drop == 0);
184 fail_unless(lwip_stats.mib2.ipreasmoks == 0);
185
186 create_ip4_input_fragment(ip_id, 1*200, 200, 0);
187 fail_unless(lwip_stats.ip_frag.recv == 3);
188 fail_unless(lwip_stats.ip_frag.err == 0);
189 fail_unless(lwip_stats.ip_frag.memerr == 0);
190 fail_unless(lwip_stats.ip_frag.drop == 0);
191 fail_unless(lwip_stats.mib2.ipreasmoks == 0);
192
193 create_ip4_input_fragment(ip_id, 2*200, 200, 0);
194 fail_unless(lwip_stats.ip_frag.recv == 4);
195 fail_unless(lwip_stats.ip_frag.err == 0);
196 fail_unless(lwip_stats.ip_frag.memerr == 0);
197 fail_unless(lwip_stats.ip_frag.drop == 0);
198 fail_unless(lwip_stats.mib2.ipreasmoks == 0);
199
200 create_ip4_input_fragment(ip_id, 3*200, 200, 0);
201 fail_unless(lwip_stats.ip_frag.recv == 5);
202 fail_unless(lwip_stats.ip_frag.err == 0);
203 fail_unless(lwip_stats.ip_frag.memerr == 0);
204 fail_unless(lwip_stats.ip_frag.drop == 0);
205 fail_unless(lwip_stats.mib2.ipreasmoks == 0);
206
207 create_ip4_input_fragment(ip_id, 4*200, 200, 0);
208 fail_unless(lwip_stats.ip_frag.recv == 6);
209 fail_unless(lwip_stats.ip_frag.err == 0);
210 fail_unless(lwip_stats.ip_frag.memerr == 0);
211 fail_unless(lwip_stats.ip_frag.drop == 0);
212 fail_unless(lwip_stats.mib2.ipreasmoks == 0);
213
214 create_ip4_input_fragment(ip_id, 7*200, 200, 0);
215 fail_unless(lwip_stats.ip_frag.recv == 7);
216 fail_unless(lwip_stats.ip_frag.err == 0);
217 fail_unless(lwip_stats.ip_frag.memerr == 0);
218 fail_unless(lwip_stats.ip_frag.drop == 0);
219 fail_unless(lwip_stats.mib2.ipreasmoks == 0);
220
221 create_ip4_input_fragment(ip_id, 6*200, 200, 0);
222 fail_unless(lwip_stats.ip_frag.recv == 8);
223 fail_unless(lwip_stats.ip_frag.err == 0);
224 fail_unless(lwip_stats.ip_frag.memerr == 0);
225 fail_unless(lwip_stats.ip_frag.drop == 0);
226 fail_unless(lwip_stats.mib2.ipreasmoks == 0);
227
228 create_ip4_input_fragment(ip_id, 5*200, 200, 0);
229 fail_unless(lwip_stats.ip_frag.recv == 9);
230 fail_unless(lwip_stats.ip_frag.err == 0);
231 fail_unless(lwip_stats.ip_frag.memerr == 0);
232 fail_unless(lwip_stats.ip_frag.drop == 0);
233 fail_unless(lwip_stats.mib2.ipreasmoks == 1);
234}
235END_TEST
236
237/* packets to 127.0.0.1 shall not be sent out to netif_default */
238START_TEST(test_127_0_0_1)
239{
240 ip4_addr_t localhost;
241 struct pbuf* p;
242 LWIP_UNUSED_ARG(_i);
243
244 linkoutput_ctr = 0;
245
247 netif_set_down(netif_get_loopif());
248
249 IP4_ADDR(&localhost, 127, 0, 0, 1);
251
252 if(ip4_output(p, netif_ip4_addr(netif_default), &localhost, 0, 0, IP_PROTO_UDP) != ERR_OK) {
253 pbuf_free(p);
254 }
255 fail_unless(linkoutput_ctr == 0);
256}
257END_TEST
258
259START_TEST(test_ip4addr_aton)
260{
261 ip4_addr_t ip_addr;
262
263 LWIP_UNUSED_ARG(_i);
264
265 fail_unless(ip4addr_aton("192.168.0.1", &ip_addr) == 1);
266 fail_unless(ip4addr_aton("192.168.0.0001", &ip_addr) == 1);
267 fail_unless(ip4addr_aton("192.168.0.zzz", &ip_addr) == 0);
268 fail_unless(ip4addr_aton("192.168.1", &ip_addr) == 1);
269 fail_unless(ip4addr_aton("192.168.0xd3", &ip_addr) == 1);
270 fail_unless(ip4addr_aton("192.168.0xz5", &ip_addr) == 0);
271 fail_unless(ip4addr_aton("192.168.095", &ip_addr) == 0);
272}
273END_TEST
274
275/* Test for bug #59364 */
276START_TEST(test_ip4_icmp_replylen_short)
277{
278 /* IP packet to 192.168.0.1 using proto 0x22 and 1 byte payload */
279 const u8_t unknown_proto[] = {
280 0x45, 0x00, 0x00, 0x15, 0xd4, 0x31, 0x00, 0x00, 0xff, 0x22,
281 0x66, 0x41, 0xc0, 0xa8, 0x00, 0x02, 0xc0, 0xa8, 0x00, 0x01,
282 0xaa };
283 struct pbuf *p;
284 const int icmp_len = IP_HLEN + sizeof(struct icmp_hdr);
285 LWIP_UNUSED_ARG(_i);
286
287 linkoutput_ctr = 0;
288
290 test_netif.output = arpless_output;
291 p = pbuf_alloc(PBUF_IP, sizeof(unknown_proto), PBUF_RAM);
292 pbuf_take(p, unknown_proto, sizeof(unknown_proto));
293 fail_unless(ip4_input(p, &test_netif) == ERR_OK);
294
295 fail_unless(linkoutput_ctr == 1);
296 /* Verify outgoing ICMP packet has no extra data */
297 fail_unless(linkoutput_pkt_len == icmp_len + sizeof(unknown_proto));
298 fail_if(memcmp(&linkoutput_pkt[icmp_len], unknown_proto, sizeof(unknown_proto)));
299}
300END_TEST
301
302START_TEST(test_ip4_icmp_replylen_first_8)
303{
304 /* IP packet to 192.168.0.1 using proto 0x22 and 11 bytes payload */
305 const u8_t unknown_proto[] = {
306 0x45, 0x00, 0x00, 0x1f, 0xd4, 0x31, 0x00, 0x00, 0xff, 0x22,
307 0x66, 0x37, 0xc0, 0xa8, 0x00, 0x02, 0xc0, 0xa8, 0x00, 0x01,
308 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
309 0xaa };
310 struct pbuf *p;
311 const int icmp_len = IP_HLEN + sizeof(struct icmp_hdr);
312 const int unreach_len = IP_HLEN + 8;
313 LWIP_UNUSED_ARG(_i);
314
315 linkoutput_ctr = 0;
316
318 test_netif.output = arpless_output;
319 p = pbuf_alloc(PBUF_IP, sizeof(unknown_proto), PBUF_RAM);
320 pbuf_take(p, unknown_proto, sizeof(unknown_proto));
321 fail_unless(ip4_input(p, &test_netif) == ERR_OK);
322
323 fail_unless(linkoutput_ctr == 1);
324 fail_unless(linkoutput_pkt_len == icmp_len + unreach_len);
325 fail_if(memcmp(&linkoutput_pkt[icmp_len], unknown_proto, unreach_len));
326}
327END_TEST
328
330Suite *
332{
333 testfunc tests[] = {
334 TESTFUNC(test_ip4_frag),
335 TESTFUNC(test_ip4_reass),
336 TESTFUNC(test_127_0_0_1),
337 TESTFUNC(test_ip4addr_aton),
338 TESTFUNC(test_ip4_icmp_replylen_short),
339 TESTFUNC(test_ip4_icmp_replylen_first_8),
340 };
341 return create_suite("IPv4", tests, sizeof(tests)/sizeof(testfunc), ip4_setup, ip4_teardown);
342}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define START_TEST(x)
Definition: atltest.h:75
#define lwip_htons(x)
Definition: def.h:86
#define lwip_htonl(x)
Definition: def.h:88
#define IP_MF
Definition: dhcpd.h:71
#define NULL
Definition: types.h:112
#define IP_PROTO_UDP
Definition: ip.h:48
GLuint start
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
uint8_t u8_t
Definition: arch.h:125
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:373
uint16_t u16_t
Definition: arch.h:127
s8_t err_t
Definition: err.h:96
@ ERR_OK
Definition: err.h:55
#define NETIF_FLAG_LINK_UP
Definition: netif.h:93
#define NETIF_FLAG_ETHARP
Definition: netif.h:97
#define NETIF_FLAG_BROADCAST
Definition: netif.h:87
void netif_set_down(struct netif *netif)
Definition: netif.c:949
void netif_remove(struct netif *netif)
Definition: netif.c:764
struct netif * netif_add(struct netif *netif, void *state, netif_init_fn init, netif_input_fn input)
Definition: netif.c:287
void netif_set_default(struct netif *netif)
Definition: netif.c:849
void netif_set_up(struct netif *netif)
Definition: netif.c:871
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
Definition: pbuf.c:224
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:727
u16_t pbuf_copy_partial(const struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
Definition: pbuf.c:1058
err_t pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len)
Definition: pbuf.c:1227
@ PBUF_RAM
Definition: pbuf.h:152
@ PBUF_POOL
Definition: pbuf.h:167
@ PBUF_RAW
Definition: pbuf.h:111
@ PBUF_IP
Definition: pbuf.h:97
u16_t inet_chksum(const void *dataptr, u16_t len)
Definition: inet_chksum.c:555
ip6_addr_t ip_addr_t
Definition: ip_addr.h:344
#define ETHARP_HWADDR_LEN
Definition: etharp.h:48
Suite * create_suite(const char *name, testfunc *tests, size_t num_tests, SFun setup, SFun teardown)
#define SKIP_POOL(x)
Definition: lwip_check.h:48
void lwip_check_ensure_no_alloc(unsigned int skip)
#define TESTFUNC(x)
Definition: lwip_check.h:22
static struct test_info tests[]
static const BYTE localhost[]
Definition: encode.c:1442
static UINT UINT last
Definition: font.c:45
struct netif * netif_list
Definition: netif.c:113
struct netif * netif_default
Definition: netif.c:115
#define IPH_VHL_SET(hdr, v, hl)
Definition: ip4.h:117
#define IPH_LEN_SET(hdr, len)
Definition: ip4.h:119
#define IPH_ID_SET(hdr, id)
Definition: ip4.h:120
#define IPH_PROTO_SET(hdr, proto)
Definition: ip4.h:123
#define IPH_OFFSET_SET(hdr, off)
Definition: ip4.h:121
#define IPH_TTL_SET(hdr, ttl)
Definition: ip4.h:122
#define IP_HLEN
Definition: ip4.h:64
#define IPH_CHKSUM_SET(hdr, chksum)
Definition: ip4.h:124
#define IPH_TOS_SET(hdr, tos)
Definition: ip4.h:118
#define err(...)
#define memset(x, y, z)
Definition: compat.h:39
Definition: icmp.h:65
Definition: ip4.h:73
Definition: netif.h:269
u8_t flags
Definition: netif.h:354
u16_t mtu
Definition: netif.h:344
netif_linkoutput_fn linkoutput
Definition: netif.h:308
u8_t hwaddr_len
Definition: netif.h:352
Definition: pbuf.h:186
static ip4_addr_t test_netmask
Definition: test_ip4.c:18
static void ip4_setup(void)
Definition: test_ip4.c:121
static u16_t linkoutput_pkt_len
Definition: test_ip4.c:21
static ip4_addr_t test_gw
Definition: test_ip4.c:18
static err_t test_netif_linkoutput(struct netif *netif, struct pbuf *p)
Definition: test_ip4.c:27
static struct netif test_netif
Definition: test_ip4.c:17
static void test_netif_add(void)
Definition: test_ip4.c:51
static void create_ip4_input_fragment(u16_t ip_id, u16_t start, u16_t len, int last)
Definition: test_ip4.c:74
END_TEST Suite * ip4_suite(void)
Definition: test_ip4.c:331
static err_t arpless_output(struct netif *netif, struct pbuf *p, const ip4_addr_t *ipaddr)
Definition: test_ip4.c:112
static u8_t linkoutput_pkt[100]
Definition: test_ip4.c:22
static err_t test_netif_init(struct netif *netif)
Definition: test_ip4.c:39
static ip4_addr_t test_ipaddr
Definition: test_ip4.c:18
static void ip4_teardown(void)
Definition: test_ip4.c:127
static void test_netif_remove(void)
Definition: test_ip4.c:65
static int linkoutput_ctr
Definition: test_ip4.c:19
static int linkoutput_byte_ctr
Definition: test_ip4.c:20