44 * SPDX-License-Identifier: GPL-3.0-or-later
55 */
66
7+ #include <mm/alloc.h>
78#include <net/icmpv6.h>
89#include <net/ipv6.h>
910
@@ -20,6 +21,8 @@ static const struct ip_address SOLICITED_NODE = {
2021 .addr = {0xff , 0x02 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x1 , 0xff ,
2122 0x9a , 0xbc , 0xde }};
2223
24+ #define CEIL (x , n ) ((x) / (n) + ((x) % (n)) ? 1 : 0) * (n)
25+
2326int ndp_discover_routers () {
2427 struct icmpv6_header icmpv6_header = icmpv6_create_header (
2528 LINK_LOCAL , ALL_ROUTERS , nullptr , 0 , NDP_ROUTER_SOLICIT , 0 );
@@ -31,6 +34,37 @@ int ndp_discover_routers() {
3134 return 0 ;
3235};
3336
37+ struct mac_address
38+ ndp_resolve_neighbor_address (struct ip_address src_address ,
39+ struct ip_address target_address ,
40+ struct mac_address src_mac_address ) {
41+ // NDP options must be 8 byte aligned
42+ usize opt_len =
43+ CEIL (sizeof (struct option_info ) + sizeof (struct mac_address ), 8 );
44+ usize len = sizeof (struct ndp_neighbor_solicit ) + opt_len ;
45+ struct ndp_option option_info = {
46+ .type = NDP_SRC_ADDR ,
47+ .len = opt_len ,
48+ };
49+ u8 * message = alloc (len );
50+ memset (message , 0 , opt_len );
51+ memcpy (message + sizeof (struct ndp_neighbor_solicit ), & option_info ,
52+ sizeof (struct ndp_option ));
53+ memcpy (message + sizeof (struct ndp_neighbor_solicit ) +
54+ sizeof (struct ndp_option ),
55+ & src_mac_address , sizeof (struct mac_address ));
56+ memcpy (message + sizeof (struct icmpv6_header ), & target_address ,
57+ sizeof (struct ipv6_address )) struct icmpv6_header icmpv6_header =
58+ icmpv6_create_header (
59+ src_address , target_address , header + sizeof (struct icmpv6_header ),
60+ len - sizeof (struct icmpv6_header ), NDP_NEIGHBOR_SOLICIT , 0 );
61+ struct ipv6_header ipv6_header =
62+ ipv6_create_header (src_address , target_address , ICMP );
63+ ipv6_send_packet (ipv6_header , (u8 * )& message , sizeof (message ));
64+
65+ return 0 ;
66+ }
67+
3468int ndp_duplicate_address_detection () {
3569 struct icmpv6_header icmpv6_header = icmpv6_create_header (
3670 UNSPECIFIED , SOLICITED_NODE , nullptr , 0 , NDP_NEIGHBOR_SOLICIT , 0 );
0 commit comments