struct interface *iface = state->interface;
struct dhcp_lease *lease = &state->lease;
struct in_addr addr;
- size_t duid_len = 0;
+ size_t len = 0;
#ifdef ENABLE_DUID
unsigned char *duid = NULL;
uint32_t ul;
if (*options->clientid) {
/* Attempt to see if the ClientID is a hardware address */
- iface->clientid_len = hwaddr_aton(NULL, options->clientid);
- if (iface->clientid_len) {
- iface->clientid = xmalloc(iface->clientid_len);
- hwaddr_aton(iface->clientid, options->clientid);
+ if ((len = hwaddr_aton(NULL, options->clientid))) {
+ iface->clientid = xmalloc(len + 1);
+ iface->clientid[0] = len;
+ hwaddr_aton(iface->clientid + 1, options->clientid);
} else {
/* Nope, so mark it as-is */
- iface->clientid_len = strlen(options->clientid) + 1;
- iface->clientid = xmalloc(iface->clientid_len);
- *iface->clientid = '\0';
- memcpy(iface->clientid + 1,
- options->clientid, iface->clientid_len - 1);
+ len = strlen(options->clientid) + 1;
+ iface->clientid = xmalloc(len + 1);
+ iface->clientid[0] = len;
+ iface->clientid[1] = 0; /* string */
+ memcpy(iface->clientid + 2, options->clientid, len);
}
} else if (options->options & DHCPCD_CLIENTID) {
#ifdef ENABLE_DUID
if (options->options & DHCPCD_DUID) {
duid = xmalloc(DUID_LEN);
- duid_len = get_duid(duid, iface);
- if (duid_len == 0)
+ if ((len = get_duid(duid, iface)) == 0)
logger(LOG_ERR, "get_duid: %s",
strerror(errno));
}
- if (duid_len > 0) {
+ if (len > 0) {
logger(LOG_INFO, "DUID = %s",
- hwaddr_ntoa(duid, duid_len));
+ hwaddr_ntoa(duid, len));
- iface->clientid_len = duid_len + 5;
- iface->clientid = xmalloc(iface->clientid_len);
- *iface->clientid = 255; /* RFC 4361 */
+ len += 5;
+ iface->clientid = xmalloc(len);
+ iface->clientid[0] = len;
+ iface->clientid[1] = 255; /* RFC 4361 */
/* IAID is 4 bytes, so if the iface name is 4 bytes
* use it */
if (strlen(iface->name) == 4) {
- memcpy(iface->clientid + 1, iface->name, 4);
+ memcpy(iface->clientid + 2, iface->name, 4);
} else {
/* Name isn't 4 bytes, so use the index */
ul = htonl(if_nametoindex(iface->name));
- memcpy(iface->clientid + 1, &ul, 4);
+ memcpy(iface->clientid + 2, &ul, 4);
}
- memcpy(iface->clientid + 5, duid, duid_len);
+ memcpy(iface->clientid + 6, duid, len);
free(duid);
}
#endif
- if (duid_len == 0) {
- iface->clientid_len = iface->hwlen + 1;
- iface->clientid = xmalloc(iface->clientid_len);
- *iface->clientid = iface->family;
+ if (len == 0) {
+ len = iface->hwlen + 1;
+ iface->clientid = xmalloc(len);
+ iface->clientid[0] = len;
+ iface->clientid[1] = iface->family;
memcpy(iface->clientid + 1, iface->hwaddr, iface->hwlen);
}
}
p += 2;
}
- if (iface->clientid_len > 0) {
+ if (iface->clientid[0]) {
*p++ = DHCP_CLIENTID;
- *p++ = iface->clientid_len;
- memcpy(p, iface->clientid, iface->clientid_len);
- p+= iface->clientid_len;
+ memcpy(p, iface->clientid, iface->clientid[0] + 1);
+ p += iface->clientid[0] + 1;
}
if (type != DHCP_DECLINE && type != DHCP_RELEASE) {
- if (options->userclass_len > 0) {
+ if (options->userclass[0]) {
*p++ = DHCP_USERCLASS;
- *p++ = options->userclass_len;
- memcpy(p, &options->userclass, options->userclass_len);
- p += options->userclass_len;
+ memcpy(p, options->userclass, options->userclass[0] + 1);
+ p += options->userclass[0] + 1;
}
- if (*options->classid > 0) {
+ if (options->classid[0]) {
*p++ = DHCP_CLASSID;
- *p++ = l = strlen(options->classid);
- memcpy(p, options->classid, l);
- p += l;
+ memcpy(p, options->classid, options->classid[0] + 1);
+ p += options->classid[0] + 1;
}
}
static int
parse_option(int opt, char *oarg, struct options *options)
{
- static int userclasses = 0;
int i;
- int j;
char *p;
size_t s;
size_t olen;
case 'i':
if (!oarg) {
*options->classid = '\0';
- } else if (olen >= CLASS_ID_MAX_LEN) {
+ } else if (olen >= CLASSID_MAX_LEN) {
logger(LOG_ERR,
"`%s' too long for ClassID string, max is %d",
- oarg, CLASS_ID_MAX_LEN);
+ oarg, CLASSID_MAX_LEN);
return -1;
- } else
- strlcpy(options->classid, oarg,
+ } else {
+ options->classid[0] = strlen(oarg);
+ strlcpy(options->classid + 1, oarg,
sizeof(options->classid));
+ }
break;
case 'l':
if (*oarg == '-') {
}
break;
case 'u':
- j = 0;
- for (i = 0; i < userclasses; i++)
- j += (int)options->userclass[j] + 1;
- if (j + 1 + olen >= USERCLASS_MAX_LEN) {
+ if (options->userclass[0] + olen + 1 >= USERCLASS_MAX_LEN) {
logger(LOG_ERR,
"userclass overrun, max is %d",
USERCLASS_MAX_LEN);
return -1;
}
- userclasses++;
- memcpy(options->userclass + j + 1, oarg, olen);
- options->userclass[j] = olen;
- options->userclass_len += olen + 1;
+ p = options->userclass + options->userclass[0] + 1;
+ *p++ = olen;
+ memcpy(p, oarg, olen);
+ options->userclass[0] += olen + 1;
break;
case 'A':
options->options &= ~DHCPCD_ARP;
break;
case 'I':
if (oarg) {
- if (olen >= CLIENT_ID_MAX_LEN) {
+ if (olen >= CLIENTID_MAX_LEN) {
logger(LOG_ERR, "`%s' is too long for"
" ClientID, max is %d",
- oarg, CLIENT_ID_MAX_LEN);
+ oarg, CLIENTID_MAX_LEN);
return -1;
}
- if (strlcpy(options->clientid, oarg,
- sizeof(options->clientid)) == 0) {
+ if (strlcpy(options->clientid + 1, oarg,
+ CLIENTID_MAX_LEN) == 0)
+ {
/* empty string disabled duid */
options->options &= ~DHCPCD_DUID;
options->options &= ~DHCPCD_CLIENTID;
- }
+ } else
+ options->clientid[0] = strlen(oarg);
} else {
options->clientid[0] = '\0';
options->options &= ~DHCPCD_DUID;
options = xzalloc(sizeof(*options));
options->script = SCRIPT;
- snprintf(options->classid, CLASS_ID_MAX_LEN, "%s %s",
- PACKAGE, VERSION);
+ options->classid[0] = snprintf(options->classid + 1, CLASSID_MAX_LEN,
+ "%s %s", PACKAGE, VERSION);
options->options |= DHCPCD_GATEWAY | DHCPCD_DAEMONISE | DHCPCD_CLIENTID;
#ifdef ENABLE_ARP
#define DEFAULT_TIMEOUT 30
#define DEFAULT_LEASETIME 3600 /* 1 hour */
-#define CLASS_ID_MAX_LEN 48
-#define CLIENT_ID_MAX_LEN 48
+#define CLASSID_MAX_LEN 48
+#define CLIENTID_MAX_LEN 48
#define USERCLASS_MAX_LEN 255
#ifdef THERE_IS_NO_FORK
char interface[IF_NAMESIZE];
char hostname[MAXHOSTNAMELEN];
int fqdn;
- char classid[CLASS_ID_MAX_LEN];
- char clientid[CLIENT_ID_MAX_LEN];
- char userclass[USERCLASS_MAX_LEN];
+ char classid[CLASSID_MAX_LEN + 1];
+ char clientid[CLIENTID_MAX_LEN + 1];
+ char userclass[USERCLASS_MAX_LEN + 1];
uint8_t reqmask[256 / 8];
uint8_t nomask[256 / 8];
- size_t userclass_len;
uint32_t leasetime;
time_t timeout;
int metric;
time_t start_uptime;
unsigned char *clientid;
- size_t clientid_len;
};
uint32_t get_netmask(uint32_t);