Use this as the default for DHCPv6 IA's as well.
Rename if_iaid to if_ia as it's really an IA containing an IAID.
{
struct dhcp_state *state;
const struct if_options *ifo;
- unsigned char *duid;
- size_t len, ifl;
+ size_t len;
state = D_STATE(ifp);
if (state == NULL) {
goto eexit;
memcpy(state->clientid, ifo->clientid, ifo->clientid[0] + 1);
} else if (ifo->options & DHCPCD_CLIENTID) {
- len = 0;
if (ifo->options & DHCPCD_DUID) {
- duid = malloc(DUID_LEN);
- 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);
+ state->clientid = malloc(duid_len + 6);
if (state->clientid == NULL)
goto eexit;
- state->clientid[0] = len + 5;
+ state->clientid[0] = duid_len + 5;
state->clientid[1] = 255; /* RFC 4361 */
- ifl = strlen(ifp->name);
- if (ifl < 5) {
- memcpy(state->clientid + 2, ifp->name, ifl);
- 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) {
+ memcpy(state->clientid + 2, ifo->iaid, 4);
+ memcpy(state->clientid + 6, duid, duid_len);
+ } else {
len = ifp->hwlen + 1;
state->clientid = malloc(len + 1);
if (state->clientid == NULL)
memcpy(state->clientid + 2, ifp->hwaddr,
ifp->hwlen);
}
- free(duid);
}
if (ifo->options & DHCPCD_CLIENTID)
syslog(LOG_DEBUG, "%s: using ClientID %s", ifp->name,
static struct iovec rcviov[2];
static unsigned char *rcvbuf;
static unsigned char ansbuf[1500];
-static unsigned char *duid;
-static uint16_t duid_len;
static char ntopbuf[INET6_ADDRSTRLEN];
static char *status;
static size_t status_len;
free(sndbuf);
free(rcvbuf);
- free(duid);
free(status);
}
#endif
/* FALLTHROUGH */
case DH6S_INIT: /* FALLTHROUGH */
case DH6S_DISCOVER:
- len += ifo->iaid_len * (sizeof(*o) + (sizeof(u32) * 3));
+ len += ifo->ia_len * (sizeof(*o) + (sizeof(u32) * 3));
IA = 1;
break;
default:
o->len = 0;
}
- for (l = 0; IA && l < ifo->iaid_len; l++) {
+ for (l = 0; IA && l < ifo->ia_len; l++) {
o = D6_NEXT_OPTION(o);
o->code = htons(ifo->ia_type);
o->len = htons(sizeof(u32) + sizeof(u32) + sizeof(u32));
p = D6_OPTION_DATA(o);
- memcpy(p, ifo->iaid[l].iaid, sizeof(u32));
+ memcpy(p, ifo->ia[l].iaid, sizeof(u32));
p += sizeof(u32);
memset(p, 0, sizeof(u32) + sizeof(u32));
TAILQ_FOREACH(ap, &state->addrs, next) {
if (ap->prefix_vltime == 0)
continue;
- if (memcmp(ifo->iaid[l].iaid, ap->iaid, sizeof(u32)))
+ if (memcmp(ifo->ia[l].iaid, ap->iaid, sizeof(u32)))
continue;
so = D6_NEXT_OPTION(o);
if (ifo->ia_type == D6_OPTION_IA_PD) {
struct dhcp6_state *state, *ifd_state;
struct ipv6_addr *ap;
size_t i, j, k;
- struct if_iaid *iaid;
+ struct if_ia *ia;
struct if_sla *sla;
struct interface *ifd;
uint8_t carrier_warned;
syslog(LOG_DEBUG, "%s: delegated prefix %s",
ifp->name, ap->saddr);
}
- for (i = 0; i < ifo->iaid_len; i++) {
- iaid = &ifo->iaid[i];
- if (memcmp(iaid->iaid, ap->iaid,
- sizeof(iaid->iaid)))
+ for (i = 0; i < ifo->ia_len; i++) {
+ ia = &ifo->ia[i];
+ if (memcmp(ia->iaid, ap->iaid,
+ sizeof(ia->iaid)))
continue;
- if (iaid->sla_len == 0) {
+ if (ia->sla_len == 0) {
/* no SLA configured, so lets
* automate it */
if (ifp == ifd)
NULL, ifp))
k++;
}
- for (j = 0; j < iaid->sla_len; j++) {
- sla = &iaid->sla[j];
+ for (j = 0; j < ia->sla_len; j++) {
+ sla = &ia->sla[j];
if (strcmp(ifd->name, sla->ifname))
continue;
if (ifd->carrier == LINK_DOWN) {
}
/* Warn about configured interfaces for delegation that do not exist */
- for (i = 0; i < ifo->iaid_len; i++) {
- iaid = &ifo->iaid[i];
- for (j = 0; j < iaid->sla_len; j++) {
- sla = &iaid->sla[j];
+ for (i = 0; i < ifo->ia_len; i++) {
+ ia = &ifo->ia[i];
+ for (j = 0; j < ia->sla_len; j++) {
+ sla = &ia->sla[j];
for (k = 0; k < i; j++)
- if (strcmp(sla->ifname, iaid->sla[j].ifname) == 0)
+ if (strcmp(sla->ifname, ia->sla[j].ifname) == 0)
break;
if (j >= i && find_interface(sla->ifname) == NULL)
syslog(LOG_ERR,
struct dhcp6_state *state;
struct ipv6_addr *ap;
size_t i, j, k;
- struct if_iaid *iaid;
+ struct if_ia *ia;
struct if_sla *sla;
struct interface *ifd;
if (state == NULL || state->state != DH6S_BOUND)
continue;
TAILQ_FOREACH(ap, &state->addrs, next) {
- for (i = 0; i < ifo->iaid_len; i++) {
- iaid = &ifo->iaid[i];
- if (memcmp(iaid->iaid, ap->iaid,
- sizeof(iaid->iaid)))
+ for (i = 0; i < ifo->ia_len; i++) {
+ ia = &ifo->ia[i];
+ if (memcmp(ia->iaid, ap->iaid,
+ sizeof(ia->iaid)))
continue;
- for (j = 0; j < iaid->sla_len; j++) {
- sla = &iaid->sla[j];
+ for (j = 0; j < ia->sla_len; j++) {
+ sla = &ia->sla[j];
if (strcmp(ifp->name, sla->ifname))
continue;
if (ipv6_linklocal(ifp) == NULL) {
if (sock == -1 && dhcp6_open() == -1)
return -1;
- if (duid == NULL) {
- duid = malloc(DUID_LEN);
- if (duid == NULL)
- return -1;
- duid_len = get_duid(duid, ifp);
- }
-
ifp->if_data[IF_DATA_DHCP6] = calloc(1, sizeof(*state));
state = D6_STATE(ifp);
if (state == NULL)
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd November 12, 2013
+.Dd November 15, 2013
.Dt DHCPCD 8
.Os
.Sh NAME
By default,
.Nm
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
If
.Nm
#include "dev.h"
#include "dhcpcd.h"
#include "dhcp6.h"
+#include "duid.h"
#include "eloop.h"
#include "if-options.h"
#include "if-pref.h"
struct interface *ifp;
int i;
+ free(duid);
free_options(if_options);
if (ifaces) {
{
struct if_options *ifo = ifp->options;
int ra_global, ra_iface;
-
+ uint32_t len;
/* Do any platform specific configuration */
if_conf(ifp);
if (ifo->metric != -1)
ifp->metric = ifo->metric;
+ if (!(ifo->options & DHCPCD_IPV6))
+ ifo->options &= ~DHCPCD_IPV6RS;
+
/* We want to disable kernel interface RA as early as possible. */
if (ifo->options & DHCPCD_IPV6RS) {
ra_global = check_ipv6(NULL, options & DHCPCD_IPV6RA_OWN ? 1:0);
ifo->options |= DHCPCD_CLIENTID | DHCPCD_BROADCAST;
break;
}
+
+ if (!(ifo->options & DHCPCD_IAID)) {
+ len = strlen(ifp->name);
+ if (len <= sizeof(ifo->iaid)) {
+ memcpy(ifo->iaid, ifp->name, len);
+ memset(ifo->iaid + len, 0, sizeof(ifo->iaid) - len);
+ } else {
+ /* IAID is the same size as a uint32_t */
+ len = htonl(ifp->index);
+ memcpy(ifo->iaid, &len, sizeof(len));
+ }
+ ifo->options |= DHCPCD_IAID;
+ }
+
+#ifdef INET6
+ if (ifo->ia == NULL && ifo->options & DHCPCD_IPV6) {
+ ifo->ia = malloc(sizeof(*ifo->ia));
+ if (ifo->ia == NULL)
+ syslog(LOG_ERR, "%s: %m", __func__);
+ else {
+ if (ifo->ia_type == 0)
+ ifo->ia_type = D6_OPTION_IA_NA;
+ memcpy(ifo->ia->iaid, ifo->iaid, sizeof(ifo->iaid));
+ ifo->ia_len = 1;
+ ifo->ia->sla = NULL;
+ ifo->ia->sla_len = 0;
+ }
+ }
+#endif
}
int
struct interface *ifp = arg;
struct if_options *ifo = ifp->options;
int nolease;
+ size_t i;
handle_carrier(LINK_UNKNOWN, 0, ifp->name);
if (ifp->carrier == LINK_DOWN) {
return;
}
+ if (ifo->options & (DHCPCD_DUID | DHCPCD_IPV6)) {
+ /* Report client DUID */
+ if (duid == NULL) {
+ if (duid_init(ifp) == 0)
+ return;
+ syslog(LOG_INFO, "DUID %s",
+ hwaddr_ntoa(duid, duid_len));
+ }
+
+ /* Report IAIDs */
+ syslog(LOG_INFO, "%s: IAID %s", ifp->name,
+ hwaddr_ntoa(ifo->iaid, sizeof(ifo->iaid)));
+ for (i = 0; i < ifo->ia_len; i++) {
+ if (memcmp(ifo->iaid, ifo->ia[i].iaid,
+ sizeof(ifo->iaid)))
+ syslog(LOG_INFO, "%s: IAID %s", ifp->name,
+ hwaddr_ntoa(ifo->ia[i].iaid,
+ sizeof(ifo->ia[i].iaid)));
+ }
+ }
+
if (ifo->options & DHCPCD_IPV6) {
if (ifo->options & DHCPCD_IPV6RS &&
!(ifo->options & DHCPCD_INFORM))
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd October 10, 2013
+.Dd November 15, 2013
.Dt DHCPCD.CONF 5
.Os
.Sh NAME
.Rs
.%T "RFC 4361"
.Re
-compliant clientid.
+compliant DHCP Unique Identifier.
If persistent storage is available then a DUID-LLT (link local address + time)
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
.Pa @SYSCONFDIR@/dhcpcd.duid
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 interface name if 4 or less characters.
+If more then it defaults to the interface index.
.It Ic persistent
.Nm dhcpcd
normally de-configures the interface and configuration when it exits.
.It Ic ia_na Op Ar iaid
Request a DHCPv6 Normal Address for
.Ar iaid .
-If none is specified, a default
.Ar iaid
-is used.
-If the interface name is 4 characters or less then that is used,
-otherwise the interface index is used.
-You can request more than one ia_na by specifying a unique iaid for each one.
+defaults to the
+.Ic iaid
+option as described above.
+You can request more than one ia_na by specifying a unique
+.Ar iaid
+for each one.
.It Ic ia_ta Op Ar iaid
Request a DHCPv6 Temporary Address for
.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
Request a DHCPv6 Delegated Prefix for
.Ar iaid .
.Sh AUTHORS
.An Roy Marples Aq Mt roy@marples.name
.Sh BUGS
+When configuring DHCPv6 you can only select one IA type.
+.Pp
Please report them to
.Lk http://roy.marples.name/projects/dhcpcd
#define LINK_DOWN -1
#define IF_DATA_IPV4 0
-#define IF_DATA_DHCP 1
+#define IF_DATA_DHCP 1
#define IF_DATA_IPV6 2
#define IF_DATA_IPV6ND 3
#define IF_DATA_DHCP6 4
/*
* dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2008 Roy Marples <roy@marples.name>
+ * Copyright (c) 2006-2013 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
#include "duid.h"
#include "net.h"
+unsigned char *duid = NULL;
+size_t duid_len = 0;
+
static size_t
-make_duid(unsigned char *duid, const struct interface *ifp, uint16_t type)
+duid_make(unsigned char *d, const struct interface *ifp, uint16_t type)
{
unsigned char *p;
uint16_t u16;
time_t t;
uint32_t u32;
- p = duid;
+ p = d;
u16 = htons(type);
memcpy(p, &u16, 2);
p += 2;
/* Finally, add the MAC address of the interface */
memcpy(p, ifp->hwaddr, ifp->hwlen);
p += ifp->hwlen;
- return p - duid;
+ return p - d;
}
-size_t
-get_duid(unsigned char *duid, const struct interface *iface)
+static size_t
+duid_get(unsigned char *d, const struct interface *ifp)
{
FILE *f;
int x = 0;
size_t len = 0;
char *line;
- const struct interface *ifp;
+ const struct interface *ifp2;
/* If we already have a DUID then use it as it's never supposed
* to change once we have one even if the interfaces do */
while ((line = get_line(f))) {
len = hwaddr_aton(NULL, line);
if (len && len <= DUID_LEN) {
- hwaddr_aton(duid, line);
+ hwaddr_aton(d, line);
break;
}
len = 0;
}
/* No file? OK, lets make one based on our interface */
- if (iface->family == ARPHRD_NETROM) {
+ if (ifp->family == ARPHRD_NETROM) {
syslog(LOG_WARNING, "%s: is a NET/ROM psuedo interface",
- iface->name);
- TAILQ_FOREACH(ifp, ifaces, next) {
- if (ifp->family != ARPHRD_NETROM)
+ ifp->name);
+ TAILQ_FOREACH(ifp2, ifaces, next) {
+ if (ifp2->family != ARPHRD_NETROM)
break;
}
- if (ifp) {
- iface = ifp;
+ if (ifp2) {
+ ifp = ifp2;
syslog(LOG_WARNING,
"picked interface %s to generate a DUID",
- iface->name);
+ ifp->name);
} else {
syslog(LOG_WARNING,
"no interfaces have a fixed hardware address");
- return make_duid(duid, iface, DUID_LL);
+ return duid_make(d, ifp, DUID_LL);
}
}
if (!(f = fopen(DUID, "w"))) {
syslog(LOG_ERR, "error writing DUID: %s: %m", DUID);
- return make_duid(duid, iface, DUID_LL);
+ return duid_make(d, ifp, DUID_LL);
}
- len = make_duid(duid, iface, DUID_LLT);
- x = fprintf(f, "%s\n", hwaddr_ntoa(duid, len));
+ len = duid_make(d, ifp, DUID_LLT);
+ x = fprintf(f, "%s\n", hwaddr_ntoa(d, len));
fclose(f);
/* Failed to write the duid? scrub it, we cannot use it */
if (x < 1) {
syslog(LOG_ERR, "error writing DUID: %s: %m", DUID);
unlink(DUID);
- return make_duid(duid, iface, DUID_LL);
+ return duid_make(d, ifp, DUID_LL);
}
return len;
}
+
+size_t duid_init(const struct interface *ifp)
+{
+
+ if (duid == NULL) {
+ duid = malloc(DUID_LEN);
+ if (duid == NULL) {
+ syslog(LOG_ERR, "%s: %m", __func__);
+ return 0;
+ }
+ duid_len = duid_get(duid, ifp);
+ }
+ return duid_len;
+}
/*
* dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2008 Roy Marples <roy@marples.name>
+ * Copyright (c) 2006-2013 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
#include "net.h"
-size_t get_duid(unsigned char *duid, const struct interface *iface);
+extern unsigned char *duid;
+extern size_t duid_len;
+
+size_t duid_init(const struct interface *);
#endif
#define O_NODEV O_BASE + 15
#define O_NOIPV4 O_BASE + 16
#define O_NOIPV6 O_BASE + 17
+#define O_IAID O_BASE + 18
char *dev_load;
{"noipv4", no_argument, NULL, O_NOIPV4},
{"noipv6", no_argument, NULL, O_NOIPV6},
{"noalias", no_argument, NULL, O_NOALIAS},
+ {"iaid", no_argument, NULL, O_IAID},
{"ia_na", no_argument, NULL, O_IA_NA},
{"ia_ta", no_argument, NULL, O_IA_TA},
{"ia_pd", no_argument, NULL, O_IA_PD},
return l;
}
+static int
+parse_iaid(uint8_t *iaid, const char *arg, size_t len)
+{
+ unsigned long l;
+ size_t s;
+ uint32_t u32;
+ char *np;
+
+ errno = 0;
+ l = strtoul(arg, &np, 0);
+ if (l <= (unsigned long)UINT32_MAX && errno == 0 && *np == '\0') {
+ u32 = htonl(l);
+ memcpy(iaid, &u32, sizeof(u32));
+ return 0;
+ }
+
+ if ((s = parse_string((char *)iaid, len, arg)) < 1) {
+ syslog(LOG_ERR, "%s: invalid IAID", arg);
+ return -1;
+ }
+ if (s < 4)
+ iaid[3] = '\0';
+ if (s < 3)
+ iaid[2] = '\0';
+ if (s < 2)
+ iaid[1] = '\0';
+ return 0;
+}
+
static char **
splitv(int *argc, char **argv, const char *arg)
{
const struct dhcp_opt *d;
uint8_t *request, *require, *no;
#ifdef INET6
- long l;
- uint32_t u32;
size_t sl;
- struct if_iaid *iaid;
- uint8_t _iaid[4];
+ struct if_ia *ia;
+ uint8_t iaid[4];
struct if_sla *sla, *slap;
#endif
return -1;
}
errno = 0;
- ifo->leasetime = (uint32_t)strtol(arg, NULL, 0);
+ ifo->leasetime = (uint32_t)strtoul(arg, NULL, 0);
if (errno == EINVAL || errno == ERANGE) {
syslog(LOG_ERR, "`%s' out of range", arg);
return -1;
}
break;
#endif
+ case O_IAID:
+ if (parse_iaid(ifo->iaid, arg, sizeof(ifo->iaid)) == -1)
+ return -1;
+ ifo->options |= DHCPCD_IAID;
case O_IPV6RS:
ifo->options |= DHCPCD_IPV6RS;
break;
fp = strchr(arg, ' ');
if (fp)
*fp++ = '\0';
- errno = 0;
- l = strtol(arg, &np, 0);
- if (l >= 0 && l <= (long)UINT32_MAX &&
- errno == 0 && *np == '\0')
- {
- u32 = htonl(l);
- memcpy(&_iaid, &u32, sizeof(_iaid));
- goto got_iaid;
- }
- if ((s = parse_string((char *)_iaid, sizeof(_iaid), arg)) < 1) {
- syslog(LOG_ERR, "%s: invalid IAID", arg);
+ if (parse_iaid(iaid, arg, sizeof(iaid)) == -1)
return -1;
- }
- if (s < 4)
- _iaid[3] = '\0';
- if (s < 3)
- _iaid[2] = '\0';
- if (s < 2)
- _iaid[1] = '\0';
-got_iaid:
- iaid = NULL;
- for (sl = 0; sl < ifo->iaid_len; sl++) {
- if (ifo->iaid[sl].iaid[0] == _iaid[0] &&
- ifo->iaid[sl].iaid[1] == _iaid[1] &&
- ifo->iaid[sl].iaid[2] == _iaid[2] &&
- ifo->iaid[sl].iaid[3] == _iaid[3])
+ ia = NULL;
+ for (sl = 0; sl < ifo->ia_len; sl++) {
+ if (ifo->ia[sl].iaid[0] == iaid[0] &&
+ ifo->ia[sl].iaid[1] == iaid[1] &&
+ ifo->ia[sl].iaid[2] == iaid[2] &&
+ ifo->ia[sl].iaid[3] == iaid[3])
{
- iaid = &ifo->iaid[sl];
+ ia = &ifo->ia[sl];
break;
}
}
- if (iaid == NULL) {
- iaid = realloc(ifo->iaid,
- sizeof(*ifo->iaid) * (ifo->iaid_len + 1));
- if (iaid == NULL) {
+ if (ia == NULL) {
+ ia = realloc(ifo->ia,
+ sizeof(*ifo->ia) * (ifo->ia_len + 1));
+ if (ia == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
return -1;
}
- ifo->iaid = iaid;
- iaid = &ifo->iaid[ifo->iaid_len++];
- iaid->iaid[0] = _iaid[0];
- iaid->iaid[1] = _iaid[1];
- iaid->iaid[2] = _iaid[2];
- iaid->iaid[3] = _iaid[3];
- iaid->sla = NULL;
- iaid->sla_len = 0;
+ ifo->ia = ia;
+ ia = &ifo->ia[ifo->ia_len++];
+ ia->iaid[0] = iaid[0];
+ ia->iaid[1] = iaid[1];
+ ia->iaid[2] = iaid[2];
+ ia->iaid[3] = iaid[3];
+ ia->sla = NULL;
+ ia->sla_len = 0;
}
if (ifo->ia_type != D6_OPTION_IA_PD)
break;
fp = strchr(p, ' ');
if (fp)
*fp++ = '\0';
- sla = realloc(iaid->sla,
- sizeof(*iaid->sla) * (iaid->sla_len + 1));
+ sla = realloc(ia->sla,
+ sizeof(*ia->sla) * (ia->sla_len + 1));
if (sla == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
return -1;
}
- iaid->sla = sla;
- sla = &iaid->sla[iaid->sla_len++];
+ ia->sla = sla;
+ sla = &ia->sla[ia->sla_len++];
np = strchr(p, '/');
if (np)
*np++ = '\0';
sla->sla_set = 0;
/* Sanity - check there are no more
* unspecified SLA's */
- for (sl = 0; sl < iaid->sla_len - 1; sl++) {
- slap = &iaid->sla[sl];
+ for (sl = 0; sl < ia->sla_len - 1; sl++) {
+ slap = &ia->sla[sl];
if (slap->sla_set == 0 &&
strcmp(slap->ifname, sla->ifname)
== 0)
"same interface twice with "
"an automatic SLA",
sla->ifname);
- iaid->sla_len--;
+ ia->sla_len--;
break;
}
}
}
}
- break;
#endif
+ break;
case O_HOSTNAME_SHORT:
ifo->options |= DHCPCD_HOSTNAME | DHCPCD_HOSTNAME_SHORT;
break;
}
}
-#ifdef INET6
-static void
-finish_config6(struct if_options *ifo, const char *ifname)
-{
-
- if (!(ifo->options & DHCPCD_IPV6))
- ifo->options &= ~DHCPCD_IPV6RS;
-
- if (ifname && ifo->iaid_len == 0 && ifo->options & DHCPCD_IPV6) {
- ifo->iaid = malloc(sizeof(*ifo->iaid));
- if (ifo->iaid == NULL)
- syslog(LOG_ERR, "%s: %m", __func__);
- else {
- if (ifo->ia_type == 0)
- ifo->ia_type = D6_OPTION_IA_NA;
- ifo->iaid_len = strlen(ifname);
- if (ifo->iaid_len <= sizeof(ifo->iaid->iaid)) {
- strncpy((char *)ifo->iaid->iaid, ifname,
- sizeof(ifo->iaid->iaid));
- memset(ifo->iaid->iaid + ifo->iaid_len, 0,
- sizeof(ifo->iaid->iaid) -ifo->iaid_len);
- } else {
- uint32_t idx = if_nametoindex(ifname);
- memcpy(ifo->iaid->iaid, &idx, sizeof(idx));
- }
- ifo->iaid_len = 1;
- ifo->iaid->sla = NULL;
- ifo->iaid->sla_len = 0;
- }
- }
-}
-#endif
-
struct if_options *
read_config(const char *file,
const char *ifname, const char *ssid, const char *profile)
}
finish_config(ifo);
-#ifdef INET6
- finish_config6(ifo, ifname);
-#endif
return ifo;
}
}
finish_config(ifo);
-#ifdef INET6
- finish_config6(ifo, NULL);
-#endif
return r;
}
free(ifo->blacklist);
free(ifo->fallback);
#ifdef INET6
- for (i = 0; i < ifo->iaid_len; i++)
- free(ifo->iaid[i].sla);
- free(ifo->iaid);
+ for (i = 0; i < ifo->ia_len; i++)
+ free(ifo->ia[i].sla);
#endif
+ free(ifo->ia);
+
free(ifo);
}
}
#define DHCPCD_WAITIP4 (1ULL << 45)
#define DHCPCD_WAITIP6 (1ULL << 46)
#define DHCPCD_DEV (1ULL << 47)
+#define DHCPCD_IAID (1ULL << 48)
extern const struct option cf_options[];
int8_t sla_set;
};
-struct if_iaid {
+struct if_ia {
uint8_t iaid[4];
+#ifdef INET6
size_t sla_len;
struct if_sla *sla;
+#endif
};
struct if_options {
+ uint8_t iaid[4];
int metric;
uint8_t requestmask[256 / 8];
uint8_t requiremask[256 / 8];
in_addr_t *arping;
char *fallback;
-#ifdef INET6
uint16_t ia_type;
- size_t iaid_len;
- struct if_iaid *iaid;
+ struct if_ia *ia;
+ size_t ia_len;
+#ifdef INET6
int dadtransmits;
#endif
};