Skip to content

Commit 3abdc47

Browse files
committed
Implement neighbor address discovery
1 parent 3c47ec3 commit 3abdc47

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

src/kernel/net/ndp.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
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+
2326
int 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+
3468
int 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

Comments
 (0)