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, ð_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 *)ð_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, ð_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 *)ð_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
prepare_arp_reply(struct net_if * iface,struct net_pkt * req,struct net_eth_addr * addr,struct net_eth_hdr ** eth_rep)152 static inline struct net_pkt *prepare_arp_reply(struct net_if *iface,
153 struct net_pkt *req,
154 struct net_eth_addr *addr,
155 struct net_eth_hdr **eth_rep)
156 {
157 struct net_pkt *pkt;
158 struct net_arp_hdr *hdr;
159 struct net_eth_hdr *eth;
160
161 pkt = net_pkt_alloc_with_buffer(iface, sizeof(struct net_eth_hdr) +
162 sizeof(struct net_eth_hdr) +
163 sizeof(struct net_arp_hdr),
164 AF_UNSPEC, 0, K_SECONDS(1));
165 zassert_not_null(pkt, "out of mem reply");
166
167 eth = NET_ETH_HDR(pkt);
168
169 net_buf_add(pkt->buffer, sizeof(struct net_eth_hdr));
170 net_buf_pull(pkt->buffer, sizeof(struct net_eth_hdr));
171
172 (void)memset(ð->dst.addr, 0xff, sizeof(struct net_eth_addr));
173 memcpy(ð->src.addr, net_if_get_link_addr(iface)->addr,
174 sizeof(struct net_eth_addr));
175 eth->type = htons(NET_ETH_PTYPE_ARP);
176
177 *eth_rep = eth;
178
179 net_buf_add(pkt->buffer, sizeof(struct net_eth_hdr));
180 net_buf_pull(pkt->buffer, sizeof(struct net_eth_hdr));
181
182 hdr = NET_ARP_HDR(pkt);
183
184 hdr->hwtype = htons(NET_ARP_HTYPE_ETH);
185 hdr->protocol = htons(NET_ETH_PTYPE_IP);
186 hdr->hwlen = sizeof(struct net_eth_addr);
187 hdr->protolen = sizeof(struct in_addr);
188 hdr->opcode = htons(NET_ARP_REPLY);
189
190 memcpy(&hdr->dst_hwaddr.addr, ð->src.addr,
191 sizeof(struct net_eth_addr));
192 memcpy(&hdr->src_hwaddr.addr, addr,
193 sizeof(struct net_eth_addr));
194
195 net_ipv4_addr_copy_raw(hdr->dst_ipaddr, NET_ARP_HDR(req)->src_ipaddr);
196 net_ipv4_addr_copy_raw(hdr->src_ipaddr, NET_ARP_HDR(req)->dst_ipaddr);
197
198 net_buf_add(pkt->buffer, sizeof(struct net_arp_hdr));
199
200 net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_ARP);
201
202 return pkt;
203 }
204
prepare_arp_request(struct net_if * iface,struct net_pkt * req,struct net_eth_addr * addr,struct net_eth_hdr ** eth_hdr)205 static inline struct net_pkt *prepare_arp_request(struct net_if *iface,
206 struct net_pkt *req,
207 struct net_eth_addr *addr,
208 struct net_eth_hdr **eth_hdr)
209 {
210 struct net_pkt *pkt;
211 struct net_arp_hdr *hdr, *req_hdr;
212 struct net_eth_hdr *eth, *eth_req;
213
214 pkt = net_pkt_alloc_with_buffer(iface, sizeof(struct net_eth_hdr) +
215 sizeof(struct net_arp_hdr),
216 AF_UNSPEC, 0, K_SECONDS(1));
217 zassert_not_null(pkt, "out of mem request");
218
219 eth_req = NET_ETH_HDR(req);
220 eth = NET_ETH_HDR(pkt);
221
222 net_buf_add(req->buffer, sizeof(struct net_eth_hdr));
223 net_buf_pull(req->buffer, sizeof(struct net_eth_hdr));
224
225 req_hdr = NET_ARP_HDR(req);
226
227 (void)memset(ð->dst.addr, 0xff, sizeof(struct net_eth_addr));
228 memcpy(ð->src.addr, addr, sizeof(struct net_eth_addr));
229
230 eth->type = htons(NET_ETH_PTYPE_ARP);
231 *eth_hdr = eth;
232
233 net_buf_add(pkt->buffer, sizeof(struct net_eth_hdr));
234 net_buf_pull(pkt->buffer, sizeof(struct net_eth_hdr));
235
236 hdr = NET_ARP_HDR(pkt);
237
238 hdr->hwtype = htons(NET_ARP_HTYPE_ETH);
239 hdr->protocol = htons(NET_ETH_PTYPE_IP);
240 hdr->hwlen = sizeof(struct net_eth_addr);
241 hdr->protolen = sizeof(struct in_addr);
242 hdr->opcode = htons(NET_ARP_REQUEST);
243
244 (void)memset(&hdr->dst_hwaddr.addr, 0x00, sizeof(struct net_eth_addr));
245 memcpy(&hdr->src_hwaddr.addr, addr, sizeof(struct net_eth_addr));
246
247 net_ipv4_addr_copy_raw(hdr->src_ipaddr, req_hdr->src_ipaddr);
248 net_ipv4_addr_copy_raw(hdr->dst_ipaddr, req_hdr->dst_ipaddr);
249
250 net_buf_add(pkt->buffer, sizeof(struct net_arp_hdr));
251
252 net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_ARP);
253
254 return pkt;
255 }
256
setup_eth_header(struct net_if * iface,struct net_pkt * pkt,const struct net_eth_addr * hwaddr,uint16_t type)257 static void setup_eth_header(struct net_if *iface, struct net_pkt *pkt,
258 const struct net_eth_addr *hwaddr, uint16_t type)
259 {
260 struct net_eth_hdr *hdr = (struct net_eth_hdr *)net_pkt_data(pkt);
261
262 memcpy(&hdr->dst.addr, hwaddr, sizeof(struct net_eth_addr));
263 memcpy(&hdr->src.addr, net_if_get_link_addr(iface)->addr,
264 sizeof(struct net_eth_addr));
265
266 hdr->type = htons(type);
267 }
268
269 struct net_arp_context net_arp_context_data;
270
271 #if defined(CONFIG_NET_ARP) && defined(CONFIG_NET_L2_ETHERNET)
272 static const struct ethernet_api net_arp_if_api = {
273 .iface_api.init = net_arp_iface_init,
274 .send = tester_send,
275 };
276
277 #define _ETH_L2_LAYER ETHERNET_L2
278 #define _ETH_L2_CTX_TYPE NET_L2_GET_CTX_TYPE(ETHERNET_L2)
279 #else
280 static const struct dummy_api net_arp_if_api = {
281 .iface_api.init = net_arp_iface_init,
282 .send = tester_send,
283 };
284
285 #define _ETH_L2_LAYER DUMMY_L2
286 #define _ETH_L2_CTX_TYPE NET_L2_GET_CTX_TYPE(DUMMY_L2)
287 #endif
288
289 NET_DEVICE_INIT(net_arp_test, "net_arp_test",
290 net_arp_dev_init, NULL,
291 &net_arp_context_data, NULL,
292 CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
293 &net_arp_if_api, _ETH_L2_LAYER, _ETH_L2_CTX_TYPE, 127);
294
arp_cb(struct arp_entry * entry,void * user_data)295 static void arp_cb(struct arp_entry *entry, void *user_data)
296 {
297 struct in_addr *addr = user_data;
298
299 if (memcmp(&entry->ip, addr, sizeof(struct in_addr)) == 0 &&
300 memcmp(&entry->eth, expected_hwaddr,
301 sizeof(struct net_eth_addr)) == 0) {
302 entry_found = true;
303 }
304 }
305
ZTEST(arp_fn_tests,test_arp)306 ZTEST(arp_fn_tests, test_arp)
307 {
308 if (IS_ENABLED(CONFIG_NET_TC_THREAD_COOPERATIVE)) {
309 k_thread_priority_set(k_current_get(),
310 K_PRIO_COOP(CONFIG_NUM_COOP_PRIORITIES - 1));
311 } else {
312 k_thread_priority_set(k_current_get(), K_PRIO_PREEMPT(9));
313 }
314
315 struct net_eth_hdr *eth_hdr = NULL;
316 struct net_eth_addr dst_lladdr;
317 struct net_pkt *pkt;
318 struct net_pkt *pkt2;
319 struct net_if *iface;
320 struct net_if_addr *ifaddr;
321 struct net_arp_hdr *arp_hdr;
322 struct net_ipv4_hdr *ipv4;
323 int len;
324
325 struct in_addr dst = { { { 192, 0, 2, 2 } } };
326 struct in_addr dst_far = { { { 10, 11, 12, 13 } } };
327 struct in_addr dst_far2 = { { { 172, 16, 14, 186 } } };
328 struct in_addr src = { { { 192, 0, 2, 1 } } };
329 struct in_addr netmask = { { { 255, 255, 255, 0 } } };
330 struct in_addr gw = { { { 192, 0, 2, 42 } } };
331
332 net_arp_init();
333
334 (void)memset(&dst_lladdr, 0xff, sizeof(struct net_eth_addr));
335
336 iface = net_if_lookup_by_dev(DEVICE_GET(net_arp_test));
337
338 net_if_ipv4_set_gw(iface, &gw);
339
340 /* Unicast test */
341 ifaddr = net_if_ipv4_addr_add(iface,
342 &src,
343 NET_ADDR_MANUAL,
344 0);
345 zassert_not_null(ifaddr, "Cannot add address");
346 ifaddr->addr_state = NET_ADDR_PREFERRED;
347
348 net_if_ipv4_set_netmask_by_addr(iface, &src, &netmask);
349
350 len = strlen(app_data);
351
352 /* Application data for testing */
353 pkt = net_pkt_alloc_with_buffer(iface, sizeof(struct net_ipv4_hdr) +
354 len, AF_INET, 0, K_SECONDS(1));
355 zassert_not_null(pkt, "out of mem");
356
357 (void)net_linkaddr_set(net_pkt_lladdr_src(pkt),
358 net_if_get_link_addr(iface)->addr,
359 sizeof(struct net_eth_addr));
360
361 ipv4 = (struct net_ipv4_hdr *)net_buf_add(pkt->buffer,
362 sizeof(struct net_ipv4_hdr));
363 net_ipv4_addr_copy_raw(ipv4->src, (uint8_t *)&src);
364 net_ipv4_addr_copy_raw(ipv4->dst, (uint8_t *)&dst);
365
366 net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_IP);
367
368 memcpy(net_buf_add(pkt->buffer, len), app_data, len);
369
370 pkt2 = net_arp_prepare(pkt, &dst, NULL);
371
372 /* pkt2 is the ARP packet and pkt is the IPv4 packet and it was
373 * stored in ARP table.
374 */
375
376 zassert_equal(net_pkt_ll_proto_type(pkt2), NET_ETH_PTYPE_ARP,
377 "ARP packet type is wrong");
378
379 /**TESTPOINTS: Check packets*/
380 zassert_not_equal((void *)(pkt2), (void *)(pkt),
381 /* The packets cannot be the same as the ARP cache has
382 * still room for the pkt.
383 */
384 "ARP cache should still have free space");
385
386 zassert_not_null(pkt2, "ARP pkt is empty");
387
388 /* The ARP cache should now have a link to pending net_pkt
389 * that is to be sent after we have got an ARP reply.
390 */
391 zassert_not_null(pkt->buffer,
392 "Pending pkt buffer is NULL");
393
394 pending_pkt = pkt;
395
396 /* pkt2 should contain the arp header, verify it */
397 arp_hdr = NET_ARP_HDR(pkt2);
398
399 if (arp_hdr->hwtype != htons(NET_ARP_HTYPE_ETH)) {
400 printk("ARP hwtype 0x%x, should be 0x%x\n",
401 arp_hdr->hwtype, htons(NET_ARP_HTYPE_ETH));
402 zassert_true(0, "exiting");
403 }
404
405 if (arp_hdr->protocol != htons(NET_ETH_PTYPE_IP)) {
406 printk("ARP protocol 0x%x, should be 0x%x\n",
407 arp_hdr->protocol, htons(NET_ETH_PTYPE_IP));
408 zassert_true(0, "exiting");
409 }
410
411 if (arp_hdr->hwlen != sizeof(struct net_eth_addr)) {
412 printk("ARP hwlen 0x%x, should be 0x%zx\n",
413 arp_hdr->hwlen, sizeof(struct net_eth_addr));
414 zassert_true(0, "exiting");
415 }
416
417 if (arp_hdr->protolen != sizeof(struct in_addr)) {
418 printk("ARP IP addr len 0x%x, should be 0x%zx\n",
419 arp_hdr->protolen, sizeof(struct in_addr));
420 zassert_true(0, "exiting");
421 }
422
423 if (arp_hdr->opcode != htons(NET_ARP_REQUEST)) {
424 printk("ARP opcode 0x%x, should be 0x%x\n",
425 arp_hdr->opcode, htons(NET_ARP_REQUEST));
426 zassert_true(0, "exiting");
427 }
428
429 if (!net_ipv4_addr_cmp_raw(arp_hdr->dst_ipaddr,
430 NET_IPV4_HDR(pkt)->dst)) {
431 printk("ARP IP dest invalid %s, should be %s",
432 net_sprint_ipv4_addr(&arp_hdr->dst_ipaddr),
433 net_sprint_ipv4_addr(&NET_IPV4_HDR(pkt)->dst));
434 zassert_true(0, "exiting");
435 }
436
437 if (!net_ipv4_addr_cmp_raw(arp_hdr->src_ipaddr,
438 NET_IPV4_HDR(pkt)->src)) {
439 printk("ARP IP src invalid %s, should be %s",
440 net_sprint_ipv4_addr(&arp_hdr->src_ipaddr),
441 net_sprint_ipv4_addr(&NET_IPV4_HDR(pkt)->src));
442 zassert_true(0, "exiting");
443 }
444
445 /* We could have send the new ARP request but for this test we
446 * just free it.
447 */
448 net_pkt_unref(pkt2);
449
450 zassert_equal(atomic_get(&pkt->atomic_ref), 2,
451 "ARP cache should own the original packet");
452
453 /* Then a case where target is not in the same subnet */
454 net_ipv4_addr_copy_raw(ipv4->dst, (uint8_t *)&dst_far);
455
456 pkt2 = net_arp_prepare(pkt, &dst_far, NULL);
457
458 zassert_not_equal((void *)(pkt2), (void *)(pkt),
459 "ARP cache should not find anything");
460
461 /**TESTPOINTS: Check if packets not empty*/
462 zassert_not_null(pkt2,
463 "ARP pkt2 is empty");
464
465 arp_hdr = NET_ARP_HDR(pkt2);
466
467 if (!net_ipv4_addr_cmp_raw(arp_hdr->dst_ipaddr,
468 (uint8_t *)&iface->config.ip.ipv4->gw)) {
469 printk("ARP IP dst invalid %s, should be %s\n",
470 net_sprint_ipv4_addr(&arp_hdr->dst_ipaddr),
471 net_sprint_ipv4_addr(&iface->config.ip.ipv4->gw));
472 zassert_true(0, "exiting");
473 }
474
475 net_pkt_unref(pkt2);
476
477 /* Try to find the same destination again, this should fail as there
478 * is a pending request in ARP cache.
479 */
480 net_ipv4_addr_copy_raw(ipv4->dst, (uint8_t *)&dst_far);
481
482 /* Make sure prepare will not free the pkt because it will be
483 * needed in the later test case.
484 */
485 net_pkt_ref(pkt);
486
487 pkt2 = net_arp_prepare(pkt, &dst_far, NULL);
488
489 zassert_not_null(pkt2,
490 "ARP cache is not sending the request again");
491
492 net_pkt_unref(pkt2);
493
494 /* Try to find the different destination, this should fail too
495 * as the cache table should be full.
496 */
497 net_ipv4_addr_copy_raw(ipv4->dst, (uint8_t *)&dst_far2);
498
499 /* Make sure prepare will not free the pkt because it will be
500 * needed in the next test case.
501 */
502 net_pkt_ref(pkt);
503
504 pkt2 = net_arp_prepare(pkt, &dst_far2, NULL);
505
506 zassert_not_null(pkt2,
507 "ARP cache did not send a req");
508
509 /* Restore the original address so that following test case can
510 * work properly.
511 */
512 net_ipv4_addr_copy_raw(ipv4->dst, (uint8_t *)&dst);
513
514 /* The arp request packet is now verified, create an arp reply.
515 * The previous value of pkt is stored in arp table and is not lost.
516 */
517 pkt = net_pkt_alloc_with_buffer(iface, sizeof(struct net_eth_hdr) +
518 sizeof(struct net_arp_hdr),
519 AF_UNSPEC, 0, K_SECONDS(1));
520 zassert_not_null(pkt, "out of mem reply");
521
522 arp_hdr = NET_ARP_HDR(pkt);
523 net_buf_add(pkt->buffer, sizeof(struct net_arp_hdr));
524
525 net_ipv4_addr_copy_raw(arp_hdr->dst_ipaddr, (uint8_t *)&dst);
526 net_ipv4_addr_copy_raw(arp_hdr->src_ipaddr, (uint8_t *)&src);
527
528 net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_ARP);
529
530 pkt2 = prepare_arp_reply(iface, pkt, ð_hwaddr, ð_hdr);
531
532 zassert_not_null(pkt2, "ARP reply generation failed.");
533
534 /* The pending packet should now be sent */
535 switch (net_arp_input(pkt2,
536 (struct net_eth_addr *)net_pkt_lladdr_src(pkt2)->addr,
537 &dst_lladdr)) {
538 case NET_OK:
539 case NET_CONTINUE:
540 break;
541 case NET_DROP:
542 break;
543 }
544
545 /* Yielding so that network interface TX thread can proceed. */
546 k_yield();
547
548 /**TESTPOINTS: Check ARP reply*/
549 zassert_false(send_status < 0, "ARP reply was not sent");
550
551 zassert_equal(atomic_get(&pkt->atomic_ref), 1,
552 "ARP cache should no longer own the original packet");
553
554 net_pkt_unref(pkt);
555
556 /* Then feed in ARP request */
557 pkt = net_pkt_alloc_with_buffer(iface, sizeof(struct net_eth_hdr) +
558 sizeof(struct net_arp_hdr),
559 AF_UNSPEC, 0, K_SECONDS(1));
560 zassert_not_null(pkt, "out of mem reply");
561
562 send_status = -EINVAL;
563
564 setup_eth_header(iface, pkt, ð_hwaddr, NET_ETH_PTYPE_ARP);
565
566 arp_hdr = (struct net_arp_hdr *)(pkt->buffer->data +
567 (sizeof(struct net_eth_hdr)));
568 net_buf_add(pkt->buffer, sizeof(struct net_arp_hdr));
569
570 net_ipv4_addr_copy_raw(arp_hdr->dst_ipaddr, (uint8_t *)&src);
571 net_ipv4_addr_copy_raw(arp_hdr->src_ipaddr, (uint8_t *)&dst);
572
573 net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_ARP);
574
575 pkt2 = prepare_arp_request(iface, pkt, ð_hwaddr, ð_hdr);
576
577 /**TESTPOINT: Check if ARP request generation failed*/
578 zassert_not_null(pkt2, "ARP request generation failed.");
579
580 req_test = true;
581
582 switch (net_arp_input(pkt2,
583 (struct net_eth_addr *)net_pkt_lladdr_src(pkt2)->addr,
584 &dst_lladdr)) {
585 case NET_OK:
586 case NET_CONTINUE:
587 break;
588 case NET_DROP:
589 break;
590 }
591
592 /* Yielding so that network interface TX thread can proceed. */
593 k_yield();
594
595 /**TESTPOINT: Check if ARP request sent*/
596 zassert_false(send_status < 0, "ARP req was not sent");
597
598 net_pkt_unref(pkt);
599
600 /**TESTPOINT: Check gratuitous ARP */
601 if (IS_ENABLED(CONFIG_NET_ARP_GRATUITOUS)) {
602 struct net_eth_addr new_hwaddr = {
603 { 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 }
604 };
605 enum net_verdict verdict;
606
607 /* First make sure that we have an entry in cache */
608 entry_found = false;
609 expected_hwaddr = ð_hwaddr;
610 net_arp_foreach(arp_cb, &dst);
611 zassert_true(entry_found, "Entry not found");
612
613 pkt = net_pkt_alloc_with_buffer(iface,
614 sizeof(struct net_eth_hdr) +
615 sizeof(struct net_arp_hdr),
616 AF_UNSPEC, 0, K_SECONDS(1));
617 zassert_not_null(pkt, "out of mem request");
618
619 setup_eth_header(iface, pkt, net_eth_broadcast_addr(),
620 NET_ETH_PTYPE_ARP);
621
622 eth_hdr = (struct net_eth_hdr *)net_pkt_data(pkt);
623 net_buf_add(pkt->buffer, sizeof(struct net_eth_hdr));
624 net_buf_pull(pkt->buffer, sizeof(struct net_eth_hdr));
625 arp_hdr = NET_ARP_HDR(pkt);
626
627 arp_hdr->hwtype = htons(NET_ARP_HTYPE_ETH);
628 arp_hdr->protocol = htons(NET_ETH_PTYPE_IP);
629 arp_hdr->hwlen = sizeof(struct net_eth_addr);
630 arp_hdr->protolen = sizeof(struct in_addr);
631 arp_hdr->opcode = htons(NET_ARP_REQUEST);
632 memcpy(&arp_hdr->src_hwaddr, &new_hwaddr, 6);
633 memcpy(&arp_hdr->dst_hwaddr, net_eth_broadcast_addr(), 6);
634 net_ipv4_addr_copy_raw(arp_hdr->dst_ipaddr, (uint8_t *)&dst);
635 net_ipv4_addr_copy_raw(arp_hdr->src_ipaddr, (uint8_t *)&dst);
636
637 net_buf_add(pkt->buffer, sizeof(struct net_arp_hdr));
638
639 net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_ARP);
640
641 verdict = net_arp_input(pkt,
642 (struct net_eth_addr *)net_pkt_lladdr_src(pkt)->addr,
643 &dst_lladdr);
644
645 zassert_not_equal(verdict, NET_DROP, "Gratuitous ARP failed");
646
647 /* Then check that the HW address is changed for an existing
648 * entry.
649 */
650 entry_found = false;
651 expected_hwaddr = &new_hwaddr;
652 net_arp_foreach(arp_cb, &dst);
653 zassert_true(entry_found, "Changed entry not found");
654
655 net_pkt_unref(pkt);
656 }
657 }
658
659 ZTEST_SUITE(arp_fn_tests, NULL, NULL, NULL, NULL, NULL);
660