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