1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2015 National Instruments
4 *
5 * (C) Copyright 2015
6 * Joe Hershberger <joe.hershberger@ni.com>
7 */
8
9 #include <common.h>
10 #include <dm.h>
11 #include <env.h>
12 #include <fdtdec.h>
13 #include <log.h>
14 #include <malloc.h>
15 #include <net.h>
16 #include <net6.h>
17 #include <asm/eth.h>
18 #include <dm/test.h>
19 #include <dm/device-internal.h>
20 #include <dm/uclass-internal.h>
21 #include <test/test.h>
22 #include <test/ut.h>
23 #include <ndisc.h>
24
25 #define DM_TEST_ETH_NUM 4
26
27 #if IS_ENABLED(CONFIG_IPV6)
dm_test_string_to_ip6(struct unit_test_state * uts)28 static int dm_test_string_to_ip6(struct unit_test_state *uts)
29 {
30 char *str;
31 struct test_ip6_pair {
32 char *string_addr;
33 struct in6_addr ip6_addr;
34 };
35
36 struct in6_addr ip6 = {0};
37
38 /* Correct statements */
39 struct test_ip6_pair test_suite[] = {
40 {"2001:db8::0:1234:1", {.s6_addr32[0] = 0xb80d0120,
41 .s6_addr32[1] = 0x00000000,
42 .s6_addr32[2] = 0x00000000,
43 .s6_addr32[3] = 0x01003412}},
44 {"2001:0db8:0000:0000:0000:0000:1234:0001",
45 {.s6_addr32[0] = 0xb80d0120,
46 .s6_addr32[1] = 0x00000000,
47 .s6_addr32[2] = 0x00000000,
48 .s6_addr32[3] = 0x01003412}},
49 {"::1", {.s6_addr32[0] = 0x00000000,
50 .s6_addr32[1] = 0x00000000,
51 .s6_addr32[2] = 0x00000000,
52 .s6_addr32[3] = 0x01000000}},
53 {"::ffff:192.168.1.1", {.s6_addr32[0] = 0x00000000,
54 .s6_addr32[1] = 0x00000000,
55 .s6_addr32[2] = 0xffff0000,
56 .s6_addr32[3] = 0x0101a8c0}},
57 };
58
59 for (int i = 0; i < ARRAY_SIZE(test_suite); ++i) {
60 ut_assertok(string_to_ip6(test_suite[i].string_addr,
61 strlen(test_suite[i].string_addr), &ip6));
62 ut_asserteq_mem(&ip6, &test_suite[i].ip6_addr,
63 sizeof(struct in6_addr));
64 }
65
66 /* Incorrect statements */
67 str = "hello:world";
68 ut_assertok(!string_to_ip6(str, strlen(str), &ip6));
69 str = "2001:db8::0::0";
70 ut_assertok(!string_to_ip6(str, strlen(str), &ip6));
71 str = "2001:db8:192.168.1.1::1";
72 ut_assertok(!string_to_ip6(str, strlen(str), &ip6));
73 str = "192.168.1.1";
74 ut_assertok(!string_to_ip6(str, strlen(str), &ip6));
75
76 return 0;
77 }
78 DM_TEST(dm_test_string_to_ip6, 0);
79
dm_test_csum_ipv6_magic(struct unit_test_state * uts)80 static int dm_test_csum_ipv6_magic(struct unit_test_state *uts)
81 {
82 unsigned short csum = 0xbeef;
83 /* Predefined correct parameters */
84 unsigned short correct_csum = 0xd8ac;
85 struct in6_addr saddr = {.s6_addr32[0] = 0x000080fe,
86 .s6_addr32[1] = 0x00000000,
87 .s6_addr32[2] = 0xffe9f242,
88 .s6_addr32[3] = 0xe8f66dfe};
89 struct in6_addr daddr = {.s6_addr32[0] = 0x000080fe,
90 .s6_addr32[1] = 0x00000000,
91 .s6_addr32[2] = 0xffd5b372,
92 .s6_addr32[3] = 0x3ef692fe};
93 u16 len = 1460;
94 unsigned short proto = 17;
95 unsigned int head_csum = 0x91f0;
96
97 csum = csum_ipv6_magic(&saddr, &daddr, len, proto, head_csum);
98 ut_asserteq(csum, correct_csum);
99
100 /* Broke a parameter */
101 proto--;
102 csum = csum_ipv6_magic(&saddr, &daddr, len, proto, head_csum);
103 ut_assert(csum != correct_csum);
104
105 return 0;
106 }
107 DM_TEST(dm_test_csum_ipv6_magic, 0);
108
dm_test_ip6_addr_in_subnet(struct unit_test_state * uts)109 static int dm_test_ip6_addr_in_subnet(struct unit_test_state *uts)
110 {
111 struct in6_addr our = {.s6_addr32[0] = 0x000080fe,
112 .s6_addr32[1] = 0x00000000,
113 .s6_addr32[2] = 0xffe9f242,
114 .s6_addr32[3] = 0xe8f66dfe};
115 struct in6_addr neigh1 = {.s6_addr32[0] = 0x000080fe,
116 .s6_addr32[1] = 0x00000000,
117 .s6_addr32[2] = 0xffd5b372,
118 .s6_addr32[3] = 0x3ef692fe};
119 struct in6_addr neigh2 = {.s6_addr32[0] = 0x60480120,
120 .s6_addr32[1] = 0x00006048,
121 .s6_addr32[2] = 0x00000000,
122 .s6_addr32[3] = 0x00008888};
123
124 /* in */
125 ut_assert(ip6_addr_in_subnet(&our, &neigh1, 64));
126 /* outside */
127 ut_assert(!ip6_addr_in_subnet(&our, &neigh2, 64));
128 ut_assert(!ip6_addr_in_subnet(&our, &neigh1, 128));
129
130 return 0;
131 }
132 DM_TEST(dm_test_ip6_addr_in_subnet, 0);
133
dm_test_ip6_make_snma(struct unit_test_state * uts)134 static int dm_test_ip6_make_snma(struct unit_test_state *uts)
135 {
136 struct in6_addr mult = {0};
137 struct in6_addr correct_addr = {
138 .s6_addr32[0] = 0x000002ff,
139 .s6_addr32[1] = 0x00000000,
140 .s6_addr32[2] = 0x01000000,
141 .s6_addr32[3] = 0xe8f66dff};
142 struct in6_addr addr = { .s6_addr32[0] = 0x000080fe,
143 .s6_addr32[1] = 0x00000000,
144 .s6_addr32[2] = 0xffe9f242,
145 .s6_addr32[3] = 0xe8f66dfe};
146
147 ip6_make_snma(&mult, &addr);
148 ut_asserteq_mem(&mult, &correct_addr, sizeof(struct in6_addr));
149
150 return 0;
151 }
152 DM_TEST(dm_test_ip6_make_snma, 0);
153
dm_test_ip6_make_lladdr(struct unit_test_state * uts)154 static int dm_test_ip6_make_lladdr(struct unit_test_state *uts)
155 {
156 struct in6_addr generated_lladdr = {0};
157 struct in6_addr correct_lladdr = {
158 .s6_addr32[0] = 0x000080fe,
159 .s6_addr32[1] = 0x00000000,
160 .s6_addr32[2] = 0xffabf33a,
161 .s6_addr32[3] = 0xfbb352fe};
162 const unsigned char mac[6] = {0x38, 0xf3, 0xab, 0x52, 0xb3, 0xfb};
163
164 ip6_make_lladdr(&generated_lladdr, mac);
165 ut_asserteq_mem(&generated_lladdr, &correct_lladdr,
166 sizeof(struct in6_addr));
167
168 return 0;
169 }
170 DM_TEST(dm_test_ip6_make_lladdr, UT_TESTF_SCAN_FDT);
171 #endif
172
dm_test_eth(struct unit_test_state * uts)173 static int dm_test_eth(struct unit_test_state *uts)
174 {
175 net_ping_ip = string_to_ip("1.1.2.2");
176
177 env_set("ethact", "eth@10002000");
178 ut_assertok(net_loop(PING));
179 ut_asserteq_str("eth@10002000", env_get("ethact"));
180
181 env_set("ethact", "eth@10003000");
182 ut_assertok(net_loop(PING));
183 ut_asserteq_str("eth@10003000", env_get("ethact"));
184
185 env_set("ethact", "eth@10004000");
186 ut_assertok(net_loop(PING));
187 ut_asserteq_str("eth@10004000", env_get("ethact"));
188
189 return 0;
190 }
191 DM_TEST(dm_test_eth, UT_TESTF_SCAN_FDT);
192
dm_test_eth_alias(struct unit_test_state * uts)193 static int dm_test_eth_alias(struct unit_test_state *uts)
194 {
195 net_ping_ip = string_to_ip("1.1.2.2");
196 env_set("ethact", "eth0");
197 ut_assertok(net_loop(PING));
198 ut_asserteq_str("eth@10002000", env_get("ethact"));
199
200 env_set("ethact", "eth6");
201 ut_assertok(net_loop(PING));
202 ut_asserteq_str("eth@10004000", env_get("ethact"));
203
204 /* Expected to fail since eth1 is not defined in the device tree */
205 env_set("ethact", "eth1");
206 ut_assertok(net_loop(PING));
207 ut_asserteq_str("eth@10002000", env_get("ethact"));
208
209 env_set("ethact", "eth5");
210 ut_assertok(net_loop(PING));
211 ut_asserteq_str("eth@10003000", env_get("ethact"));
212
213 return 0;
214 }
215 DM_TEST(dm_test_eth_alias, UT_TESTF_SCAN_FDT);
216
dm_test_eth_prime(struct unit_test_state * uts)217 static int dm_test_eth_prime(struct unit_test_state *uts)
218 {
219 net_ping_ip = string_to_ip("1.1.2.2");
220
221 /* Expected to be "eth@10003000" because of ethprime variable */
222 env_set("ethact", NULL);
223 env_set("ethprime", "eth5");
224 ut_assertok(net_loop(PING));
225 ut_asserteq_str("eth@10003000", env_get("ethact"));
226
227 /* Expected to be "eth@10002000" because it is first */
228 env_set("ethact", NULL);
229 env_set("ethprime", NULL);
230 ut_assertok(net_loop(PING));
231 ut_asserteq_str("eth@10002000", env_get("ethact"));
232
233 return 0;
234 }
235 DM_TEST(dm_test_eth_prime, UT_TESTF_SCAN_FDT);
236
237 /**
238 * This test case is trying to test the following scenario:
239 * - All ethernet devices are not probed
240 * - "ethaddr" for all ethernet devices are not set
241 * - "ethact" is set to a valid ethernet device name
242 *
243 * With Sandbox default test configuration, all ethernet devices are
244 * probed after power-up, so we have to manually create such scenario:
245 * - Remove all ethernet devices
246 * - Remove all "ethaddr" environment variables
247 * - Set "ethact" to the first ethernet device
248 *
249 * Do a ping test to see if anything goes wrong.
250 */
dm_test_eth_act(struct unit_test_state * uts)251 static int dm_test_eth_act(struct unit_test_state *uts)
252 {
253 struct udevice *dev[DM_TEST_ETH_NUM];
254 const char *ethname[DM_TEST_ETH_NUM] = {"eth@10002000", "eth@10003000",
255 "sbe5", "eth@10004000"};
256 const char *addrname[DM_TEST_ETH_NUM] = {"ethaddr", "eth5addr",
257 "eth3addr", "eth6addr"};
258 char ethaddr[DM_TEST_ETH_NUM][18];
259 int i;
260
261 memset(ethaddr, '\0', sizeof(ethaddr));
262 net_ping_ip = string_to_ip("1.1.2.2");
263
264 /* Prepare the test scenario */
265 for (i = 0; i < DM_TEST_ETH_NUM; i++) {
266 ut_assertok(uclass_find_device_by_name(UCLASS_ETH,
267 ethname[i], &dev[i]));
268 ut_assertok(device_remove(dev[i], DM_REMOVE_NORMAL));
269
270 /* Invalidate MAC address */
271 strncpy(ethaddr[i], env_get(addrname[i]), 17);
272 /* Must disable access protection for ethaddr before clearing */
273 env_set(".flags", addrname[i]);
274 env_set(addrname[i], NULL);
275 }
276
277 /* Set ethact to "eth@10002000" */
278 env_set("ethact", ethname[0]);
279
280 /* Segment fault might happen if something is wrong */
281 ut_asserteq(-ENODEV, net_loop(PING));
282
283 for (i = 0; i < DM_TEST_ETH_NUM; i++) {
284 /* Restore the env */
285 env_set(".flags", addrname[i]);
286 env_set(addrname[i], ethaddr[i]);
287
288 /* Probe the device again */
289 ut_assertok(device_probe(dev[i]));
290 }
291 env_set(".flags", NULL);
292 env_set("ethact", NULL);
293
294 return 0;
295 }
296 DM_TEST(dm_test_eth_act, UT_TESTF_SCAN_FDT);
297
298 /* Ensure that all addresses are loaded properly */
dm_test_ethaddr(struct unit_test_state * uts)299 static int dm_test_ethaddr(struct unit_test_state *uts)
300 {
301 static const char *const addr[] = {
302 "02:00:11:22:33:44",
303 "02:00:11:22:33:48", /* dsa slave */
304 "02:00:11:22:33:45",
305 "02:00:11:22:33:48", /* dsa master */
306 "02:00:11:22:33:46",
307 "02:00:11:22:33:47",
308 "02:00:11:22:33:48", /* dsa slave */
309 "02:00:11:22:33:49",
310 };
311 int i;
312
313 for (i = 0; i < ARRAY_SIZE(addr); i++) {
314 char addrname[10];
315
316 if (i)
317 snprintf(addrname, sizeof(addrname), "eth%daddr", i + 1);
318 else
319 strcpy(addrname, "ethaddr");
320 ut_asserteq_str(addr[i], env_get(addrname));
321 }
322
323 return 0;
324 }
325 DM_TEST(dm_test_ethaddr, UT_TESTF_SCAN_FDT);
326
327 /* The asserts include a return on fail; cleanup in the caller */
_dm_test_eth_rotate1(struct unit_test_state * uts)328 static int _dm_test_eth_rotate1(struct unit_test_state *uts)
329 {
330 /* Make sure that the default is to rotate to the next interface */
331 env_set("ethact", "eth@10004000");
332 ut_assertok(net_loop(PING));
333 ut_asserteq_str("eth@10002000", env_get("ethact"));
334
335 /* If ethrotate is no, then we should fail on a bad MAC */
336 env_set("ethact", "eth@10004000");
337 env_set("ethrotate", "no");
338 ut_asserteq(-EINVAL, net_loop(PING));
339 ut_asserteq_str("eth@10004000", env_get("ethact"));
340
341 return 0;
342 }
343
_dm_test_eth_rotate2(struct unit_test_state * uts)344 static int _dm_test_eth_rotate2(struct unit_test_state *uts)
345 {
346 /* Make sure we can skip invalid devices */
347 env_set("ethact", "eth@10004000");
348 ut_assertok(net_loop(PING));
349 ut_asserteq_str("eth@10004000", env_get("ethact"));
350
351 /* Make sure we can handle device name which is not eth# */
352 env_set("ethact", "sbe5");
353 ut_assertok(net_loop(PING));
354 ut_asserteq_str("sbe5", env_get("ethact"));
355
356 return 0;
357 }
358
dm_test_eth_rotate(struct unit_test_state * uts)359 static int dm_test_eth_rotate(struct unit_test_state *uts)
360 {
361 char ethaddr[18];
362 int retval;
363
364 /* Set target IP to mock ping */
365 net_ping_ip = string_to_ip("1.1.2.2");
366
367 /* Invalidate eth1's MAC address */
368 memset(ethaddr, '\0', sizeof(ethaddr));
369 strncpy(ethaddr, env_get("eth6addr"), 17);
370 /* Must disable access protection for eth6addr before clearing */
371 env_set(".flags", "eth6addr");
372 env_set("eth6addr", NULL);
373
374 retval = _dm_test_eth_rotate1(uts);
375
376 /* Restore the env */
377 env_set("eth6addr", ethaddr);
378 env_set("ethrotate", NULL);
379
380 if (!retval) {
381 /* Invalidate eth0's MAC address */
382 strncpy(ethaddr, env_get("ethaddr"), 17);
383 /* Must disable access protection for ethaddr before clearing */
384 env_set(".flags", "ethaddr");
385 env_set("ethaddr", NULL);
386
387 retval = _dm_test_eth_rotate2(uts);
388
389 /* Restore the env */
390 env_set("ethaddr", ethaddr);
391 }
392 /* Restore the env */
393 env_set(".flags", NULL);
394
395 return retval;
396 }
397 DM_TEST(dm_test_eth_rotate, UT_TESTF_SCAN_FDT);
398
399 /* The asserts include a return on fail; cleanup in the caller */
_dm_test_net_retry(struct unit_test_state * uts)400 static int _dm_test_net_retry(struct unit_test_state *uts)
401 {
402 /*
403 * eth1 is disabled and netretry is yes, so the ping should succeed and
404 * the active device should be eth0
405 */
406 sandbox_eth_disable_response(1, true);
407 env_set("ethact", "lan1");
408 env_set("netretry", "yes");
409 sandbox_eth_skip_timeout();
410 ut_assertok(net_loop(PING));
411 ut_asserteq_str("eth@10002000", env_get("ethact"));
412
413 /*
414 * eth1 is disabled and netretry is no, so the ping should fail and the
415 * active device should be eth1
416 */
417 env_set("ethact", "lan1");
418 env_set("netretry", "no");
419 sandbox_eth_skip_timeout();
420 ut_asserteq(-ENONET, net_loop(PING));
421 ut_asserteq_str("lan1", env_get("ethact"));
422
423 return 0;
424 }
425
dm_test_net_retry(struct unit_test_state * uts)426 static int dm_test_net_retry(struct unit_test_state *uts)
427 {
428 int retval;
429
430 net_ping_ip = string_to_ip("1.1.2.2");
431
432 retval = _dm_test_net_retry(uts);
433
434 /* Restore the env */
435 env_set("netretry", NULL);
436 sandbox_eth_disable_response(1, false);
437
438 return retval;
439 }
440 DM_TEST(dm_test_net_retry, UT_TESTF_SCAN_FDT);
441
sb_check_arp_reply(struct udevice * dev,void * packet,unsigned int len)442 static int sb_check_arp_reply(struct udevice *dev, void *packet,
443 unsigned int len)
444 {
445 struct eth_sandbox_priv *priv = dev_get_priv(dev);
446 struct ethernet_hdr *eth = packet;
447 struct arp_hdr *arp;
448 /* Used by all of the ut_assert macros */
449 struct unit_test_state *uts = priv->priv;
450
451 if (ntohs(eth->et_protlen) != PROT_ARP)
452 return 0;
453
454 arp = packet + ETHER_HDR_SIZE;
455
456 if (ntohs(arp->ar_op) != ARPOP_REPLY)
457 return 0;
458
459 /* This test would be worthless if we are not waiting */
460 ut_assert(arp_is_waiting());
461
462 /* Validate response */
463 ut_asserteq_mem(eth->et_src, net_ethaddr, ARP_HLEN);
464 ut_asserteq_mem(eth->et_dest, priv->fake_host_hwaddr, ARP_HLEN);
465 ut_assert(eth->et_protlen == htons(PROT_ARP));
466
467 ut_assert(arp->ar_hrd == htons(ARP_ETHER));
468 ut_assert(arp->ar_pro == htons(PROT_IP));
469 ut_assert(arp->ar_hln == ARP_HLEN);
470 ut_assert(arp->ar_pln == ARP_PLEN);
471 ut_asserteq_mem(&arp->ar_sha, net_ethaddr, ARP_HLEN);
472 ut_assert(net_read_ip(&arp->ar_spa).s_addr == net_ip.s_addr);
473 ut_asserteq_mem(&arp->ar_tha, priv->fake_host_hwaddr, ARP_HLEN);
474 ut_assert(net_read_ip(&arp->ar_tpa).s_addr ==
475 string_to_ip("1.1.2.4").s_addr);
476
477 return 0;
478 }
479
sb_with_async_arp_handler(struct udevice * dev,void * packet,unsigned int len)480 static int sb_with_async_arp_handler(struct udevice *dev, void *packet,
481 unsigned int len)
482 {
483 struct eth_sandbox_priv *priv = dev_get_priv(dev);
484 struct ethernet_hdr *eth = packet;
485 struct arp_hdr *arp = packet + ETHER_HDR_SIZE;
486 int ret;
487
488 /*
489 * If we are about to generate a reply to ARP, first inject a request
490 * from another host
491 */
492 if (ntohs(eth->et_protlen) == PROT_ARP &&
493 ntohs(arp->ar_op) == ARPOP_REQUEST) {
494 /* Make sure sandbox_eth_recv_arp_req() knows who is asking */
495 priv->fake_host_ipaddr = string_to_ip("1.1.2.4");
496
497 ret = sandbox_eth_recv_arp_req(dev);
498 if (ret)
499 return ret;
500 }
501
502 sandbox_eth_arp_req_to_reply(dev, packet, len);
503 sandbox_eth_ping_req_to_reply(dev, packet, len);
504
505 return sb_check_arp_reply(dev, packet, len);
506 }
507
dm_test_eth_async_arp_reply(struct unit_test_state * uts)508 static int dm_test_eth_async_arp_reply(struct unit_test_state *uts)
509 {
510 net_ping_ip = string_to_ip("1.1.2.2");
511
512 sandbox_eth_set_tx_handler(0, sb_with_async_arp_handler);
513 /* Used by all of the ut_assert macros in the tx_handler */
514 sandbox_eth_set_priv(0, uts);
515
516 env_set("ethact", "eth@10002000");
517 ut_assertok(net_loop(PING));
518 ut_asserteq_str("eth@10002000", env_get("ethact"));
519
520 sandbox_eth_set_tx_handler(0, NULL);
521
522 return 0;
523 }
524
525 DM_TEST(dm_test_eth_async_arp_reply, UT_TESTF_SCAN_FDT);
526
sb_check_ping_reply(struct udevice * dev,void * packet,unsigned int len)527 static int sb_check_ping_reply(struct udevice *dev, void *packet,
528 unsigned int len)
529 {
530 struct eth_sandbox_priv *priv = dev_get_priv(dev);
531 struct ethernet_hdr *eth = packet;
532 struct ip_udp_hdr *ip;
533 struct icmp_hdr *icmp;
534 /* Used by all of the ut_assert macros */
535 struct unit_test_state *uts = priv->priv;
536
537 if (ntohs(eth->et_protlen) != PROT_IP)
538 return 0;
539
540 ip = packet + ETHER_HDR_SIZE;
541
542 if (ip->ip_p != IPPROTO_ICMP)
543 return 0;
544
545 icmp = (struct icmp_hdr *)&ip->udp_src;
546
547 if (icmp->type != ICMP_ECHO_REPLY)
548 return 0;
549
550 /* This test would be worthless if we are not waiting */
551 ut_assert(arp_is_waiting());
552
553 /* Validate response */
554 ut_asserteq_mem(eth->et_src, net_ethaddr, ARP_HLEN);
555 ut_asserteq_mem(eth->et_dest, priv->fake_host_hwaddr, ARP_HLEN);
556 ut_assert(eth->et_protlen == htons(PROT_IP));
557
558 ut_assert(net_read_ip(&ip->ip_src).s_addr == net_ip.s_addr);
559 ut_assert(net_read_ip(&ip->ip_dst).s_addr ==
560 string_to_ip("1.1.2.4").s_addr);
561
562 return 0;
563 }
564
sb_with_async_ping_handler(struct udevice * dev,void * packet,unsigned int len)565 static int sb_with_async_ping_handler(struct udevice *dev, void *packet,
566 unsigned int len)
567 {
568 struct eth_sandbox_priv *priv = dev_get_priv(dev);
569 struct ethernet_hdr *eth = packet;
570 struct arp_hdr *arp = packet + ETHER_HDR_SIZE;
571 int ret;
572
573 /*
574 * If we are about to generate a reply to ARP, first inject a request
575 * from another host
576 */
577 if (ntohs(eth->et_protlen) == PROT_ARP &&
578 ntohs(arp->ar_op) == ARPOP_REQUEST) {
579 /* Make sure sandbox_eth_recv_arp_req() knows who is asking */
580 priv->fake_host_ipaddr = string_to_ip("1.1.2.4");
581
582 ret = sandbox_eth_recv_ping_req(dev);
583 if (ret)
584 return ret;
585 }
586
587 sandbox_eth_arp_req_to_reply(dev, packet, len);
588 sandbox_eth_ping_req_to_reply(dev, packet, len);
589
590 return sb_check_ping_reply(dev, packet, len);
591 }
592
dm_test_eth_async_ping_reply(struct unit_test_state * uts)593 static int dm_test_eth_async_ping_reply(struct unit_test_state *uts)
594 {
595 net_ping_ip = string_to_ip("1.1.2.2");
596
597 sandbox_eth_set_tx_handler(0, sb_with_async_ping_handler);
598 /* Used by all of the ut_assert macros in the tx_handler */
599 sandbox_eth_set_priv(0, uts);
600
601 env_set("ethact", "eth@10002000");
602 ut_assertok(net_loop(PING));
603 ut_asserteq_str("eth@10002000", env_get("ethact"));
604
605 sandbox_eth_set_tx_handler(0, NULL);
606
607 return 0;
608 }
609
610 DM_TEST(dm_test_eth_async_ping_reply, UT_TESTF_SCAN_FDT);
611
612 #if IS_ENABLED(CONFIG_IPV6_ROUTER_DISCOVERY)
613
614 static u8 ip6_ra_buf[] = {0x60, 0xf, 0xc5, 0x4a, 0x0, 0x38, 0x3a, 0xff, 0xfe,
615 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x85, 0xe6,
616 0x29, 0x77, 0xcb, 0xc8, 0x53, 0xff, 0x2, 0x0, 0x0,
617 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
618 0x1, 0x86, 0x0, 0xdc, 0x90, 0x40, 0x80, 0x15, 0x18,
619 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x4,
620 0x40, 0xc0, 0x0, 0x0, 0x37, 0xdc, 0x0, 0x0, 0x37,
621 0x78, 0x0, 0x0, 0x0, 0x0, 0x20, 0x1, 0xca, 0xfe, 0xca,
622 0xfe, 0xca, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
623 0x0, 0x1, 0x1, 0x0, 0x15, 0x5d, 0xe2, 0x8a, 0x2};
624
dm_test_validate_ra(struct unit_test_state * uts)625 static int dm_test_validate_ra(struct unit_test_state *uts)
626 {
627 struct ip6_hdr *ip6 = (struct ip6_hdr *)ip6_ra_buf;
628 struct icmp6hdr *icmp = (struct icmp6hdr *)(ip6 + 1);
629 __be16 temp = 0;
630
631 ut_assert(validate_ra(ip6) == true);
632
633 temp = ip6->payload_len;
634 ip6->payload_len = 15;
635 ut_assert(validate_ra(ip6) == false);
636 ip6->payload_len = temp;
637
638 temp = ip6->saddr.s6_addr16[0];
639 ip6->saddr.s6_addr16[0] = 0x2001;
640 ut_assert(validate_ra(ip6) == false);
641 ip6->saddr.s6_addr16[0] = temp;
642
643 temp = ip6->hop_limit;
644 ip6->hop_limit = 15;
645 ut_assert(validate_ra(ip6) == false);
646 ip6->hop_limit = temp;
647
648 temp = icmp->icmp6_code;
649 icmp->icmp6_code = 15;
650 ut_assert(validate_ra(ip6) == false);
651 icmp->icmp6_code = temp;
652
653 return 0;
654 }
655
656 DM_TEST(dm_test_validate_ra, 0);
657
dm_test_process_ra(struct unit_test_state * uts)658 static int dm_test_process_ra(struct unit_test_state *uts)
659 {
660 int len = sizeof(ip6_ra_buf);
661 struct ip6_hdr *ip6 = (struct ip6_hdr *)ip6_ra_buf;
662 struct icmp6hdr *icmp = (struct icmp6hdr *)(ip6 + 1);
663 struct ra_msg *msg = (struct ra_msg *)icmp;
664 unsigned char *option = msg->opt;
665 struct icmp6_ra_prefix_info *prefix =
666 (struct icmp6_ra_prefix_info *)option;
667 __be16 temp = 0;
668 unsigned char option_len = option[1];
669
670 ut_assert(process_ra(ip6, len) == 0);
671
672 temp = icmp->icmp6_rt_lifetime;
673 icmp->icmp6_rt_lifetime = 0;
674 ut_assert(process_ra(ip6, len) != 0);
675 icmp->icmp6_rt_lifetime = temp;
676
677 ut_assert(process_ra(ip6, 0) != 0);
678
679 option[1] = 0;
680 ut_assert(process_ra(ip6, len) != 0);
681 option[1] = option_len;
682
683 prefix->on_link = false;
684 ut_assert(process_ra(ip6, len) != 0);
685 prefix->on_link = true;
686
687 temp = prefix->prefix.s6_addr16[0];
688 prefix->prefix.s6_addr16[0] = 0x80fe;
689 ut_assert(process_ra(ip6, len) != 0);
690 prefix->prefix.s6_addr16[0] = temp;
691
692 return 0;
693 }
694
695 DM_TEST(dm_test_process_ra, 0);
696
697 #endif
698