Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dhcpv6c: exportable DUID #73

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion src/dhcpv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <unistd.h>
#include <syslog.h>
#include <stdbool.h>
#include <stdio.h>
#include <ctype.h>
#include <sys/time.h>
#include <sys/ioctl.h>
Expand Down Expand Up @@ -194,7 +195,7 @@ static char *dhcpv6_status_code_to_str(uint16_t code)
return "Unknown";
}

int init_dhcpv6(const char *ifname, unsigned int options, int sol_timeout)
int init_dhcpv6(const char *ifname, unsigned int options, int sol_timeout, const char *duid_path)
{
client_options = options;
dhcpv6_retx[DHCPV6_MSG_SOLICIT].max_timeo = sol_timeout;
Expand Down Expand Up @@ -247,6 +248,29 @@ int init_dhcpv6(const char *ifname, unsigned int options, int sol_timeout)
odhcp6c_add_state(STATE_CLIENT_ID, duid, sizeof(duid));
}

// Write duid to path
if (duid_path) {
// read duid
size_t duid_len;
void *duid = odhcp6c_get_state(STATE_CLIENT_ID, &duid_len);
char duid_buf[duid_len * 2 + 1];
script_hexlify(duid_buf, &((uint8_t *) duid)[4], duid_len - 4);
duid_buf[duid_len * 2] = 0;

// generate path
char file_path[strlen(duid_path) + strlen(ifname) + 2];
sprintf(file_path, "%s.%s", duid_path, ifname);

// write to file
FILE *fp = fopen(file_path, "w");
if (fp) {
fprintf(fp, "%s\n", duid_buf);
fclose(fp);
} else {
syslog(LOG_ERR, "Failed to write DUID '%s' into file '%s'!", duid_buf, file_path);
};
}

// Create ORO
if (!(client_options & DHCPV6_STRICT_OPTIONS)) {
uint16_t oro[] = {
Expand Down
10 changes: 8 additions & 2 deletions src/odhcp6c.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ int main(_unused int argc, char* const argv[])
// Allocate resources
const char *pidfile = NULL;
const char *script = "/usr/sbin/odhcp6c-update";
const char *duid_path = "/var/run/odhcp6c-duid";
ssize_t l;
uint8_t buf[134], *o_data;
char *optpos;
Expand All @@ -187,7 +188,7 @@ int main(_unused int argc, char* const argv[])
unsigned int ra_options = RA_RDNSS_DEFAULT_LIFETIME;
unsigned int ra_holdoff_interval = RA_MIN_ADV_INTERVAL;

while ((c = getopt(argc, argv, "S::DN:V:P:FB:c:i:r:Ru:Ux:s:kt:m:Lhedp:fav")) != -1) {
while ((c = getopt(argc, argv, "S::DN:V:P:FB:c:C:i:r:Ru:Ux:s:kt:m:Lhedp:fav")) != -1) {
switch (c) {
case 'S':
allow_slaac_only = (optarg) ? atoi(optarg) : -1;
Expand Down Expand Up @@ -284,6 +285,10 @@ int main(_unused int argc, char* const argv[])
help = true;
break;

case 'C':
duid_path = optarg;
break;

case 'i':
if (inet_pton(AF_INET6, optarg, &ifid) != 1)
help = true;
Expand Down Expand Up @@ -417,7 +422,7 @@ int main(_unused int argc, char* const argv[])
signal(SIGUSR2, sighandler);

if ((urandom_fd = open("/dev/urandom", O_CLOEXEC | O_RDONLY)) < 0 ||
init_dhcpv6(ifname, client_options, sol_timeout) ||
init_dhcpv6(ifname, client_options, sol_timeout, duid_path) ||
ra_init(ifname, &ifid, ra_options, ra_holdoff_interval) ||
script_init(script, ifname)) {
syslog(LOG_ERR, "failed to initialize: %s", strerror(errno));
Expand Down Expand Up @@ -620,6 +625,7 @@ static int usage(void)
" -x 0x1f4:ABBA - option 500\n"
" -x 202:'\"file\"' - option 202\n"
" -c <clientid> Override client-ID (base-16 encoded 16-bit type + value)\n"
" -C <path> Export used client-ID to specified path\n"
" -i <iface-id> Use a custom interface identifier for RA handling\n"
" -r <options> Options to be requested (comma-separated)\n"
" -R Do not request any options except those specified with -r\n"
Expand Down
3 changes: 2 additions & 1 deletion src/odhcp6c.h
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ struct odhcp6c_opt {
const char *str;
};

int init_dhcpv6(const char *ifname, unsigned int client_options, int sol_timeout);
int init_dhcpv6(const char *ifname, unsigned int client_options, int sol_timeout, const char *duid_path);
int dhcpv6_set_ia_mode(enum odhcp6c_ia_mode na, enum odhcp6c_ia_mode pd, bool stateful_only);
int dhcpv6_request(enum dhcpv6_msg type);
int dhcpv6_poll_reconfigure(void);
Expand All @@ -408,6 +408,7 @@ int ra_get_reachable(void);
int ra_get_retransmit(void);

int script_init(const char *path, const char *ifname);
void script_hexlify(char *dst, const uint8_t *src, size_t len);
ssize_t script_unhexlify(uint8_t *dst, size_t len, const char *src);
void script_call(const char *status, int delay, bool resume);

Expand Down
2 changes: 1 addition & 1 deletion src/script.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ ssize_t script_unhexlify(uint8_t *dst, size_t len, const char *src)
return c;
}

static void script_hexlify(char *dst, const uint8_t *src, size_t len)
void script_hexlify(char *dst, const uint8_t *src, size_t len)
{
for (size_t i = 0; i < len; ++i) {
*dst++ = hexdigits[src[i] >> 4];
Expand Down