mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
Use random address allocation for DHCPv6 temporary addresses.
This commit is contained in:
14
src/dhcp6.c
14
src/dhcp6.c
@@ -394,7 +394,7 @@ struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned char *clid, int clid_len,
|
struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned char *clid, int clid_len, int temp_addr,
|
||||||
int iaid, int serial, struct dhcp_netid *netids, int plain_range, struct in6_addr *ans)
|
int iaid, int serial, struct dhcp_netid *netids, int plain_range, struct in6_addr *ans)
|
||||||
{
|
{
|
||||||
/* Find a free address: exclude anything in use and anything allocated to
|
/* Find a free address: exclude anything in use and anything allocated to
|
||||||
@@ -411,9 +411,13 @@ struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned c
|
|||||||
u64 j;
|
u64 j;
|
||||||
|
|
||||||
/* hash hwaddr: use the SDBM hashing algorithm. This works
|
/* hash hwaddr: use the SDBM hashing algorithm. This works
|
||||||
for MAC addresses, let's see how it manages with client-ids! */
|
for MAC addresses, let's see how it manages with client-ids!
|
||||||
for (j = iaid, i = 0; i < clid_len; i++)
|
For temporary addresses, we generate a new random one each time. */
|
||||||
j += clid[i] + (j << 6) + (j << 16) - j;
|
if (temp_addr)
|
||||||
|
j = rand64();
|
||||||
|
else
|
||||||
|
for (j = iaid, i = 0; i < clid_len; i++)
|
||||||
|
j += clid[i] + (j << 6) + (j << 16) - j;
|
||||||
|
|
||||||
for (pass = 0; pass <= plain_range ? 1 : 0; pass++)
|
for (pass = 0; pass <= plain_range ? 1 : 0; pass++)
|
||||||
for (c = context; c; c = c->current)
|
for (c = context; c; c = c->current)
|
||||||
@@ -423,7 +427,7 @@ struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned c
|
|||||||
continue;
|
continue;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (option_bool(OPT_CONSEC_ADDR))
|
if (!temp_addr && option_bool(OPT_CONSEC_ADDR))
|
||||||
/* seed is largest extant lease addr in this context */
|
/* seed is largest extant lease addr in this context */
|
||||||
start = lease_find_max_addr6(c) + serial;
|
start = lease_find_max_addr6(c) + serial;
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -1000,6 +1000,7 @@ int in_zone(struct auth_zone *zone, char *name, char **cut);
|
|||||||
/* util.c */
|
/* util.c */
|
||||||
void rand_init(void);
|
void rand_init(void);
|
||||||
unsigned short rand16(void);
|
unsigned short rand16(void);
|
||||||
|
u64 rand64(void);
|
||||||
int legal_hostname(char *c);
|
int legal_hostname(char *c);
|
||||||
char *canonicalise(char *s, int *nomem);
|
char *canonicalise(char *s, int *nomem);
|
||||||
unsigned char *do_rfc1035_name(unsigned char *p, char *sval);
|
unsigned char *do_rfc1035_name(unsigned char *p, char *sval);
|
||||||
@@ -1221,7 +1222,7 @@ int get_incoming_mark(union mysockaddr *peer_addr, struct all_addr *local_addr,
|
|||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
void dhcp6_init(void);
|
void dhcp6_init(void);
|
||||||
void dhcp6_packet(time_t now);
|
void dhcp6_packet(time_t now);
|
||||||
struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned char *clid, int clid_len,
|
struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned char *clid, int clid_len, int temp_addr,
|
||||||
int iaid, int serial, struct dhcp_netid *netids, int plain_range, struct in6_addr *ans);
|
int iaid, int serial, struct dhcp_netid *netids, int plain_range, struct in6_addr *ans);
|
||||||
int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr);
|
int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr);
|
||||||
struct dhcp_context *address6_available(struct dhcp_context *context,
|
struct dhcp_context *address6_available(struct dhcp_context *context,
|
||||||
|
|||||||
@@ -764,7 +764,8 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Return addresses for all valid contexts which don't yet have one */
|
/* Return addresses for all valid contexts which don't yet have one */
|
||||||
while ((c = address6_allocate(state->context, state->clid, state->clid_len, state->iaid, ia_counter, solicit_tags, plain_range, &addr)))
|
while ((c = address6_allocate(state->context, state->clid, state->clid_len, state->ia_type == OPTION6_IA_TA,
|
||||||
|
state->iaid, ia_counter, solicit_tags, plain_range, &addr)))
|
||||||
{
|
{
|
||||||
#ifdef OPTION6_PREFIX_CLASS
|
#ifdef OPTION6_PREFIX_CLASS
|
||||||
if (dump_all_prefix_classes && state->ia_type == OPTION6_IA_NA)
|
if (dump_all_prefix_classes && state->ia_type == OPTION6_IA_NA)
|
||||||
|
|||||||
37
src/util.c
37
src/util.c
@@ -39,6 +39,15 @@ unsigned short rand16(void)
|
|||||||
return (unsigned short) (arc4random() >> 15);
|
return (unsigned short) (arc4random() >> 15);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 rand64(void)
|
||||||
|
{
|
||||||
|
u64 ret;
|
||||||
|
|
||||||
|
arc4random_buf(&ret, sizeof(ret));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/* SURF random number generator */
|
/* SURF random number generator */
|
||||||
@@ -46,6 +55,7 @@ unsigned short rand16(void)
|
|||||||
static u32 seed[32];
|
static u32 seed[32];
|
||||||
static u32 in[12];
|
static u32 in[12];
|
||||||
static u32 out[8];
|
static u32 out[8];
|
||||||
|
static int outleft = 0;
|
||||||
|
|
||||||
void rand_init()
|
void rand_init()
|
||||||
{
|
{
|
||||||
@@ -82,16 +92,31 @@ static void surf(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned short rand16(void)
|
unsigned short rand16(void)
|
||||||
|
{
|
||||||
|
if (!outleft)
|
||||||
|
{
|
||||||
|
if (!++in[0]) if (!++in[1]) if (!++in[2]) ++in[3];
|
||||||
|
surf();
|
||||||
|
outleft = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (unsigned short) out[--outleft];
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 rand64(void)
|
||||||
{
|
{
|
||||||
static int outleft = 0;
|
static int outleft = 0;
|
||||||
|
|
||||||
if (!outleft) {
|
if (outleft < 2)
|
||||||
if (!++in[0]) if (!++in[1]) if (!++in[2]) ++in[3];
|
{
|
||||||
surf();
|
if (!++in[0]) if (!++in[1]) if (!++in[2]) ++in[3];
|
||||||
outleft = 8;
|
surf();
|
||||||
}
|
outleft = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
outleft -= 2;
|
||||||
|
|
||||||
return (unsigned short) out[--outleft];
|
return (u64)out[outleft+1] + (((u64)out[outleft]) << 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user