Prod neighbour discovery with ARP instead of PING.
diff --git a/src/dhcp6.c b/src/dhcp6.c
index 9ad8912..5e151d6 100644
--- a/src/dhcp6.c
+++ b/src/dhcp6.c
@@ -183,13 +183,13 @@
return;
/* Recieving a packet from a host does not populate the neighbour
- cache, so we send a ping to prompt neighbour discovery if we can't
+ cache, so we send a neighbour discovery request if we can't
find the sender. Repeat a few times in case of packet loss. */
for (i = 0; i < 5; i++)
{
struct timespec ts;
- struct ping_packet *ping;
+ struct neigh_packet *neigh;
struct sockaddr_in6 addr;
mac_param.target = &from.sin6_addr;
@@ -201,12 +201,12 @@
break;
save_counter(0);
- ping = expand(sizeof(struct ping_packet));
- ping->type = ICMP6_ECHO_REQUEST;
- ping->code = 0;
- ping->identifier = 1;
- ping->sequence_no = 1;
-
+ neigh = expand(sizeof(struct neigh_packet));
+ neigh->type = ND_NEIGHBOR_SOLICIT;
+ neigh->code = 0;
+ neigh->reserved = 0;
+ neigh->target = from.sin6_addr;
+
memset(&addr, 0, sizeof(addr));
#ifdef HAVE_SOCKADDR_SA_LEN
addr.sin6_len = sizeof(struct sockaddr_in6);
@@ -214,6 +214,7 @@
addr.sin6_family = AF_INET6;
addr.sin6_port = htons(IPPROTO_ICMPV6);
addr.sin6_addr = from.sin6_addr;
+ addr.sin6_scope_id = from.sin6_scope_id;
sendto(daemon->icmp6fd, daemon->outpacket.iov_base, save_counter(0), 0,
(struct sockaddr *)&addr, sizeof(addr));
diff --git a/src/radv-protocol.h b/src/radv-protocol.h
index 1f0f88a..8d5b153 100644
--- a/src/radv-protocol.h
+++ b/src/radv-protocol.h
@@ -33,6 +33,13 @@
u32 retrans_time;
};
+struct neigh_packet {
+ u8 type, code;
+ u16 checksum;
+ u16 reserved;
+ struct in6_addr target;
+};
+
struct prefix_opt {
u8 type, len, prefix_len, flags;
u32 valid_lifetime, preferred_lifetime, reserved;
diff --git a/src/rfc3315.c b/src/rfc3315.c
index ee06353..26dca71 100644
--- a/src/rfc3315.c
+++ b/src/rfc3315.c
@@ -419,14 +419,22 @@
}
if (mac_len != 0)
- for (mac_opt = daemon->dhcp_macs; mac_opt; mac_opt = mac_opt->next)
- if ((unsigned)mac_opt->hwaddr_len == mac_len &&
- ((unsigned)mac_opt->hwaddr_type == mac_type || mac_opt->hwaddr_type == 0) &&
- memcmp_masked(mac_opt->hwaddr, mac, mac_len, mac_opt->mask))
+ {
+ if (option_bool(OPT_LOG_OPTS))
{
- mac_opt->netid.next = state.tags;
- state.tags = &mac_opt->netid;
+ print_mac(daemon->dhcp_buff, mac, mac_len);
+ my_syslog(MS_DHCP | LOG_INFO, _("%u client MAC address: %s"), state.xid, daemon->dhcp_buff);
}
+
+ for (mac_opt = daemon->dhcp_macs; mac_opt; mac_opt = mac_opt->next)
+ if ((unsigned)mac_opt->hwaddr_len == mac_len &&
+ ((unsigned)mac_opt->hwaddr_type == mac_type || mac_opt->hwaddr_type == 0) &&
+ memcmp_masked(mac_opt->hwaddr, mac, mac_len, mac_opt->mask))
+ {
+ mac_opt->netid.next = state.tags;
+ state.tags = &mac_opt->netid;
+ }
+ }
if ((opt = opt6_find(state.packet_options, state.end, OPTION6_FQDN, 1)))
{
@@ -1225,18 +1233,8 @@
}
log_tags(tagif, state.xid);
+ log6_opts(0, state.xid, daemon->outpacket.iov_base + start_opts, daemon->outpacket.iov_base + save_counter(-1));
- if (option_bool(OPT_LOG_OPTS))
- {
- if (mac_len != 0)
- {
- print_mac(daemon->dhcp_buff, mac, mac_len);
- my_syslog(MS_DHCP | LOG_INFO, _("%u client MAC address: %s"), state.xid, daemon->dhcp_buff);
- }
-
- log6_opts(0, state.xid, daemon->outpacket.iov_base + start_opts, daemon->outpacket.iov_base + save_counter(-1));
- }
-
return 1;
}
@@ -1824,7 +1822,7 @@
void *opt;
char *desc = nest ? "nest" : "sent";
- if (start_opts == end_opts)
+ if (!option_bool(OPT_LOG_OPTS) || start_opts == end_opts)
return;
for (opt = start_opts; opt; opt = opt6_next(opt, end_opts))