1 /*
2 * Copyright (c) 2022 Jamie McCrae
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_REGISTER(net_ipv4_test, CONFIG_NET_IPV4_LOG_LEVEL);
9
10 #include <zephyr/types.h>
11 #include <stdbool.h>
12 #include <stddef.h>
13 #include <string.h>
14 #include <errno.h>
15 #include <zephyr/linker/sections.h>
16 #include <zephyr/random/random.h>
17 #include <zephyr/ztest.h>
18 #include <zephyr/net/ethernet.h>
19 #include <zephyr/net/dummy.h>
20 #include <zephyr/net_buf.h>
21 #include <zephyr/net/net_ip.h>
22 #include <zephyr/net/net_if.h>
23 #include <zephyr/posix/fcntl.h>
24 #include <zephyr/net/socket.h>
25 #include <net_private.h>
26 #include <ipv4.h>
27 #include <udp_internal.h>
28 #include <tcp_internal.h>
29
30 /* Packet size for tests, excluding headers */
31 #define IPV4_TEST_PACKET_SIZE 2048
32
33 /* Wait times for semaphores and buffers */
34 #define WAIT_TIME K_MSEC(1100)
35 #define ALLOC_TIMEOUT K_MSEC(500)
36
37 /* Dummy network addresses, 192.168.8.1 and 192.168.8.2 */
38 static struct in_addr my_addr1 = { { { 0xc0, 0xa8, 0x08, 0x01 } } };
39 static struct in_addr my_addr2 = { { { 0xc0, 0xa8, 0x08, 0x02 } } };
40
41 /* IPv4 TCP packet header */
42 static const unsigned char ipv4_tcp[] = {
43 /* IPv4 header */
44 0x45, 0x00, 0x00, 0x00,
45 0x00, 0x00, 0x00, 0x00,
46 0x80, 0x06, 0x00, 0x00,
47 0xc0, 0xa8, 0x08, 0x01,
48 0xc0, 0xa8, 0x08, 0x02,
49
50 /* TCP header */
51 0x0f, 0xfc, 0x4c, 0x5f,
52 0x00, 0x00, 0x00, 0x00,
53 0x00, 0x00, 0x00, 0x00,
54 0x50, 0x10, 0x00, 0x00,
55 0x00, 0x00, 0x00, 0x00,
56 };
57
58 /* IPv4 UDP packet header */
59 static const unsigned char ipv4_udp[] = {
60 /* IPv4 header */
61 0x45, 0x00, 0x00, 0x00,
62 0x00, 0x00, 0x00, 0x00,
63 0x80, 0x11, 0x00, 0x00,
64 0xc0, 0xa8, 0x08, 0x01,
65 0xc0, 0xa8, 0x08, 0x02,
66
67 /* UDP header */
68 0x11, 0x00, 0x63, 0x04,
69 0x00, 0x00, 0x00, 0x00,
70 };
71
72 /* IPv4 UDP Single fragment packet (with more fragment bit set) */
73 static const unsigned char ipv4_udp_frag[] = {
74 /* IPv4 header */
75 0x45, 0x00, 0x00, 0x24,
76 0x12, 0x34, 0x20, 0x00,
77 0x80, 0x11, 0x00, 0x00,
78 0xc0, 0xa8, 0x08, 0x02,
79 0xc0, 0xa8, 0x08, 0x01,
80
81 /* UDP header */
82 0x11, 0x00, 0x63, 0x04,
83 0x00, 0x80, 0x00, 0x00,
84
85 /* UDP data */
86 0xaa, 0xbb, 0xcc, 0xdd,
87 0xee, 0xff, 0x94, 0x12,
88 };
89
90 /* IPv4 ICMP fragment assembly time exceeded packet (in response to ipv4_udp_frag) */
91 static const unsigned char ipv4_icmp_reassembly_time[] = {
92 /* IPv4 Header */
93 0x45, 0x00, 0x00, 0x38,
94 0x00, 0x00, 0x00, 0x00,
95 0x40, 0x01, 0xe9, 0x71,
96 0xc0, 0xa8, 0x08, 0x01,
97 0xc0, 0xa8, 0x08, 0x02,
98
99 /* ICMPv4 fragment assembly time exceeded */
100 0x0b, 0x01, 0x80, 0x7a,
101 0x00, 0x00, 0x00, 0x00,
102
103 /* Original IPv4 packet data */
104 0x45, 0x00, 0x00, 0x24,
105 0x12, 0x34, 0x20, 0x00,
106 0x80, 0x11, 0x77, 0x41,
107 0xc0, 0xa8, 0x08, 0x02,
108 0xc0, 0xa8, 0x08, 0x01,
109 0x11, 0x00, 0x63, 0x04,
110 0x00, 0x80, 0x00, 0x00,
111 };
112
113 /* IPv4 UDP packet header with do not fragment flag set */
114 static const unsigned char ipv4_udp_do_not_frag[] = {
115 /* IPv4 header */
116 0x45, 0x00, 0x00, 0x00,
117 0x00, 0x00, 0x40, 0x00,
118 0x80, 0x11, 0x00, 0x00,
119 0xc0, 0xa8, 0x08, 0x01,
120 0xc0, 0xa8, 0x08, 0x02,
121
122 /* UDP header */
123 0x11, 0x00, 0x63, 0x04,
124 0x00, 0x00, 0x00, 0x00,
125 };
126
127 enum {
128 TEST_UDP,
129 TEST_TCP,
130 TEST_SINGLE_FRAGMENT,
131 TEST_NO_FRAGMENT,
132 };
133
134 static struct net_if *iface1;
135
136 static struct k_sem wait_data;
137 static struct k_sem wait_received_data;
138
139 static bool test_started;
140 static uint16_t pkt_id;
141 static uint16_t pkt_recv_size;
142 static uint16_t pkt_recv_expected_size;
143 static bool last_packet_received;
144 static uint8_t active_test;
145 static uint8_t lower_layer_packet_count;
146 static uint8_t upper_layer_packet_count;
147 static uint16_t lower_layer_total_size;
148 static uint16_t upper_layer_total_size;
149
150 static uint8_t test_tmp_buf[256];
151 static uint8_t net_iface_dummy_data;
152
153 static void net_iface_init(struct net_if *iface);
154 static int sender_iface(const struct device *dev, struct net_pkt *pkt);
155
156 static struct dummy_api net_iface_api = {
157 .iface_api.init = net_iface_init,
158 .send = sender_iface,
159 };
160
161 NET_DEVICE_INIT_INSTANCE(net_iface1_test,
162 "iface1",
163 iface1,
164 NULL,
165 NULL,
166 &net_iface_dummy_data,
167 NULL,
168 CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
169 &net_iface_api,
170 DUMMY_L2,
171 NET_L2_GET_CTX_TYPE(DUMMY_L2),
172 NET_IPV4_MTU);
173
174
net_iface_init(struct net_if * iface)175 static void net_iface_init(struct net_if *iface)
176 {
177 static uint8_t mac[6] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
178
179 net_if_set_link_addr(iface, mac, sizeof(mac), NET_LINK_DUMMY);
180 }
181
182 /* Generates dummy data to use in tests */
generate_dummy_data(uint8_t * buffer,uint16_t buffer_size)183 static void generate_dummy_data(uint8_t *buffer, uint16_t buffer_size)
184 {
185 uint16_t i = 0;
186
187 while (i < buffer_size) {
188 buffer[i] = (uint8_t)(i & 0xff);
189 ++i;
190 }
191 }
192
193 /* Callback function for processing all reassembly buffers */
reassembly_foreach_cb(struct net_ipv4_reassembly * reassembly,void * data)194 static void reassembly_foreach_cb(struct net_ipv4_reassembly *reassembly, void *data)
195 {
196 uint8_t *packets = (uint8_t *)data;
197 ++*packets;
198 }
199
200 /* Checks all IPv4 headers against expected values */
check_ipv4_fragment_header(struct net_pkt * pkt,const uint8_t * orig_hdr,uint16_t id,uint16_t current_length,bool final)201 static void check_ipv4_fragment_header(struct net_pkt *pkt, const uint8_t *orig_hdr, uint16_t id,
202 uint16_t current_length, bool final)
203 {
204 uint16_t pkt_len;
205 uint16_t pkt_offset;
206 uint8_t pkt_flags;
207 const struct net_ipv4_hdr *hdr = NET_IPV4_HDR(pkt);
208
209 zassert_equal(hdr->vhl, orig_hdr[offsetof(struct net_ipv4_hdr, vhl)],
210 "IPv4 header vhl mismatch");
211 zassert_equal(hdr->tos, orig_hdr[offsetof(struct net_ipv4_hdr, tos)],
212 "IPv4 header tos mismatch");
213 zassert_equal(hdr->ttl, orig_hdr[offsetof(struct net_ipv4_hdr, ttl)],
214 "IPv4 header ttl mismatch");
215 zassert_equal(hdr->proto, orig_hdr[offsetof(struct net_ipv4_hdr, proto)],
216 "IPv4 header protocol mismatch");
217 zassert_equal(*((uint16_t *)&hdr->id), pkt_id, "IPv4 header ID mismatch");
218 zassert_mem_equal(hdr->src, &orig_hdr[offsetof(struct net_ipv4_hdr, src)],
219 NET_IPV4_ADDR_SIZE, "IPv4 header source IP mismatch");
220 zassert_mem_equal(hdr->dst, &orig_hdr[offsetof(struct net_ipv4_hdr, dst)],
221 NET_IPV4_ADDR_SIZE, "IPv4 header destination IP mismatch");
222
223 pkt_len = ntohs(hdr->len);
224 pkt_offset = ntohs(*((uint16_t *)&hdr->offset));
225 pkt_flags = (pkt_offset & ~NET_IPV4_FRAGH_OFFSET_MASK) >> 13;
226 pkt_offset &= NET_IPV4_FRAGH_OFFSET_MASK;
227 pkt_offset *= 8;
228
229 if (final) {
230 zassert_equal(pkt_flags, 0, "IPv4 header fragment flags mismatch");
231 } else {
232 zassert_equal(pkt_flags, BIT(0), "IPv4 header fragment flags mismatch");
233 }
234
235 zassert_equal(net_pkt_get_len(pkt), pkt_len, "IPv4 header length mismatch");
236 zassert_equal(pkt_offset, current_length, "IPv4 header length mismatch");
237 zassert_equal(net_calc_chksum_ipv4(pkt), 0, "IPv4 header checksum mismatch");
238 }
239
sender_iface(const struct device * dev,struct net_pkt * pkt)240 static int sender_iface(const struct device *dev, struct net_pkt *pkt)
241 {
242 struct net_pkt *recv_pkt;
243 int ret;
244 uint8_t buf_ip_src[4];
245 uint8_t buf_ip_dst[4];
246 uint16_t buf_port_src;
247 uint16_t buf_port_dst;
248 uint16_t offset;
249
250 if (!pkt->buffer) {
251 LOG_ERR("No data to send!");
252 return -ENODATA;
253 }
254
255 if (net_pkt_get_len(pkt) > NET_IPV4_MTU) {
256 LOG_DBG("Too large for test");
257 pkt_recv_size = net_pkt_get_len(pkt);
258 return -EMSGSIZE;
259 }
260
261 if (test_started) {
262 ++lower_layer_packet_count;
263 lower_layer_total_size += net_pkt_get_len(pkt);
264
265 /* Verify the fragments */
266 bool last_packet;
267
268 net_pkt_cursor_init(pkt);
269
270 if (lower_layer_packet_count == 1 && pkt_id == 0) {
271 /* Extract ID from first packet */
272 pkt_id = *((uint16_t *)&NET_IPV4_HDR(pkt)->id);
273
274 /* Check ID is 0 for non-fragmented packets and non-0 for fragmented
275 * packets
276 */
277 if (active_test == TEST_UDP || active_test == TEST_TCP) {
278 zassert_not_equal(pkt_id, 0, "IPv4 header ID should not be 0");
279 } else if (active_test == TEST_SINGLE_FRAGMENT) {
280 zassert_equal(pkt_id, 0, "IPv4 header ID should be 0");
281 }
282 }
283
284 last_packet = ((pkt_recv_size + net_pkt_get_len(pkt)) >= pkt_recv_expected_size ?
285 true : false);
286 check_ipv4_fragment_header(pkt, (active_test == TEST_UDP ? ipv4_udp :
287 (active_test == TEST_TCP ? ipv4_tcp :
288 ipv4_icmp_reassembly_time)), pkt_id, pkt_recv_size,
289 last_packet);
290 pkt_recv_size += net_pkt_get_len(pkt) - NET_IPV4H_LEN;
291
292 if (last_packet) {
293 last_packet_received = true;
294 }
295
296 if (active_test == TEST_SINGLE_FRAGMENT) {
297 /* Verify that this is an ICMPv4 response */
298 zassert_mem_equal(ipv4_icmp_reassembly_time, pkt->buffer->data,
299 sizeof(ipv4_icmp_reassembly_time), "Expected ICMP error");
300 goto no_duplicate;
301 }
302
303 /* Duplicate the packet and flip the source/destination IPs and ports then
304 * re-insert the packets back into the same interface
305 */
306 recv_pkt = net_pkt_rx_clone(pkt, K_NO_WAIT);
307 net_pkt_set_overwrite(recv_pkt, true);
308
309 /* Read IPs */
310 net_pkt_cursor_init(recv_pkt);
311 net_pkt_skip(recv_pkt, 12);
312 net_pkt_read(recv_pkt, buf_ip_src, sizeof(buf_ip_src));
313 net_pkt_read(recv_pkt, buf_ip_dst, sizeof(buf_ip_dst));
314
315 /* Write opposite IPs */
316 net_pkt_cursor_init(recv_pkt);
317 net_pkt_skip(recv_pkt, 12);
318 net_pkt_write(recv_pkt, buf_ip_dst, sizeof(buf_ip_dst));
319 net_pkt_write(recv_pkt, buf_ip_src, sizeof(buf_ip_src));
320
321 /* Get offset to check if this is the first packet */
322 net_pkt_cursor_init(recv_pkt);
323 net_pkt_skip(recv_pkt, 6);
324 net_pkt_read_be16(recv_pkt, &offset);
325 offset &= NET_IPV4_FRAGH_OFFSET_MASK;
326
327 if (offset == 0) {
328 /* Offset is 0, flip ports of packet */
329 net_pkt_cursor_init(recv_pkt);
330 net_pkt_skip(recv_pkt, NET_IPV4H_LEN);
331 net_pkt_read_be16(recv_pkt, &buf_port_src);
332 net_pkt_read_be16(recv_pkt, &buf_port_dst);
333
334 net_pkt_cursor_init(recv_pkt);
335 net_pkt_skip(recv_pkt, NET_IPV4H_LEN);
336 net_pkt_write_be16(recv_pkt, buf_port_dst);
337 net_pkt_write_be16(recv_pkt, buf_port_src);
338 }
339
340 /* Reset position to beginning and ready packet for insertion */
341 net_pkt_cursor_init(recv_pkt);
342 net_pkt_set_overwrite(recv_pkt, false);
343 net_pkt_set_iface(recv_pkt, iface1);
344 ret = net_recv_data(net_pkt_iface(recv_pkt), recv_pkt);
345 zassert_equal(ret, 0, "Cannot receive data (%d)", ret);
346 k_sleep(K_MSEC(10));
347
348 no_duplicate:
349 k_sem_give(&wait_data);
350
351 }
352
353 return 0;
354 }
355
356
udp_data_received(struct net_conn * conn,struct net_pkt * pkt,union net_ip_header * ip_hdr,union net_proto_header * proto_hdr,void * user_data)357 static enum net_verdict udp_data_received(struct net_conn *conn, struct net_pkt *pkt,
358 union net_ip_header *ip_hdr,
359 union net_proto_header *proto_hdr, void *user_data)
360 {
361 const struct net_ipv4_hdr *hdr = NET_IPV4_HDR(pkt);
362 uint8_t tmp_buf[256];
363 uint8_t verify_buf[256];
364 uint16_t i;
365 uint16_t pkt_len;
366 uint16_t pkt_offset;
367 uint8_t pkt_flags;
368 uint16_t udp_src_port;
369 uint16_t udp_dst_port;
370 uint16_t udp_len;
371 uint16_t udp_checksum;
372
373 /* Update counts */
374 ++upper_layer_packet_count;
375 upper_layer_total_size += net_pkt_get_len(pkt);
376
377 /* Generate dummy data to verify */
378 generate_dummy_data(tmp_buf, sizeof(tmp_buf));
379
380 /* Verify IPv4 header is valid */
381 zassert_equal(hdr->vhl, ipv4_udp[offsetof(struct net_ipv4_hdr, vhl)],
382 "IPv4 header vhl mismatch");
383 zassert_equal(hdr->tos, ipv4_udp[offsetof(struct net_ipv4_hdr, tos)],
384 "IPv4 header tos mismatch");
385 zassert_equal(hdr->ttl, ipv4_udp[offsetof(struct net_ipv4_hdr, ttl)],
386 "IPv4 header ttl mismatch");
387 zassert_equal(hdr->proto, ipv4_udp[offsetof(struct net_ipv4_hdr, proto)],
388 "IPv4 header protocol mismatch");
389 zassert_equal(*((uint16_t *)&hdr->id), pkt_id, "IPv4 header ID mismatch");
390 zassert_mem_equal(hdr->src, &ipv4_udp[offsetof(struct net_ipv4_hdr, dst)],
391 NET_IPV4_ADDR_SIZE, "IPv4 header source IP mismatch");
392 zassert_mem_equal(hdr->dst, &ipv4_udp[offsetof(struct net_ipv4_hdr, src)],
393 NET_IPV4_ADDR_SIZE, "IPv4 header destination IP mismatch");
394
395 pkt_len = ntohs(hdr->len);
396 pkt_offset = ntohs(*((uint16_t *)&hdr->offset));
397 pkt_flags = (pkt_offset & ~NET_IPV4_FRAGH_OFFSET_MASK) >> 13;
398 pkt_offset &= NET_IPV4_FRAGH_OFFSET_MASK;
399 pkt_offset *= 8;
400
401 zassert_equal(pkt_flags, 0, "IPv4 header fragment flags mismatch");
402 zassert_equal(net_pkt_get_len(pkt), pkt_len, "IPv4 header length mismatch");
403 zassert_equal(pkt_offset, 0, "IPv4 header length mismatch");
404 zassert_equal(net_calc_chksum_ipv4(pkt), 0, "IPv4 header checksum mismatch");
405
406 /* Verify IPv4 UDP header is valid */
407 net_pkt_cursor_init(pkt);
408 net_pkt_read(pkt, verify_buf, NET_IPV4H_LEN);
409
410 net_pkt_read_be16(pkt, &udp_src_port);
411 net_pkt_read_be16(pkt, &udp_dst_port);
412 net_pkt_read_be16(pkt, &udp_len);
413 net_pkt_read_be16(pkt, &udp_checksum);
414
415 /* Verify IPv4 UDP data is valid */
416 i = NET_IPV4H_LEN;
417 while (i < net_pkt_get_len(pkt)) {
418 net_pkt_read(pkt, verify_buf, sizeof(verify_buf));
419
420 zassert_mem_equal(tmp_buf, verify_buf, sizeof(verify_buf),
421 "IPv4 data verification failure");
422 i += sizeof(verify_buf);
423 }
424
425 LOG_DBG("Data %p received", pkt);
426
427 net_pkt_unref(pkt);
428
429 k_sem_give(&wait_received_data);
430
431 return NET_OK;
432 }
433
tcp_data_received(struct net_conn * conn,struct net_pkt * pkt,union net_ip_header * ip_hdr,union net_proto_header * proto_hdr,void * user_data)434 static enum net_verdict tcp_data_received(struct net_conn *conn, struct net_pkt *pkt,
435 union net_ip_header *ip_hdr,
436 union net_proto_header *proto_hdr, void *user_data)
437 {
438 const struct net_ipv4_hdr *hdr = NET_IPV4_HDR(pkt);
439 uint8_t tmp_buf[256];
440 uint8_t verify_buf[256];
441 uint16_t i;
442 uint16_t pkt_len;
443 uint16_t pkt_offset;
444 uint8_t pkt_flags;
445 uint16_t tcp_src_port;
446 uint16_t tcp_dst_port;
447 uint32_t tcp_sequence;
448 uint32_t tcp_acknowledgment;
449 uint16_t tcp_flags;
450 uint16_t tcp_window_size;
451 uint16_t tcp_checksum;
452 uint16_t tcp_urgent;
453
454 /* Update counts */
455 ++upper_layer_packet_count;
456 upper_layer_total_size += net_pkt_get_len(pkt);
457
458 /* Generate dummy data to verify */
459 generate_dummy_data(tmp_buf, sizeof(tmp_buf));
460
461 /* Verify IPv4 header is valid */
462 zassert_equal(hdr->vhl, ipv4_tcp[offsetof(struct net_ipv4_hdr, vhl)],
463 "IPv4 header vhl mismatch");
464 zassert_equal(hdr->tos, ipv4_tcp[offsetof(struct net_ipv4_hdr, tos)],
465 "IPv4 header tos mismatch");
466 zassert_equal(hdr->ttl, ipv4_tcp[offsetof(struct net_ipv4_hdr, ttl)],
467 "IPv4 header ttl mismatch");
468 zassert_equal(hdr->proto, ipv4_tcp[offsetof(struct net_ipv4_hdr, proto)],
469 "IPv4 header protocol mismatch");
470 zassert_equal(*((uint16_t *)&hdr->id), pkt_id, "IPv4 header ID mismatch");
471 zassert_mem_equal(hdr->src, &ipv4_tcp[offsetof(struct net_ipv4_hdr, dst)],
472 NET_IPV4_ADDR_SIZE, "IPv4 header source IP mismatch");
473 zassert_mem_equal(hdr->dst, &ipv4_tcp[offsetof(struct net_ipv4_hdr, src)],
474 NET_IPV4_ADDR_SIZE, "IPv4 header destination IP mismatch");
475
476 pkt_len = ntohs(hdr->len);
477 pkt_offset = ntohs(*((uint16_t *)&hdr->offset));
478 pkt_flags = (pkt_offset & ~NET_IPV4_FRAGH_OFFSET_MASK) >> 13;
479 pkt_offset &= NET_IPV4_FRAGH_OFFSET_MASK;
480 pkt_offset *= 8;
481
482 zassert_equal(pkt_flags, 0, "IPv4 header fragment flags mismatch");
483 zassert_equal(net_pkt_get_len(pkt), pkt_len, "IPv4 header length mismatch");
484 zassert_equal(pkt_offset, 0, "IPv4 header length mismatch");
485 zassert_equal(net_calc_chksum_ipv4(pkt), 0, "IPv4 header checksum mismatch");
486
487 /* Verify IPv4 UDP header is valid */
488 net_pkt_cursor_init(pkt);
489 net_pkt_read(pkt, verify_buf, NET_IPV4H_LEN);
490
491 net_pkt_read_be16(pkt, &tcp_src_port);
492 net_pkt_read_be16(pkt, &tcp_dst_port);
493 net_pkt_read_be32(pkt, &tcp_sequence);
494 net_pkt_read_be32(pkt, &tcp_acknowledgment);
495 net_pkt_read_be16(pkt, &tcp_flags);
496 net_pkt_read_be16(pkt, &tcp_window_size);
497 net_pkt_read_be16(pkt, &tcp_checksum);
498 net_pkt_read_be16(pkt, &tcp_urgent);
499
500 zassert_equal(tcp_src_port, 19551, "IPv4 TCP source port verification failure");
501 zassert_equal(tcp_dst_port, 4092, "IPv4 TCP destination port verification failure");
502 zassert_equal(tcp_sequence, 0, "IPv4 TCP sequence verification failure");
503 zassert_equal(tcp_acknowledgment, 0, "IPv4 TCP acknowledgment verification failure");
504 zassert_equal(tcp_flags, 0x5010, "IPv4 TCP flags verification failure");
505 zassert_equal(tcp_window_size, 0, "IPv4 TCP window size verification failure");
506 zassert_equal(tcp_urgent, 0, "IPv4 TCP urgent verification failure");
507
508 /* Verify IPv4 TCP data is valid */
509 i = NET_IPV4H_LEN;
510 while (i < net_pkt_get_len(pkt)) {
511 net_pkt_read(pkt, verify_buf, sizeof(verify_buf));
512
513 zassert_mem_equal(tmp_buf, verify_buf, sizeof(verify_buf),
514 "IPv4 data verification failure");
515 i += sizeof(verify_buf);
516 }
517
518 LOG_DBG("Data %p received", pkt);
519
520 net_pkt_unref(pkt);
521
522 k_sem_give(&wait_received_data);
523
524 return NET_OK;
525 }
526
setup_udp_handler(const struct in_addr * raddr,const struct in_addr * laddr,uint16_t remote_port,uint16_t local_port)527 static void setup_udp_handler(const struct in_addr *raddr, const struct in_addr *laddr,
528 uint16_t remote_port, uint16_t local_port)
529 {
530 static struct net_conn_handle *handle;
531 struct sockaddr remote_addr = { 0 };
532 struct sockaddr local_addr = { 0 };
533 int ret;
534
535 net_ipaddr_copy(&net_sin(&local_addr)->sin_addr, laddr);
536 local_addr.sa_family = AF_INET;
537
538 net_ipaddr_copy(&net_sin(&remote_addr)->sin_addr, raddr);
539 remote_addr.sa_family = AF_INET;
540
541 ret = net_udp_register(AF_INET, &local_addr, &remote_addr, local_port, remote_port, NULL,
542 udp_data_received, NULL, &handle);
543
544 zassert_equal(ret, 0, "Cannot register UDP connection");
545 }
546
setup_tcp_handler(const struct in_addr * raddr,const struct in_addr * laddr,uint16_t remote_port,uint16_t local_port)547 static void setup_tcp_handler(const struct in_addr *raddr, const struct in_addr *laddr,
548 uint16_t remote_port, uint16_t local_port)
549 {
550 static struct net_conn_handle *handle;
551 struct sockaddr remote_addr = { 0 };
552 struct sockaddr local_addr = { 0 };
553 int ret;
554
555 net_ipaddr_copy(&net_sin(&local_addr)->sin_addr, laddr);
556 local_addr.sa_family = AF_INET;
557
558 net_ipaddr_copy(&net_sin(&remote_addr)->sin_addr, raddr);
559 remote_addr.sa_family = AF_INET;
560
561 ret = net_conn_register(IPPROTO_TCP, AF_INET, &local_addr, &remote_addr, local_port,
562 remote_port, NULL, tcp_data_received, NULL, &handle);
563
564 zassert_equal(ret, 0, "Cannot register TCP connection");
565 }
566
test_setup(void)567 static void *test_setup(void)
568 {
569 struct net_if_addr *ifaddr;
570
571 /* The semaphore is there to wait the data to be received. */
572 k_sem_init(&wait_data, 0, UINT_MAX);
573 k_sem_init(&wait_received_data, 0, UINT_MAX);
574
575 iface1 = net_if_get_by_index(1);
576 zassert_not_null(iface1, "Network interface is null");
577
578 ifaddr = net_if_ipv4_addr_add(iface1, &my_addr1, NET_ADDR_MANUAL, 0);
579 LOG_DBG("Add IPv4 address %s", net_sprint_ipv4_addr(&my_addr1));
580
581 if (!ifaddr) {
582 LOG_DBG("Cannot add IPv4 address %s", net_sprint_ipv4_addr(&my_addr1));
583 zassert_not_null(ifaddr, "addr1");
584 }
585
586 net_if_up(iface1);
587
588 /* Setup TCP and UDP connections */
589 setup_udp_handler(&my_addr1, &my_addr2, 4352, 25348);
590 setup_tcp_handler(&my_addr1, &my_addr2, 4092, 19551);
591
592 /* Generate test data */
593 generate_dummy_data(test_tmp_buf, sizeof(test_tmp_buf));
594
595 return NULL;
596 }
597
ZTEST(net_ipv4_fragment,test_udp)598 ZTEST(net_ipv4_fragment, test_udp)
599 {
600 struct net_pkt *pkt;
601 int ret;
602 uint16_t i;
603 uint16_t packet_len;
604
605 /* Setup test variables */
606 active_test = TEST_UDP;
607 test_started = true;
608
609 /* Create packet */
610 pkt = net_pkt_alloc_with_buffer(iface1, sizeof(ipv4_udp) + IPV4_TEST_PACKET_SIZE, AF_INET,
611 IPPROTO_UDP, ALLOC_TIMEOUT);
612 zassert_not_null(pkt, "Packet creation failed");
613
614 /* Add IPv4 and UDP headers */
615 ret = net_pkt_write(pkt, ipv4_udp, sizeof(ipv4_udp));
616 zassert_equal(ret, 0, "IPv4 header append failed");
617
618 /* Add enough data until we have 4 packets */
619 i = 0;
620 while (i < IPV4_TEST_PACKET_SIZE) {
621 ret = net_pkt_write(pkt, test_tmp_buf, sizeof(test_tmp_buf));
622 zassert_equal(ret, 0, "IPv4 data append failed");
623 i += sizeof(test_tmp_buf);
624 }
625
626 /* Setup packet for insertion */
627 net_pkt_set_iface(pkt, iface1);
628 net_pkt_set_family(pkt, AF_INET);
629 net_pkt_set_ip_hdr_len(pkt, sizeof(struct net_ipv4_hdr));
630
631 /* Update IPv4 headers */
632 packet_len = net_pkt_get_len(pkt);
633 NET_IPV4_HDR(pkt)->len = htons(packet_len);
634 NET_IPV4_HDR(pkt)->chksum = net_calc_chksum_ipv4(pkt);
635
636 net_pkt_cursor_init(pkt);
637 net_pkt_set_overwrite(pkt, true);
638 net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt));
639 net_udp_finalize(pkt, false);
640
641 pkt_recv_expected_size = net_pkt_get_len(pkt);
642
643 ret = net_send_data(pkt);
644 zassert_equal(ret, 0, "Packet send failure");
645
646 zassert_equal(k_sem_take(&wait_data, WAIT_TIME), 0,
647 "Timeout waiting for packet to be sent");
648 zassert_equal(k_sem_take(&wait_received_data, WAIT_TIME), 0,
649 "Timeout waiting for packet to be received");
650
651 /* Check packet counts are valid */
652 k_sleep(K_SECONDS(1));
653 zassert_equal(lower_layer_packet_count, 4, "Expected 4 packets at lower layers");
654 zassert_equal(upper_layer_packet_count, 1, "Expected 1 packet at upper layers");
655 zassert_equal(last_packet_received, 1, "Expected last packet");
656 zassert_equal(lower_layer_total_size, (NET_IPV4H_LEN * 3) + packet_len,
657 "Expected data send size mismatch at lower layers");
658 zassert_equal(upper_layer_total_size, packet_len,
659 "Expected data received size mismatch at upper layers");
660 zassert_equal(pkt_recv_expected_size, (pkt_recv_size + NET_IPV4H_LEN),
661 "Packet size mismatch");
662 }
663
ZTEST(net_ipv4_fragment,test_tcp)664 ZTEST(net_ipv4_fragment, test_tcp)
665 {
666 struct net_pkt *pkt;
667 int ret;
668 uint8_t tmp_buf[256];
669 uint16_t i;
670 uint16_t packet_len;
671
672 /* Setup test variables */
673 active_test = TEST_TCP;
674 test_started = true;
675
676 generate_dummy_data(tmp_buf, sizeof(tmp_buf));
677
678 pkt = net_pkt_alloc_with_buffer(iface1, (sizeof(ipv4_tcp) + IPV4_TEST_PACKET_SIZE),
679 AF_INET, IPPROTO_TCP, ALLOC_TIMEOUT);
680 zassert_not_null(pkt, "Packet creation failure");
681
682 net_pkt_set_ip_hdr_len(pkt, sizeof(struct net_ipv4_hdr));
683
684 /* Add IPv4 and TCP headers */
685 ret = net_pkt_write(pkt, ipv4_tcp, sizeof(ipv4_tcp));
686 zassert_equal(ret, 0, "IPv4 header append failed");
687
688 /* Add enough data until we have 4 packets */
689 i = 0;
690 while (i < IPV4_TEST_PACKET_SIZE) {
691 ret = net_pkt_write(pkt, tmp_buf, sizeof(tmp_buf));
692 zassert_equal(ret, 0, "IPv4 data append failed");
693 i += sizeof(tmp_buf);
694 }
695
696 net_pkt_set_iface(pkt, iface1);
697 net_pkt_set_family(pkt, AF_INET);
698 net_pkt_set_ip_hdr_len(pkt, sizeof(struct net_ipv4_hdr));
699
700 packet_len = net_pkt_get_len(pkt);
701
702 NET_IPV4_HDR(pkt)->len = htons(packet_len);
703 NET_IPV4_HDR(pkt)->chksum = net_calc_chksum_ipv4(pkt);
704
705 net_pkt_cursor_init(pkt);
706 net_pkt_set_overwrite(pkt, true);
707 net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt));
708
709 net_tcp_finalize(pkt, false);
710
711 pkt_recv_expected_size = net_pkt_get_len(pkt);
712
713 ret = net_send_data(pkt);
714 zassert_equal(ret, 0, "Packet send failure");
715
716 zassert_equal(k_sem_take(&wait_data, WAIT_TIME), 0,
717 "Timeout waiting for packet to be sent");
718 zassert_equal(k_sem_take(&wait_received_data, WAIT_TIME), 0,
719 "Timeout waiting for packet to be received");
720
721 /* Check packet counts are valid */
722 k_sleep(K_SECONDS(1));
723 zassert_equal(lower_layer_packet_count, 4, "Expected 4 packets at lower layers");
724 zassert_equal(upper_layer_packet_count, 1, "Expected 1 packet at upper layers");
725 zassert_equal(last_packet_received, 1, "Expected last packet");
726 zassert_equal(lower_layer_total_size, (NET_IPV4H_LEN * 3) + packet_len,
727 "Expected data send size mismatch at lower layers");
728 zassert_equal(upper_layer_total_size, packet_len,
729 "Expected data received size mismatch at upper layers");
730 zassert_equal(pkt_recv_expected_size, (pkt_recv_size + NET_IPV4H_LEN),
731 "Packet size mismatch");
732 }
733
734 /* Test inserting only 1 fragment and ensuring that it is removed after the timeout elapses */
ZTEST(net_ipv4_fragment,test_fragment_timeout)735 ZTEST(net_ipv4_fragment, test_fragment_timeout)
736 {
737 struct net_pkt *pkt;
738 int ret;
739 uint8_t packets;
740 int sem_count;
741
742 /* Setup test variables */
743 active_test = TEST_SINGLE_FRAGMENT;
744 test_started = true;
745
746 /* Create a packet for the test */
747 pkt = net_pkt_alloc_with_buffer(iface1, sizeof(ipv4_udp_frag), AF_INET,
748 IPPROTO_UDP, ALLOC_TIMEOUT);
749 zassert_not_null(pkt, "Packet creation failure");
750
751 net_pkt_set_family(pkt, AF_INET);
752 net_pkt_set_ip_hdr_len(pkt, sizeof(struct net_ipv4_hdr));
753
754 /* Create packet from base data */
755 net_pkt_cursor_init(pkt);
756 ret = net_pkt_write(pkt, ipv4_udp_frag, sizeof(ipv4_udp_frag));
757 zassert_equal(ret, 0, "IPv4 fragmented frame append failed");
758
759 /* Generate valid checksum for frame */
760 net_pkt_cursor_init(pkt);
761 net_pkt_set_overwrite(pkt, true);
762 NET_IPV4_HDR(pkt)->chksum = net_calc_chksum_ipv4(pkt);
763 net_pkt_set_overwrite(pkt, false);
764
765 pkt_recv_expected_size = sizeof(ipv4_icmp_reassembly_time);
766
767 /* Directly put the packet into the interface */
768 net_pkt_set_iface(pkt, iface1);
769 ret = net_recv_data(net_pkt_iface(pkt), pkt);
770 zassert_equal(ret, 0, "Cannot receive data (%d)", ret);
771
772 /* Check number of pending reassembly packets */
773 k_sleep(K_MSEC(10));
774 packets = 0;
775 net_ipv4_frag_foreach(reassembly_foreach_cb, &packets);
776 zassert_equal(packets, 1, "Expected fragment to be present in buffer");
777
778 /* Delay briefly and re-check number of pending reassembly packets */
779 k_sleep(K_MSEC(1100));
780 packets = 0;
781 net_ipv4_frag_foreach(reassembly_foreach_cb, &packets);
782 zassert_equal(packets, 0, "Expected fragment to be dropped after timeout");
783
784 /* Ensure a lower-layer frame was received */
785 sem_count = k_sem_count_get(&wait_data);
786 zassert_equal(sem_count, 1, "Expected one lower-layer frame");
787
788 /* Ensure no complete upper-layer packets were received */
789 sem_count = k_sem_count_get(&wait_received_data);
790 zassert_equal(sem_count, 0, "Expected no complete upper-layer packets");
791
792 /* Check packet counts are valid */
793 k_sleep(K_MSEC(500));
794 zassert_equal(lower_layer_packet_count, 1, "Expected 1 packet at lower layers");
795 zassert_equal(upper_layer_packet_count, 0, "Expected no packets at upper layers");
796 zassert_equal(last_packet_received, 1, "Expected last packet");
797 zassert_equal(lower_layer_total_size, sizeof(ipv4_icmp_reassembly_time),
798 "Expected 56 total bytes sent at lower layers");
799 zassert_equal(upper_layer_total_size, 0,
800 "Expected 0 total bytes received at upper layers");
801 zassert_equal(pkt_recv_expected_size, (pkt_recv_size + NET_IPV4H_LEN),
802 "Packet size mismatch");
803 }
804
805 /* Test inserting large packet with do not fragment bit set */
ZTEST(net_ipv4_fragment,test_do_not_fragment)806 ZTEST(net_ipv4_fragment, test_do_not_fragment)
807 {
808 struct net_pkt *pkt;
809 int ret;
810 uint8_t tmp_buf[256];
811 uint16_t i;
812 uint16_t packet_len;
813
814 /* Setup test variables */
815 active_test = TEST_NO_FRAGMENT;
816 test_started = true;
817
818 /* Generate test data */
819 generate_dummy_data(tmp_buf, sizeof(tmp_buf));
820
821 /* Create packet */
822 pkt = net_pkt_alloc_with_buffer(iface1,
823 (sizeof(ipv4_udp_do_not_frag) + IPV4_TEST_PACKET_SIZE),
824 AF_INET, IPPROTO_UDP, ALLOC_TIMEOUT);
825 zassert_not_null(pkt, "Packet creation failed");
826
827 /* Add IPv4 and UDP headers */
828 ret = net_pkt_write(pkt, ipv4_udp_do_not_frag, sizeof(ipv4_udp_do_not_frag));
829 zassert_equal(ret, 0, "IPv4 header append failed");
830
831 /* Add enough data until we have 4 packets */
832 i = 0;
833 while (i < IPV4_TEST_PACKET_SIZE) {
834 ret = net_pkt_write(pkt, tmp_buf, sizeof(tmp_buf));
835 zassert_equal(ret, 0, "IPv4 data append failed");
836 i += sizeof(tmp_buf);
837 }
838
839 /* Setup packet for insertion */
840 net_pkt_set_iface(pkt, iface1);
841 net_pkt_set_family(pkt, AF_INET);
842 net_pkt_set_ip_hdr_len(pkt, sizeof(struct net_ipv4_hdr));
843
844 /* Update IPv4 headers */
845 packet_len = net_pkt_get_len(pkt);
846 NET_IPV4_HDR(pkt)->len = htons(packet_len);
847 NET_IPV4_HDR(pkt)->chksum = net_calc_chksum_ipv4(pkt);
848
849 net_pkt_cursor_init(pkt);
850 net_pkt_set_overwrite(pkt, true);
851 net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt));
852 net_udp_finalize(pkt, false);
853
854 pkt_recv_expected_size = net_pkt_get_len(pkt);
855
856 ret = net_send_data(pkt);
857 zassert_equal(ret, 0, "Packet send failure");
858
859 zassert_equal(k_sem_take(&wait_data, WAIT_TIME), -EAGAIN,
860 "Expected timeout waiting for packet to be sent");
861 zassert_equal(k_sem_take(&wait_received_data, WAIT_TIME), -EAGAIN,
862 "Expected timeout waiting for packet to be received");
863
864 /* Check packet counts are valid */
865 k_sleep(K_MSEC(100));
866 zassert_equal(lower_layer_packet_count, 0, "Expected no packets at lower layers");
867 zassert_equal(upper_layer_packet_count, 0, "Expected no packets at upper layers");
868 zassert_equal(last_packet_received, 0, "Did not expect last packet");
869 zassert_equal(lower_layer_total_size, 0,
870 "Expected data send size mismatch at lower layers");
871 zassert_equal(upper_layer_total_size, 0,
872 "Expected data received size mismatch at upper layers");
873 zassert_equal(pkt_recv_size, pkt_recv_expected_size, "Packet size mismatch");
874 }
875
test_pre(void * ptr)876 static void test_pre(void *ptr)
877 {
878 k_sem_reset(&wait_data);
879 k_sem_reset(&wait_received_data);
880
881 lower_layer_packet_count = 0;
882 upper_layer_packet_count = 0;
883 lower_layer_total_size = 0;
884 upper_layer_total_size = 0;
885 last_packet_received = false;
886 test_started = false;
887 pkt_id = 0;
888 pkt_recv_size = 0;
889 pkt_recv_expected_size = 0;
890 }
891
892 ZTEST_SUITE(net_ipv4_fragment, NULL, test_setup, test_pre, NULL, NULL);
893