1 /* main.c - Application main entry point */
2 
3 /*
4  * Copyright (c) 2016 Intel Corporation
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <zephyr/logging/log.h>
10 LOG_MODULE_REGISTER(net_test, CONFIG_NET_ARP_LOG_LEVEL);
11 
12 #include <zephyr/kernel.h>
13 #include <zephyr/linker/sections.h>
14 
15 #include <zephyr/tc_util.h>
16 
17 #include <zephyr/types.h>
18 #include <stddef.h>
19 #include <string.h>
20 #include <errno.h>
21 #include <zephyr/device.h>
22 #include <zephyr/init.h>
23 #include <zephyr/net/net_core.h>
24 #include <zephyr/net/net_pkt.h>
25 #include <zephyr/net/net_ip.h>
26 #include <zephyr/net/dummy.h>
27 #include <zephyr/ztest.h>
28 #include <zephyr/random/random.h>
29 
30 #include "arp.h"
31 
32 #define NET_LOG_ENABLED 1
33 #include "net_private.h"
34 
35 static bool req_test;
36 
37 static char *app_data = "0123456789";
38 
39 static bool entry_found;
40 static struct net_eth_addr *expected_hwaddr;
41 
42 static struct net_pkt *pending_pkt;
43 
44 static struct net_eth_addr eth_hwaddr = { { 0x42, 0x11, 0x69, 0xde, 0xfa, 0xec } };
45 
46 static int send_status = -EINVAL;
47 
48 struct net_arp_context {
49 	uint8_t mac_addr[sizeof(struct net_eth_addr)];
50 	struct net_linkaddr ll_addr;
51 };
52 
net_arp_dev_init(const struct device * dev)53 int net_arp_dev_init(const struct device *dev)
54 {
55 	struct net_arp_context *net_arp_context = dev->data;
56 
57 	net_arp_context = net_arp_context;
58 
59 	return 0;
60 }
61 
net_arp_get_mac(const struct device * dev)62 static uint8_t *net_arp_get_mac(const struct device *dev)
63 {
64 	struct net_arp_context *context = dev->data;
65 
66 	if (context->mac_addr[2] == 0x00) {
67 		/* 00-00-5E-00-53-xx Documentation RFC 7042 */
68 		context->mac_addr[0] = 0x00;
69 		context->mac_addr[1] = 0x00;
70 		context->mac_addr[2] = 0x5E;
71 		context->mac_addr[3] = 0x00;
72 		context->mac_addr[4] = 0x53;
73 		context->mac_addr[5] = sys_rand8_get();
74 	}
75 
76 	return context->mac_addr;
77 }
78 
net_arp_iface_init(struct net_if * iface)79 static void net_arp_iface_init(struct net_if *iface)
80 {
81 	uint8_t *mac = net_arp_get_mac(net_if_get_device(iface));
82 
83 	net_if_set_link_addr(iface, mac, 6, NET_LINK_ETHERNET);
84 }
85 
tester_send(const struct device * dev,struct net_pkt * pkt)86 static int tester_send(const struct device *dev, struct net_pkt *pkt)
87 {
88 	struct net_eth_hdr *hdr;
89 
90 	if (!pkt->buffer) {
91 		printk("No data to send!\n");
92 		return -ENODATA;
93 	}
94 
95 	hdr = (struct net_eth_hdr *)net_pkt_data(pkt);
96 
97 	if (ntohs(hdr->type) == NET_ETH_PTYPE_ARP) {
98 		/* First frag has eth hdr */
99 		struct net_arp_hdr *arp_hdr =
100 			(struct net_arp_hdr *)pkt->frags->frags;
101 
102 		if (ntohs(arp_hdr->opcode) == NET_ARP_REPLY) {
103 			if (!req_test && pkt != pending_pkt) {
104 				printk("Pending data but to be sent is wrong, "
105 				       "expecting %p but got %p\n",
106 				       pending_pkt, pkt);
107 				return -EINVAL;
108 			}
109 
110 			if (!req_test && memcmp(&hdr->dst, &eth_hwaddr,
111 						sizeof(struct net_eth_addr))) {
112 				char out[sizeof("xx:xx:xx:xx:xx:xx")];
113 
114 				snprintk(out, sizeof(out), "%s",
115 					 net_sprint_ll_addr(
116 						 (uint8_t *)&hdr->dst,
117 						 sizeof(struct net_eth_addr)));
118 				printk("Invalid dst hwaddr %s, should be %s\n",
119 				       out,
120 				       net_sprint_ll_addr(
121 					       (uint8_t *)&eth_hwaddr,
122 					       sizeof(struct net_eth_addr)));
123 				send_status = -EINVAL;
124 				return send_status;
125 			}
126 
127 		} else if (ntohs(arp_hdr->opcode) == NET_ARP_REQUEST) {
128 			if (memcmp(&hdr->src, &eth_hwaddr,
129 				   sizeof(struct net_eth_addr))) {
130 				char out[sizeof("xx:xx:xx:xx:xx:xx")];
131 
132 				snprintk(out, sizeof(out), "%s",
133 					 net_sprint_ll_addr(
134 						 (uint8_t *)&hdr->src,
135 						 sizeof(struct net_eth_addr)));
136 				printk("Invalid src hwaddr %s, should be %s\n",
137 				       out,
138 				       net_sprint_ll_addr(
139 					       (uint8_t *)&eth_hwaddr,
140 					       sizeof(struct net_eth_addr)));
141 				send_status = -EINVAL;
142 				return send_status;
143 			}
144 		}
145 	}
146 
147 	send_status = 0;
148 
149 	return 0;
150 }
151 
if_get_addr(struct net_if * iface)152 static inline struct in_addr *if_get_addr(struct net_if *iface)
153 {
154 	int i;
155 
156 	for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) {
157 		if (iface->config.ip.ipv4->unicast[i].ipv4.is_used &&
158 		    iface->config.ip.ipv4->unicast[i].ipv4.address.family ==
159 								AF_INET &&
160 		    iface->config.ip.ipv4->unicast[i].ipv4.addr_state ==
161 							NET_ADDR_PREFERRED) {
162 			return
163 			    &iface->config.ip.ipv4->unicast[i].ipv4.address.in_addr;
164 		}
165 	}
166 
167 	return NULL;
168 }
169 
prepare_arp_reply(struct net_if * iface,struct net_pkt * req,struct net_eth_addr * addr,struct net_eth_hdr ** eth_rep)170 static inline struct net_pkt *prepare_arp_reply(struct net_if *iface,
171 						struct net_pkt *req,
172 						struct net_eth_addr *addr,
173 						struct net_eth_hdr **eth_rep)
174 {
175 	struct net_pkt *pkt;
176 	struct net_arp_hdr *hdr;
177 	struct net_eth_hdr *eth;
178 
179 	pkt = net_pkt_alloc_with_buffer(iface, sizeof(struct net_eth_hdr) +
180 					sizeof(struct net_eth_hdr) +
181 					sizeof(struct net_arp_hdr),
182 					AF_UNSPEC, 0, K_SECONDS(1));
183 	zassert_not_null(pkt, "out of mem reply");
184 
185 	eth = NET_ETH_HDR(pkt);
186 
187 	net_buf_add(pkt->buffer, sizeof(struct net_eth_hdr));
188 	net_buf_pull(pkt->buffer, sizeof(struct net_eth_hdr));
189 
190 	(void)memset(&eth->dst.addr, 0xff, sizeof(struct net_eth_addr));
191 	memcpy(&eth->src.addr, net_if_get_link_addr(iface)->addr,
192 	       sizeof(struct net_eth_addr));
193 	eth->type = htons(NET_ETH_PTYPE_ARP);
194 
195 	*eth_rep = eth;
196 
197 	net_buf_add(pkt->buffer, sizeof(struct net_eth_hdr));
198 	net_buf_pull(pkt->buffer, sizeof(struct net_eth_hdr));
199 
200 	hdr = NET_ARP_HDR(pkt);
201 
202 	hdr->hwtype = htons(NET_ARP_HTYPE_ETH);
203 	hdr->protocol = htons(NET_ETH_PTYPE_IP);
204 	hdr->hwlen = sizeof(struct net_eth_addr);
205 	hdr->protolen = sizeof(struct in_addr);
206 	hdr->opcode = htons(NET_ARP_REPLY);
207 
208 	memcpy(&hdr->dst_hwaddr.addr, &eth->src.addr,
209 	       sizeof(struct net_eth_addr));
210 	memcpy(&hdr->src_hwaddr.addr, addr,
211 	       sizeof(struct net_eth_addr));
212 
213 	net_ipv4_addr_copy_raw(hdr->dst_ipaddr, NET_ARP_HDR(req)->src_ipaddr);
214 	net_ipv4_addr_copy_raw(hdr->src_ipaddr, NET_ARP_HDR(req)->dst_ipaddr);
215 
216 	net_buf_add(pkt->buffer, sizeof(struct net_arp_hdr));
217 
218 	return pkt;
219 }
220 
prepare_arp_request(struct net_if * iface,struct net_pkt * req,struct net_eth_addr * addr,struct net_eth_hdr ** eth_hdr)221 static inline struct net_pkt *prepare_arp_request(struct net_if *iface,
222 						  struct net_pkt *req,
223 						  struct net_eth_addr *addr,
224 						  struct net_eth_hdr **eth_hdr)
225 {
226 	struct net_pkt *pkt;
227 	struct net_arp_hdr *hdr, *req_hdr;
228 	struct net_eth_hdr *eth, *eth_req;
229 
230 	pkt = net_pkt_alloc_with_buffer(iface, sizeof(struct net_eth_hdr) +
231 					sizeof(struct net_arp_hdr),
232 					AF_UNSPEC, 0, K_SECONDS(1));
233 	zassert_not_null(pkt, "out of mem request");
234 
235 	eth_req = NET_ETH_HDR(req);
236 	eth = NET_ETH_HDR(pkt);
237 
238 	net_buf_add(req->buffer, sizeof(struct net_eth_hdr));
239 	net_buf_pull(req->buffer, sizeof(struct net_eth_hdr));
240 
241 	req_hdr = NET_ARP_HDR(req);
242 
243 	(void)memset(&eth->dst.addr, 0xff, sizeof(struct net_eth_addr));
244 	memcpy(&eth->src.addr, addr, sizeof(struct net_eth_addr));
245 
246 	eth->type = htons(NET_ETH_PTYPE_ARP);
247 	*eth_hdr = eth;
248 
249 	net_buf_add(pkt->buffer, sizeof(struct net_eth_hdr));
250 	net_buf_pull(pkt->buffer, sizeof(struct net_eth_hdr));
251 
252 	hdr = NET_ARP_HDR(pkt);
253 
254 	hdr->hwtype = htons(NET_ARP_HTYPE_ETH);
255 	hdr->protocol = htons(NET_ETH_PTYPE_IP);
256 	hdr->hwlen = sizeof(struct net_eth_addr);
257 	hdr->protolen = sizeof(struct in_addr);
258 	hdr->opcode = htons(NET_ARP_REQUEST);
259 
260 	(void)memset(&hdr->dst_hwaddr.addr, 0x00, sizeof(struct net_eth_addr));
261 	memcpy(&hdr->src_hwaddr.addr, addr, sizeof(struct net_eth_addr));
262 
263 	net_ipv4_addr_copy_raw(hdr->src_ipaddr, req_hdr->src_ipaddr);
264 	net_ipv4_addr_copy_raw(hdr->dst_ipaddr, req_hdr->dst_ipaddr);
265 
266 	net_buf_add(pkt->buffer, sizeof(struct net_arp_hdr));
267 
268 	return pkt;
269 }
270 
setup_eth_header(struct net_if * iface,struct net_pkt * pkt,const struct net_eth_addr * hwaddr,uint16_t type)271 static void setup_eth_header(struct net_if *iface, struct net_pkt *pkt,
272 			     const struct net_eth_addr *hwaddr, uint16_t type)
273 {
274 	struct net_eth_hdr *hdr = (struct net_eth_hdr *)net_pkt_data(pkt);
275 
276 	memcpy(&hdr->dst.addr, hwaddr, sizeof(struct net_eth_addr));
277 	memcpy(&hdr->src.addr, net_if_get_link_addr(iface)->addr,
278 	       sizeof(struct net_eth_addr));
279 
280 	hdr->type = htons(type);
281 }
282 
283 struct net_arp_context net_arp_context_data;
284 
285 #if defined(CONFIG_NET_ARP) && defined(CONFIG_NET_L2_ETHERNET)
286 static const struct ethernet_api net_arp_if_api = {
287 	.iface_api.init = net_arp_iface_init,
288 	.send = tester_send,
289 };
290 
291 #define _ETH_L2_LAYER ETHERNET_L2
292 #define _ETH_L2_CTX_TYPE NET_L2_GET_CTX_TYPE(ETHERNET_L2)
293 #else
294 static const struct dummy_api net_arp_if_api = {
295 	.iface_api.init = net_arp_iface_init,
296 	.send = tester_send,
297 };
298 
299 #define _ETH_L2_LAYER DUMMY_L2
300 #define _ETH_L2_CTX_TYPE NET_L2_GET_CTX_TYPE(DUMMY_L2)
301 #endif
302 
303 NET_DEVICE_INIT(net_arp_test, "net_arp_test",
304 		net_arp_dev_init, NULL,
305 		&net_arp_context_data, NULL,
306 		CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
307 		&net_arp_if_api, _ETH_L2_LAYER, _ETH_L2_CTX_TYPE, 127);
308 
arp_cb(struct arp_entry * entry,void * user_data)309 static void arp_cb(struct arp_entry *entry, void *user_data)
310 {
311 	struct in_addr *addr = user_data;
312 
313 	if (memcmp(&entry->ip, addr, sizeof(struct in_addr)) == 0 &&
314 	    memcmp(&entry->eth, expected_hwaddr,
315 		   sizeof(struct net_eth_addr)) == 0) {
316 		entry_found = true;
317 	}
318 }
319 
ZTEST(arp_fn_tests,test_arp)320 ZTEST(arp_fn_tests, test_arp)
321 {
322 	if (IS_ENABLED(CONFIG_NET_TC_THREAD_COOPERATIVE)) {
323 		k_thread_priority_set(k_current_get(),
324 				K_PRIO_COOP(CONFIG_NUM_COOP_PRIORITIES - 1));
325 	} else {
326 		k_thread_priority_set(k_current_get(), K_PRIO_PREEMPT(9));
327 	}
328 
329 	struct net_eth_hdr *eth_hdr = NULL;
330 	struct net_pkt *pkt;
331 	struct net_pkt *pkt2;
332 	struct net_if *iface;
333 	struct net_if_addr *ifaddr;
334 	struct net_arp_hdr *arp_hdr;
335 	struct net_ipv4_hdr *ipv4;
336 	int len;
337 
338 	struct in_addr dst = { { { 192, 168, 0, 2 } } };
339 	struct in_addr dst_far = { { { 10, 11, 12, 13 } } };
340 	struct in_addr dst_far2 = { { { 172, 16, 14, 186 } } };
341 	struct in_addr src = { { { 192, 168, 0, 1 } } };
342 	struct in_addr netmask = { { { 255, 255, 255, 0 } } };
343 	struct in_addr gw = { { { 192, 168, 0, 42 } } };
344 
345 	net_arp_init();
346 
347 	iface = net_if_lookup_by_dev(DEVICE_GET(net_arp_test));
348 
349 	net_if_ipv4_set_gw(iface, &gw);
350 
351 	/* Unicast test */
352 	ifaddr = net_if_ipv4_addr_add(iface,
353 				      &src,
354 				      NET_ADDR_MANUAL,
355 				      0);
356 	zassert_not_null(ifaddr, "Cannot add address");
357 	ifaddr->addr_state = NET_ADDR_PREFERRED;
358 
359 	net_if_ipv4_set_netmask_by_addr(iface, &src, &netmask);
360 
361 	len = strlen(app_data);
362 
363 	/* Application data for testing */
364 	pkt = net_pkt_alloc_with_buffer(iface, sizeof(struct net_ipv4_hdr) +
365 		len, AF_INET, 0, K_SECONDS(1));
366 	zassert_not_null(pkt, "out of mem");
367 
368 	net_pkt_lladdr_src(pkt)->addr = (uint8_t *)net_if_get_link_addr(iface);
369 	net_pkt_lladdr_src(pkt)->len = sizeof(struct net_eth_addr);
370 
371 	ipv4 = (struct net_ipv4_hdr *)net_buf_add(pkt->buffer,
372 						  sizeof(struct net_ipv4_hdr));
373 	net_ipv4_addr_copy_raw(ipv4->src, (uint8_t *)&src);
374 	net_ipv4_addr_copy_raw(ipv4->dst, (uint8_t *)&dst);
375 
376 	memcpy(net_buf_add(pkt->buffer, len), app_data, len);
377 
378 	pkt2 = net_arp_prepare(pkt, &dst, NULL);
379 
380 	/* pkt2 is the ARP packet and pkt is the IPv4 packet and it was
381 	 * stored in ARP table.
382 	 */
383 
384 	/**TESTPOINTS: Check packets*/
385 	zassert_not_equal((void *)(pkt2), (void *)(pkt),
386 		/* The packets cannot be the same as the ARP cache has
387 		 * still room for the pkt.
388 		 */
389 		"ARP cache should still have free space");
390 
391 	zassert_not_null(pkt2, "ARP pkt is empty");
392 
393 	/* The ARP cache should now have a link to pending net_pkt
394 	 * that is to be sent after we have got an ARP reply.
395 	 */
396 	zassert_not_null(pkt->buffer,
397 		"Pending pkt buffer is NULL");
398 
399 	pending_pkt = pkt;
400 
401 	/* pkt2 should contain the arp header, verify it */
402 	arp_hdr = NET_ARP_HDR(pkt2);
403 
404 	if (arp_hdr->hwtype != htons(NET_ARP_HTYPE_ETH)) {
405 		printk("ARP hwtype 0x%x, should be 0x%x\n",
406 		       arp_hdr->hwtype, htons(NET_ARP_HTYPE_ETH));
407 		zassert_true(0, "exiting");
408 	}
409 
410 	if (arp_hdr->protocol != htons(NET_ETH_PTYPE_IP)) {
411 		printk("ARP protocol 0x%x, should be 0x%x\n",
412 		       arp_hdr->protocol, htons(NET_ETH_PTYPE_IP));
413 		zassert_true(0, "exiting");
414 	}
415 
416 	if (arp_hdr->hwlen != sizeof(struct net_eth_addr)) {
417 		printk("ARP hwlen 0x%x, should be 0x%zx\n",
418 		       arp_hdr->hwlen, sizeof(struct net_eth_addr));
419 		zassert_true(0, "exiting");
420 	}
421 
422 	if (arp_hdr->protolen != sizeof(struct in_addr)) {
423 		printk("ARP IP addr len 0x%x, should be 0x%zx\n",
424 		       arp_hdr->protolen, sizeof(struct in_addr));
425 		zassert_true(0, "exiting");
426 	}
427 
428 	if (arp_hdr->opcode != htons(NET_ARP_REQUEST)) {
429 		printk("ARP opcode 0x%x, should be 0x%x\n",
430 		       arp_hdr->opcode, htons(NET_ARP_REQUEST));
431 		zassert_true(0, "exiting");
432 	}
433 
434 	if (!net_ipv4_addr_cmp_raw(arp_hdr->dst_ipaddr,
435 				   NET_IPV4_HDR(pkt)->dst)) {
436 		printk("ARP IP dest invalid %s, should be %s",
437 			net_sprint_ipv4_addr(&arp_hdr->dst_ipaddr),
438 			net_sprint_ipv4_addr(&NET_IPV4_HDR(pkt)->dst));
439 		zassert_true(0, "exiting");
440 	}
441 
442 	if (!net_ipv4_addr_cmp_raw(arp_hdr->src_ipaddr,
443 				   NET_IPV4_HDR(pkt)->src)) {
444 		printk("ARP IP src invalid %s, should be %s",
445 			net_sprint_ipv4_addr(&arp_hdr->src_ipaddr),
446 			net_sprint_ipv4_addr(&NET_IPV4_HDR(pkt)->src));
447 		zassert_true(0, "exiting");
448 	}
449 
450 	/* We could have send the new ARP request but for this test we
451 	 * just free it.
452 	 */
453 	net_pkt_unref(pkt2);
454 
455 	zassert_equal(atomic_get(&pkt->atomic_ref), 2,
456 		"ARP cache should own the original packet");
457 
458 	/* Then a case where target is not in the same subnet */
459 	net_ipv4_addr_copy_raw(ipv4->dst, (uint8_t *)&dst_far);
460 
461 	pkt2 = net_arp_prepare(pkt, &dst_far, NULL);
462 
463 	zassert_not_equal((void *)(pkt2), (void *)(pkt),
464 		"ARP cache should not find anything");
465 
466 	/**TESTPOINTS: Check if packets not empty*/
467 	zassert_not_null(pkt2,
468 		"ARP pkt2 is empty");
469 
470 	arp_hdr = NET_ARP_HDR(pkt2);
471 
472 	if (!net_ipv4_addr_cmp_raw(arp_hdr->dst_ipaddr,
473 				   (uint8_t *)&iface->config.ip.ipv4->gw)) {
474 		printk("ARP IP dst invalid %s, should be %s\n",
475 			net_sprint_ipv4_addr(&arp_hdr->dst_ipaddr),
476 			net_sprint_ipv4_addr(&iface->config.ip.ipv4->gw));
477 		zassert_true(0, "exiting");
478 	}
479 
480 	net_pkt_unref(pkt2);
481 
482 	/* Try to find the same destination again, this should fail as there
483 	 * is a pending request in ARP cache.
484 	 */
485 	net_ipv4_addr_copy_raw(ipv4->dst, (uint8_t *)&dst_far);
486 
487 	/* Make sure prepare will not free the pkt because it will be
488 	 * needed in the later test case.
489 	 */
490 	net_pkt_ref(pkt);
491 
492 	pkt2 = net_arp_prepare(pkt, &dst_far, NULL);
493 
494 	zassert_not_null(pkt2,
495 		"ARP cache is not sending the request again");
496 
497 	net_pkt_unref(pkt2);
498 
499 	/* Try to find the different destination, this should fail too
500 	 * as the cache table should be full.
501 	 */
502 	net_ipv4_addr_copy_raw(ipv4->dst, (uint8_t *)&dst_far2);
503 
504 	/* Make sure prepare will not free the pkt because it will be
505 	 * needed in the next test case.
506 	 */
507 	net_pkt_ref(pkt);
508 
509 	pkt2 = net_arp_prepare(pkt, &dst_far2, NULL);
510 
511 	zassert_not_null(pkt2,
512 		"ARP cache did not send a req");
513 
514 	/* Restore the original address so that following test case can
515 	 * work properly.
516 	 */
517 	net_ipv4_addr_copy_raw(ipv4->dst, (uint8_t *)&dst);
518 
519 	/* The arp request packet is now verified, create an arp reply.
520 	 * The previous value of pkt is stored in arp table and is not lost.
521 	 */
522 	pkt = net_pkt_alloc_with_buffer(iface, sizeof(struct net_eth_hdr) +
523 					sizeof(struct net_arp_hdr),
524 					AF_UNSPEC, 0, K_SECONDS(1));
525 	zassert_not_null(pkt, "out of mem reply");
526 
527 	arp_hdr = NET_ARP_HDR(pkt);
528 	net_buf_add(pkt->buffer, sizeof(struct net_arp_hdr));
529 
530 	net_ipv4_addr_copy_raw(arp_hdr->dst_ipaddr, (uint8_t *)&dst);
531 	net_ipv4_addr_copy_raw(arp_hdr->src_ipaddr, (uint8_t *)&src);
532 
533 	pkt2 = prepare_arp_reply(iface, pkt, &eth_hwaddr, &eth_hdr);
534 
535 	zassert_not_null(pkt2, "ARP reply generation failed.");
536 
537 	/* The pending packet should now be sent */
538 	switch (net_arp_input(pkt2, eth_hdr)) {
539 	case NET_OK:
540 	case NET_CONTINUE:
541 		break;
542 	case NET_DROP:
543 		break;
544 	}
545 
546 	/* Yielding so that network interface TX thread can proceed. */
547 	k_yield();
548 
549 	/**TESTPOINTS: Check ARP reply*/
550 	zassert_false(send_status < 0, "ARP reply was not sent");
551 
552 	zassert_equal(atomic_get(&pkt->atomic_ref), 1,
553 		      "ARP cache should no longer own the original packet");
554 
555 	net_pkt_unref(pkt);
556 
557 	/* Then feed in ARP request */
558 	pkt = net_pkt_alloc_with_buffer(iface, sizeof(struct net_eth_hdr) +
559 					sizeof(struct net_arp_hdr),
560 					AF_UNSPEC, 0, K_SECONDS(1));
561 	zassert_not_null(pkt, "out of mem reply");
562 
563 	send_status = -EINVAL;
564 
565 	setup_eth_header(iface, pkt, &eth_hwaddr, NET_ETH_PTYPE_ARP);
566 
567 	arp_hdr = (struct net_arp_hdr *)(pkt->buffer->data +
568 					 (sizeof(struct net_eth_hdr)));
569 	net_buf_add(pkt->buffer, sizeof(struct net_arp_hdr));
570 
571 	net_ipv4_addr_copy_raw(arp_hdr->dst_ipaddr, (uint8_t *)&src);
572 	net_ipv4_addr_copy_raw(arp_hdr->src_ipaddr, (uint8_t *)&dst);
573 
574 	pkt2 = prepare_arp_request(iface, pkt, &eth_hwaddr, &eth_hdr);
575 
576 	/**TESTPOINT: Check if ARP request generation failed*/
577 	zassert_not_null(pkt2, "ARP request generation failed.");
578 
579 	req_test = true;
580 
581 	switch (net_arp_input(pkt2, eth_hdr)) {
582 	case NET_OK:
583 	case NET_CONTINUE:
584 		break;
585 	case NET_DROP:
586 		break;
587 	}
588 
589 	/* Yielding so that network interface TX thread can proceed. */
590 	k_yield();
591 
592 	/**TESTPOINT: Check if ARP request sent*/
593 	zassert_false(send_status < 0, "ARP req was not sent");
594 
595 	net_pkt_unref(pkt);
596 
597 	/**TESTPOINT: Check gratuitous ARP */
598 	if (IS_ENABLED(CONFIG_NET_ARP_GRATUITOUS)) {
599 		struct net_eth_addr new_hwaddr = {
600 			{ 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 }
601 		};
602 		enum net_verdict verdict;
603 
604 		/* First make sure that we have an entry in cache */
605 		entry_found = false;
606 		expected_hwaddr = &eth_hwaddr;
607 		net_arp_foreach(arp_cb, &dst);
608 		zassert_true(entry_found, "Entry not found");
609 
610 		pkt = net_pkt_alloc_with_buffer(iface,
611 						sizeof(struct net_eth_hdr) +
612 						sizeof(struct net_arp_hdr),
613 						AF_UNSPEC, 0, K_SECONDS(1));
614 		zassert_not_null(pkt, "out of mem request");
615 
616 		setup_eth_header(iface, pkt, net_eth_broadcast_addr(),
617 				 NET_ETH_PTYPE_ARP);
618 
619 		eth_hdr = (struct net_eth_hdr *)net_pkt_data(pkt);
620 		net_buf_add(pkt->buffer, sizeof(struct net_eth_hdr));
621 		net_buf_pull(pkt->buffer, sizeof(struct net_eth_hdr));
622 		arp_hdr = NET_ARP_HDR(pkt);
623 
624 		arp_hdr->hwtype = htons(NET_ARP_HTYPE_ETH);
625 		arp_hdr->protocol = htons(NET_ETH_PTYPE_IP);
626 		arp_hdr->hwlen = sizeof(struct net_eth_addr);
627 		arp_hdr->protolen = sizeof(struct in_addr);
628 		arp_hdr->opcode = htons(NET_ARP_REQUEST);
629 		memcpy(&arp_hdr->src_hwaddr, &new_hwaddr, 6);
630 		memcpy(&arp_hdr->dst_hwaddr, net_eth_broadcast_addr(), 6);
631 		net_ipv4_addr_copy_raw(arp_hdr->dst_ipaddr, (uint8_t *)&dst);
632 		net_ipv4_addr_copy_raw(arp_hdr->src_ipaddr, (uint8_t *)&dst);
633 
634 		net_buf_add(pkt->buffer, sizeof(struct net_arp_hdr));
635 
636 		verdict = net_arp_input(pkt, eth_hdr);
637 		zassert_not_equal(verdict, NET_DROP, "Gratuitous ARP failed");
638 
639 		/* Then check that the HW address is changed for an existing
640 		 * entry.
641 		 */
642 		entry_found = false;
643 		expected_hwaddr = &new_hwaddr;
644 		net_arp_foreach(arp_cb, &dst);
645 		zassert_true(entry_found, "Changed entry not found");
646 
647 		net_pkt_unref(pkt);
648 	}
649 }
650 
651 ZTEST_SUITE(arp_fn_tests, NULL, NULL, NULL, NULL, NULL);
652