mirror of
https://github.com/rsmarples/dhcpcd.git
synced 2024-11-23 18:14:09 +08:00
Remove the .info file and now set environment vars in the same vein as dhclient. This allows similar scripts to be used.
This commit is contained in:
parent
2cb85d9bb2
commit
dcab79de5e
10
Makefile
10
Makefile
@ -9,13 +9,13 @@ SRCS+= ${SRC_IF} ${SRC_SOCKET}
|
||||
SCRIPT= dhcpcd.sh
|
||||
MAN= dhcpcd.8
|
||||
|
||||
VERSION= 3.3.0-alpha1
|
||||
CLEANFILES= dhcpcd.8
|
||||
VERSION= 4.0.0-alpha1
|
||||
CLEANFILES= dhcpcd.sh dhcpcd.8
|
||||
|
||||
BINDIR= ${PREFIX}/sbin
|
||||
SYSCONFDIR?= ${PREFIX}/etc
|
||||
|
||||
.SUFFIXES: .in
|
||||
.SUFFIXES: .in .sh.in
|
||||
|
||||
MK= mk
|
||||
include ${MK}/prog.mk
|
||||
@ -27,3 +27,7 @@ LDADD+= ${LIBRT}
|
||||
|
||||
.in:
|
||||
${SED} 's:@SYSCONFDIR@:${SYSCONFDIR}:g; s:@DBDIR@:${DBDIR}:g' $< > $@
|
||||
|
||||
.sh.in.sh:
|
||||
${SED} 's:@SYSCONFDIR@:${SYSCONFDIR}:g' $< > $@
|
||||
|
||||
|
224
client.c
224
client.c
@ -95,6 +95,7 @@ struct if_state {
|
||||
int options;
|
||||
struct interface *interface;
|
||||
struct dhcp_message *dhcp;
|
||||
struct dhcp_message *old_dhcp;
|
||||
struct dhcp_lease lease;
|
||||
time_t start;
|
||||
time_t last_sent;
|
||||
@ -139,8 +140,8 @@ get_dhcp_op(uint8_t type)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static pid_t
|
||||
daemonise(int *pidfd)
|
||||
static int
|
||||
daemonise(struct if_state *state, const struct options *options)
|
||||
{
|
||||
pid_t pid;
|
||||
sigset_t full;
|
||||
@ -150,6 +151,10 @@ daemonise(int *pidfd)
|
||||
int i;
|
||||
#endif
|
||||
|
||||
if (state->options & DHCPCD_DAEMONISED ||
|
||||
!(options->options & DHCPCD_DAEMONISE))
|
||||
return 0;
|
||||
|
||||
sigfillset(&full);
|
||||
sigprocmask(SIG_SETMASK, &full, &old);
|
||||
|
||||
@ -202,13 +207,21 @@ daemonise(int *pidfd)
|
||||
|
||||
/* Done with the fd now */
|
||||
if (pid != 0) {
|
||||
writepid(*pidfd, pid);
|
||||
close(*pidfd);
|
||||
*pidfd = -1;
|
||||
writepid(*state->pidfd, pid);
|
||||
close(*state->pidfd);
|
||||
*state->pidfd = -1;
|
||||
}
|
||||
|
||||
sigprocmask(SIG_SETMASK, &old, NULL);
|
||||
return pid;
|
||||
|
||||
state->state = STATE_BOUND;
|
||||
if (pid == 0) {
|
||||
state->options |= DHCPCD_DAEMONISED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
state->options |= DHCPCD_PERSISTENT | DHCPCD_FORKED;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@ -316,7 +329,7 @@ static void
|
||||
get_lease(struct dhcp_lease *lease, const struct dhcp_message *dhcp)
|
||||
{
|
||||
lease->addr.s_addr = dhcp->yiaddr;
|
||||
if (get_option_addr(&lease->net.s_addr, dhcp, DHCP_NETMASK) == -1)
|
||||
if (get_option_addr(&lease->net.s_addr, dhcp, DHCP_SUBNETMASK) == -1)
|
||||
lease->net.s_addr = get_netmask(dhcp->yiaddr);
|
||||
if (get_option_uint32(&lease->leasetime, dhcp, DHCP_LEASETIME) != 0)
|
||||
lease->leasetime = DEFAULT_LEASETIME;
|
||||
@ -372,7 +385,8 @@ get_old_lease(struct if_state *state, const struct options *options)
|
||||
|
||||
/* Ok, lets use this */
|
||||
if (IN_LINKLOCAL(dhcp->yiaddr)) {
|
||||
free(state->dhcp);
|
||||
free(state->old_dhcp);
|
||||
state->old_dhcp = state->dhcp;
|
||||
state->dhcp = dhcp;
|
||||
return 0;
|
||||
}
|
||||
@ -399,7 +413,8 @@ get_old_lease(struct if_state *state, const struct options *options)
|
||||
offset = 0;
|
||||
state->timeout = lease->renewaltime - offset;
|
||||
iface->start_uptime = uptime();
|
||||
free(state->dhcp);
|
||||
free(state->old_dhcp);
|
||||
state->old_dhcp = state->dhcp;
|
||||
state->dhcp = dhcp;
|
||||
return 0;
|
||||
}
|
||||
@ -611,11 +626,14 @@ send_message(struct if_state *state, int type, const struct options *options)
|
||||
}
|
||||
|
||||
static void
|
||||
drop_config(struct if_state *state, const struct options *options)
|
||||
drop_config(struct if_state *state, const char *reason, const struct options *options)
|
||||
{
|
||||
if (!(state->options & DHCPCD_PERSISTENT))
|
||||
configure(state->interface, state->dhcp,
|
||||
&state->lease, options, 0);
|
||||
configure(state->interface, reason, NULL, state->dhcp,
|
||||
&state->lease, options, 0);
|
||||
free(state->old_dhcp);
|
||||
state->old_dhcp = NULL;
|
||||
free(state->dhcp);
|
||||
state->dhcp = NULL;
|
||||
|
||||
state->lease.addr.s_addr = 0;
|
||||
}
|
||||
@ -715,9 +733,11 @@ handle_signal(int sig, struct if_state *state, const struct options *options)
|
||||
switch (sig) {
|
||||
case SIGINT:
|
||||
logger(LOG_INFO, "received SIGINT, stopping");
|
||||
drop_config(state, "STOP", options);
|
||||
return -1;
|
||||
case SIGTERM:
|
||||
logger(LOG_INFO, "received SIGTERM, stopping");
|
||||
drop_config(state, "STOP", options);
|
||||
return -1;
|
||||
|
||||
case SIGALRM:
|
||||
@ -750,13 +770,13 @@ handle_signal(int sig, struct if_state *state, const struct options *options)
|
||||
|
||||
logger (LOG_INFO, "received SIGHUP, releasing lease");
|
||||
if (!IN_LINKLOCAL(ntohl(lease->addr.s_addr))) {
|
||||
do_socket(state, SOCKET_OPEN);
|
||||
state->xid = (uint32_t)random();
|
||||
send_message(state, DHCP_RELEASE, options);
|
||||
do_socket(state, SOCKET_CLOSED);
|
||||
}
|
||||
unlink(state->interface->infofile);
|
||||
return -1;
|
||||
do_socket(state, SOCKET_OPEN);
|
||||
state->xid = (uint32_t)random();
|
||||
send_message(state, DHCP_RELEASE, options);
|
||||
do_socket(state, SOCKET_CLOSED);
|
||||
}
|
||||
drop_config(state, "RELEASE", options);
|
||||
return -1;
|
||||
|
||||
default:
|
||||
logger (LOG_ERR,
|
||||
@ -772,96 +792,80 @@ handle_timeout(struct if_state *state, const struct options *options)
|
||||
{
|
||||
struct dhcp_lease *lease = &state->lease;
|
||||
struct interface *iface = state->interface;
|
||||
int gotlease = -1;
|
||||
char *reason = NULL;
|
||||
|
||||
/* No NAK, so reset the backoff */
|
||||
state->nakoff = 1;
|
||||
|
||||
if (state->state == STATE_INIT && state->xid != 0) {
|
||||
if (iface->addr.s_addr != 0 &&
|
||||
!IN_LINKLOCAL(ntohl(iface->addr.s_addr)) &&
|
||||
!(state->options & DHCPCD_INFORM))
|
||||
{
|
||||
logger(LOG_ERR, "lost lease");
|
||||
if (!(state->options & DHCPCD_PERSISTENT))
|
||||
drop_config(state, options);
|
||||
} else if (!IN_LINKLOCAL(ntohl(iface->addr.s_addr)))
|
||||
logger(LOG_ERR, "timed out");
|
||||
if (!IN_LINKLOCAL(ntohl(iface->addr.s_addr))) {
|
||||
if (iface->addr.s_addr != 0 &&
|
||||
!(state->options & DHCPCD_INFORM))
|
||||
logger(LOG_ERR, "lost lease");
|
||||
else
|
||||
logger(LOG_ERR, "timed out");
|
||||
}
|
||||
|
||||
do_socket(state, SOCKET_CLOSED);
|
||||
|
||||
if (options->options & DHCPCD_INFORM)
|
||||
return -1;
|
||||
|
||||
if (!(state->options & DHCPCD_TEST) &&
|
||||
(state->options & DHCPCD_IPV4LL ||
|
||||
state->options & DHCPCD_LASTLEASE))
|
||||
if (state->options & DHCPCD_IPV4LL ||
|
||||
state->options & DHCPCD_LASTLEASE)
|
||||
{
|
||||
errno = 0;
|
||||
if (get_old_lease(state, options) != 0) {
|
||||
if (errno == EINTR)
|
||||
return 0;
|
||||
if (state->options & DHCPCD_LASTLEASE)
|
||||
return -1;
|
||||
gotlease = get_old_lease(state, options);
|
||||
if (gotlease == 0) {
|
||||
if (!(state->options & DHCPCD_DAEMONISED))
|
||||
reason = "REBOOT";
|
||||
} else if (errno == EINTR)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_IPV4LL
|
||||
if (!(state->options & DHCPCD_TEST) &&
|
||||
state->options & DHCPCD_IPV4LL &&
|
||||
(!lease->addr.s_addr ||
|
||||
(!IN_LINKLOCAL(ntohl(lease->addr.s_addr)) &&
|
||||
!(state->options & DHCPCD_LASTLEASE))))
|
||||
{
|
||||
if (state->options & DHCPCD_IPV4LL && gotlease != -1) {
|
||||
logger(LOG_INFO, "probing for an IPV4LL address");
|
||||
if (ipv4ll_get_address(iface, lease) == -1) {
|
||||
if (!(state->options & DHCPCD_DAEMONISED))
|
||||
return -1;
|
||||
|
||||
/* start over */
|
||||
state->xid = 0;
|
||||
return 0;
|
||||
}
|
||||
state->timeout = lease->renewaltime;
|
||||
if (!state->dhcp)
|
||||
errno = 0;
|
||||
gotlease = ipv4ll_get_address(iface, lease);
|
||||
if (gotlease != 0) {
|
||||
if (errno == EINTR)
|
||||
return 0;
|
||||
} else {
|
||||
free(state->old_dhcp);
|
||||
state->old_dhcp = state->dhcp;
|
||||
state->dhcp = xmalloc(sizeof(*state->dhcp));
|
||||
memset(state->dhcp, 0, sizeof(*state->dhcp));
|
||||
state->dhcp->yiaddr = lease->addr.s_addr;
|
||||
state->dhcp->options[0] = DHCP_END;
|
||||
memset(state->dhcp, 0, sizeof(*state->dhcp));
|
||||
state->dhcp->yiaddr = lease->addr.s_addr;
|
||||
state->dhcp->options[0] = DHCP_END;
|
||||
reason = "IPV4LL";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (lease->addr.s_addr) {
|
||||
if (!(state->options & DHCPCD_DAEMONISED) &&
|
||||
IN_LINKLOCAL(ntohl(lease->addr.s_addr)))
|
||||
logger(LOG_WARNING, "using IPV4LL address %s",
|
||||
inet_ntoa(lease->addr));
|
||||
if (configure(iface, state->dhcp, lease, options, 1) != 0 &&
|
||||
!(state->options & DHCPCD_DAEMONISED))
|
||||
return -1;
|
||||
|
||||
state->state = STATE_BOUND;
|
||||
if (!(state->options & DHCPCD_DAEMONISED) &&
|
||||
options->options & DHCPCD_DAEMONISE) {
|
||||
switch (daemonise(state->pidfd)) {
|
||||
case -1:
|
||||
return -1;
|
||||
case 0:
|
||||
state->options |= DHCPCD_DAEMONISED;
|
||||
return 0;
|
||||
default:
|
||||
state->options |= DHCPCD_PERSISTENT | DHCPCD_FORKED;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
state->timeout = lease->renewaltime;
|
||||
state->xid = 0;
|
||||
return 0;
|
||||
if (gotlease != 0) {
|
||||
if (state->dhcp && !IN_LINKLOCAL(state->dhcp->yiaddr))
|
||||
reason = "EXPIRE";
|
||||
if (!reason)
|
||||
reason = "FAIL";
|
||||
drop_config(state, reason, options);
|
||||
if (!(state->options & DHCPCD_DAEMONISED))
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(state->options & DHCPCD_DAEMONISED))
|
||||
return -1;
|
||||
if (!(state->options & DHCPCD_DAEMONISED) &&
|
||||
IN_LINKLOCAL(ntohl(lease->addr.s_addr)))
|
||||
logger(LOG_WARNING, "using IPV4LL address %s",
|
||||
inet_ntoa(lease->addr));
|
||||
if (!reason)
|
||||
reason = "TIMEOUT";
|
||||
if (configure(iface, reason,
|
||||
state->dhcp, state->old_dhcp,
|
||||
lease, options, 1) == 0)
|
||||
daemonise(state, options);
|
||||
state->timeout = lease->renewaltime;
|
||||
state->xid = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (state->state) {
|
||||
@ -942,6 +946,7 @@ handle_dhcp(struct if_state *state, struct dhcp_message **dhcpp, const struct op
|
||||
uint8_t type;
|
||||
struct timeval tv;
|
||||
int r;
|
||||
const char *reason = NULL;
|
||||
|
||||
if (get_option_uint8(&type, dhcp, DHCP_MESSAGETYPE) == -1) {
|
||||
logger(LOG_ERR, "no DHCP type in message");
|
||||
@ -991,9 +996,9 @@ handle_dhcp(struct if_state *state, struct dhcp_message **dhcpp, const struct op
|
||||
logger(LOG_INFO, "offered %s", addr);
|
||||
free(addr);
|
||||
|
||||
if (options->options & DHCPCD_TEST) {
|
||||
write_info(iface, dhcp, lease, options, 0);
|
||||
errno = 0;
|
||||
if (state->options & DHCPCD_TEST) {
|
||||
exec_script(options->script, iface->name,
|
||||
"TEST", dhcp, NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1061,11 +1066,11 @@ handle_dhcp(struct if_state *state, struct dhcp_message **dhcpp, const struct op
|
||||
}
|
||||
#endif
|
||||
|
||||
if (state->dhcp)
|
||||
free(state->dhcp);
|
||||
free(state->old_dhcp);
|
||||
state->old_dhcp = state->dhcp;
|
||||
state->dhcp = dhcp;
|
||||
*dhcpp = NULL;
|
||||
|
||||
|
||||
if (options->options & DHCPCD_INFORM) {
|
||||
if (options->request_address.s_addr != 0)
|
||||
lease->addr.s_addr = options->request_address.s_addr;
|
||||
@ -1078,6 +1083,7 @@ handle_dhcp(struct if_state *state, struct dhcp_message **dhcpp, const struct op
|
||||
if (state->timeout == 0)
|
||||
state->timeout = DEFAULT_LEASETIME;
|
||||
state->state = STATE_INIT;
|
||||
reason = "INFORM";
|
||||
} else {
|
||||
if (gettimeofday(&tv, NULL) == 0)
|
||||
lease->leasedfrom = tv.tv_sec;
|
||||
@ -1135,25 +1141,21 @@ handle_dhcp(struct if_state *state, struct dhcp_message **dhcpp, const struct op
|
||||
}
|
||||
|
||||
state->xid = 0;
|
||||
if (configure(iface, dhcp, &state->lease, options, 1) != 0)
|
||||
if (!reason) {
|
||||
if (state->old_dhcp) {
|
||||
if (state->old_dhcp->yiaddr == dhcp->yiaddr &&
|
||||
lease->server.s_addr)
|
||||
reason = "RENEW";
|
||||
else
|
||||
reason = "REBIND";
|
||||
} else
|
||||
reason = "BOUND";
|
||||
}
|
||||
r = configure(iface, reason, dhcp, state->old_dhcp,
|
||||
&state->lease, options, 1);
|
||||
if (r != 0)
|
||||
return -1;
|
||||
|
||||
if (!(state->options & DHCPCD_DAEMONISED) &&
|
||||
state->options & DHCPCD_DAEMONISE)
|
||||
{
|
||||
switch (daemonise(state->pidfd)) {
|
||||
case 0:
|
||||
state->options |= DHCPCD_DAEMONISED;
|
||||
return 0;
|
||||
case -1:
|
||||
return -1;
|
||||
default:
|
||||
state->options |= DHCPCD_PERSISTENT | DHCPCD_FORKED;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return daemonise(state, options);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1261,7 +1263,6 @@ dhcp_run(const struct options *options, int *pidfd)
|
||||
eexit:
|
||||
if (iface) {
|
||||
do_socket(state, SOCKET_CLOSED);
|
||||
drop_config(state, options);
|
||||
free_routes(iface->routes);
|
||||
free(iface->clientid);
|
||||
free(iface);
|
||||
@ -1274,6 +1275,7 @@ eexit:
|
||||
unlink(options->pidfile);
|
||||
free(state->buffer);
|
||||
free(state->dhcp);
|
||||
free(state->old_dhcp);
|
||||
free(state);
|
||||
}
|
||||
|
||||
|
1
config.h
1
config.h
@ -64,7 +64,6 @@
|
||||
# define DBDIR "/var/db"
|
||||
#endif
|
||||
#define LEASEFILE DBDIR "/" PACKAGE "-%s.lease"
|
||||
#define INFOFILE DBDIR "/" PACKAGE "-%s.info"
|
||||
#define DUIDFILE DBDIR "/" PACKAGE ".duid"
|
||||
|
||||
#endif
|
||||
|
146
configure.c
146
configure.c
@ -45,10 +45,11 @@
|
||||
#include "net.h"
|
||||
#include "signal.h"
|
||||
|
||||
static int
|
||||
exec_script(const char *cmd, const char *arg1, const char *arg2)
|
||||
int
|
||||
exec_script(const char *script, const char *iface, const char *reason,
|
||||
const struct dhcp_message *dhcpn, const struct dhcp_message *dhcpo)
|
||||
{
|
||||
char *const argv[4] = { (char *)cmd, (char *)arg1, (char *)arg2, NULL};
|
||||
char *const argv[2] = { (char *)script, NULL };
|
||||
int ret = 0;
|
||||
pid_t pid;
|
||||
pid_t wpid;
|
||||
@ -56,7 +57,7 @@ exec_script(const char *cmd, const char *arg1, const char *arg2)
|
||||
sigset_t full;
|
||||
sigset_t old;
|
||||
|
||||
logger(LOG_DEBUG, "exec `%s' `%s' `%s'", cmd, arg1, arg2);
|
||||
logger(LOG_DEBUG, "exec `%s'", script);
|
||||
|
||||
/* OK, we need to block signals */
|
||||
sigfillset(&full);
|
||||
@ -79,8 +80,14 @@ exec_script(const char *cmd, const char *arg1, const char *arg2)
|
||||
signal_reset();
|
||||
#endif
|
||||
sigprocmask(SIG_SETMASK, &old, NULL);
|
||||
execvp(cmd, argv);
|
||||
logger(LOG_ERR, "%s: %s", cmd, strerror(errno));
|
||||
if (dhcpo)
|
||||
configure_env("old", dhcpo);
|
||||
if (dhcpn)
|
||||
configure_env("new", dhcpn);
|
||||
setenv("interface", iface, 1);
|
||||
setenv("reason", reason, 1);
|
||||
execvp(script, argv);
|
||||
logger(LOG_ERR, "%s: %s", script, strerror(errno));
|
||||
_exit(111);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
@ -99,6 +106,8 @@ exec_script(const char *cmd, const char *arg1, const char *arg2)
|
||||
logger(LOG_ERR, "waitpid: %s", strerror(errno));
|
||||
} while (!WIFEXITED(status) && !WIFSIGNALED(status));
|
||||
|
||||
if (WIFSIGNALED(status))
|
||||
logger(LOG_ERR, "script signaled");
|
||||
if (WIFEXITED(status))
|
||||
ret = WEXITSTATUS(status);
|
||||
else
|
||||
@ -336,116 +345,9 @@ configure_routes(struct interface *iface, const struct dhcp_message *dhcp,
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
print_clean(FILE *f, const char *name, const char *value)
|
||||
{
|
||||
fprintf(f, "%s=", name);
|
||||
if (value)
|
||||
write_string(f, (const uint8_t*)value, strlen(value));
|
||||
fputc('\n', f);
|
||||
}
|
||||
|
||||
int
|
||||
write_info(const struct interface *iface, const struct dhcp_message *dhcp,
|
||||
const struct dhcp_lease *lease, const struct options *options,
|
||||
int overwrite)
|
||||
{
|
||||
FILE *f;
|
||||
struct rt *rt, *ort;
|
||||
struct stat sb;
|
||||
struct in_addr addr;
|
||||
int doneone;
|
||||
|
||||
if (options->options & DHCPCD_TEST)
|
||||
f = stdout;
|
||||
else {
|
||||
if (!overwrite && stat(iface->infofile, &sb) == 0)
|
||||
return 0;
|
||||
|
||||
if ((f = fopen(iface->infofile, "w")) == NULL)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dhcp->yiaddr) {
|
||||
fprintf(f, "IPADDR=%s\n", inet_ntoa(iface->addr));
|
||||
fprintf(f, "NETMASK=%s\n", inet_ntoa(iface->net));
|
||||
addr.s_addr = dhcp->yiaddr & iface->net.s_addr;
|
||||
fprintf(f, "NETWORK=%s\n", inet_ntoa(addr));
|
||||
if (get_option_addr(&addr.s_addr, dhcp, DHCP_BROADCAST) == -1)
|
||||
addr.s_addr = dhcp->yiaddr | ~iface->net.s_addr;
|
||||
fprintf(f, "BROADCAST=%s\n", inet_ntoa(addr));
|
||||
|
||||
ort = get_option_routes(dhcp);
|
||||
doneone = 0;
|
||||
fprintf(f, "ROUTES=");
|
||||
for (rt = ort; rt; rt = rt->next) {
|
||||
if (rt->dest.s_addr == 0)
|
||||
continue;
|
||||
if (doneone)
|
||||
fprintf(f, "\\ ");
|
||||
else
|
||||
doneone = 1;
|
||||
fprintf(f, "%s", inet_ntoa(rt->dest));
|
||||
fprintf(f, ",%s", inet_ntoa(rt->net));
|
||||
fprintf(f, ",%s", inet_ntoa(rt->gate));
|
||||
}
|
||||
fputc('\n', f);
|
||||
|
||||
doneone = 0;
|
||||
fprintf(f, "GATEWAYS=");
|
||||
for (rt = ort; rt; rt = rt->next) {
|
||||
if (rt->dest.s_addr != 0)
|
||||
continue;
|
||||
if (doneone)
|
||||
fprintf(f, "\\ ");
|
||||
else
|
||||
doneone = 1;
|
||||
fprintf(f, "%s", inet_ntoa(rt->gate));
|
||||
}
|
||||
fputc('\n', f);
|
||||
free_routes(ort);
|
||||
}
|
||||
|
||||
write_options(f, dhcp);
|
||||
|
||||
/* FIXME
|
||||
if (dhcp->fqdn) {
|
||||
fprintf(f, "FQDNFLAGS='%u'\n", dhcp->fqdn->flags);
|
||||
fprintf(f, "FQDNRCODE1='%u'\n", dhcp->fqdn->r1);
|
||||
fprintf(f, "FQDNRCODE2='%u'\n", dhcp->fqdn->r2);
|
||||
print_clean(f, "FQDNHOSTNAME", dhcp->fqdn->name);
|
||||
}
|
||||
*/
|
||||
if (dhcp->siaddr) {
|
||||
addr.s_addr = dhcp->siaddr;
|
||||
fprintf(f, "DHCPSID=%s\n", inet_ntoa(addr));
|
||||
}
|
||||
if (dhcp->servername[0])
|
||||
print_clean(f, "DHCPSNAME", (const char *)dhcp->servername);
|
||||
|
||||
if (!(options->options & DHCPCD_INFORM) && dhcp->yiaddr) {
|
||||
if (!(options->options & DHCPCD_TEST))
|
||||
fprintf(f, "LEASEDFROM=%u\n", lease->leasedfrom);
|
||||
fprintf(f, "LEASETIME=%u\n", lease->leasetime);
|
||||
fprintf(f, "RENEWALTIME=%u\n", lease->renewaltime);
|
||||
fprintf(f, "REBINDTIME=%u\n", lease->rebindtime);
|
||||
}
|
||||
print_clean(f, "INTERFACE", iface->name);
|
||||
print_clean(f, "CLASSID", options->classid);
|
||||
if (iface->clientid_len > 0) {
|
||||
fprintf(f, "CLIENTID=%s\n",
|
||||
hwaddr_ntoa(iface->clientid, iface->clientid_len));
|
||||
}
|
||||
fprintf(f, "DHCPCHADDR=%s\n",
|
||||
hwaddr_ntoa(iface->hwaddr, iface->hwlen));
|
||||
|
||||
if (!(options->options & DHCPCD_TEST))
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
configure(struct interface *iface, const struct dhcp_message *dhcp,
|
||||
configure(struct interface *iface, const char *reason,
|
||||
const struct dhcp_message *dhcp, const struct dhcp_message *old,
|
||||
const struct dhcp_lease *lease, const struct options *options,
|
||||
int up)
|
||||
{
|
||||
@ -463,7 +365,7 @@ configure(struct interface *iface, const struct dhcp_message *dhcp,
|
||||
else {
|
||||
addr.s_addr = dhcp->yiaddr;
|
||||
/* Ensure we have all the needed values */
|
||||
if (get_option_addr(&net.s_addr, dhcp, DHCP_NETMASK) == -1)
|
||||
if (get_option_addr(&net.s_addr, dhcp, DHCP_SUBNETMASK) == -1)
|
||||
net.s_addr = get_netmask(addr.s_addr);
|
||||
if (get_option_addr(&brd.s_addr, dhcp, DHCP_BROADCAST) == -1)
|
||||
brd.s_addr = addr.s_addr | ~net.s_addr;
|
||||
@ -471,13 +373,6 @@ configure(struct interface *iface, const struct dhcp_message *dhcp,
|
||||
|
||||
/* If we aren't up, then reset the interface as much as we can */
|
||||
if (!up) {
|
||||
/* If we haven't created an info file, do so now */
|
||||
if (!lease->frominfo) {
|
||||
if (write_info(iface, dhcp, lease, options, 0) == -1)
|
||||
logger(LOG_ERR, "write_info: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
|
||||
/* Only reset things if we had set them before */
|
||||
if (iface->addr.s_addr != 0) {
|
||||
if (!(options->options & DHCPCD_KEEPADDRESS)) {
|
||||
@ -495,7 +390,7 @@ configure(struct interface *iface, const struct dhcp_message *dhcp,
|
||||
}
|
||||
}
|
||||
|
||||
exec_script(options->script, iface->infofile, "down");
|
||||
exec_script(options->script, iface->name, reason, NULL, old);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -537,10 +432,9 @@ configure(struct interface *iface, const struct dhcp_message *dhcp,
|
||||
iface->net.s_addr = net.s_addr;
|
||||
|
||||
if (!lease->frominfo)
|
||||
write_info(iface, dhcp, lease, options, 1);
|
||||
if (write_lease(iface, dhcp) == -1)
|
||||
logger(LOG_ERR, "write_lease: %s", strerror(errno));
|
||||
|
||||
exec_script(options->script, iface->infofile, up ? "new" : "up");
|
||||
exec_script(options->script, iface->name, reason, dhcp, old);
|
||||
return 0;
|
||||
}
|
||||
|
@ -32,9 +32,10 @@
|
||||
#include "dhcp.h"
|
||||
#include "net.h"
|
||||
|
||||
int write_info(const struct interface *, const struct dhcp_message *,
|
||||
const struct dhcp_lease *, const struct options *, int);
|
||||
int configure(struct interface *, const struct dhcp_message *,
|
||||
const struct dhcp_lease *, const struct options *, int);
|
||||
int exec_script(const char *, const char *, const char *,
|
||||
const struct dhcp_message *, const struct dhcp_message *);
|
||||
int configure(struct interface *, const char *,
|
||||
const struct dhcp_message *, const struct dhcp_message *,
|
||||
const struct dhcp_lease *, const struct options *, int);
|
||||
|
||||
#endif
|
||||
|
431
dhcp.c
431
dhcp.c
@ -39,12 +39,16 @@
|
||||
#define REQUEST (1 << 0)
|
||||
#define UINT8 (1 << 1)
|
||||
#define UINT16 (1 << 2)
|
||||
#define UINT32 (1 << 3)
|
||||
#define IPV4 (1 << 4)
|
||||
#define STRING (1 << 5)
|
||||
#define ARRAY (1 << 6)
|
||||
#define RFC3361 (1 << 7)
|
||||
#define RFC3397 (1 << 8)
|
||||
#define SINT16 (1 << 3)
|
||||
#define UINT32 (1 << 4)
|
||||
#define SINT32 (1 << 5)
|
||||
#define IPV4 (1 << 6)
|
||||
#define STRING (1 << 7)
|
||||
#define PAIR (1 << 8)
|
||||
#define ARRAY (1 << 9)
|
||||
#define RFC3361 (1 << 10)
|
||||
#define RFC3397 (1 << 11)
|
||||
#define RFC3442 (1 << 12)
|
||||
|
||||
#define IPV4R IPV4 | REQUEST
|
||||
|
||||
@ -55,80 +59,93 @@ struct dhcp_option {
|
||||
};
|
||||
|
||||
const struct dhcp_option dhcp_options[] = {
|
||||
{ DHCP_NETMASK, IPV4R, NULL },
|
||||
{ DHCP_TIMEOFFSET, UINT32, "TIMEOFFSET" },
|
||||
{ DHCP_ROUTER, IPV4R, NULL },
|
||||
{ DHCP_TIMESERVER, IPV4, "TIMESERVER" },
|
||||
{ DHCP_NAMESERVER, IPV4, "NAMESERVER" },
|
||||
{ DHCP_DNSSERVER, IPV4, "DNSSERVER" },
|
||||
{ DHCP_LOGSERVER, IPV4, "LOGSERVER" },
|
||||
{ DHCP_COOKIESERVER, IPV4, "COOKIESERVER" },
|
||||
{ DHCP_LPRSERVER, IPV4, "LPRSERVER" },
|
||||
{ DHCP_IMPRESSSERVER, IPV4, "IMPRESSSERVER" },
|
||||
{ DHCP_RESOURCELOCATIONSERVER, IPV4, "RESOURCELOCATIONSERVER" },
|
||||
{ DHCP_HOSTNAME, STRING, "HOSTNAME" },
|
||||
{ DHCP_BOOTFILESIZE, UINT16, "BOOTFILESIZE" },
|
||||
{ DHCP_MERITDUMPFILE, STRING, "MERITDUMPFILE" },
|
||||
{ DHCP_DNSDOMAIN, STRING, "DNSDOMAIN" },
|
||||
{ DHCP_SWAPSERVER, IPV4, "SWAPSERVER" },
|
||||
{ DHCP_ROOTPATH, STRING, "ROOTPATH" },
|
||||
{ DHCP_EXTENSIONSPATH, STRING, "EXTENSIONSPATH" },
|
||||
|
||||
{ DHCP_IPFORWARDING, UINT8, "IPFORWARDING" },
|
||||
{ DHCP_NONLOCALSOURCEROUTING, UINT8, "NONLOCALSOURCEROUTING" },
|
||||
{ DHCP_POLICYFILTER, IPV4, "POLICYFILTER" },
|
||||
{ DHCP_MAXDGRAMSIZE, UINT16, "MAXDGRAMSIZE" },
|
||||
{ DHCP_DEFAULTIPTTL, UINT16, "DEFAULTIPTTL" },
|
||||
{ DHCP_PATHMTUAGINGTIMEOUT, UINT32, "PATHMTUAGINGTIMEOUT" },
|
||||
{ DHCP_PATHMTUPLATEAUTABLE, UINT16 | ARRAY, "PATHMTUPLATEAUTABLE" },
|
||||
|
||||
{ DHCP_MTU, UINT16, "MTU" },
|
||||
{ DHCP_ALLSUBNETSLOCAL, UINT8, "ALLSUBNETSLOCAL" },
|
||||
{ DHCP_BROADCAST, IPV4R, NULL },
|
||||
{ DHCP_MASKDISCOVERY, UINT8, "MASKDISCOVERY" },
|
||||
{ DHCP_MASKSUPPLIER, UINT8, "MASKSUPPLIER" },
|
||||
{ DHCP_ROUTERDISCOVERY, UINT8, "ROUTERDISCOVERY" },
|
||||
{ DHCP_ROUTERSOLICITATIONADDR, UINT8, "ROUTERSOLICITATIONADDR" },
|
||||
{ DHCP_STATICROUTE, IPV4R, NULL },
|
||||
|
||||
{ DHCP_TRAILERENCAPSULATION, UINT8, "TRAILERENCAPSULATION" },
|
||||
{ DHCP_ARPCACHETIMEOUT, UINT32, "ARPCACHETIMEOUT" },
|
||||
{ DHCP_ETHERNETENCAPSULATION, UINT8, "ETHERNETENCAPSULATION" },
|
||||
|
||||
{ DHCP_TCPDEFAULTTTL, UINT8, "TCPDEFAULTTTL" },
|
||||
{ DHCP_TCPKEEPALIVEINTERVAL, UINT32, "TCPKEEPALIVEINTERVAL" },
|
||||
{ DHCP_TCPKEEPALIVEGARBAGE, UINT8, "TCPKEEPALIVEGARBAGE" },
|
||||
|
||||
{ DHCP_NISDOMAIN, IPV4, "NISDOMAIN" },
|
||||
{ DHCP_NISSERVER, IPV4, "NISSERVER" },
|
||||
{ DHCP_NTPSERVER, IPV4, "NTPSERVER" },
|
||||
{ DHCP_VENDORSPECIFICINFO, STRING, "VENDORSPECIFICINFO" },
|
||||
{ DHCP_NETBIOSNAMESERVER, IPV4, "NETBIOSNAMESERVER" },
|
||||
{ DHCP_NETBIOSDGRAMSERVER, IPV4, "NETBIOSDGRAMSERVER" },
|
||||
{ DHCP_NETBIOSNODETYPE, UINT8, "NETBIOSNODETYPE" },
|
||||
{ DHCP_NETBIOSSCOPE, STRING, "NETBIOSSCOPE" },
|
||||
{ DHCP_XFONTSERVER, IPV4, "XFONTSERVER" },
|
||||
{ DHCP_XDISPLAYMANAGER, IPV4, "XDISPLAYMANAGER" },
|
||||
{ DHCP_NISPLUSDOMAIN, IPV4, "NISPLUSDOMAIN" },
|
||||
{ DHCP_NISPLUSSERVER, IPV4, "NISPLUSSERVER" },
|
||||
{ DHCP_MOBILEIPHOMEAGENT, IPV4, "MOBILEIPHOMEAGENT" },
|
||||
{ DHCP_SMTPSERVER, IPV4, "SMTPSERVER" },
|
||||
{ DHCP_POP3SERVER, IPV4, "POP3SERVER" },
|
||||
{ DHCP_NNTPSERVER, IPV4, "NNTPSERVER" },
|
||||
{ DHCP_WWWSERVER, IPV4, "WWWSERVER" },
|
||||
{ DHCP_FINGERSERVER, IPV4, "FINGERSERVER" },
|
||||
{ DHCP_IRCSERVER, IPV4, "IRCSERVER" },
|
||||
{ DHCP_STREETTALKSERVER, IPV4, "STREETTALKSERVER" },
|
||||
{ DHCP_STREETTALKDASERVER, IPV4, "STREETTALKDASERVER" },
|
||||
|
||||
{ DHCP_LEASETIME, UINT32, NULL },
|
||||
{ DHCP_SERVERID, IPV4, "SERVERID" },
|
||||
{ DHCP_RENEWALTIME, UINT32 | REQUEST, NULL },
|
||||
{ DHCP_REBINDTIME, UINT32 | REQUEST, NULL },
|
||||
|
||||
{ DHCP_MESSAGE, STRING, NULL},
|
||||
{ DHCP_DNSSEARCH, STRING | RFC3397, "DNSSEARCH" },
|
||||
{ DHCP_SIPSERVER, STRING | RFC3361, "SIPSERVER" },
|
||||
{ 1, IPV4 | REQUEST, "subnet_mask" },
|
||||
{ 2, UINT32, "time_offset" },
|
||||
{ 3, IPV4 | ARRAY | REQUEST, "routers" },
|
||||
{ 4, IPV4 | ARRAY, "time_servers" },
|
||||
{ 5, IPV4 | ARRAY, "ien116_name_servers" },
|
||||
{ 6, IPV4 | ARRAY, "domain_name_servers" },
|
||||
{ 7, IPV4 | ARRAY, "log_servers" },
|
||||
{ 8, IPV4 | ARRAY, "cookie_servers" },
|
||||
{ 9, IPV4 | ARRAY, "lpr_servers" },
|
||||
{ 10, IPV4 | ARRAY, "impress_servers" },
|
||||
{ 11, IPV4 | ARRAY, "resource_location_servers" },
|
||||
{ 12, STRING, "host_name" },
|
||||
{ 13, UINT16, "boot_size" },
|
||||
{ 14, STRING, "merit_dump" },
|
||||
{ 15, STRING, "domain_name" },
|
||||
{ 16, IPV4, "swap_server" },
|
||||
{ 17, STRING, "root_path" },
|
||||
{ 18, STRING, "extensions_path" },
|
||||
{ 19, UINT8, "ip_forwarding" },
|
||||
{ 20, UINT8, "non_local_source_routing" },
|
||||
{ 21, IPV4 | ARRAY, "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, IPV4 | REQUEST, "broadcast_address" },
|
||||
{ 29, UINT8, "perform_mask_discovery" },
|
||||
{ 30, UINT8, "mask_supplier" },
|
||||
{ 31, UINT8, "router_discovery" },
|
||||
{ 32, IPV4, "router_solicitation_address" },
|
||||
{ 33, IPV4 | ARRAY | REQUEST, "static_routes" },
|
||||
{ 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" },
|
||||
{ 30, STRING, "nis_domain" },
|
||||
{ 31, IPV4 | ARRAY, "nis_servers" },
|
||||
{ 32, IPV4 | ARRAY, "ntp_servers" },
|
||||
{ 43, STRING, "vendor_encapsulated_options" },
|
||||
{ 44, IPV4 | ARRAY, "netbios_name_servers" },
|
||||
{ 45, IPV4, "netbios_dd_server" },
|
||||
{ 46, UINT8, "netbios_node_type" },
|
||||
{ 47, STRING, "netbios_scope" },
|
||||
{ 48, IPV4 | ARRAY, "font_servers" },
|
||||
{ 49, IPV4 | ARRAY, "x_display_manager" },
|
||||
{ 50, IPV4, "dhcp_requested_address" },
|
||||
{ 51, UINT32 | REQUEST, "dhcp_lease_time" },
|
||||
{ 52, UINT8, "dhcp_option_overload" },
|
||||
{ 53, UINT8, "dhcp_message_type" },
|
||||
{ 54, IPV4, "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, IPV4 | ARRAY, "nisplus_servers" },
|
||||
{ 66, STRING, "tftp_server_name" },
|
||||
{ 67, STRING, "bootfile_name" },
|
||||
{ 68, IPV4 | ARRAY, "mobile_ip_home_agent" },
|
||||
{ 69, IPV4 | ARRAY, "smtp_server" },
|
||||
{ 70, IPV4 | ARRAY, "pop_server" },
|
||||
{ 71, IPV4 | ARRAY, "nntp_server" },
|
||||
{ 72, IPV4 | ARRAY, "www_server" },
|
||||
{ 73, IPV4 | ARRAY, "finger_server" },
|
||||
{ 74, IPV4 | ARRAY, "irc_server" },
|
||||
{ 75, IPV4 | ARRAY, "streettalk_server" },
|
||||
{ 76, IPV4 | ARRAY, "streettalk_directory_assistance_server" },
|
||||
{ 77, STRING, "user_class" },
|
||||
{ 85, IPV4 | ARRAY, "nds_servers" },
|
||||
{ 86, STRING, "nds_tree_name" },
|
||||
{ 87, STRING, "nds_context" },
|
||||
{ 88, STRING | RFC3397, "bcms_controller_names" },
|
||||
{ 89, IPV4 | ARRAY, "bcms_controller_address" },
|
||||
{ 91, UINT32, "client_last_transaction_time" },
|
||||
{ 92, IPV4 | ARRAY, "associated_ip" },
|
||||
{ 98, STRING, "uap_servers" },
|
||||
{ 112, IPV4 | ARRAY, "netinfo_server_address" },
|
||||
{ 113, STRING, "netinfo_server_tag" },
|
||||
{ 114, STRING, "default_url" },
|
||||
{ 118, IPV4, "subnet_selection" },
|
||||
{ 119, STRING | RFC3397, "domain_search" },
|
||||
{ 121, RFC3442, "classless_static_routes" },
|
||||
{ 0, 0, NULL }
|
||||
};
|
||||
|
||||
@ -693,7 +710,7 @@ make_message(struct dhcp_message **message,
|
||||
lease->addr.s_addr != iface->addr.s_addr &&
|
||||
!IN_LINKLOCAL(ntohl(lease->addr.s_addr)))
|
||||
{
|
||||
PUTADDR(DHCP_ADDRESS, lease->addr);
|
||||
PUTADDR(DHCP_IPADDRESS, lease->addr);
|
||||
if (lease->server.s_addr)
|
||||
PUTADDR(DHCP_SERVERID, lease->server);
|
||||
}
|
||||
@ -832,19 +849,29 @@ read_lease(const struct interface *iface)
|
||||
}
|
||||
|
||||
ssize_t
|
||||
write_string(FILE *f, const uint8_t *data, ssize_t len)
|
||||
print_string(char *s, const uint8_t *data, ssize_t len)
|
||||
{
|
||||
uint8_t c;
|
||||
const uint8_t *e;
|
||||
ssize_t bytes = 0;
|
||||
ssize_t r;
|
||||
|
||||
if (!len)
|
||||
len = *data++;
|
||||
e = data + len;
|
||||
c = *data++;
|
||||
e = data + c;
|
||||
while (data < e) {
|
||||
c = *data++;
|
||||
if (!isascii(c) || !isprint(c)) {
|
||||
bytes += fprintf(f, "\\%03o", c);
|
||||
if (s) {
|
||||
if (len < 5) {
|
||||
errno = ENOBUFS;
|
||||
return -1;
|
||||
}
|
||||
r = snprintf(s, len, "\\%03o", c);
|
||||
len -= r;
|
||||
bytes += r;
|
||||
s += r;
|
||||
} else
|
||||
bytes += 4;
|
||||
continue;
|
||||
}
|
||||
switch (c) {
|
||||
@ -853,88 +880,184 @@ write_string(FILE *f, const uint8_t *data, ssize_t len)
|
||||
case '$': /* FALLTHROUGH */
|
||||
case '`': /* FALLTHROUGH */
|
||||
case '\\': /* FALLTHROUGH */
|
||||
case ' ': /* FALLTHROUGH */
|
||||
if (fputc('\\', f))
|
||||
bytes++;
|
||||
if (s) {
|
||||
if (len < 3) {
|
||||
errno = ENOBUFS;
|
||||
return -1;
|
||||
}
|
||||
*s++ = '\\';
|
||||
len--;
|
||||
}
|
||||
bytes++;
|
||||
break;
|
||||
}
|
||||
if (fputc(c, f))
|
||||
bytes++;
|
||||
if (s) {
|
||||
*s++ = c;
|
||||
len--;
|
||||
}
|
||||
bytes++;
|
||||
}
|
||||
|
||||
/* NULL */
|
||||
if (s)
|
||||
*s = '\0';
|
||||
bytes++;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
write_options(FILE *f, const struct dhcp_message *dhcp)
|
||||
static ssize_t
|
||||
print_option(char *s, int type, const uint8_t *data, ssize_t len)
|
||||
{
|
||||
uint8_t i;
|
||||
const uint8_t *e, *t;
|
||||
uint8_t u8;
|
||||
uint16_t u16;
|
||||
int16_t s16;
|
||||
uint32_t u32;
|
||||
int32_t s32;
|
||||
struct in_addr addr;
|
||||
ssize_t bytes = 0;
|
||||
ssize_t l;
|
||||
|
||||
if (!type || type & STRING)
|
||||
return print_string(s, data, len);
|
||||
|
||||
if (!s) {
|
||||
if (type & UINT8)
|
||||
l = 3;
|
||||
else if (type & UINT16)
|
||||
l = 5;
|
||||
else if (type & SINT16)
|
||||
l = 6;
|
||||
else if (type & UINT32)
|
||||
l = 10;
|
||||
else if (type & SINT32)
|
||||
l = 11;
|
||||
else if (type & IPV4)
|
||||
l = 16;
|
||||
else {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
return (l + 1) * *data;
|
||||
}
|
||||
|
||||
l = *data++;
|
||||
t = data;
|
||||
e = data + l;
|
||||
while (data < e) {
|
||||
if (data != t) {
|
||||
*s++ = ' ';
|
||||
bytes++;
|
||||
len--;
|
||||
}
|
||||
if (type & UINT8) {
|
||||
l = snprintf(s, len, "%d", *data);
|
||||
data++;
|
||||
} else if (type & UINT16) {
|
||||
memcpy(&u16, data, sizeof(u16));
|
||||
u16 = ntohs(u16);
|
||||
l = snprintf(s, len, "%d", u16);
|
||||
data += sizeof(u16);
|
||||
} else if (type & SINT16) {
|
||||
memcpy(&s16, data, sizeof(s16));
|
||||
s16 = ntohs(s16);
|
||||
l = snprintf(s, len, "%d", s16);
|
||||
data += sizeof(s16);
|
||||
} else if (type & UINT32) {
|
||||
memcpy(&u32, data, sizeof(u32));
|
||||
u32 = ntohl(u32);
|
||||
l = snprintf(s, len, "%d", u32);
|
||||
data += sizeof(u32);
|
||||
} else if (type & SINT32) {
|
||||
memcpy(&s32, data, sizeof(s32));
|
||||
s32 = ntohl(s32);
|
||||
l = snprintf(s, len, "%d", s32);
|
||||
data += sizeof(s32);
|
||||
} else if (type & IPV4) {
|
||||
memcpy(&addr.s_addr, data, sizeof(addr.s_addr));
|
||||
l = snprintf(s, len, "%s", inet_ntoa(addr));
|
||||
data += sizeof(addr.s_addr);
|
||||
}
|
||||
len -= l;
|
||||
bytes += l;
|
||||
s += l;
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static int
|
||||
_setenv(const char *prefix, const char *var, const char *value)
|
||||
{
|
||||
size_t len = strlen(prefix) + strlen(var) + 3;
|
||||
char *name = xmalloc(len);
|
||||
int r;
|
||||
|
||||
snprintf(name, len, "%s_%s", prefix, var);
|
||||
if (value)
|
||||
r = setenv(name, value, 1);
|
||||
else
|
||||
r = unsetenv(name);
|
||||
free(name);
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
configure_env(const char *prefix, const struct dhcp_message *dhcp)
|
||||
{
|
||||
int i;
|
||||
const uint8_t *p, *e, *t;
|
||||
uint32_t u32;
|
||||
uint16_t u16;
|
||||
uint8_t u8;
|
||||
struct in_addr addr;
|
||||
ssize_t retval = 0;
|
||||
struct in_addr net;
|
||||
struct in_addr brd;
|
||||
char *val;
|
||||
const struct dhcp_option *opt;
|
||||
ssize_t len;
|
||||
char cidr[4];
|
||||
|
||||
if (dhcp->yiaddr) {
|
||||
/* Set some useful variables that we drive from the DHCP
|
||||
* message but are not necessarily in the options */
|
||||
addr.s_addr = dhcp->yiaddr;
|
||||
_setenv(prefix, "ip_address", inet_ntoa(addr));
|
||||
if (get_option_addr(&net.s_addr, dhcp, DHCP_SUBNETMASK) == -1) {
|
||||
net.s_addr = get_netmask(addr.s_addr);
|
||||
_setenv(prefix, "subnet_mask", inet_ntoa(net));
|
||||
}
|
||||
i = inet_ntocidr(net);
|
||||
snprintf(cidr, sizeof(cidr), "%d", inet_ntocidr(net));
|
||||
_setenv(prefix, "subnet_cidr", cidr);
|
||||
if (get_option_addr(&brd.s_addr, dhcp, DHCP_BROADCAST) == -1) {
|
||||
brd.s_addr = addr.s_addr | ~net.s_addr;
|
||||
_setenv(prefix, "broadcast_address", inet_ntoa(net));
|
||||
}
|
||||
addr.s_addr = dhcp->yiaddr & net.s_addr;
|
||||
_setenv(prefix, "network_address", inet_ntoa(addr));
|
||||
|
||||
} else {
|
||||
_setenv(prefix, "ip_address", NULL);
|
||||
_setenv(prefix, "subnet_cidr", NULL);
|
||||
_setenv(prefix, "network_address", NULL);
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(dhcp_options) / sizeof(dhcp_options[0]); i++) {
|
||||
if (!dhcp_options[i].var)
|
||||
opt = &dhcp_options[i];
|
||||
if (!opt->var)
|
||||
continue;
|
||||
|
||||
retval += fprintf(f, "%s=", dhcp_options[i].var);
|
||||
|
||||
/* Unknown type, so just print escape codes */
|
||||
if (dhcp_options[i].type == STRING) {
|
||||
p = get_option(dhcp, dhcp_options[i].option);
|
||||
if (p)
|
||||
retval += write_string(f, p, 0);
|
||||
val = NULL;
|
||||
p = get_option(dhcp, opt->option);
|
||||
if (p) {
|
||||
len = print_option(NULL, opt->type, p, 0);
|
||||
if (len < 0)
|
||||
return -1;
|
||||
val = xmalloc(len);
|
||||
print_option(val, opt->type, p, len);
|
||||
}
|
||||
|
||||
if ((dhcp_options[i].type & IPV4 ||
|
||||
dhcp_options[i].type & ARRAY) &&
|
||||
(p = get_option(dhcp, dhcp_options[i].option)))
|
||||
{
|
||||
u8 = *p++;
|
||||
t = p;
|
||||
e = p + u8;
|
||||
while (p < e) {
|
||||
if (p != t)
|
||||
retval += fprintf(f, "\\ ");
|
||||
if (dhcp_options[i].type & UINT8) {
|
||||
retval += fprintf(f, "%d", *p);
|
||||
p++;
|
||||
} else if (dhcp_options[i].type & UINT16) {
|
||||
memcpy(&u16, p, sizeof(u16));
|
||||
u16 = ntohs(u16);
|
||||
retval += fprintf(f, "%d", *p);
|
||||
p += sizeof(u16);
|
||||
} else if (dhcp_options[i].type & UINT32) {
|
||||
memcpy(&u32, p, sizeof(u32));
|
||||
u32 = ntohl(u32);
|
||||
retval += fprintf(f, "%d", *p);
|
||||
p += sizeof(u32);
|
||||
} else if (dhcp_options[i].type & IPV4) {
|
||||
memcpy(&addr.s_addr, p,
|
||||
sizeof(addr.s_addr));
|
||||
retval += fprintf(f, "%s",
|
||||
inet_ntoa(addr));
|
||||
p += sizeof(addr.s_addr);
|
||||
} else
|
||||
/* Sanity check */
|
||||
p = e;
|
||||
}
|
||||
}
|
||||
|
||||
if (dhcp_options[i].type & UINT32) {
|
||||
if (get_option_uint32(&u32, dhcp,
|
||||
dhcp_options[i].option) == 0)
|
||||
retval += fprintf(f, "%d", u32);
|
||||
}
|
||||
|
||||
if (dhcp_options[i].type & UINT16) {
|
||||
if (get_option_uint16(&u16, dhcp,
|
||||
dhcp_options[i].option) == 0)
|
||||
retval += fprintf(f, "%d", u16);
|
||||
}
|
||||
|
||||
retval += fprintf(f, "\n");
|
||||
_setenv(prefix, opt->var, val);
|
||||
free(val);
|
||||
}
|
||||
return retval;
|
||||
return 0;
|
||||
}
|
||||
|
60
dhcp.h
60
dhcp.h
@ -65,56 +65,17 @@
|
||||
enum DHCP_OPTIONS
|
||||
{
|
||||
DHCP_PAD = 0,
|
||||
DHCP_NETMASK = 1,
|
||||
DHCP_TIMEOFFSET = 2,
|
||||
DHCP_SUBNETMASK = 1,
|
||||
DHCP_ROUTER = 3,
|
||||
DHCP_TIMESERVER = 4,
|
||||
DHCP_NAMESERVER = 5,
|
||||
DHCP_DNSSERVER = 6,
|
||||
DHCP_LOGSERVER = 7,
|
||||
DHCP_COOKIESERVER = 8,
|
||||
DHCP_LPRSERVER = 9,
|
||||
DHCP_IMPRESSSERVER = 10,
|
||||
DHCP_RESOURCELOCATIONSERVER = 11,
|
||||
DHCP_HOSTNAME = 12,
|
||||
DHCP_BOOTFILESIZE = 13,
|
||||
DHCP_MERITDUMPFILE = 14,
|
||||
DHCP_DNSDOMAIN = 15,
|
||||
DHCP_SWAPSERVER = 16,
|
||||
DHCP_ROOTPATH = 17,
|
||||
DHCP_EXTENSIONSPATH = 18,
|
||||
DHCP_IPFORWARDING = 19,
|
||||
DHCP_NONLOCALSOURCEROUTING = 20,
|
||||
DHCP_POLICYFILTER = 21,
|
||||
DHCP_MAXDGRAMSIZE = 22,
|
||||
DHCP_DEFAULTIPTTL = 23,
|
||||
DHCP_PATHMTUAGINGTIMEOUT = 24,
|
||||
DHCP_PATHMTUPLATEAUTABLE = 25,
|
||||
DHCP_MTU = 26,
|
||||
DHCP_ALLSUBNETSLOCAL = 27,
|
||||
DHCP_BROADCAST = 28,
|
||||
DHCP_MASKDISCOVERY = 29,
|
||||
DHCP_MASKSUPPLIER = 30,
|
||||
DHCP_ROUTERDISCOVERY = 31,
|
||||
DHCP_ROUTERSOLICITATIONADDR = 32,
|
||||
DHCP_STATICROUTE = 33,
|
||||
DHCP_TRAILERENCAPSULATION = 34,
|
||||
DHCP_ARPCACHETIMEOUT = 35,
|
||||
DHCP_ETHERNETENCAPSULATION = 36,
|
||||
DHCP_TCPDEFAULTTTL = 37,
|
||||
DHCP_TCPKEEPALIVEINTERVAL = 38,
|
||||
DHCP_TCPKEEPALIVEGARBAGE = 39,
|
||||
DHCP_NISDOMAIN = 40,
|
||||
DHCP_NISSERVER = 41,
|
||||
DHCP_NTPSERVER = 42,
|
||||
DHCP_VENDORSPECIFICINFO = 43,
|
||||
DHCP_NETBIOSNAMESERVER = 44,
|
||||
DHCP_NETBIOSDGRAMSERVER = 45,
|
||||
DHCP_NETBIOSNODETYPE = 46,
|
||||
DHCP_NETBIOSSCOPE = 47,
|
||||
DHCP_XFONTSERVER = 48,
|
||||
DHCP_XDISPLAYMANAGER = 49,
|
||||
DHCP_ADDRESS = 50,
|
||||
DHCP_IPADDRESS = 50,
|
||||
DHCP_LEASETIME = 51,
|
||||
DHCP_OPTIONSOVERLOADED = 52,
|
||||
DHCP_MESSAGETYPE = 53,
|
||||
@ -126,21 +87,9 @@ enum DHCP_OPTIONS
|
||||
DHCP_REBINDTIME = 59,
|
||||
DHCP_CLASSID = 60,
|
||||
DHCP_CLIENTID = 61,
|
||||
DHCP_NISPLUSDOMAIN = 64,
|
||||
DHCP_NISPLUSSERVER = 65,
|
||||
DHCP_MOBILEIPHOMEAGENT = 68,
|
||||
DHCP_SMTPSERVER = 69,
|
||||
DHCP_POP3SERVER = 70,
|
||||
DHCP_NNTPSERVER = 71,
|
||||
DHCP_WWWSERVER = 72,
|
||||
DHCP_FINGERSERVER = 73,
|
||||
DHCP_IRCSERVER = 74,
|
||||
DHCP_STREETTALKSERVER = 75,
|
||||
DHCP_STREETTALKDASERVER = 76,
|
||||
DHCP_USERCLASS = 77, /* RFC 3004 */
|
||||
DHCP_FQDN = 81,
|
||||
DHCP_DNSSEARCH = 119, /* RFC 3397 */
|
||||
DHCP_SIPSERVER = 120, /* RFC 3361 */
|
||||
DHCP_CSR = 121, /* RFC 3442 */
|
||||
DHCP_MSCSR = 249, /* MS code for RFC 3442 */
|
||||
DHCP_END = 255
|
||||
@ -221,6 +170,8 @@ int get_option_uint16(uint16_t *, const struct dhcp_message *, uint8_t);
|
||||
int get_option_uint8(uint8_t *, const struct dhcp_message *, uint8_t);
|
||||
struct rt *get_option_routes(const struct dhcp_message *);
|
||||
struct rt *decode_rfc3442(const uint8_t *);
|
||||
int configure_env(const char *, const struct dhcp_message *);
|
||||
|
||||
ssize_t make_message(struct dhcp_message **,
|
||||
const struct interface *, const struct dhcp_lease *,
|
||||
uint32_t, uint8_t, const struct options *);
|
||||
@ -228,7 +179,4 @@ int valid_dhcp_packet(unsigned char *);
|
||||
|
||||
ssize_t write_lease(const struct interface *, const struct dhcp_message *);
|
||||
struct dhcp_message *read_lease(const struct interface *iface);
|
||||
|
||||
ssize_t write_string(FILE *f, const uint8_t *, ssize_t);
|
||||
ssize_t write_options(FILE *f, const struct dhcp_message *);
|
||||
#endif
|
||||
|
16
dhcpcd.8.in
16
dhcpcd.8.in
@ -284,13 +284,11 @@ Don't request any options beyond what is needed to configure the interface.
|
||||
.It Fl R , -nodns
|
||||
Don't send DNS information to resolvconf or touch
|
||||
.Pa /etc/resolv.conf .
|
||||
.It Fl T , -test
|
||||
On receipt of discover messages, simply print the contents of the DHCP
|
||||
message to the console.
|
||||
.Nm
|
||||
will not configure the
|
||||
.Ar interface ,
|
||||
touch any files or restart any services.
|
||||
.It Fl T, -test
|
||||
On receipt of discover messages we just call @SYSCONFDIR@/dhcpcd.sh with the
|
||||
reason of TEST which echo's the DHCP variables found in the message to the
|
||||
console. The interface configuration isn't touched and neither are any
|
||||
configuration files.
|
||||
.It Fl Y , -nonis
|
||||
Don't touch
|
||||
.Pa /etc/yp.conf
|
||||
@ -331,10 +329,6 @@ Linux Socket Filter, or LPF device on Linux based systems.
|
||||
Bourne shell script that is run when we configure or deconfigure an interface.
|
||||
.It Pa @DBDIR@/dhcpcd.duid
|
||||
Text file that holds the DUID used to identify the host.
|
||||
.It Pa @DBDIR@/dhcpcd- Ns Ar interface Ns .info
|
||||
Bourne shell file that holds the DHCP values used in configuring the interface.
|
||||
This path is passed as the first argument to
|
||||
.Pa @SYSCONFDIR@/dhcpcd.sh .
|
||||
.It Pa @DBDIR@/dhcpcd- Ns Ar interface Ns .lease
|
||||
The actual DHCP message send by the server. We use this when reading the last
|
||||
lease and use the files mtime as when it was issued.
|
||||
|
271
dhcpcd.sh
271
dhcpcd.sh
@ -1,271 +0,0 @@
|
||||
#!/bin/sh
|
||||
# dhcpcd - DHCP client daemon
|
||||
# Copyright 2006-2008 Roy Marples <roy@marples.name>
|
||||
# All rights reserved
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
|
||||
info="$1"
|
||||
state="$2"
|
||||
|
||||
[ -e "${info}" ] && . "${info}"
|
||||
|
||||
do_hooks()
|
||||
{
|
||||
local x= retval=0
|
||||
for x in /etc/dhcpcd/"$1"-hook /etc/dhcpcd/"$1"-hook.d/*; do
|
||||
if [ -e "${x}" ]; then
|
||||
. "${x}"
|
||||
retval=$((${retval} + $?))
|
||||
fi
|
||||
done
|
||||
return ${retval}
|
||||
}
|
||||
|
||||
# Try and locate a service pidfile
|
||||
service_pid()
|
||||
{
|
||||
local service="$1" x=
|
||||
for x in "${service}".pid \
|
||||
"${service}"/pid \
|
||||
"${service}"/"${service}".pid;
|
||||
do
|
||||
if [ -s "/var/run/${x}" ]; then
|
||||
echo "/var/run/${x}"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
# Try and detect how to handle services so we're pretty
|
||||
# platform independant
|
||||
do_service()
|
||||
{
|
||||
local service="$1" action="$2"
|
||||
shift; shift
|
||||
|
||||
# If restarting check if service is running or not if we can
|
||||
if [ "${action}" = "restart" ]; then
|
||||
pidfile=$(service_pid "${service}")
|
||||
[ -s "${pidfile}" ] || return 0
|
||||
kill -0 $(cat "${pidfile}") 2>/dev/null || return 0
|
||||
fi
|
||||
|
||||
if type rc-service >/dev/null 2>/dev/null; then
|
||||
rc-service "${service}" -- --nodeps "${action}" "$@"
|
||||
elif [ -x /sbin/service ]; then
|
||||
service "${service}" "${action}" "$@"
|
||||
elif [ -x /etc/init.d/"${service}" -a -x /sbin/runscript ]; then
|
||||
/etc/init.d/"${service}" --quiet --nodeps "${action}" "$@"
|
||||
elif [ -x /etc/init.d/"${service}" ]; then
|
||||
/etc/init.d/"${service}" "${action}" "$@"
|
||||
elif [ -x /etc/rc.d/"${service}" ]; then
|
||||
/etc/rc.d/"${service}" "${action}" "$@"
|
||||
elif [ -x /etc/rc.d/rc."${service}" ]; then
|
||||
/etc/rc.d/rc."${service}" "${action}" "$@"
|
||||
else
|
||||
echo "Don't know how to interact with services on this platform" >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
yesno()
|
||||
{
|
||||
[ -z "$1" ] && return 2
|
||||
|
||||
case "$1" in
|
||||
[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) return 0;;
|
||||
[Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) return 1;;
|
||||
esac
|
||||
return 2
|
||||
}
|
||||
|
||||
save_conf()
|
||||
{
|
||||
if [ -e "$1" ]; then
|
||||
rm -f "$1"-pre."${INTERFACE}"
|
||||
mv -f "$1" "$1"-pre."${INTERFACE}"
|
||||
fi
|
||||
}
|
||||
|
||||
restore_conf()
|
||||
{
|
||||
[ -e "$1"-pre."${INTERFACE}" ] || return 1
|
||||
rm -f "$1"
|
||||
mv -f "$1"-pre."${INTERFACE}" "$1"
|
||||
}
|
||||
|
||||
make_mtu()
|
||||
{
|
||||
if [ -n "${MTU}" ]; then
|
||||
ifconfig "${INTERFACE}" mtu "${MTU}"
|
||||
fi
|
||||
}
|
||||
|
||||
make_nis_conf() {
|
||||
[ -z "${NISDOMAIN}" -a -z "${NISSERVER}" ] && return 0
|
||||
local cf=/etc/yp.conf."${INTERFACE}" prefix= x= pidfile=
|
||||
echo "# Generated by dhcpcd for interface ${INTERFACE}" > "${cf}"
|
||||
if [ -n "${NISDOMAIN}" ]; then
|
||||
domainname "${NISDOMAIN}"
|
||||
if [ -n "${NISSERVER}" ]; then
|
||||
prefix="domain ${NISDOMAIN} server "
|
||||
else
|
||||
echo "domain ${NISDOMAIN} broadcast" >> "${cf}"
|
||||
fi
|
||||
else
|
||||
prefix="ypserver "
|
||||
fi
|
||||
for x in ${NISSERVER}; do
|
||||
echo "${prefix}${x}" >> "${cf}"
|
||||
done
|
||||
save_conf /etc/yp.conf
|
||||
mv -f "${cf}" /etc/yp.conf
|
||||
pidfile="$(service_pidfile ypbind)"
|
||||
if [ -s "${pidfile}" ]; then
|
||||
kill -HUP "${pidfile}"
|
||||
fi
|
||||
}
|
||||
|
||||
restore_nis_conf()
|
||||
{
|
||||
restore_conf /etc/yp.conf || return 0
|
||||
pidfile="$(service_pidfile ypbind)"
|
||||
if [ -s "${pidfile}" ]; then
|
||||
kill -HUP "${pidfile}"
|
||||
fi
|
||||
}
|
||||
|
||||
make_ntp_conf()
|
||||
{
|
||||
[ -z "${NTPSERVER}" ] && return 0
|
||||
local cf=/etc/ntp.conf."${INTERFACE}" x=
|
||||
echo "# Generated by dhcpcd for interface ${INTERFACE}" > "${cf}"
|
||||
echo "restrict default noquery notrust nomodify" >> "${cf}"
|
||||
echo "restrict 127.0.0.1" >> "${cf}"
|
||||
for x in ${NTPSERVER}; do
|
||||
echo "restrict ${x} nomodify notrap noquery" >> "${cf}"
|
||||
echo "server ${x}" >> "${cf}"
|
||||
done
|
||||
if [ ! -e /etc/ntp.conf ]; then
|
||||
true
|
||||
elif type cmp >/dev/null 2>&1; then
|
||||
cmp -s /etc/ntp.conf "${cf}"
|
||||
elif type diff >/dev/null 2>&1; then
|
||||
diff -q /etc/ntp.conf "${cf}" >/dev/null
|
||||
else
|
||||
false
|
||||
fi
|
||||
if [ $? = 0 ]; then
|
||||
rm -f "${cf}"
|
||||
else
|
||||
save_conf /etc/ntp.conf
|
||||
mv -f "${cf}" /etc/ntp.conf
|
||||
do_service ntp restart
|
||||
fi
|
||||
}
|
||||
|
||||
restore_ntp_conf()
|
||||
{
|
||||
restore_conf /etc/ntp.conf || return 0
|
||||
do_service ntp restart
|
||||
}
|
||||
|
||||
make_resolv_conf()
|
||||
{
|
||||
if [ -z "${DNSSERVER}" -a -z "${DNSDOMAIN}" -a -z "${DNSSEARCH}" ]; then
|
||||
return 0
|
||||
fi
|
||||
local x= conf="# Generated by dhcpcd for interface ${INTERFACE}\n"
|
||||
if [ -n "${DNSSEARCH}" ]; then
|
||||
conf="${conf}search ${DNSSEARCH}\n"
|
||||
elif [ -n "${DNSDOMAIN}" ]; then
|
||||
conf="${conf}search ${DNSDOMAIN}\n"
|
||||
fi
|
||||
for x in ${DNSSERVER}; do
|
||||
conf="${conf}nameserver ${x}\n"
|
||||
done
|
||||
if type resolvconf >/dev/null 2>&1; then
|
||||
printf "${conf}" | resolvconf -a "${INTERFACE}"
|
||||
else
|
||||
save_conf /etc/resolv.conf
|
||||
printf "${conf}" > /etc/resolv.conf
|
||||
do_service nscd restart
|
||||
fi
|
||||
}
|
||||
|
||||
restore_resolv_conf()
|
||||
{
|
||||
if type resolvconf >/dev/null 2>&1; then
|
||||
resolvconf -d "${INTERFACE}"
|
||||
else
|
||||
restore_conf /etc/resolv.conf || return 0
|
||||
do_service nscd restart
|
||||
fi
|
||||
}
|
||||
|
||||
need_hostname()
|
||||
{
|
||||
case "$(hostname)" in
|
||||
""|"(none)"|localhost) return 0;;
|
||||
esac
|
||||
return 1
|
||||
}
|
||||
|
||||
lookup_hostname()
|
||||
{
|
||||
if type host >/dev/null 2>&1; then
|
||||
host "${IPADDR}" | sed 's/.* domain name pointer \(.*\)./\1/'
|
||||
elif type dig >/dev/null 2>&1; then
|
||||
dig +short -x "${IPADDR}" | sed 's/\.$//'
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
make_hostname()
|
||||
{
|
||||
if need_hostname; then
|
||||
local name="${HOSTNAME}"
|
||||
[ -z "${name}" ] && name="$(lookup_hostname)"
|
||||
[ -n "${name}" ] && hostname "${name}"
|
||||
fi
|
||||
}
|
||||
|
||||
do_hooks enter
|
||||
|
||||
# Don't do anything by default when we go down
|
||||
if [ "${state}" = "down" ]; then
|
||||
restore_resolv_conf
|
||||
restore_nis_conf
|
||||
restore_ntp_conf
|
||||
exit $?
|
||||
fi
|
||||
|
||||
make_mtu
|
||||
make_resolv_conf
|
||||
make_hostname
|
||||
make_nis_conf
|
||||
make_ntp_conf
|
||||
|
||||
do_hooks exit
|
@ -15,9 +15,9 @@ SYSCONFDIR?= ${PREFIX}/etc
|
||||
INSTALL?= install
|
||||
SED?= sed
|
||||
|
||||
all: ${PROG} ${MAN}
|
||||
all: ${PROG} ${SCRIPT} ${MAN}
|
||||
|
||||
${PROG}: ${SCRIPTS} ${OBJS}
|
||||
${PROG}: ${OBJS}
|
||||
${CC} ${LDFLAGS} -o $@ ${OBJS} ${LDADD}
|
||||
|
||||
# We could save about 600 bytes by building it like this
|
||||
|
1
net.c
1
net.c
@ -358,7 +358,6 @@ read_interface(const char *ifname, _unused int metric)
|
||||
iface = xzalloc(sizeof(*iface));
|
||||
strlcpy(iface->name, ifname, IF_NAMESIZE);
|
||||
snprintf(iface->leasefile, PATH_MAX, LEASEFILE, ifname);
|
||||
snprintf(iface->infofile, PATH_MAX, INFOFILE, ifname);
|
||||
memcpy(&iface->hwaddr, hwaddr, hwlen);
|
||||
iface->hwlen = hwlen;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user