Sync
This commit is contained in:
parent
322001baf8
commit
8ad72a7637
540
external/bsd/dhcpcd/dist/dhcp.c
vendored
540
external/bsd/dhcpcd/dist/dhcp.c
vendored
@ -1,5 +1,5 @@
|
|||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__RCSID("$NetBSD: dhcp.c,v 1.7 2013/09/20 10:56:32 roy Exp $");
|
__RCSID("$NetBSD: dhcp.c,v 1.8 2014/01/03 22:24:41 roy Exp $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dhcpcd - DHCP client daemon
|
* dhcpcd - DHCP client daemon
|
||||||
@ -107,107 +107,6 @@ static const struct dhcp_op dhcp_ops[] = {
|
|||||||
{ 0, NULL }
|
{ 0, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct dhcp_opt dhcp_opts[] = {
|
|
||||||
{ 1, ADDRIPV4 | REQUEST, "subnet_mask" },
|
|
||||||
/* RFC 3442 states that the CSR has to come before all other
|
|
||||||
* routes. For completeness, we also specify static routes,
|
|
||||||
* then routers. */
|
|
||||||
{ 121, RFC3442, "classless_static_routes" },
|
|
||||||
{ 249, RFC3442, "ms_classless_static_routes" },
|
|
||||||
{ 33, IPV4A | REQUEST, "static_routes" },
|
|
||||||
{ 3, IPV4A | REQUEST, "routers" },
|
|
||||||
{ 2, UINT32, "time_offset" },
|
|
||||||
{ 4, IPV4A, "time_servers" },
|
|
||||||
{ 5, IPV4A, "ien116_name_servers" },
|
|
||||||
{ 6, IPV4A, "domain_name_servers" },
|
|
||||||
{ 7, IPV4A, "log_servers" },
|
|
||||||
{ 8, IPV4A, "cookie_servers" },
|
|
||||||
{ 9, IPV4A, "lpr_servers" },
|
|
||||||
{ 10, IPV4A, "impress_servers" },
|
|
||||||
{ 11, IPV4A, "resource_location_servers" },
|
|
||||||
{ 12, STRING, "host_name" },
|
|
||||||
{ 13, UINT16, "boot_size" },
|
|
||||||
{ 14, STRING, "merit_dump" },
|
|
||||||
{ 15, STRING, "domain_name" },
|
|
||||||
{ 16, ADDRIPV4, "swap_server" },
|
|
||||||
{ 17, STRING, "root_path" },
|
|
||||||
{ 18, STRING, "extensions_path" },
|
|
||||||
{ 19, UINT8, "ip_forwarding" },
|
|
||||||
{ 20, UINT8, "non_local_source_routing" },
|
|
||||||
{ 21, IPV4A, "policy_filter" },
|
|
||||||
{ 22, SINT16, "max_dgram_reassembly" },
|
|
||||||
{ 23, UINT16, "default_ip_ttl" },
|
|
||||||
{ 24, UINT32, "path_mtu_aging_timeout" },
|
|
||||||
{ 25, UINT16 | ARRAY, "path_mtu_plateau_table" },
|
|
||||||
{ 26, UINT16, "interface_mtu" },
|
|
||||||
{ 27, UINT8, "all_subnets_local" },
|
|
||||||
{ 28, ADDRIPV4 | REQUEST, "broadcast_address" },
|
|
||||||
{ 29, UINT8, "perform_mask_discovery" },
|
|
||||||
{ 30, UINT8, "mask_supplier" },
|
|
||||||
{ 31, UINT8, "router_discovery" },
|
|
||||||
{ 32, ADDRIPV4, "router_solicitation_address" },
|
|
||||||
{ 34, UINT8, "trailer_encapsulation" },
|
|
||||||
{ 35, UINT32, "arp_cache_timeout" },
|
|
||||||
{ 36, UINT16, "ieee802_3_encapsulation" },
|
|
||||||
{ 37, UINT8, "default_tcp_ttl" },
|
|
||||||
{ 38, UINT32, "tcp_keepalive_interval" },
|
|
||||||
{ 39, UINT8, "tcp_keepalive_garbage" },
|
|
||||||
{ 40, STRING, "nis_domain" },
|
|
||||||
{ 41, IPV4A, "nis_servers" },
|
|
||||||
{ 42, IPV4A, "ntp_servers" },
|
|
||||||
{ 43, STRING, "vendor_encapsulated_options" },
|
|
||||||
{ 44, IPV4A, "netbios_name_servers" },
|
|
||||||
{ 45, ADDRIPV4, "netbios_dd_server" },
|
|
||||||
{ 46, UINT8, "netbios_node_type" },
|
|
||||||
{ 47, STRING, "netbios_scope" },
|
|
||||||
{ 48, IPV4A, "font_servers" },
|
|
||||||
{ 49, IPV4A, "x_display_manager" },
|
|
||||||
{ 50, ADDRIPV4, "dhcp_requested_address" },
|
|
||||||
{ 51, UINT32 | REQUEST, "dhcp_lease_time" },
|
|
||||||
{ 52, UINT8, "dhcp_option_overload" },
|
|
||||||
{ 53, UINT8, "dhcp_message_type" },
|
|
||||||
{ 54, ADDRIPV4, "dhcp_server_identifier" },
|
|
||||||
{ 55, UINT8 | ARRAY, "dhcp_parameter_request_list" },
|
|
||||||
{ 56, STRING, "dhcp_message" },
|
|
||||||
{ 57, UINT16, "dhcp_max_message_size" },
|
|
||||||
{ 58, UINT32 | REQUEST, "dhcp_renewal_time" },
|
|
||||||
{ 59, UINT32 | REQUEST, "dhcp_rebinding_time" },
|
|
||||||
{ 64, STRING, "nisplus_domain" },
|
|
||||||
{ 65, IPV4A, "nisplus_servers" },
|
|
||||||
{ 66, STRING, "tftp_server_name" },
|
|
||||||
{ 67, STRING, "bootfile_name" },
|
|
||||||
{ 68, IPV4A, "mobile_ip_home_agent" },
|
|
||||||
{ 69, IPV4A, "smtp_server" },
|
|
||||||
{ 70, IPV4A, "pop_server" },
|
|
||||||
{ 71, IPV4A, "nntp_server" },
|
|
||||||
{ 72, IPV4A, "www_server" },
|
|
||||||
{ 73, IPV4A, "finger_server" },
|
|
||||||
{ 74, IPV4A, "irc_server" },
|
|
||||||
{ 75, IPV4A, "streettalk_server" },
|
|
||||||
{ 76, IPV4A, "streettalk_directory_assistance_server" },
|
|
||||||
{ 77, STRING, "user_class" },
|
|
||||||
{ 80, FLAG | NOREQ, "rapid_commit" },
|
|
||||||
{ 81, STRING | RFC3397, "fqdn" },
|
|
||||||
{ 85, IPV4A, "nds_servers" },
|
|
||||||
{ 86, STRING, "nds_tree_name" },
|
|
||||||
{ 87, STRING, "nds_context" },
|
|
||||||
{ 88, STRING | RFC3397, "bcms_controller_names" },
|
|
||||||
{ 89, IPV4A, "bcms_controller_address" },
|
|
||||||
{ 91, UINT32, "client_last_transaction_time" },
|
|
||||||
{ 92, IPV4A, "associated_ip" },
|
|
||||||
{ 98, STRING, "uap_servers" },
|
|
||||||
{ 100, STRING, "posix_timezone" },
|
|
||||||
{ 101, STRING, "tzdb_timezone" },
|
|
||||||
{ 112, IPV4A, "netinfo_server_address" },
|
|
||||||
{ 113, STRING, "netinfo_server_tag" },
|
|
||||||
{ 114, STRING, "default_url" },
|
|
||||||
{ 118, ADDRIPV4, "subnet_selection" },
|
|
||||||
{ 119, STRING | RFC3397, "domain_search" },
|
|
||||||
{ 120, STRING | RFC3361, "sip_server" },
|
|
||||||
{ 212, RFC5969, "sixrd" },
|
|
||||||
{ 0, 0, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char *dhcp_params[] = {
|
static const char *dhcp_params[] = {
|
||||||
"ip_address",
|
"ip_address",
|
||||||
"subnet_cidr",
|
"subnet_cidr",
|
||||||
@ -223,6 +122,10 @@ struct udp_dhcp_packet
|
|||||||
struct udphdr udp;
|
struct udphdr udp;
|
||||||
struct dhcp_message dhcp;
|
struct dhcp_message dhcp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct dhcp_opt *dhcp_opts = NULL;
|
||||||
|
size_t dhcp_opts_len = 0;
|
||||||
|
|
||||||
static const size_t udp_dhcp_len = sizeof(struct udp_dhcp_packet);
|
static const size_t udp_dhcp_len = sizeof(struct udp_dhcp_packet);
|
||||||
|
|
||||||
static int dhcp_open(struct interface *);
|
static int dhcp_open(struct interface *);
|
||||||
@ -230,63 +133,20 @@ static int dhcp_open(struct interface *);
|
|||||||
void
|
void
|
||||||
dhcp_printoptions(void)
|
dhcp_printoptions(void)
|
||||||
{
|
{
|
||||||
const struct dhcp_opt *opt;
|
|
||||||
const char **p;
|
const char **p;
|
||||||
|
size_t i;
|
||||||
|
const struct dhcp_opt *opt;
|
||||||
|
|
||||||
for (p = dhcp_params; *p; p++)
|
for (p = dhcp_params; *p; p++)
|
||||||
printf(" %s\n", *p);
|
printf(" %s\n", *p);
|
||||||
|
|
||||||
for (opt = dhcp_opts; opt->option; opt++)
|
for (i = 0, opt = dhcp_opts; i < dhcp_opts_len; i++, opt++)
|
||||||
if (opt->var)
|
printf("%03d %s\n", opt->option, opt->var);
|
||||||
printf("%03d %s\n", opt->option, opt->var);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
validate_length(uint8_t option, int dl, int *type)
|
|
||||||
{
|
|
||||||
const struct dhcp_opt *opt;
|
|
||||||
ssize_t sz;
|
|
||||||
|
|
||||||
if (dl == 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
for (opt = dhcp_opts; opt->option; opt++) {
|
|
||||||
if (opt->option != option)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (type)
|
|
||||||
*type = opt->type;
|
|
||||||
|
|
||||||
if (opt->type == 0 ||
|
|
||||||
opt->type & (STRING | RFC3442 | RFC5969))
|
|
||||||
return dl;
|
|
||||||
|
|
||||||
if (opt->type & ADDRIPV4 && opt->type & ARRAY) {
|
|
||||||
if (dl < (int)sizeof(uint32_t))
|
|
||||||
return -1;
|
|
||||||
return dl - (dl % sizeof(uint32_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
sz = 0;
|
|
||||||
if (opt->type & (UINT32 | ADDRIPV4))
|
|
||||||
sz = sizeof(uint32_t);
|
|
||||||
if (opt->type & UINT16)
|
|
||||||
sz = sizeof(uint16_t);
|
|
||||||
if (opt->type & UINT8)
|
|
||||||
sz = sizeof(uint8_t);
|
|
||||||
/* If we don't know the size, assume it's valid */
|
|
||||||
if (sz == 0)
|
|
||||||
return dl;
|
|
||||||
return (dl < sz ? -1 : sz);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* unknown option, so let it pass */
|
|
||||||
return dl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_MEMORY
|
#ifdef DEBUG_MEMORY
|
||||||
static void
|
static void
|
||||||
free_option_buffer(void)
|
dhcp_cleanup(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
free(packet);
|
free(packet);
|
||||||
@ -294,9 +154,9 @@ free_option_buffer(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define get_option_raw(dhcp, opt) get_option(dhcp, opt, NULL, NULL)
|
#define get_option_raw(dhcp, opt) get_option(dhcp, opt, NULL)
|
||||||
static const uint8_t *
|
static const uint8_t *
|
||||||
get_option(const struct dhcp_message *dhcp, uint8_t opt, int *len, int *type)
|
get_option(const struct dhcp_message *dhcp, uint8_t opt, int *len)
|
||||||
{
|
{
|
||||||
const uint8_t *p = dhcp->options;
|
const uint8_t *p = dhcp->options;
|
||||||
const uint8_t *e = p + sizeof(dhcp->options);
|
const uint8_t *e = p + sizeof(dhcp->options);
|
||||||
@ -305,7 +165,7 @@ get_option(const struct dhcp_message *dhcp, uint8_t opt, int *len, int *type)
|
|||||||
uint8_t overl = 0;
|
uint8_t overl = 0;
|
||||||
uint8_t *bp = NULL;
|
uint8_t *bp = NULL;
|
||||||
const uint8_t *op = NULL;
|
const uint8_t *op = NULL;
|
||||||
ssize_t bl = 0;
|
int bl = 0;
|
||||||
|
|
||||||
while (p < e) {
|
while (p < e) {
|
||||||
o = *p++;
|
o = *p++;
|
||||||
@ -315,9 +175,6 @@ get_option(const struct dhcp_message *dhcp, uint8_t opt, int *len, int *type)
|
|||||||
opt_buffer = malloc(sizeof(*dhcp));
|
opt_buffer = malloc(sizeof(*dhcp));
|
||||||
if (opt_buffer == NULL)
|
if (opt_buffer == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
#ifdef DEBUG_MEMORY
|
|
||||||
atexit(free_option_buffer);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
if (!bp)
|
if (!bp)
|
||||||
bp = opt_buffer;
|
bp = opt_buffer;
|
||||||
@ -325,6 +182,10 @@ get_option(const struct dhcp_message *dhcp, uint8_t opt, int *len, int *type)
|
|||||||
bp += ol;
|
bp += ol;
|
||||||
}
|
}
|
||||||
ol = *p;
|
ol = *p;
|
||||||
|
if (p + ol > e) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
op = p + 1;
|
op = p + 1;
|
||||||
bl += ol;
|
bl += ol;
|
||||||
}
|
}
|
||||||
@ -356,12 +217,6 @@ get_option(const struct dhcp_message *dhcp, uint8_t opt, int *len, int *type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
|
||||||
bl = validate_length(opt, bl, type);
|
|
||||||
if (bl == -1) {
|
|
||||||
errno = EINVAL;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (len)
|
if (len)
|
||||||
*len = bl;
|
*len = bl;
|
||||||
if (bp) {
|
if (bp) {
|
||||||
@ -378,46 +233,40 @@ int
|
|||||||
get_option_addr(struct in_addr *a, const struct dhcp_message *dhcp,
|
get_option_addr(struct in_addr *a, const struct dhcp_message *dhcp,
|
||||||
uint8_t option)
|
uint8_t option)
|
||||||
{
|
{
|
||||||
const uint8_t *p = get_option_raw(dhcp, option);
|
const uint8_t *p;
|
||||||
|
int len;
|
||||||
|
|
||||||
if (!p)
|
p = get_option(dhcp, option, &len);
|
||||||
|
if (!p || len < (ssize_t)sizeof(a->s_addr))
|
||||||
return -1;
|
return -1;
|
||||||
memcpy(&a->s_addr, p, sizeof(a->s_addr));
|
memcpy(&a->s_addr, p, sizeof(a->s_addr));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int
|
||||||
get_option_uint32(uint32_t *i, const struct dhcp_message *dhcp, uint8_t option)
|
get_option_uint32(uint32_t *i, const struct dhcp_message *dhcp, uint8_t option)
|
||||||
{
|
{
|
||||||
const uint8_t *p = get_option_raw(dhcp, option);
|
const uint8_t *p;
|
||||||
|
int len;
|
||||||
uint32_t d;
|
uint32_t d;
|
||||||
|
|
||||||
if (!p)
|
p = get_option(dhcp, option, &len);
|
||||||
|
if (!p || len < (ssize_t)sizeof(d))
|
||||||
return -1;
|
return -1;
|
||||||
memcpy(&d, p, sizeof(d));
|
memcpy(&d, p, sizeof(d));
|
||||||
*i = ntohl(d);
|
if (i)
|
||||||
|
*i = ntohl(d);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int
|
||||||
get_option_uint16(uint16_t *i, const struct dhcp_message *dhcp, uint8_t option)
|
|
||||||
{
|
|
||||||
const uint8_t *p = get_option_raw(dhcp, option);
|
|
||||||
uint16_t d;
|
|
||||||
|
|
||||||
if (!p)
|
|
||||||
return -1;
|
|
||||||
memcpy(&d, p, sizeof(d));
|
|
||||||
*i = ntohs(d);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
get_option_uint8(uint8_t *i, const struct dhcp_message *dhcp, uint8_t option)
|
get_option_uint8(uint8_t *i, const struct dhcp_message *dhcp, uint8_t option)
|
||||||
{
|
{
|
||||||
const uint8_t *p = get_option_raw(dhcp, option);
|
const uint8_t *p;
|
||||||
|
int len;
|
||||||
|
|
||||||
if (!p)
|
p = get_option(dhcp, option, &len);
|
||||||
|
if (!p || len < (ssize_t)sizeof(*p))
|
||||||
return -1;
|
return -1;
|
||||||
if (i)
|
if (i)
|
||||||
*i = *(p);
|
*i = *(p);
|
||||||
@ -654,30 +503,14 @@ decode_rfc5969(char *out, ssize_t len, int pl, const uint8_t *p)
|
|||||||
char *
|
char *
|
||||||
get_option_string(const struct dhcp_message *dhcp, uint8_t option)
|
get_option_string(const struct dhcp_message *dhcp, uint8_t option)
|
||||||
{
|
{
|
||||||
int type = 0;
|
|
||||||
int len;
|
int len;
|
||||||
const uint8_t *p;
|
const uint8_t *p;
|
||||||
char *s;
|
char *s;
|
||||||
|
|
||||||
p = get_option(dhcp, option, &len, &type);
|
p = get_option(dhcp, option, &len);
|
||||||
if (!p || *p == '\0')
|
if (!p || len == 0 || *p == '\0')
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (type & RFC3397) {
|
|
||||||
type = decode_rfc3397(NULL, 0, len, p);
|
|
||||||
if (!type) {
|
|
||||||
errno = EINVAL;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
s = malloc(sizeof(char) * type);
|
|
||||||
if (s)
|
|
||||||
decode_rfc3397(s, type, len, p);
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type & RFC3361)
|
|
||||||
return decode_rfc3361(len, p);
|
|
||||||
|
|
||||||
s = malloc(sizeof(char) * (len + 1));
|
s = malloc(sizeof(char) * (len + 1));
|
||||||
if (s) {
|
if (s) {
|
||||||
memcpy(s, p, len);
|
memcpy(s, p, len);
|
||||||
@ -731,12 +564,12 @@ get_option_routes(struct interface *ifp, const struct dhcp_message *dhcp)
|
|||||||
|
|
||||||
/* If we have CSR's then we MUST use these only */
|
/* If we have CSR's then we MUST use these only */
|
||||||
if (!has_option_mask(ifo->nomask, DHO_CSR))
|
if (!has_option_mask(ifo->nomask, DHO_CSR))
|
||||||
p = get_option(dhcp, DHO_CSR, &len, NULL);
|
p = get_option(dhcp, DHO_CSR, &len);
|
||||||
else
|
else
|
||||||
p = NULL;
|
p = NULL;
|
||||||
/* Check for crappy MS option */
|
/* Check for crappy MS option */
|
||||||
if (!p && !has_option_mask(ifo->nomask, DHO_MSCSR)) {
|
if (!p && !has_option_mask(ifo->nomask, DHO_MSCSR)) {
|
||||||
p = get_option(dhcp, DHO_MSCSR, &len, NULL);
|
p = get_option(dhcp, DHO_MSCSR, &len);
|
||||||
if (p)
|
if (p)
|
||||||
csr = "MS ";
|
csr = "MS ";
|
||||||
}
|
}
|
||||||
@ -761,7 +594,7 @@ get_option_routes(struct interface *ifp, const struct dhcp_message *dhcp)
|
|||||||
}
|
}
|
||||||
TAILQ_INIT(routes);
|
TAILQ_INIT(routes);
|
||||||
if (!has_option_mask(ifo->nomask, DHO_STATICROUTE))
|
if (!has_option_mask(ifo->nomask, DHO_STATICROUTE))
|
||||||
p = get_option(dhcp, DHO_STATICROUTE, &len, NULL);
|
p = get_option(dhcp, DHO_STATICROUTE, &len);
|
||||||
else
|
else
|
||||||
p = NULL;
|
p = NULL;
|
||||||
if (p) {
|
if (p) {
|
||||||
@ -784,7 +617,7 @@ get_option_routes(struct interface *ifp, const struct dhcp_message *dhcp)
|
|||||||
|
|
||||||
/* Now grab our routers */
|
/* Now grab our routers */
|
||||||
if (!has_option_mask(ifo->nomask, DHO_ROUTER))
|
if (!has_option_mask(ifo->nomask, DHO_ROUTER))
|
||||||
p = get_option(dhcp, DHO_ROUTER, &len, NULL);
|
p = get_option(dhcp, DHO_ROUTER, &len);
|
||||||
else
|
else
|
||||||
p = NULL;
|
p = NULL;
|
||||||
if (p) {
|
if (p) {
|
||||||
@ -847,13 +680,14 @@ make_message(struct dhcp_message **message,
|
|||||||
uint8_t *n_params = NULL;
|
uint8_t *n_params = NULL;
|
||||||
uint32_t ul;
|
uint32_t ul;
|
||||||
uint16_t sz;
|
uint16_t sz;
|
||||||
size_t len;
|
size_t len, i;
|
||||||
const struct dhcp_opt *opt;
|
const struct dhcp_opt *opt;
|
||||||
const struct if_options *ifo = iface->options;
|
const struct if_options *ifo = iface->options;
|
||||||
const struct dhcp_state *state = D_CSTATE(iface);
|
const struct dhcp_state *state = D_CSTATE(iface);
|
||||||
const struct dhcp_lease *lease = &state->lease;
|
const struct dhcp_lease *lease = &state->lease;
|
||||||
time_t up = uptime() - state->start_uptime;
|
time_t up = uptime() - state->start_uptime;
|
||||||
const char *hostname;
|
const char *hostname;
|
||||||
|
const struct vivco *vivco;
|
||||||
|
|
||||||
dhcp = calloc(1, sizeof (*dhcp));
|
dhcp = calloc(1, sizeof (*dhcp));
|
||||||
if (dhcp == NULL)
|
if (dhcp == NULL)
|
||||||
@ -1034,10 +868,41 @@ make_message(struct dhcp_message **message,
|
|||||||
p += ifo->vendor[0] + 1;
|
p += ifo->vendor[0] + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ifo->vivco_len) {
|
||||||
|
*p++ = DHO_VIVCO;
|
||||||
|
lp = p++;
|
||||||
|
*lp = sizeof(ul);
|
||||||
|
ul = htonl(ifo->vivco_en);
|
||||||
|
memcpy(p, &ul, sizeof(ul));
|
||||||
|
p += sizeof(ul);
|
||||||
|
for (i = 0, vivco = ifo->vivco;
|
||||||
|
i < ifo->vivco_len;
|
||||||
|
i++, vivco++)
|
||||||
|
{
|
||||||
|
len = (p - m) + vivco->len + 1;
|
||||||
|
if (len > sizeof(*dhcp))
|
||||||
|
goto toobig;
|
||||||
|
if (vivco->len + 2 + *lp > 255) {
|
||||||
|
syslog(LOG_ERR,
|
||||||
|
"%s: VIVCO option too big",
|
||||||
|
iface->name);
|
||||||
|
free(dhcp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*p++ = (uint8_t)vivco->len;
|
||||||
|
memcpy(p, vivco->data, vivco->len);
|
||||||
|
p += vivco->len;
|
||||||
|
*lp += (uint8_t)vivco->len + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
len = (p - m) + 3;
|
||||||
|
if (len > sizeof(*dhcp))
|
||||||
|
goto toobig;
|
||||||
*p++ = DHO_PARAMETERREQUESTLIST;
|
*p++ = DHO_PARAMETERREQUESTLIST;
|
||||||
n_params = p;
|
n_params = p;
|
||||||
*p++ = 0;
|
*p++ = 0;
|
||||||
for (opt = dhcp_opts; opt->option; opt++) {
|
for (i = 0, opt = dhcp_opts; i < dhcp_opts_len; i++, opt++) {
|
||||||
if (!(opt->type & REQUEST ||
|
if (!(opt->type & REQUEST ||
|
||||||
has_option_mask(ifo->requestmask, opt->option)))
|
has_option_mask(ifo->requestmask, opt->option)))
|
||||||
continue;
|
continue;
|
||||||
@ -1047,6 +912,9 @@ make_message(struct dhcp_message **message,
|
|||||||
(opt->option == DHO_RENEWALTIME ||
|
(opt->option == DHO_RENEWALTIME ||
|
||||||
opt->option == DHO_REBINDTIME))
|
opt->option == DHO_REBINDTIME))
|
||||||
continue;
|
continue;
|
||||||
|
len = (p - m) + 2;
|
||||||
|
if (len > sizeof(*dhcp))
|
||||||
|
goto toobig;
|
||||||
*p++ = opt->option;
|
*p++ = opt->option;
|
||||||
}
|
}
|
||||||
*n_params = p - n_params - 1;
|
*n_params = p - n_params - 1;
|
||||||
@ -1063,6 +931,11 @@ make_message(struct dhcp_message **message,
|
|||||||
|
|
||||||
*message = dhcp;
|
*message = dhcp;
|
||||||
return p - m;
|
return p - m;
|
||||||
|
|
||||||
|
toobig:
|
||||||
|
syslog(LOG_ERR, "%s: DHCP messge too big", iface->name);
|
||||||
|
free(dhcp);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
@ -1138,6 +1011,53 @@ read_lease(const struct interface *ifp)
|
|||||||
return dhcp;
|
return dhcp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct dhcp_opt *
|
||||||
|
dhcp_getoverride(const struct if_options *ifo, uint16_t o)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
const struct dhcp_opt *opt;
|
||||||
|
|
||||||
|
for (i = 0, opt = ifo->dhcp_override;
|
||||||
|
i < ifo->dhcp_override_len;
|
||||||
|
i++, opt++)
|
||||||
|
{
|
||||||
|
if (opt->option == o)
|
||||||
|
return opt;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const uint8_t *
|
||||||
|
dhcp_getoption(unsigned int *os, unsigned int *code, unsigned int *len,
|
||||||
|
const uint8_t *od, unsigned int ol, struct dhcp_opt **oopt)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
struct dhcp_opt *opt;
|
||||||
|
|
||||||
|
if (od) {
|
||||||
|
if (ol < 2) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
*os = 2; /* code + len */
|
||||||
|
*code = (int)*od++;
|
||||||
|
*len = (int)*od++;
|
||||||
|
if (*len > ol) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0, opt = dhcp_opts; i < dhcp_opts_len; i++, opt++) {
|
||||||
|
if (opt->option == *code) {
|
||||||
|
*oopt = opt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return od;
|
||||||
|
}
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
dhcp_env(char **env, const char *prefix, const struct dhcp_message *dhcp,
|
dhcp_env(char **env, const char *prefix, const struct dhcp_message *dhcp,
|
||||||
const struct interface *ifp)
|
const struct interface *ifp)
|
||||||
@ -1148,31 +1068,50 @@ dhcp_env(char **env, const char *prefix, const struct dhcp_message *dhcp,
|
|||||||
struct in_addr addr;
|
struct in_addr addr;
|
||||||
struct in_addr net;
|
struct in_addr net;
|
||||||
struct in_addr brd;
|
struct in_addr brd;
|
||||||
char *val, *v;
|
struct dhcp_opt *opt, *vo;
|
||||||
const struct dhcp_opt *opt;
|
ssize_t e = 0;
|
||||||
ssize_t len, e = 0;
|
|
||||||
char **ep;
|
char **ep;
|
||||||
char cidr[4];
|
char cidr[4];
|
||||||
uint8_t overl = 0;
|
uint8_t overl = 0;
|
||||||
|
size_t i;
|
||||||
|
uint32_t en;
|
||||||
|
|
||||||
ifo = ifp->options;
|
ifo = ifp->options;
|
||||||
get_option_uint8(&overl, dhcp, DHO_OPTIONSOVERLOADED);
|
get_option_uint8(&overl, dhcp, DHO_OPTIONSOVERLOADED);
|
||||||
|
|
||||||
if (!env) {
|
if (!env) {
|
||||||
for (opt = dhcp_opts; opt->option; opt++) {
|
|
||||||
if (!opt->var)
|
|
||||||
continue;
|
|
||||||
if (has_option_mask(ifo->nomask, opt->option))
|
|
||||||
continue;
|
|
||||||
if (get_option_raw(dhcp, opt->option))
|
|
||||||
e++;
|
|
||||||
}
|
|
||||||
if (dhcp->yiaddr || dhcp->ciaddr)
|
if (dhcp->yiaddr || dhcp->ciaddr)
|
||||||
e += 5;
|
e += 5;
|
||||||
if (*dhcp->bootfile && !(overl & 1))
|
if (*dhcp->bootfile && !(overl & 1))
|
||||||
e++;
|
e++;
|
||||||
if (*dhcp->servername && !(overl & 2))
|
if (*dhcp->servername && !(overl & 2))
|
||||||
e++;
|
e++;
|
||||||
|
for (i = 0, opt = dhcp_opts;
|
||||||
|
i < dhcp_opts_len;
|
||||||
|
i++, opt++)
|
||||||
|
{
|
||||||
|
if (has_option_mask(ifo->nomask, opt->option))
|
||||||
|
continue;
|
||||||
|
if (dhcp_getoverride(ifo, opt->option))
|
||||||
|
continue;
|
||||||
|
p = get_option(dhcp, opt->option, &pl);
|
||||||
|
if (!p)
|
||||||
|
continue;
|
||||||
|
e += dhcp_envoption(NULL, NULL, ifp->name,
|
||||||
|
opt, dhcp_getoption, p, pl);
|
||||||
|
}
|
||||||
|
for (i = 0, opt = ifo->dhcp_override;
|
||||||
|
i < ifo->dhcp_override_len;
|
||||||
|
i++, opt++)
|
||||||
|
{
|
||||||
|
if (has_option_mask(ifo->nomask, opt->option))
|
||||||
|
continue;
|
||||||
|
p = get_option(dhcp, opt->option, &pl);
|
||||||
|
if (!p)
|
||||||
|
continue;
|
||||||
|
e += dhcp_envoption(NULL, NULL, ifp->name,
|
||||||
|
opt, dhcp_getoption, p, pl);
|
||||||
|
}
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1190,7 +1129,8 @@ dhcp_env(char **env, const char *prefix, const struct dhcp_message *dhcp,
|
|||||||
setvar(&ep, prefix, "subnet_cidr", cidr);
|
setvar(&ep, prefix, "subnet_cidr", cidr);
|
||||||
if (get_option_addr(&brd, dhcp, DHO_BROADCAST) == -1) {
|
if (get_option_addr(&brd, dhcp, DHO_BROADCAST) == -1) {
|
||||||
brd.s_addr = addr.s_addr | ~net.s_addr;
|
brd.s_addr = addr.s_addr | ~net.s_addr;
|
||||||
setvar(&ep, prefix, "broadcast_address", inet_ntoa(brd));
|
setvar(&ep, prefix, "broadcast_address",
|
||||||
|
inet_ntoa(brd));
|
||||||
}
|
}
|
||||||
addr.s_addr = dhcp->yiaddr & net.s_addr;
|
addr.s_addr = dhcp->yiaddr & net.s_addr;
|
||||||
setvar(&ep, prefix, "network_number", inet_ntoa(addr));
|
setvar(&ep, prefix, "network_number", inet_ntoa(addr));
|
||||||
@ -1199,32 +1139,59 @@ dhcp_env(char **env, const char *prefix, const struct dhcp_message *dhcp,
|
|||||||
if (*dhcp->bootfile && !(overl & 1))
|
if (*dhcp->bootfile && !(overl & 1))
|
||||||
setvar(&ep, prefix, "filename", (const char *)dhcp->bootfile);
|
setvar(&ep, prefix, "filename", (const char *)dhcp->bootfile);
|
||||||
if (*dhcp->servername && !(overl & 2))
|
if (*dhcp->servername && !(overl & 2))
|
||||||
setvar(&ep, prefix, "server_name", (const char *)dhcp->servername);
|
setvar(&ep, prefix, "server_name",
|
||||||
|
(const char *)dhcp->servername);
|
||||||
|
|
||||||
for (opt = dhcp_opts; opt->option; opt++) {
|
/* Zero our indexes */
|
||||||
if (!opt->var)
|
if (env) {
|
||||||
continue;
|
for (i = 0, opt = dhcp_opts; i < dhcp_opts_len; i++, opt++)
|
||||||
|
dhcp_zero_index(opt);
|
||||||
|
for (i = 0, opt = ifp->options->dhcp_override;
|
||||||
|
i < ifp->options->dhcp_override_len;
|
||||||
|
i++, opt++)
|
||||||
|
dhcp_zero_index(opt);
|
||||||
|
for (i = 0, opt = vivso; i < vivso_len; i++, opt++)
|
||||||
|
dhcp_zero_index(opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0, opt = dhcp_opts;
|
||||||
|
i < dhcp_opts_len;
|
||||||
|
i++, opt++)
|
||||||
|
{
|
||||||
if (has_option_mask(ifo->nomask, opt->option))
|
if (has_option_mask(ifo->nomask, opt->option))
|
||||||
continue;
|
continue;
|
||||||
val = NULL;
|
if (dhcp_getoverride(ifo, opt->option))
|
||||||
p = get_option(dhcp, opt->option, &pl, NULL);
|
|
||||||
if (!p)
|
|
||||||
continue;
|
continue;
|
||||||
/* We only want the FQDN name */
|
if ((p = get_option(dhcp, opt->option, &pl))) {
|
||||||
if (opt->option == DHO_FQDN) {
|
ep += dhcp_envoption(ep, prefix, ifp->name,
|
||||||
p += 3;
|
opt, dhcp_getoption, p, pl);
|
||||||
pl -= 3;
|
if (opt->option == DHO_VIVSO &&
|
||||||
|
pl > (int)sizeof(uint32_t))
|
||||||
|
{
|
||||||
|
memcpy(&en, p, sizeof(en));
|
||||||
|
en = ntohl(en);
|
||||||
|
vo = vivso_find(en, ifp);
|
||||||
|
if (vo) {
|
||||||
|
/* Skip over en + total size */
|
||||||
|
p += sizeof(en) + 1;
|
||||||
|
pl -= sizeof(en) + 1;
|
||||||
|
ep += dhcp_envoption(ep, prefix,
|
||||||
|
ifp->name,
|
||||||
|
vo, dhcp_getoption, p, pl);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
len = print_option(NULL, 0, opt->type, pl, p, ifp->name);
|
}
|
||||||
if (len < 0)
|
|
||||||
return -1;
|
for (i = 0, opt = ifo->dhcp_override;
|
||||||
e = strlen(prefix) + strlen(opt->var) + len + 4;
|
i < ifo->dhcp_override_len;
|
||||||
v = val = *ep++ = malloc(e);
|
i++, opt++)
|
||||||
if (v == NULL)
|
{
|
||||||
return -1;
|
if (has_option_mask(ifo->nomask, opt->option))
|
||||||
v += snprintf(val, e, "%s_%s=", prefix, opt->var);
|
continue;
|
||||||
if (len != 0)
|
if ((p = get_option(dhcp, opt->option, &pl)))
|
||||||
print_option(v, len, opt->type, pl, p, ifp->name);
|
ep += dhcp_envoption(ep, prefix, ifp->name,
|
||||||
|
opt, dhcp_getoption, p, pl);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ep - env;
|
return ep - env;
|
||||||
@ -1643,20 +1610,13 @@ dhcp_expire(void *arg)
|
|||||||
struct interface *ifp = arg;
|
struct interface *ifp = arg;
|
||||||
struct dhcp_state *state = D_STATE(ifp);
|
struct dhcp_state *state = D_STATE(ifp);
|
||||||
|
|
||||||
state->interval = 0;
|
|
||||||
if (state->addr.s_addr == 0) {
|
|
||||||
/* We failed to reboot, so enter discovery. */
|
|
||||||
state->lease.addr.s_addr = 0;
|
|
||||||
dhcp_discover(ifp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
syslog(LOG_ERR, "%s: DHCP lease expired", ifp->name);
|
syslog(LOG_ERR, "%s: DHCP lease expired", ifp->name);
|
||||||
eloop_timeout_delete(NULL, ifp);
|
eloop_timeout_delete(NULL, ifp);
|
||||||
dhcp_drop(ifp, "EXPIRE");
|
dhcp_drop(ifp, "EXPIRE");
|
||||||
unlink(state->leasefile);
|
unlink(state->leasefile);
|
||||||
if (ifp->carrier != LINK_DOWN)
|
|
||||||
start_interface(ifp);
|
state->interval = 0;
|
||||||
|
dhcp_discover(ifp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2100,7 +2060,7 @@ whitelisted_ip(const struct if_options *ifo, in_addr_t addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dhcp_handle(struct interface *iface, struct dhcp_message **dhcpp,
|
dhcp_handledhcp(struct interface *iface, struct dhcp_message **dhcpp,
|
||||||
const struct in_addr *from)
|
const struct in_addr *from)
|
||||||
{
|
{
|
||||||
struct dhcp_state *state = D_STATE(iface);
|
struct dhcp_state *state = D_STATE(iface);
|
||||||
@ -2134,7 +2094,7 @@ dhcp_handle(struct interface *iface, struct dhcp_message **dhcpp,
|
|||||||
}
|
}
|
||||||
dhcp_close(iface);
|
dhcp_close(iface);
|
||||||
/* If we constantly get NAKS then we should slowly back off */
|
/* If we constantly get NAKS then we should slowly back off */
|
||||||
eloop_timeout_add_sec(state->nakoff, start_interface, iface);
|
eloop_timeout_add_sec(state->nakoff, dhcp_discover, iface);
|
||||||
if (state->nakoff == 0)
|
if (state->nakoff == 0)
|
||||||
state->nakoff = 1;
|
state->nakoff = 1;
|
||||||
else {
|
else {
|
||||||
@ -2169,9 +2129,6 @@ dhcp_handle(struct interface *iface, struct dhcp_message **dhcpp,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No NAK, so reset the backoff */
|
|
||||||
state->nakoff = 0;
|
|
||||||
|
|
||||||
if ((type == 0 || type == DHCP_OFFER) &&
|
if ((type == 0 || type == DHCP_OFFER) &&
|
||||||
state->state == DHS_DISCOVER)
|
state->state == DHS_DISCOVER)
|
||||||
{
|
{
|
||||||
@ -2228,6 +2185,12 @@ dhcp_handle(struct interface *iface, struct dhcp_message **dhcpp,
|
|||||||
ifo->options &= ~DHCPCD_STATIC;
|
ifo->options &= ~DHCPCD_STATIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* No NAK, so reset the backoff
|
||||||
|
* We don't reset on an OFFER message because the server could
|
||||||
|
* potentially NAK the REQUEST. */
|
||||||
|
state->nakoff = 0;
|
||||||
|
|
||||||
/* BOOTP could have already assigned this above, so check we still
|
/* BOOTP could have already assigned this above, so check we still
|
||||||
* have a pointer. */
|
* have a pointer. */
|
||||||
if (*dhcpp) {
|
if (*dhcpp) {
|
||||||
@ -2338,14 +2301,6 @@ dhcp_handlepacket(void *arg)
|
|||||||
/* We loop through until our buffer is empty.
|
/* We loop through until our buffer is empty.
|
||||||
* The benefit is that if we get >1 DHCP packet in our buffer and
|
* The benefit is that if we get >1 DHCP packet in our buffer and
|
||||||
* the first one fails for any reason, we can use the next. */
|
* the first one fails for any reason, we can use the next. */
|
||||||
if (packet == NULL) {
|
|
||||||
packet = malloc(udp_dhcp_len);
|
|
||||||
if (packet == NULL) {
|
|
||||||
syslog(LOG_ERR, "%s: %m", __func__);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
bytes = ipv4_getrawpacket(iface, ETHERTYPE_IP,
|
bytes = ipv4_getrawpacket(iface, ETHERTYPE_IP,
|
||||||
packet, udp_dhcp_len, &partialcsum);
|
packet, udp_dhcp_len, &partialcsum);
|
||||||
@ -2414,24 +2369,33 @@ dhcp_handlepacket(void *arg)
|
|||||||
hwaddr_ntoa(dhcp->chaddr, sizeof(dhcp->chaddr)));
|
hwaddr_ntoa(dhcp->chaddr, sizeof(dhcp->chaddr)));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
dhcp_handle(iface, &dhcp, &from);
|
dhcp_handledhcp(iface, &dhcp, &from);
|
||||||
if (state->raw_fd == -1)
|
if (state->raw_fd == -1)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
free(packet);
|
|
||||||
packet = NULL;
|
|
||||||
free(dhcp);
|
free(dhcp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dhcp_open(struct interface *ifp)
|
dhcp_open(struct interface *ifp)
|
||||||
{
|
{
|
||||||
int r = 0;
|
|
||||||
struct dhcp_state *state;
|
struct dhcp_state *state;
|
||||||
|
|
||||||
|
if (packet == NULL) {
|
||||||
|
packet = malloc(udp_dhcp_len);
|
||||||
|
if (packet == NULL) {
|
||||||
|
syslog(LOG_ERR, "%s: %m", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#ifdef DEBUG_MEMORY
|
||||||
|
atexit(dhcp_cleanup);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
state = D_STATE(ifp);
|
state = D_STATE(ifp);
|
||||||
if (state->raw_fd == -1) {
|
if (state->raw_fd == -1) {
|
||||||
if ((r = ipv4_opensocket(ifp, ETHERTYPE_IP)) == -1) {
|
state->raw_fd = ipv4_opensocket(ifp, ETHERTYPE_IP);
|
||||||
|
if (state->raw_fd == -1) {
|
||||||
syslog(LOG_ERR, "%s: %s: %m", __func__, ifp->name);
|
syslog(LOG_ERR, "%s: %s: %m", __func__, ifp->name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -2515,8 +2479,7 @@ dhcp_init(struct interface *ifp)
|
|||||||
{
|
{
|
||||||
struct dhcp_state *state;
|
struct dhcp_state *state;
|
||||||
const struct if_options *ifo;
|
const struct if_options *ifo;
|
||||||
unsigned char *duid;
|
size_t len;
|
||||||
size_t len, ifl;
|
|
||||||
|
|
||||||
state = D_STATE(ifp);
|
state = D_STATE(ifp);
|
||||||
if (state == NULL) {
|
if (state == NULL) {
|
||||||
@ -2549,33 +2512,15 @@ dhcp_init(struct interface *ifp)
|
|||||||
goto eexit;
|
goto eexit;
|
||||||
memcpy(state->clientid, ifo->clientid, ifo->clientid[0] + 1);
|
memcpy(state->clientid, ifo->clientid, ifo->clientid[0] + 1);
|
||||||
} else if (ifo->options & DHCPCD_CLIENTID) {
|
} else if (ifo->options & DHCPCD_CLIENTID) {
|
||||||
len = 0;
|
|
||||||
if (ifo->options & DHCPCD_DUID) {
|
if (ifo->options & DHCPCD_DUID) {
|
||||||
duid = malloc(DUID_LEN);
|
state->clientid = malloc(duid_len + 6);
|
||||||
if (duid == NULL)
|
|
||||||
goto eexit;
|
|
||||||
if ((len = get_duid(duid, ifp)) == 0)
|
|
||||||
syslog(LOG_ERR, "get_duid: %m");
|
|
||||||
} else
|
|
||||||
duid = NULL;
|
|
||||||
if (len > 0) {
|
|
||||||
state->clientid = malloc(len + 6);
|
|
||||||
if (state->clientid == NULL)
|
if (state->clientid == NULL)
|
||||||
goto eexit;
|
goto eexit;
|
||||||
state->clientid[0] = len + 5;
|
state->clientid[0] = duid_len + 5;
|
||||||
state->clientid[1] = 255; /* RFC 4361 */
|
state->clientid[1] = 255; /* RFC 4361 */
|
||||||
ifl = strlen(ifp->name);
|
memcpy(state->clientid + 2, ifo->iaid, 4);
|
||||||
if (ifl < 5) {
|
memcpy(state->clientid + 6, duid, duid_len);
|
||||||
memcpy(state->clientid + 2, ifp->name, ifl);
|
} else {
|
||||||
if (ifl < 4)
|
|
||||||
memset(state->clientid + 2 + ifl,
|
|
||||||
0, 4 - ifl);
|
|
||||||
} else {
|
|
||||||
ifl = htonl(ifp->index);
|
|
||||||
memcpy(state->clientid + 2, &ifl, 4);
|
|
||||||
}
|
|
||||||
memcpy(state->clientid + 6, duid, len);
|
|
||||||
} else if (len == 0) {
|
|
||||||
len = ifp->hwlen + 1;
|
len = ifp->hwlen + 1;
|
||||||
state->clientid = malloc(len + 1);
|
state->clientid = malloc(len + 1);
|
||||||
if (state->clientid == NULL)
|
if (state->clientid == NULL)
|
||||||
@ -2585,8 +2530,13 @@ dhcp_init(struct interface *ifp)
|
|||||||
memcpy(state->clientid + 2, ifp->hwaddr,
|
memcpy(state->clientid + 2, ifp->hwaddr,
|
||||||
ifp->hwlen);
|
ifp->hwlen);
|
||||||
}
|
}
|
||||||
free(duid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ifo->options & DHCPCD_DUID)
|
||||||
|
/* Don't bother logging as DUID and IAID are reported
|
||||||
|
* at device start. */
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (ifo->options & DHCPCD_CLIENTID)
|
if (ifo->options & DHCPCD_CLIENTID)
|
||||||
syslog(LOG_DEBUG, "%s: using ClientID %s", ifp->name,
|
syslog(LOG_DEBUG, "%s: using ClientID %s", ifp->name,
|
||||||
hwaddr_ntoa(state->clientid + 1, state->clientid[0]));
|
hwaddr_ntoa(state->clientid + 1, state->clientid[0]));
|
||||||
|
23
external/bsd/dhcpcd/dist/dhcpcd.8.in
vendored
23
external/bsd/dhcpcd/dist/dhcpcd.8.in
vendored
@ -1,4 +1,4 @@
|
|||||||
.\" $NetBSD: dhcpcd.8.in,v 1.23 2013/09/20 21:40:56 wiz Exp $
|
.\" $NetBSD: dhcpcd.8.in,v 1.24 2014/01/03 22:24:41 roy Exp $
|
||||||
.\" Copyright (c) 2006-2013 Roy Marples
|
.\" Copyright (c) 2006-2013 Roy Marples
|
||||||
.\" All rights reserved
|
.\" All rights reserved
|
||||||
.\"
|
.\"
|
||||||
@ -23,7 +23,7 @@
|
|||||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
.\" SUCH DAMAGE.
|
.\" SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.Dd September 12, 2013
|
.Dd December 6, 2013
|
||||||
.Dt DHCPCD 8
|
.Dt DHCPCD 8
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -126,6 +126,8 @@ is also an implemenation of the DHCPv6 client as specified in
|
|||||||
By default,
|
By default,
|
||||||
.Nm
|
.Nm
|
||||||
only starts DHCPv6 when instructed to do so by an IPV6 Router Advertisement.
|
only starts DHCPv6 when instructed to do so by an IPV6 Router Advertisement.
|
||||||
|
If no Identity Association is configured,
|
||||||
|
then a Non-temporary Address is requested.
|
||||||
.Ss Local Link configuration
|
.Ss Local Link configuration
|
||||||
If
|
If
|
||||||
.Nm
|
.Nm
|
||||||
@ -408,6 +410,17 @@ A setting of 0
|
|||||||
causes
|
causes
|
||||||
.Nm
|
.Nm
|
||||||
to wait forever to get a lease.
|
to wait forever to get a lease.
|
||||||
|
If
|
||||||
|
.Nm
|
||||||
|
is working on a single interface then
|
||||||
|
.Nm
|
||||||
|
will exit when a timeout occurs, otherwise
|
||||||
|
.Nm
|
||||||
|
will fork into the background.
|
||||||
|
If using IPv4LL then
|
||||||
|
.Nm
|
||||||
|
start the IPv4LL process after the timeout and then wait a little longer
|
||||||
|
before really timing out.
|
||||||
.It Fl u , Fl Fl userclass Ar class
|
.It Fl u , Fl Fl userclass Ar class
|
||||||
Tags the DHCP message with the userclass
|
Tags the DHCP message with the userclass
|
||||||
.Ar class .
|
.Ar class .
|
||||||
@ -636,9 +649,9 @@ running on the
|
|||||||
.Xr resolvconf 8
|
.Xr resolvconf 8
|
||||||
.Sh STANDARDS
|
.Sh STANDARDS
|
||||||
RFC\ 951 RFC\ 1534 RFC\ 2131, RFC\ 2132, RFC\ 2855, RFC\ 3004, RFC\ 3315,
|
RFC\ 951 RFC\ 1534 RFC\ 2131, RFC\ 2132, RFC\ 2855, RFC\ 3004, RFC\ 3315,
|
||||||
RFC\ 3361, RFC\ 3633, RFC\ 3396, RFC\ 3397, RFC\ 3442, RFC\ 3927, RFC\ 4039
|
RFC\ 3361, RFC\ 3633, RFC\ 3396, RFC\ 3397, RFC\ 3442, RFC\ 3925, RFC\ 3927,
|
||||||
RFC\ 4075, RFC\ 4361, RFC\ 4390, RFC\ 4702, RFC\ 4704, RFC\ 4861, RFC\ 4833,
|
RFC\ 4039, RFC\ 4075, RFC\ 4242, RFC\ 4361, RFC\ 4390, RFC\ 4702, RFC\ 4704,
|
||||||
RFC\ 5227, RFC\ 5942, RFC\ 5969, RFC\ 6106.
|
RFC\ 4861, RFC\ 4833, RFC\ 5227, RFC\ 5942, RFC\ 5969, RFC\ 6106.
|
||||||
.Sh AUTHORS
|
.Sh AUTHORS
|
||||||
.An Roy Marples Aq Mt roy@marples.name
|
.An Roy Marples Aq Mt roy@marples.name
|
||||||
.Sh BUGS
|
.Sh BUGS
|
||||||
|
201
external/bsd/dhcpcd/dist/dhcpcd.conf.5.in
vendored
201
external/bsd/dhcpcd/dist/dhcpcd.conf.5.in
vendored
@ -1,4 +1,4 @@
|
|||||||
.\" $NetBSD: dhcpcd.conf.5.in,v 1.5 2013/09/20 21:39:59 wiz Exp $
|
.\" $NetBSD: dhcpcd.conf.5.in,v 1.6 2014/01/03 22:24:41 roy Exp $
|
||||||
.\" Copyright (c) 2006-2013 Roy Marples
|
.\" Copyright (c) 2006-2013 Roy Marples
|
||||||
.\" All rights reserved
|
.\" All rights reserved
|
||||||
.\"
|
.\"
|
||||||
@ -23,7 +23,7 @@
|
|||||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
.\" SUCH DAMAGE.
|
.\" SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.Dd September 12, 2013
|
.Dd December 6, 2013
|
||||||
.Dt DHCPCD.CONF 5
|
.Dt DHCPCD.CONF 5
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -136,12 +136,24 @@ Generate an
|
|||||||
.Rs
|
.Rs
|
||||||
.%T "RFC 4361"
|
.%T "RFC 4361"
|
||||||
.Re
|
.Re
|
||||||
compliant clientid.
|
compliant DHCP Unique Identifier.
|
||||||
If persistent storage is available then a DUID-LLT (link local address + time)
|
If persistent storage is available then a DUID-LLT (link local address + time)
|
||||||
is generated, otherwise DUID-LL is generated (link local address).
|
is generated, otherwise DUID-LL is generated (link local address).
|
||||||
|
This, plus the IAID will be used as the
|
||||||
|
.Ic clientid .
|
||||||
The DUID-LLT generated will be held in
|
The DUID-LLT generated will be held in
|
||||||
.Pa @SYSCONFDIR@/dhcpcd.duid
|
.Pa @SYSCONFDIR@/dhcpcd.duid
|
||||||
and should not be copied to other hosts.
|
and should not be copied to other hosts.
|
||||||
|
.It Ic iaid Ar iaid
|
||||||
|
Set the Interface Association Identifier to
|
||||||
|
.Ar iaid .
|
||||||
|
This defaults to the last 4 bytes of the hardware address assigned to the
|
||||||
|
interface.
|
||||||
|
Each instance of this should be unique within the scope of the client and
|
||||||
|
.Nm dhcpcd
|
||||||
|
warns if a conflict is detected.
|
||||||
|
If there is a conflict, it is only a problem if the conflicted IAIDs are
|
||||||
|
used on the same network.
|
||||||
.It Ic persistent
|
.It Ic persistent
|
||||||
.Nm dhcpcd
|
.Nm dhcpcd
|
||||||
normally de-configures the interface and configuration when it exits.
|
normally de-configures the interface and configuration when it exits.
|
||||||
@ -173,16 +185,19 @@ option above to control how the hostname is set on the host.
|
|||||||
.It Ic ia_na Op Ar iaid
|
.It Ic ia_na Op Ar iaid
|
||||||
Request a DHCPv6 Normal Address for
|
Request a DHCPv6 Normal Address for
|
||||||
.Ar iaid .
|
.Ar iaid .
|
||||||
If none is specified, a default
|
|
||||||
.Ar iaid
|
.Ar iaid
|
||||||
is used.
|
defaults to the
|
||||||
If the interface name is 4 characters or less then that is used,
|
.Ic iaid
|
||||||
otherwise the interface index is used.
|
option as described above.
|
||||||
You can request more than one ia_na by specifying a unique iaid for each one.
|
You can request more than one ia_na by specifying a unique
|
||||||
|
.Ar iaid
|
||||||
|
for each one.
|
||||||
.It Ic ia_ta Op Ar iaid
|
.It Ic ia_ta Op Ar iaid
|
||||||
Request a DHCPv6 Temporary Address for
|
Request a DHCPv6 Temporary Address for
|
||||||
.Ar iaid .
|
.Ar iaid .
|
||||||
You can request more than one ia_ta by specifying a unique iaid for each one.
|
You can request more than one ia_ta by specifying a unique
|
||||||
|
.Ar iaid
|
||||||
|
for each one.
|
||||||
.It Ic ia_pd Op Ar iaid Op Ar interface Op / Ar sla_id Op / Ar prefix_len
|
.It Ic ia_pd Op Ar iaid Op Ar interface Op / Ar sla_id Op / Ar prefix_len
|
||||||
Request a DHCPv6 Delegated Prefix for
|
Request a DHCPv6 Delegated Prefix for
|
||||||
.Ar iaid .
|
.Ar iaid .
|
||||||
@ -286,12 +301,16 @@ So to stop
|
|||||||
.Nm dhcpcd
|
.Nm dhcpcd
|
||||||
from touching your DNS or MTU settings you would do:-
|
from touching your DNS or MTU settings you would do:-
|
||||||
.D1 nohook resolv.conf, mtu
|
.D1 nohook resolv.conf, mtu
|
||||||
|
.It Ic noipv4
|
||||||
|
Don't attempt to configure an IPv4 address.
|
||||||
.It Ic noipv4ll
|
.It Ic noipv4ll
|
||||||
Don't attempt to obtain an IPv4LL address if we failed to get one via DHCP.
|
Don't attempt to obtain an IPv4LL address if we failed to get one via DHCP.
|
||||||
See
|
See
|
||||||
.Rs
|
.Rs
|
||||||
.%T "RFC 3927"
|
.%T "RFC 3927"
|
||||||
.Re
|
.Re
|
||||||
|
.It Ic noipv6
|
||||||
|
Don't attmept to configure an IPv6 address.
|
||||||
.It Ic noipv6rs
|
.It Ic noipv6rs
|
||||||
Disable solicitation and receipt of IPv6 Router Advertisements.
|
Disable solicitation and receipt of IPv6 Router Advertisements.
|
||||||
.It Ic nolink
|
.It Ic nolink
|
||||||
@ -389,13 +408,25 @@ into the value.
|
|||||||
.D1 static ip_address=
|
.D1 static ip_address=
|
||||||
.D1 destination routers
|
.D1 destination routers
|
||||||
.It Ic timeout Ar seconds
|
.It Ic timeout Ar seconds
|
||||||
The default timeout for waiting for a DHCP response is 30 seconds which may
|
Timeout after
|
||||||
be too long or too short and can be changed here.
|
.Ar seconds ,
|
||||||
|
instead of the default 30.
|
||||||
A setting of 0
|
A setting of 0
|
||||||
.Ar seconds
|
.Ar seconds
|
||||||
causes
|
causes
|
||||||
.Nm dhcpcd
|
.Nm dhcpcd
|
||||||
to wait forever to get a lease.
|
to wait forever to get a lease.
|
||||||
|
If
|
||||||
|
.Nm dhcpcd
|
||||||
|
is working on a single interface then
|
||||||
|
.Nm dhcpcd
|
||||||
|
will exit when a timeout occurs, otherwise
|
||||||
|
.Nm dhcpcd
|
||||||
|
will fork into the background.
|
||||||
|
If using IPv4LL then
|
||||||
|
.Nm dhcpcd
|
||||||
|
start the IPv4LL process after the timeout and then wait a little longer
|
||||||
|
before really timing out.
|
||||||
.It Ic userclass Ar string
|
.It Ic userclass Ar string
|
||||||
Tag the DHCP messages with the userclass.
|
Tag the DHCP messages with the userclass.
|
||||||
You can specify more than one.
|
You can specify more than one.
|
||||||
@ -424,6 +455,16 @@ For example
|
|||||||
If not set then none is sent.
|
If not set then none is sent.
|
||||||
Some badly configured DHCP servers reject unknown vendorclassids.
|
Some badly configured DHCP servers reject unknown vendorclassids.
|
||||||
To work around it, try and impersonate Windows by using the MSFT vendorclassid.
|
To work around it, try and impersonate Windows by using the MSFT vendorclassid.
|
||||||
|
.It Ic vendclass Ar en Ar data
|
||||||
|
Add the Vendor Indetifying Vendor Class with the IANA assigned Enterprise
|
||||||
|
Number
|
||||||
|
.Ar en
|
||||||
|
with the
|
||||||
|
.Ar data .
|
||||||
|
This option can be set more than once to add more data, but the behaviour,
|
||||||
|
as per
|
||||||
|
.Xr RFC 3925
|
||||||
|
is undefined if the Enterprise Number differs.
|
||||||
.It Ic waitip Op 4 | 6
|
.It Ic waitip Op 4 | 6
|
||||||
Wait for an address to be assigned before forking to the background.
|
Wait for an address to be assigned before forking to the background.
|
||||||
4 means wait for an IPv4 address to be assigned.
|
4 means wait for an IPv4 address to be assigned.
|
||||||
@ -438,6 +479,138 @@ will only fork to the background when all waiting conditions are satisfied.
|
|||||||
Use the last four bytes of the hardware address as the DHCP xid instead
|
Use the last four bytes of the hardware address as the DHCP xid instead
|
||||||
of a randomly generated number.
|
of a randomly generated number.
|
||||||
.El
|
.El
|
||||||
|
.Ss Defining new options
|
||||||
|
DHCP allows for the use of custom options.
|
||||||
|
Each option needs to be started with the
|
||||||
|
.Ic define
|
||||||
|
or
|
||||||
|
.Ic define6
|
||||||
|
directive.
|
||||||
|
This can optionally be followed by both
|
||||||
|
.Ic embed
|
||||||
|
or
|
||||||
|
.Ic encap
|
||||||
|
options.
|
||||||
|
Both can be specified more than once and
|
||||||
|
.Ic embed
|
||||||
|
must come before
|
||||||
|
.Ic encap .
|
||||||
|
.Bl -tag -width indent
|
||||||
|
.It Ic define Ar code Ar type Ar variable
|
||||||
|
Defines the DHCP option
|
||||||
|
.Ar code
|
||||||
|
of
|
||||||
|
.Ar type
|
||||||
|
with a name of
|
||||||
|
.Ar variable
|
||||||
|
exported to
|
||||||
|
.Xr dhcpcd-run-hooks 8 .
|
||||||
|
.It Ic define6 Ar code Ar type Ar variable
|
||||||
|
Defines the DHCPv6 option
|
||||||
|
.Ar code
|
||||||
|
of
|
||||||
|
.Ar type
|
||||||
|
with a name of
|
||||||
|
.Ar variable
|
||||||
|
exported to
|
||||||
|
.Xr dhcpcd-run-hooks 8 ,
|
||||||
|
with a prefix of
|
||||||
|
.Va _dhcp6 .
|
||||||
|
.It Ic vendopt Ar code Ar type Ar variable
|
||||||
|
Defines the Vendor-Identifying Vendor Options.
|
||||||
|
The
|
||||||
|
.Ar code
|
||||||
|
is the IANA Enterprise Number which will unqiuely describe the encapsulated
|
||||||
|
options.
|
||||||
|
.Ar type
|
||||||
|
is normally
|
||||||
|
.Ar encap .
|
||||||
|
.Ar variable
|
||||||
|
names the Vendor option to be exported.
|
||||||
|
.It Ic embed Ar type Ar variable
|
||||||
|
Defines an embedded variable within the defined option.
|
||||||
|
The length is determined by the
|
||||||
|
.Ar type .
|
||||||
|
If the
|
||||||
|
.Ar variable
|
||||||
|
is not the same as defined in the parent option,
|
||||||
|
it is prefixed with the parent
|
||||||
|
.Ar variable
|
||||||
|
first with an underscore.
|
||||||
|
.It Ic encap Ar code Ar type Ar variable
|
||||||
|
Defines an encapsulated variable within the defined option.
|
||||||
|
The length is determined by the
|
||||||
|
.Ar type .
|
||||||
|
If the
|
||||||
|
.Ar variable
|
||||||
|
is not the same as defined in the parent option,
|
||||||
|
it is prefixed with the parent
|
||||||
|
.Ar variable
|
||||||
|
first with an underscore.
|
||||||
|
.El
|
||||||
|
.Ss Type prefix
|
||||||
|
These keywords come before the type itself, to describe it more fully.
|
||||||
|
You can use more than one, but they must appear in the order listed below.
|
||||||
|
.Bl -tag -width -indent
|
||||||
|
.It Ic request
|
||||||
|
Requests the option by default without having to be specified in user
|
||||||
|
configuration
|
||||||
|
.It Ic norequest
|
||||||
|
This option cannot be requested, regardless of user configuration
|
||||||
|
.It Ic index
|
||||||
|
The option can appear more than once and will be indexed.
|
||||||
|
.It Ic array
|
||||||
|
The option data is split into a space seperated array, each element being
|
||||||
|
the same type.
|
||||||
|
.El
|
||||||
|
.Ss Types to define
|
||||||
|
The type directly affects the length of data consumed inside the option.
|
||||||
|
Any remaining data is normally discarded.
|
||||||
|
Lengths can be specified for string and binhex types, but this is generally
|
||||||
|
with other data embedded afterwards in the same option.
|
||||||
|
.Bl -tag -width indent
|
||||||
|
.It Ic ipaddress
|
||||||
|
An IPv4 address, 4 bytes
|
||||||
|
.It Ic ip6address
|
||||||
|
An IPv6 address, 16 bytes
|
||||||
|
.It Ic string Op : Ic length
|
||||||
|
A shell escaped string (binary data escaped as octal)
|
||||||
|
.It Ic byte
|
||||||
|
A byte
|
||||||
|
.It Ic int16
|
||||||
|
A signed 16bit integer, 2 bytes
|
||||||
|
.It Ic uint16
|
||||||
|
An unsigned 16bit integer, 2 bytes
|
||||||
|
.It Ic int32
|
||||||
|
A signed 32bit integer, 4 bytes
|
||||||
|
.It Ic uint32
|
||||||
|
An unsigned 32bit integer, 4 bytes
|
||||||
|
.It Ic flag
|
||||||
|
A fixed value (1) to indicate that the option is present, 0 bytes
|
||||||
|
.It Ic domain
|
||||||
|
A RFC 3397 encoded string
|
||||||
|
.It Ic binhex Op : Ic length
|
||||||
|
Binary data expressed as hexadecimal
|
||||||
|
.It Ic embed
|
||||||
|
Contains embedded options (implies encap as well)
|
||||||
|
.It Ic encap
|
||||||
|
Contains encapsulated options (implies embed as well)
|
||||||
|
.It Ic option
|
||||||
|
References an option from the global definition
|
||||||
|
.El
|
||||||
|
.Ss Example definition
|
||||||
|
.D1 # DHCP option 81, Fully Qualified Domain Name, RFC4702
|
||||||
|
.D1 define 81 embed fqdn
|
||||||
|
.D1 embed byte flags
|
||||||
|
.D1 embed byte rcode1
|
||||||
|
.D1 embed byte rcode2
|
||||||
|
.D1 embed domain fqdn
|
||||||
|
.Pp
|
||||||
|
.D1 # DHCP option 125, Vendor Specific Information Option, RFC3925
|
||||||
|
.D1 define 125 encap vsio
|
||||||
|
.D1 embed uint32 enterprise_number
|
||||||
|
.D1 # Options defined for the enterprise number
|
||||||
|
.D1 encap 1 ipaddress ipaddress
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr fnmatch 3 ,
|
.Xr fnmatch 3 ,
|
||||||
.Xr if_nametoindex 3 ,
|
.Xr if_nametoindex 3 ,
|
||||||
@ -446,5 +619,11 @@ of a randomly generated number.
|
|||||||
.Sh AUTHORS
|
.Sh AUTHORS
|
||||||
.An Roy Marples Aq Mt roy@marples.name
|
.An Roy Marples Aq Mt roy@marples.name
|
||||||
.Sh BUGS
|
.Sh BUGS
|
||||||
|
When configuring DHCPv6 you can only select one IA type.
|
||||||
|
I can't think of a use case where you would want different types,
|
||||||
|
so if you have one then please bring it up for discussion on the
|
||||||
|
.Aq Mt dhcpcd-discuss@marples.name
|
||||||
|
mailing list.
|
||||||
|
.Pp
|
||||||
Please report them to
|
Please report them to
|
||||||
.Lk http://roy.marples.name/projects/dhcpcd
|
.Lk http://roy.marples.name/projects/dhcpcd
|
||||||
|
4
external/bsd/dhcpcd/dist/if-bsd.c
vendored
4
external/bsd/dhcpcd/dist/if-bsd.c
vendored
@ -1,5 +1,5 @@
|
|||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__RCSID("$NetBSD: if-bsd.c,v 1.2 2013/10/20 03:14:34 christos Exp $");
|
__RCSID("$NetBSD: if-bsd.c,v 1.3 2014/01/03 22:24:41 roy Exp $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dhcpcd - DHCP client daemon
|
* dhcpcd - DHCP client daemon
|
||||||
@ -385,7 +385,7 @@ if_route6(const struct rt6 *rt, int action)
|
|||||||
if (IN6_IS_ADDR_LINKLOCAL(&su.sin.sin6_addr)) { \
|
if (IN6_IS_ADDR_LINKLOCAL(&su.sin.sin6_addr)) { \
|
||||||
uint16_t scope = htons(su.sin.sin6_scope_id); \
|
uint16_t scope = htons(su.sin.sin6_scope_id); \
|
||||||
memcpy(&su.sin.sin6_addr.s6_addr[2], &scope, \
|
memcpy(&su.sin.sin6_addr.s6_addr[2], &scope, \
|
||||||
sizeof(scope)); \
|
sizeof(scope)); \
|
||||||
su.sin.sin6_scope_id = 0; \
|
su.sin.sin6_scope_id = 0; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
762
external/bsd/dhcpcd/dist/if-options.c
vendored
762
external/bsd/dhcpcd/dist/if-options.c
vendored
File diff suppressed because it is too large
Load Diff
39
external/bsd/dhcpcd/dist/ipv6nd.c
vendored
39
external/bsd/dhcpcd/dist/ipv6nd.c
vendored
@ -1,5 +1,5 @@
|
|||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__RCSID("$NetBSD: ipv6nd.c,v 1.2 2013/11/14 01:28:16 christos Exp $");
|
__RCSID("$NetBSD: ipv6nd.c,v 1.3 2014/01/03 22:24:41 roy Exp $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dhcpcd - DHCP client daemon
|
* dhcpcd - DHCP client daemon
|
||||||
@ -57,6 +57,11 @@
|
|||||||
#include "ipv6nd.h"
|
#include "ipv6nd.h"
|
||||||
#include "script.h"
|
#include "script.h"
|
||||||
|
|
||||||
|
#if defined(LISTEN_DAD) && defined(INET6)
|
||||||
|
# warning kernel does not report DAD results to userland
|
||||||
|
# warning listening to duplicated addresses on the wire
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Debugging Router Solicitations is a lot of spam, so disable it */
|
/* Debugging Router Solicitations is a lot of spam, so disable it */
|
||||||
//#define DEBUG_RS
|
//#define DEBUG_RS
|
||||||
|
|
||||||
@ -150,6 +155,34 @@ struct rahead ipv6_routers = TAILQ_HEAD_INITIALIZER(ipv6_routers);
|
|||||||
|
|
||||||
static void ipv6nd_handledata(void *arg);
|
static void ipv6nd_handledata(void *arg);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Android ships buggy ICMP6 filter headers.
|
||||||
|
* Supply our own until they fix their shit.
|
||||||
|
* References:
|
||||||
|
* https://android-review.googlesource.com/#/c/58438/
|
||||||
|
* http://code.google.com/p/android/issues/original?id=32621&seq=24
|
||||||
|
*/
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
#undef ICMP6_FILTER_WILLPASS
|
||||||
|
#undef ICMP6_FILTER_WILLBLOCK
|
||||||
|
#undef ICMP6_FILTER_SETPASS
|
||||||
|
#undef ICMP6_FILTER_SETBLOCK
|
||||||
|
#undef ICMP6_FILTER_SETPASSALL
|
||||||
|
#undef ICMP6_FILTER_SETBLOCKALL
|
||||||
|
#define ICMP6_FILTER_WILLPASS(type, filterp) \
|
||||||
|
((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) == 0)
|
||||||
|
#define ICMP6_FILTER_WILLBLOCK(type, filterp) \
|
||||||
|
((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) != 0)
|
||||||
|
#define ICMP6_FILTER_SETPASS(type, filterp) \
|
||||||
|
((((filterp)->icmp6_filt[(type) >> 5]) &= ~(1 << ((type) & 31))))
|
||||||
|
#define ICMP6_FILTER_SETBLOCK(type, filterp) \
|
||||||
|
((((filterp)->icmp6_filt[(type) >> 5]) |= (1 << ((type) & 31))))
|
||||||
|
#define ICMP6_FILTER_SETPASSALL(filterp) \
|
||||||
|
memset(filterp, 0, sizeof(struct icmp6_filter));
|
||||||
|
#define ICMP6_FILTER_SETBLOCKALL(filterp) \
|
||||||
|
memset(filterp, 0xff, sizeof(struct icmp6_filter));
|
||||||
|
#endif
|
||||||
|
|
||||||
#if DEBUG_MEMORY
|
#if DEBUG_MEMORY
|
||||||
static void
|
static void
|
||||||
ipv6nd_cleanup(void)
|
ipv6nd_cleanup(void)
|
||||||
@ -1464,9 +1497,7 @@ ipv6nd_probeaddrs(struct ipv6_addrhead *addrs)
|
|||||||
eloop_q_timeout_delete(0, NULL,
|
eloop_q_timeout_delete(0, NULL,
|
||||||
ap->dadcallback);
|
ap->dadcallback);
|
||||||
free(ap);
|
free(ap);
|
||||||
} else if (!IN6_IS_ADDR_UNSPECIFIED(&ap->addr) &&
|
} else if (!IN6_IS_ADDR_UNSPECIFIED(&ap->addr)) {
|
||||||
!(ap->flags & IPV6_AF_DELEGATED))
|
|
||||||
{
|
|
||||||
ipv6nd_probeaddr(ap);
|
ipv6nd_probeaddr(ap);
|
||||||
if (ap->flags & IPV6_AF_NEW)
|
if (ap->flags & IPV6_AF_NEW)
|
||||||
i++;
|
i++;
|
||||||
|
4
external/bsd/dhcpcd/dist/net.c
vendored
4
external/bsd/dhcpcd/dist/net.c
vendored
@ -1,5 +1,5 @@
|
|||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__RCSID("$NetBSD: net.c,v 1.3 2013/09/20 10:56:32 roy Exp $");
|
__RCSID("$NetBSD: net.c,v 1.4 2014/01/03 22:24:41 roy Exp $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dhcpcd - DHCP client daemon
|
* dhcpcd - DHCP client daemon
|
||||||
@ -233,6 +233,7 @@ discover_interfaces(int argc, char * const *argv)
|
|||||||
const struct sockaddr_in *addr;
|
const struct sockaddr_in *addr;
|
||||||
const struct sockaddr_in *net;
|
const struct sockaddr_in *net;
|
||||||
const struct sockaddr_in *dst;
|
const struct sockaddr_in *dst;
|
||||||
|
#endif
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
const struct sockaddr_in6 *sin6;
|
const struct sockaddr_in6 *sin6;
|
||||||
int ifa_flags;
|
int ifa_flags;
|
||||||
@ -490,7 +491,6 @@ discover_interfaces(int argc, char * const *argv)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
freeifaddrs(ifaddrs);
|
freeifaddrs(ifaddrs);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user