Compare commits

...
5 Commits
Author SHA1 Message Date
Petr Menšík 46bdfe691a Fix error in IPv6 prefix calculation.
Error with prefixed address assignment. When it is calculating number of
addresses from prefixlen, it rotates only 32bit int instead of 64b uint.
Only result is assigned to 64b variable.

Two examples:

dhcp-host=[2000::1230:0:0/92],correct-prefix
dhcp-host=[2000::1234:5678:0/92],incorrect-prefix

If prefix length is lower than 96, the result is zero. It means
incorrect-prefix is not refused as it should. Fix is simple, attaching
patch with it. Just rotate 64b int.
2020-03-08 15:56:19 +00:00
Vladislav Grishenko dded78b233 Add DHCPv6 ntp-server (56) option handling.
There was discussion in the past regarding DHCPv6 NTP server option
which needs special subclassing per RFC5908.

Patch adds support for unicast, multicast IPv6 address and for FQDN string,
preserving possibly used (as suggested earlier) hex value.

Unfortunately it's still not fully free from limitations - only address list or
only fqdn value list is possible, not mixed due current
state option parsing & flagging.
2020-03-08 15:34:34 +00:00
Kevin Darbyshire-Bryant b594e8defa rfc3315: fix incorrect logical '&&' warning
rfc3315.c:1711:28: warning: use of logical '&&' with constant operand [-Wconstant-logical-operand]
    if (!(addr_list->flags && ADDRLIST_DECLINED) ||
                           ^  ~~~~~~~~~~~~~~~~~

It's a flag bit so should be bitwise '&' operator

Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
2020-03-08 15:10:27 +00:00
Kevin Darbyshire-Bryant 70c50efd0d suppress non linux network unused var warnings
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
2020-03-08 15:09:44 +00:00
Brad Smith ea3c60ac07 Diverge error handling between *BSD and Linux. 2020-03-08 14:53:59 +00:00
7 changed files with 56 additions and 15 deletions

No files matched your search

+1 -1
View File
@@ -649,7 +649,7 @@ static const struct opttab_t opttab6[] = {
{ "sntp-server", 31, OT_ADDR_LIST }, { "sntp-server", 31, OT_ADDR_LIST },
{ "information-refresh-time", 32, OT_TIME }, { "information-refresh-time", 32, OT_TIME },
{ "FQDN", 39, OT_INTERNAL | OT_RFC1035_NAME }, { "FQDN", 39, OT_INTERNAL | OT_RFC1035_NAME },
{ "ntp-server", 56, 0 }, { "ntp-server", 56, 0 /* OT_ADDR_LIST | OT_RFC1035_NAME */ },
{ "bootfile-url", 59, OT_NAME }, { "bootfile-url", 59, OT_NAME },
{ "bootfile-param", 60, OT_CSTRING }, { "bootfile-param", 60, OT_CSTRING },
{ NULL, 0, 0 } { NULL, 0, 0 }
+4
View File
@@ -59,8 +59,12 @@
#define OPTION6_REMOTE_ID 37 #define OPTION6_REMOTE_ID 37
#define OPTION6_SUBSCRIBER_ID 38 #define OPTION6_SUBSCRIBER_ID 38
#define OPTION6_FQDN 39 #define OPTION6_FQDN 39
#define OPTION6_NTP_SERVER 56
#define OPTION6_CLIENT_MAC 79 #define OPTION6_CLIENT_MAC 79
#define NTP_SUBOPTION_SRV_ADDR 1
#define NTP_SUBOPTION_MC_ADDR 2
#define NTP_SUBOPTION_SRV_FQDN 3
#define DHCP6SUCCESS 0 #define DHCP6SUCCESS 0
#define DHCP6UNSPEC 1 #define DHCP6UNSPEC 1
+3 -1
View File
@@ -1860,7 +1860,8 @@ static void check_dns_listeners(time_t now)
if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1) if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1)
{ {
char a; char a;
(void)a; /* suppress potential unused warning */
daemon->tcp_pids[i] = p; daemon->tcp_pids[i] = p;
daemon->tcp_pipes[i] = pipefd[0]; daemon->tcp_pipes[i] = pipefd[0];
#ifdef HAVE_LINUX_NETWORK #ifdef HAVE_LINUX_NETWORK
@@ -1911,6 +1912,7 @@ static void check_dns_listeners(time_t now)
if (!option_bool(OPT_DEBUG)) if (!option_bool(OPT_DEBUG))
{ {
char a = 0; char a = 0;
(void)a; /* suppress potential unused warning */
alarm(CHILD_LIFETIME); alarm(CHILD_LIFETIME);
close(pipefd[0]); /* close read end in child. */ close(pipefd[0]); /* close read end in child. */
daemon->pipe_to_parent = pipefd[1]; daemon->pipe_to_parent = pipefd[1];
+6 -3
View File
@@ -93,10 +93,13 @@ int send_from(int fd, int nowild, char *packet, size_t len,
while (retry_send(sendmsg(fd, &msg, 0))); while (retry_send(sendmsg(fd, &msg, 0)));
/* If interface is still in DAD, EINVAL results - ignore that. */ if (errno != 0)
if (errno != 0 && errno != EINVAL)
{ {
my_syslog(LOG_ERR, _("failed to send packet: %s"), strerror(errno)); #ifdef HAVE_LINUX_NETWORK
/* If interface is still in DAD, EINVAL results - ignore that. */
if (errno != EINVAL)
my_syslog(LOG_ERR, _("failed to send packet: %s"), strerror(errno));
#endif
return 0; return 0;
} }
+3
View File
@@ -785,6 +785,8 @@ int set_ipv6pktinfo(int fd)
/* Find the interface on which a TCP connection arrived, if possible, or zero otherwise. */ /* Find the interface on which a TCP connection arrived, if possible, or zero otherwise. */
int tcp_interface(int fd, int af) int tcp_interface(int fd, int af)
{ {
(void)fd; /* suppress potential unused warning */
(void)af; /* suppress potential unused warning */
int if_index = 0; int if_index = 0;
#ifdef HAVE_LINUX_NETWORK #ifdef HAVE_LINUX_NETWORK
@@ -1187,6 +1189,7 @@ int local_bind(int fd, union mysockaddr *addr, char *intname, unsigned int ifind
#endif #endif
} }
(void)intname; /* suppress potential unused warning */
#if defined(SO_BINDTODEVICE) #if defined(SO_BINDTODEVICE)
if (intname[0] != 0 && if (intname[0] != 0 &&
setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, intname, IF_NAMESIZE) == -1) setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, intname, IF_NAMESIZE) == -1)
+17 -4
View File
@@ -1260,6 +1260,12 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
if (!found_colon) if (!found_colon)
is_addr6 = 0; is_addr6 = 0;
#ifdef HAVE_DHCP6
/* NTP server option takes hex, addresses or FQDN */
if (is6 && new->opt == OPTION6_NTP_SERVER && !is_hex)
opt_len |= is_addr6 ? OT_ADDR_LIST : OT_RFC1035_NAME;
#endif
/* We know that some options take addresses */ /* We know that some options take addresses */
if (opt_len & OT_ADDR_LIST) if (opt_len & OT_ADDR_LIST)
@@ -1521,8 +1527,9 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
} }
else if (comma && (opt_len & OT_RFC1035_NAME)) else if (comma && (opt_len & OT_RFC1035_NAME))
{ {
unsigned char *p = NULL, *newp, *end; unsigned char *p = NULL, *q, *newp, *end;
int len = 0; int len = 0;
int header_size = (is6 && new->opt == OPTION6_NTP_SERVER) ? 4 : 0;
arg = comma; arg = comma;
comma = split(arg); comma = split(arg);
@@ -1532,7 +1539,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
if (!dom) if (!dom)
goto_err(_("bad domain in dhcp-option")); goto_err(_("bad domain in dhcp-option"));
newp = opt_malloc(len + strlen(dom) + 2); newp = opt_malloc(len + header_size + strlen(dom) + 2);
if (p) if (p)
{ {
@@ -1541,8 +1548,14 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
} }
p = newp; p = newp;
end = do_rfc1035_name(p + len, dom, NULL); q = p + len;
end = do_rfc1035_name(q + header_size, dom, NULL);
*end++ = 0; *end++ = 0;
if (is6 && new->opt == OPTION6_NTP_SERVER)
{
PUTSHORT(NTP_SUBOPTION_SRV_FQDN, q);
PUTSHORT(end - q - 2, q);
}
len = end - p; len = end - p;
free(dom); free(dom);
@@ -3309,7 +3322,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
if (!atoi_check(pref, &new_addr->prefixlen) || if (!atoi_check(pref, &new_addr->prefixlen) ||
new_addr->prefixlen > 128 || new_addr->prefixlen > 128 ||
(((1<<(128-new_addr->prefixlen))-1) & addrpart) != 0) ((((u64)1<<(128-new_addr->prefixlen))-1) & addrpart) != 0)
{ {
dhcp_config_free(new); dhcp_config_free(new);
ret_err(_("bad IPv6 prefix")); ret_err(_("bad IPv6 prefix"));
+22 -6
View File
@@ -1311,23 +1311,39 @@ static struct dhcp_netid *add_options(struct state *state, int do_refresh)
for (a = (struct in6_addr *)opt_cfg->val, j = 0; j < opt_cfg->len; j+=IN6ADDRSZ, a++) for (a = (struct in6_addr *)opt_cfg->val, j = 0; j < opt_cfg->len; j+=IN6ADDRSZ, a++)
{ {
struct in6_addr *p = NULL;
if (IN6_IS_ADDR_UNSPECIFIED(a)) if (IN6_IS_ADDR_UNSPECIFIED(a))
{ {
if (!add_local_addrs(state->context)) if (!add_local_addrs(state->context))
put_opt6(state->fallback, IN6ADDRSZ); p = state->fallback;
} }
else if (IN6_IS_ADDR_ULA_ZERO(a)) else if (IN6_IS_ADDR_ULA_ZERO(a))
{ {
if (!IN6_IS_ADDR_UNSPECIFIED(state->ula_addr)) if (!IN6_IS_ADDR_UNSPECIFIED(state->ula_addr))
put_opt6(state->ula_addr, IN6ADDRSZ); p = state->ula_addr;
} }
else if (IN6_IS_ADDR_LINK_LOCAL_ZERO(a)) else if (IN6_IS_ADDR_LINK_LOCAL_ZERO(a))
{ {
if (!IN6_IS_ADDR_UNSPECIFIED(state->ll_addr)) if (!IN6_IS_ADDR_UNSPECIFIED(state->ll_addr))
put_opt6(state->ll_addr, IN6ADDRSZ); p = state->ll_addr;
} }
else else
put_opt6(a, IN6ADDRSZ); p = a;
if (!p)
continue;
else if (opt_cfg->opt == OPTION6_NTP_SERVER)
{
if (IN6_IS_ADDR_MULTICAST(p))
o1 = new_opt6(NTP_SUBOPTION_MC_ADDR);
else
o1 = new_opt6(NTP_SUBOPTION_SRV_ADDR);
put_opt6(p, IN6ADDRSZ);
end_opt6(o1);
}
else
put_opt6(p, IN6ADDRSZ);
} }
end_opt6(o); end_opt6(o);
@@ -1708,14 +1724,14 @@ static int config_valid(struct dhcp_config *config, struct dhcp_context *context
return 0; return 0;
for (addr_list = config->addr6; addr_list; addr_list = addr_list->next) for (addr_list = config->addr6; addr_list; addr_list = addr_list->next)
if (!(addr_list->flags && ADDRLIST_DECLINED) || if (!(addr_list->flags & ADDRLIST_DECLINED) ||
difftime(now, addr_list->decline_time) >= (float)DECLINE_BACKOFF) difftime(now, addr_list->decline_time) >= (float)DECLINE_BACKOFF)
{ {
addrpart = addr6part(&addr_list->addr.addr6); addrpart = addr6part(&addr_list->addr.addr6);
addresses = 1; addresses = 1;
if (addr_list->flags & ADDRLIST_PREFIX) if (addr_list->flags & ADDRLIST_PREFIX)
addresses = 1<<(128-addr_list->prefixlen); addresses = (u64)1<<(128-addr_list->prefixlen);
if ((addr_list->flags & ADDRLIST_WILDCARD)) if ((addr_list->flags & ADDRLIST_WILDCARD))
{ {