Commit d81b42d0 authored by Simon Kelley's avatar Simon Kelley

Prod neighbour discovery with ARP instead of PING.

parent 724789de
......@@ -183,13 +183,13 @@ void dhcp6_packet(time_t now)
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 @@ void dhcp6_packet(time_t now)
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 @@ void dhcp6_packet(time_t now)
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));
......
......@@ -33,6 +33,13 @@ struct ra_packet {
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;
......
......@@ -419,14 +419,22 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
}
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 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
}
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 @@ static void log6_opts(int nest, unsigned int xid, void *start_opts, void *end_op
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))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment