summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Barth2014-10-06 08:29:43 +0000
committerSteven Barth2014-10-06 08:29:43 +0000
commitd6fe99f6d03873e7a670c9b6f26fa03b219422f5 (patch)
tree7a0dff1d97d69611b3e54ed5db65b117c63e5ec4
parent3e52a1448eee0fbf7ff67c123265bedcbc9c26d0 (diff)
downloadodhcp6c-d6fe99f6d03873e7a670c9b6f26fa03b219422f5.tar.gz
Export DHCPv6 server address to env
-rw-r--r--src/dhcpv6.c25
-rw-r--r--src/odhcp6c.c2
-rw-r--r--src/odhcp6c.h3
-rw-r--r--src/script.c4
4 files changed, 23 insertions, 11 deletions
diff --git a/src/dhcpv6.c b/src/dhcpv6.c
index b7fccac..30c9fb2 100644
--- a/src/dhcpv6.c
+++ b/src/dhcpv6.c
@@ -551,10 +551,12 @@ int dhcpv6_request(enum dhcpv6_msg type)
round_start = odhcp6c_get_milli_time()) {
uint8_t buf[1536], cmsg_buf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
struct iovec iov = {buf, sizeof(buf)};
- struct msghdr msg = {NULL, 0, &iov, 1,
+ struct sockaddr_in6 addr;
+ struct msghdr msg = {&addr, sizeof(addr), &iov, 1,
cmsg_buf, sizeof(cmsg_buf), 0};
struct in6_pktinfo *pktinfo = NULL;
+
// Check for pending signal
if (odhcp6c_signal_process())
return -1;
@@ -599,7 +601,7 @@ int dhcpv6_request(enum dhcpv6_msg type)
"%llums", (unsigned long long)elapsed);
if (retx->handler_reply)
- len = retx->handler_reply(type, rc, opt, opt_end);
+ len = retx->handler_reply(type, rc, opt, opt_end, &addr);
if (len > 0 && round_end - round_start > 1000)
round_end = 1000 + round_start;
@@ -729,7 +731,7 @@ int dhcpv6_poll_reconfigure(void)
static int dhcpv6_handle_reconfigure(_unused enum dhcpv6_msg orig, const int rc,
- const void *opt, const void *end)
+ const void *opt, const void *end, _unused const struct sockaddr_in6 *from)
{
uint16_t otype, olen;
uint8_t *odata, msg = DHCPV6_MSG_RENEW;
@@ -739,14 +741,14 @@ static int dhcpv6_handle_reconfigure(_unused enum dhcpv6_msg orig, const int rc,
odata[0] == DHCPV6_MSG_INFO_REQ))
msg = odata[0];
- dhcpv6_handle_reply(DHCPV6_MSG_UNKNOWN, rc, NULL, NULL);
+ dhcpv6_handle_reply(DHCPV6_MSG_UNKNOWN, rc, NULL, NULL, NULL);
return msg;
}
// Collect all advertised servers
static int dhcpv6_handle_advert(enum dhcpv6_msg orig, const int rc,
- const void *opt, const void *end)
+ const void *opt, const void *end, _unused const struct sockaddr_in6 *from)
{
uint16_t olen, otype;
uint8_t *odata, pref = 0;
@@ -854,18 +856,18 @@ static int dhcpv6_commit_advert(void)
static int dhcpv6_handle_rebind_reply(enum dhcpv6_msg orig, const int rc,
- const void *opt, const void *end)
+ const void *opt, const void *end, const struct sockaddr_in6 *from)
{
- dhcpv6_handle_advert(orig, rc, opt, end);
+ dhcpv6_handle_advert(orig, rc, opt, end, from);
if (dhcpv6_commit_advert() < 0)
return -1;
- return dhcpv6_handle_reply(orig, rc, opt, end);
+ return dhcpv6_handle_reply(orig, rc, opt, end, from);
}
static int dhcpv6_handle_reply(enum dhcpv6_msg orig, _unused const int rc,
- const void *opt, const void *end)
+ const void *opt, const void *end, const struct sockaddr_in6 *from)
{
uint8_t *odata;
uint16_t otype, olen;
@@ -1090,6 +1092,11 @@ static int dhcpv6_handle_reply(enum dhcpv6_msg orig, _unused const int rc,
default :
break;
}
+
+ if (orig == DHCPV6_MSG_REBIND || orig == DHCPV6_MSG_REQUEST) {
+ odhcp6c_clear_state(STATE_SERVER_ADDR);
+ odhcp6c_add_state(STATE_SERVER_ADDR, &from->sin6_addr, 16);
+ }
}
}
else if (ret > 0) {
diff --git a/src/odhcp6c.c b/src/odhcp6c.c
index 2357a9a..c76c813 100644
--- a/src/odhcp6c.c
+++ b/src/odhcp6c.c
@@ -266,6 +266,7 @@ int main(_unused int argc, char* const argv[])
while (!signal_term) { // Main logic
odhcp6c_clear_state(STATE_SERVER_ID);
+ odhcp6c_clear_state(STATE_SERVER_ADDR);
odhcp6c_clear_state(STATE_IA_NA);
odhcp6c_clear_state(STATE_IA_PD);
odhcp6c_clear_state(STATE_SNTP_IP);
@@ -365,6 +366,7 @@ int main(_unused int argc, char* const argv[])
}
odhcp6c_clear_state(STATE_SERVER_ID); // Remove binding
+ odhcp6c_clear_state(STATE_SERVER_ADDR);
size_t ia_pd_len, ia_na_len;
odhcp6c_get_state(STATE_IA_PD, &ia_pd_len);
diff --git a/src/odhcp6c.h b/src/odhcp6c.h
index 59c4a42..a4343b1 100644
--- a/src/odhcp6c.h
+++ b/src/odhcp6c.h
@@ -123,7 +123,7 @@ enum dhcpv6_config {
};
typedef int(reply_handler)(enum dhcpv6_msg orig, const int rc,
- const void *opt, const void *end);
+ const void *opt, const void *end, const struct sockaddr_in6 *from);
// retransmission strategy
struct dhcpv6_retx {
@@ -246,6 +246,7 @@ enum odhcp6c_state {
STATE_CLIENT_ID,
STATE_SERVER_ID,
STATE_SERVER_CAND,
+ STATE_SERVER_ADDR,
STATE_ORO,
STATE_DNS,
STATE_SEARCH,
diff --git a/src/script.c b/src/script.c
index d443ede..e389cc9 100644
--- a/src/script.c
+++ b/src/script.c
@@ -354,7 +354,7 @@ void script_delay_call(const char *status, int timeout)
void script_call(const char *status)
{
size_t dns_len, search_len, custom_len, sntp_ip_len, ntp_ip_len, ntp_dns_len;
- size_t sip_ip_len, sip_fqdn_len, aftr_name_len, cer_len;
+ size_t sip_ip_len, sip_fqdn_len, aftr_name_len, cer_len, addr_len;
size_t s46_mapt_len, s46_mape_len, s46_lw_len, passthru_len;
odhcp6c_expire();
@@ -363,6 +363,7 @@ void script_call(const char *status)
dont_delay = true;
}
+ struct in6_addr *addr = odhcp6c_get_state(STATE_SERVER_ADDR, &addr_len);
struct in6_addr *dns = odhcp6c_get_state(STATE_DNS, &dns_len);
uint8_t *search = odhcp6c_get_state(STATE_SEARCH, &search_len);
uint8_t *custom = odhcp6c_get_state(STATE_CUSTOM_OPTS, &custom_len);
@@ -387,6 +388,7 @@ void script_call(const char *status)
// Don't set environment before forking, because env is leaky.
if (fork() == 0) {
+ ipv6_to_env("SERVER", addr, addr_len / sizeof(*addr));
ipv6_to_env("RDNSS", dns, dns_len / sizeof(*dns));
ipv6_to_env("SNTP_IP", sntp, sntp_ip_len / sizeof(*sntp));
ipv6_to_env("NTP_IP", ntp, ntp_ip_len / sizeof(*ntp));