From: Roy Marples Date: Sat, 12 Apr 2008 23:00:23 +0000 (+0000) Subject: Move configuration file setup to dhcpcd.sh so that it's possible for the user to... X-Git-Tag: v4.0.2~508 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5a98646f72f9be4fe116d544f8b3d607d682789f;p=thirdparty%2Fdhcpcd.git Move configuration file setup to dhcpcd.sh so that it's possible for the user to change more easily. We now have enter/exit hooks similar to dhclient to make things even easier for the user. At this time, we are still 100% commandline compatible. However, we have lost the feature to lookup hostnames. --- diff --git a/Makefile b/Makefile index 41085cc0..4f0c669b 100644 --- a/Makefile +++ b/Makefile @@ -6,12 +6,14 @@ PROG= dhcpcd SRCS= common.c dhcp.c dhcpcd.c logger.c net.c signal.c SRCS+= configure.c client.c SRCS+= ${SRC_IF} ${SRC_SOCKET} +SCRIPT= dhcpcd.sh MAN= dhcpcd.8 VERSION= 3.3.0-alpha1 CLEANFILES= dhcpcd.8 BINDIR= ${PREFIX}/sbin +SCRIPTDIR= ${PREFIX}/etc .SUFFIXES: .in @@ -19,21 +21,8 @@ MK= mk include ${MK}/prog.mk CFLAGS+= -DVERSION=\"${VERSION}\" - -# Work out how to restart services -_RC_SH= if test -n "${HAVE_INIT}"; then \ - test "${HAVE_INIT}" = "no" || echo "-DENABLE_${HAVE_INIT}"; \ - elif test -x /sbin/runscript; then echo "-DENABLE_OPENRC"; \ - elif test -x /sbin/service; then echo "-DENABLE_SERVICE"; \ - elif test -x /etc/rc.d/rc.S -a -x /etc/rc.d/rc.M; then echo "-DENABLE_SLACKRC"; \ - elif test -d /etc/rc.d; then echo "-DENABLE_BSDRC"; \ - elif test -d /etc/init.d; then echo "-DENABLE_SYSV"; \ - fi -_RC!= ${_RC_SH} -CFLAGS+= ${_RC}$(shell ${_RC_SH}) - CFLAGS+= -DINFODIR=\"${INFODIR}\" -LDADD+= ${LIBRESOLV} ${LIBRT} +LDADD+= ${LIBRT} .in: ${SED} 's:@PREFIX@:${PREFIX}:g; s:@INFODIR@:${INFODIR}:g' $< > $@ diff --git a/client.c b/client.c index cdaa4734..087ba1f0 100644 --- a/client.c +++ b/client.c @@ -53,12 +53,6 @@ #include "logger.h" #include "signal.h" -#ifdef THERE_IS_NO_FORK -# ifndef ENABLE_INFO - # error "Non MMU requires ENABLE_INFO to work" -# endif -#endif - #ifdef ENABLE_IPV4LL # ifndef ENABLE_ARP # error "IPv4LL requires ENABLE_ARP to work" @@ -333,7 +327,6 @@ get_lease(struct dhcp_lease *lease, const struct dhcp_message *dhcp) lease->frominfo = 0; } -#ifdef ENABLE_INFO static int get_old_lease(struct if_state *state, const struct options *options) { @@ -410,7 +403,6 @@ get_old_lease(struct if_state *state, const struct options *options) state->dhcp = dhcp; return 0; } -#endif static int client_setup(struct if_state *state, const struct options *options) @@ -430,9 +422,7 @@ client_setup(struct if_state *state, const struct options *options) options->options & DHCPCD_REQUEST || options->options & DHCPCD_DAEMONISED)) { -#ifdef ENABLE_INFO if (!get_old_lease(state, options)) -#endif return -1; state->timeout = 0; @@ -802,7 +792,6 @@ handle_timeout(struct if_state *state, const struct options *options) if (options->options & DHCPCD_INFORM) return -1; -#ifdef ENABLE_INFO if (!(state->options & DHCPCD_TEST) && (state->options & DHCPCD_IPV4LL || state->options & DHCPCD_LASTLEASE)) @@ -816,7 +805,6 @@ handle_timeout(struct if_state *state, const struct options *options) } else if (errno == EINTR) return 0; } -#endif #ifdef ENABLE_IPV4LL if (!(state->options & DHCPCD_TEST) && @@ -842,7 +830,6 @@ handle_timeout(struct if_state *state, const struct options *options) } #endif -#if defined (ENABLE_INFO) || defined (ENABLE_IPV4LL) if (lease->addr.s_addr) { if (!(state->options & DHCPCD_DAEMONISED) && IN_LINKLOCAL(ntohl(lease->addr.s_addr))) @@ -871,7 +858,6 @@ handle_timeout(struct if_state *state, const struct options *options) state->xid = 0; return 0; } -#endif if (!(state->options & DHCPCD_DAEMONISED)) return -1; @@ -1004,13 +990,11 @@ handle_dhcp(struct if_state *state, struct dhcp_message *dhcp, const struct opti logger(LOG_INFO, "offered %s", addr); free(addr); -#ifdef ENABLE_INFO if (options->options & DHCPCD_TEST) { write_info(iface, dhcp, lease, options, 0); errno = 0; return -1; } -#endif free(dhcp); send_message(state, DHCP_REQUEST, options); diff --git a/config.h b/config.h index 5c30106b..f97bfd81 100644 --- a/config.h +++ b/config.h @@ -30,11 +30,7 @@ /* You can enable/disable various chunks of optional code here. * You would only do this to try and shrink the end binary if dhcpcd * was running on a low memory device */ - #define ENABLE_ARP -#define ENABLE_NTP -#define ENABLE_NIS -#define ENABLE_INFO /* IPV4LL, aka ZeroConf, aka APIPA, aka RFC 3927. * Needs ARP. */ @@ -46,9 +42,6 @@ * See RFC 3315 for details on this. */ #define ENABLE_DUID -/* resolvconf is framework for multiple interfaces to manage resolv.conf */ -#define ENABLE_RESOLVCONF - /* Some systems do not have a working fork. */ /* #define THERE_IS_NO_FORK */ @@ -58,15 +51,6 @@ #define ETCDIR "/etc" #define RESOLVFILE ETCDIR "/resolv.conf" - -#define NISFILE ETCDIR "/yp.conf" - -#define NTPFILE ETCDIR "/ntp.conf" -#define NTPDRIFTFILE ETCDIR "/ntp.drift" -#define NTPLOGFILE "/var/log/ntp.log" - -#define OPENNTPFILE ETCDIR "/ntpd.conf" - #define DEFAULT_SCRIPT ETCDIR "/" PACKAGE ".sh" #define STATEDIR "/var" @@ -79,52 +63,4 @@ #define INFOFILE INFODIR "/" PACKAGE "-%s.info" #define DUIDFILE INFODIR "/" PACKAGE ".duid" -/* OPENRC is Open Run Control, forked from Gentoo's baselayout package - * BSDRC is BSD style Run Control - * SLACKRC is Slackware Run Control - * SERVICE is RedHat service command - * SYSV should cover everthing else */ -#ifdef ENABLE_OPENRC -# define SERVICE "OPENRC" -# define NISSERVICE ETCDIR "/init.d/ypbind" -# define NISRESTARTARGS "--nodeps", "--quiet", "conditionalrestart" -# define NTPSERVICE ETCDIR "/init.d/ntpd" -# define NTPRESTARTARGS "--nodeps", "--quiet", "conditionalrestart" -#endif -#if ENABLE_BSDRC -# define SERVICE "BSDRC" -# define NISSERVICE ETCDIR "/rc.d/ypbind" -# define NISRESTARTARGS "restart" -# define NTPSERVICE ETCDIR "/rc.d/ntpd" -# define NTPRESTARTARGS "restart" -#endif -#if ENABLE_SLACKRC -# define SERVICE "SLACKRC" -# define NISSERVICE ETCDIR "/rc.d/rc.ypbind" -# define NISRESTARTARGS "restart" -# define NTPSERVICE ETCDIR "/rc.d/rc.ntpd" -# define NTPRESTARTARGS "restart" -#endif -#if ENABLE_SERVICE -# define SERVICE "SERVICE" -# define NISSERVICE "service" -# define NISRESTARTARGS "ypbind", "restart" -# define NTPSERVICE "service" -# define NTPRESTARTARGS "ntpd", "restart" -#endif -#if ENABLE_SYSV -# define SERVICE "SYSV" -# define NISSERVICE ETCDIR "/init.d/ypbind" -# define NISRESTARTARGS "restart" -# define NTPSERVICE ETCDIR "/init.d/ntpd" -# define NTPRESTARTARGS "restart" -#endif - -#ifndef NISSERVICE -# undef ENABLE_NIS -#endif -#ifndef NTPSERVICE -# undef ENABLE_NTP -#endif - #endif diff --git a/configure.c b/configure.c index 2fabd8c5..4eea2ce4 100644 --- a/configure.c +++ b/configure.c @@ -26,14 +26,12 @@ */ #include +#include #include #include -#include #include -#include -#include #include #include #include @@ -56,6 +54,8 @@ exec_cmd(const char *cmd, const char *args, ...) int n = 1; int ret = 0; pid_t pid; + pid_t wpid; + int status = 0; sigset_t full; sigset_t old; @@ -107,8 +107,21 @@ exec_cmd(const char *cmd, const char *args, ...) /* Restore our signals */ sigprocmask(SIG_SETMASK, &old, NULL); - free(argv); + + /* Wait for the script to finish */ + do { + wpid = waitpid(pid, &status, 0); + if (wpid < 1) + logger(LOG_ERR, "waitpid: %s", strerror(errno)); + } while (!WIFEXITED(status) && !WIFSIGNALED(status)); + + if (WIFEXITED(status)) + ret = WEXITSTATUS(status); + else + ret = -1; + if (ret != 0) + logger(LOG_ERR, "%s exited non zero", cmd); return ret; } @@ -124,380 +137,10 @@ exec_script(const char *script, _unused const char *infofile, const char *arg) return; } -#ifdef ENABLE_INFO logger(LOG_DEBUG, "exec \"%s\" \"%s\" \"%s\"", script, infofile, arg); exec_cmd(script, infofile, arg, (char *)NULL); -#else - logger(LOG_DEBUG, "exec \"%s\" \"\" \"%s\"", script, arg); - exec_cmd(script, "", arg, (char *)NULL); -#endif -} - -static char * -lookuphostname(in_addr_t addr) -{ - union { - struct sockaddr sa; - struct sockaddr_in sin; - } su; - socklen_t salen; - char *name; - struct addrinfo hints; - struct addrinfo *res = NULL; - int r; - - name = xmalloc(sizeof(char) * NI_MAXHOST); - salen = sizeof(su.sa); - memset(&su.sa, 0, salen); - su.sin.sin_family = AF_INET; - su.sin.sin_addr.s_addr = addr; - - r = getnameinfo(&su.sa, salen, name, NI_MAXHOST, NULL, 0, NI_NAMEREQD); - if (r != 0) { - free(name); - switch (r) { -#ifdef EAI_NODATA - case EAI_NODATA: /* FALLTHROUGH */ -#endif - case EAI_NONAME: - errno = ENOENT; - break; - case EAI_SYSTEM: - break; - default: - errno = EIO; - break; - } - return NULL; - } - - /* Check for a malicious PTR record */ - memset(&hints, 0, sizeof(hints)); - hints.ai_socktype = SOCK_DGRAM; - hints.ai_flags = AI_NUMERICHOST; - r = getaddrinfo(name, "0", &hints, &res); - if (res) - freeaddrinfo(res); - if (r == 0 || !*name) { - free(name); - errno = ENOENT; - return NULL; - } - - return name; -} - -static int -configure_hostname(const struct dhcp_message *dhcp, in_addr_t addr, int h) -{ - char *newhostname; - char *curhostname; - - curhostname = xmalloc(sizeof(char) * MAXHOSTNAMELEN); - *curhostname = '\0'; - - gethostname(curhostname, MAXHOSTNAMELEN); - if (h || - strlen(curhostname) == 0 || - strcmp(curhostname, "(none)") == 0 || - strcmp(curhostname, "localhost") == 0) - { - newhostname = get_option_string(dhcp, DHCP_HOSTNAME); - if (!newhostname || h) - newhostname = lookuphostname(addr); - - if (newhostname) { - logger(LOG_INFO, "setting hostname to `%s'", newhostname); - sethostname(newhostname, (int)strlen(newhostname)); - free(newhostname); - } - } - - free(curhostname); - return 0; -} - -#ifdef ENABLE_NIS -#define PREFIXSIZE 300 -static int -configure_nis(const char *ifname, const struct dhcp_message *dhcp) -{ - const uint8_t *servers; - char *domain; - FILE *f; - char *prefix; - const uint8_t *e; - uint8_t l; - struct in_addr addr; - - servers = get_option(dhcp, DHCP_NISSERVER); - domain = get_option_string(dhcp, DHCP_NISDOMAIN); - - if (!servers && !domain) { - if (errno == ENOENT) - return 0; - return -1; - } - - if (!(f = fopen(NISFILE, "w"))) - return -1; - - prefix = xmalloc(sizeof(char) * PREFIXSIZE); - *prefix = '\0'; - fprintf(f, "# Generated by dhcpcd for interface %s\n", ifname); - - if (domain) { - setdomainname(domain, (int)strlen(domain)); - if (servers) - snprintf(prefix, PREFIXSIZE, "domain %s server", - domain); - else - fprintf(f, "domain %s broadcast\n", domain); - free(domain); - } - else - strlcpy(prefix, "ypserver", PREFIXSIZE); - - if (servers) { - l = *servers++; - e = servers + l; - for(; servers < e; servers += sizeof(uint32_t)) { - memcpy(&addr.s_addr, servers, sizeof(uint32_t)); - fprintf(f, "%s %s\n", prefix, inet_ntoa(addr)); - } - } - - free(prefix); - fclose(f); - - return exec_cmd(NISSERVICE, NISRESTARTARGS, (char *)NULL); -} -#endif - -#ifdef ENABLE_NTP -static int -in_addresses(const uint8_t *addresses, uint32_t addr) -{ - uint8_t l = *addresses++; - const uint8_t *e = addresses + l; - uint32_t a; - - for (; addresses < e; addresses += sizeof(a)) { - memcpy(&a, addresses, sizeof(a)); - if (a == addr) - return 0; - } - return -1; -} - -static int -_make_ntp(const char *file, const char *ifname, const uint8_t *ntp) -{ - FILE *f; - char *a; - char *line = NULL; - size_t len = 0; - char *token; - struct in_addr addr; - uint8_t tomatch = *ntp; - const uint8_t *e; -#ifdef NTPFILE - int ntpfile; -#endif - - /* Check that we really need to update the servers. - * We do this because ntp has to be restarted to - * work with a changed config. */ - if (!(f = fopen(file, "r"))) { - if (errno != ENOENT) - return -1; - } else { - while (tomatch != 0 && (get_line(&line, &len, f))) { - a = line; - token = strsep(&a, " "); - if (!token || strcmp(token, "server") != 0) - continue; - if ((token = strsep(&a, " \n")) == NULL) - continue; - if (inet_aton(token, &addr) == 1 && - in_addresses(ntp, addr.s_addr) == 0) - tomatch--; - } - fclose(f); - free(line); - - /* File has the same name servers that we do, - * so no need to restart ntp */ - if (tomatch == 0) - return 0; - } - - if (!(f = fopen(file, "w"))) - return -1; - - fprintf(f, "# Generated by dhcpcd for interface %s\n", ifname); -#ifdef NTPFILE - if ((ntpfile = strcmp(file, NTPFILE)) == 0) { - fprintf(f, "restrict default noquery notrust nomodify\n"); - fprintf(f, "restrict 127.0.0.1\n"); - } -#endif - - tomatch = *ntp++; - e = ntp + tomatch; - for (; ntp < e; ntp += sizeof(uint32_t)) { - memcpy(&addr.s_addr, ntp, sizeof(uint32_t)); - a = inet_ntoa(addr); -#ifdef NTPFILE - if (ntpfile == 0) - fprintf(f, "restrict %s nomodify notrap noquery\n", a); -#endif - fprintf(f, "server %s\n", a); - } - fclose(f); - - return 1; -} -#endif - -static int -configure_ntp(const char *ifname, const struct dhcp_message *dhcp) -{ - const uint8_t *ntp = get_option(dhcp, DHCP_NTPSERVER); - int restart = 0; - int r; - - if (!ntp) { - if (errno == ENOENT) - return 0; - return -1; - } - -#ifdef NTPFILE - r = _make_ntp(NTPFILE, ifname, ntp); - if (r == -1) - return -1; - if (r > 0) - restart |= 1; -#endif - -#ifdef OPENNTPFILE - r = _make_ntp(OPENNTPFILE, ifname, ntp); - if (r == -1) - return -1; - if (r > 0) - restart |= 2; -#endif - - if (restart) - return exec_cmd(NTPSERVICE, NTPRESTARTARGS, (char *)NULL); - return 0; -} - -#ifdef ENABLE_RESOLVCONF -static int -file_in_path(const char *file) -{ - char *p = getenv("PATH"); - char *path; - char *token; - struct stat s; - char mypath[PATH_MAX]; - int retval = -1; - - if (!p) { - errno = ENOENT; - return -1; - } - - path = strdup(p); - p = path; - while ((token = strsep(&p, ":"))) { - snprintf(mypath, PATH_MAX, "%s/%s", token, file); - if (stat(mypath, &s) == 0) { - retval = 0; - break; - } - } - free(path); - return(retval); -} -#endif - -static int -configure_resolv(const char *ifname, const struct dhcp_message *dhcp) -{ - FILE *f = NULL; - const uint8_t *servers; - const uint8_t *e; - uint8_t l; - struct in_addr addr; - char *p; - -#ifdef ENABLE_RESOLVCONF - char *resolvconf = NULL; - size_t len; -#endif - - servers = get_option(dhcp, DHCP_DNSSERVER); - if (!servers) { - if (errno == ENOENT) - return 0; - return -1; - } - -#ifdef ENABLE_RESOLVCONF - if (file_in_path("resolvconf") == 0) { - len = strlen("resolvconf -a ") + strlen(ifname) + 1; - resolvconf = xmalloc(sizeof(char) * len); - snprintf(resolvconf, len, "resolvconf -a %s", ifname); - f = popen(resolvconf , "w"); - free(resolvconf); - } -#endif - if (!f && !(f = fopen(RESOLVFILE, "w"))) - return -1; - - fprintf(f, "# Generated by dhcpcd for interface %s\n", ifname); - p = get_option_string(dhcp, DHCP_DNSSEARCH); - if (!p) - p = get_option_string(dhcp, DHCP_DNSDOMAIN); - if (p) { - fprintf(f, "search %s\n", p); - free(p); - } - - l = *servers++; - e = servers + l; - for (; servers < e; servers += sizeof(uint32_t)) { - memcpy(&addr.s_addr, servers, sizeof(uint32_t)); - fprintf(f, "nameserver %s\n", inet_ntoa(addr)); - } - -#ifdef ENABLE_RESOLVCONF - if (resolvconf) - pclose(f); - else -#endif - fclose(f); - - /* Refresh the local resolver */ - res_init(); - return 0; } -#ifdef ENABLE_RESOLVCONF -static int -restore_resolv(const char *ifname) -{ - if (file_in_path("resolvconf") != 0) - return 0; - - return exec_cmd("resolvconf", "-d", ifname, (char *)NULL); -} -#endif - - static struct rt * reverse_routes(struct rt *routes) { @@ -728,7 +371,6 @@ configure_routes(struct interface *iface, const struct dhcp_message *dhcp, return retval; } -#ifdef ENABLE_INFO static void print_clean(FILE *f, const char *name, const char *value) { @@ -848,7 +490,6 @@ write_info(const struct interface *iface, const struct dhcp_message *dhcp, fclose(f); return 0; } -#endif int configure(struct interface *iface, const struct dhcp_message *dhcp, @@ -884,14 +525,12 @@ configure(struct interface *iface, const struct dhcp_message *dhcp, iface->mtu = iface->initial_mtu; } -#ifdef ENABLE_INFO /* 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)); } -#endif /* Only reset things if we had set them before */ if (iface->addr.s_addr != 0) { @@ -908,10 +547,6 @@ configure(struct interface *iface, const struct dhcp_message *dhcp, iface->addr.s_addr = 0; iface->net.s_addr = 0; } -#ifdef ENABLE_RESOLVCONF - if (options->options & DHCPCD_DNS) - restore_resolv(iface->name); -#endif } exec_script(options->script, iface->infofile, "down"); @@ -961,32 +596,16 @@ configure(struct interface *iface, const struct dhcp_message *dhcp, #endif configure_routes(iface, dhcp, options); - if (options->options & DHCPCD_DNS) - configure_resolv(iface->name, dhcp); -#ifdef ENABLE_NTP - if (options->options & DHCPCD_NTP) - configure_ntp(iface->name, dhcp); -#endif -#ifdef ENABLE_NIS - if (options->options & DHCPCD_NIS) - configure_nis(iface->name, dhcp); -#endif - configure_hostname(dhcp, addr.s_addr, - options->options & DHCPCD_HOSTNAME); - up = (iface->addr.s_addr != addr.s_addr || iface->net.s_addr != net.s_addr); - iface->addr.s_addr = addr.s_addr; iface->net.s_addr = net.s_addr; -#ifdef ENABLE_INFO - //if (!lease->frominfo) + if (!lease->frominfo) write_info(iface, dhcp, lease, options, 1); if (write_lease(iface, dhcp) == -1) logger(LOG_ERR, "write_lease: %s", strerror(errno)); -#endif - + exec_script(options->script, iface->infofile, up ? "new" : "up"); return 0; diff --git a/dhcp.c b/dhcp.c index cd30ad00..dce84c55 100644 --- a/dhcp.c +++ b/dhcp.c @@ -60,8 +60,8 @@ const struct dhcp_option dhcp_options[] = { { DHCP_NETMASK, OPT_IPV4R, NULL }, { DHCP_BROADCAST, OPT_IPV4R, NULL }, { DHCP_LEASETIME, OPT_UINT32, NULL }, - { DHCP_RENEWALTIME, OPT_UINT32R, "RENEWALTIME" }, - { DHCP_REBINDTIME, OPT_UINT32R, "REBINDTIME" }, + { DHCP_RENEWALTIME, OPT_UINT32R, NULL }, + { DHCP_REBINDTIME, OPT_UINT32R, NULL }, { DHCP_MTU, OPT_UINT16R, "MTU" }, { DHCP_STATICROUTE, OPT_IPV4R, NULL }, { DHCP_ROUTER, OPT_IPV4R, NULL }, @@ -69,17 +69,11 @@ const struct dhcp_option dhcp_options[] = { { DHCP_DNSSERVER, OPT_IPV4R, "DNSSERVER" }, { DHCP_DNSDOMAIN, OPT_STRINGR, "DNSDOMAIN" }, { DHCP_DNSSEARCH, OPT_STRINGR | OPT_RFC3397, "DNSSEARCH" }, -#ifdef ENABLE_NTP { DHCP_NTPSERVER, OPT_IPV4R, "NTPSERVER" }, -#endif -#ifdef ENABLE_NIS { DHCP_NISSERVER, OPT_IPV4R, "NISSERVER" }, { DHCP_NISDOMAIN, OPT_IPV4R, "NISDOMAIN" }, -#endif -#ifdef ENABLE_INFO { DHCP_ROOTPATH, OPT_STRINGR, "ROOTPATH" }, { DHCP_SIPSERVER, OPT_STRINGR | OPT_RFC3361, "SIPSERVER" }, -#endif { DHCP_MESSAGE, OPT_STRING, NULL}, { 0, 0, NULL } }; @@ -332,7 +326,6 @@ decode_rfc3442(const uint8_t *data) return routes; } -#ifdef ENABLE_INFO static char * decode_rfc3361(const uint8_t *data) { @@ -380,7 +373,6 @@ decode_rfc3361(const uint8_t *data) return sip; } -#endif char * get_option_string(const struct dhcp_message *dhcp, uint8_t option) @@ -750,7 +742,6 @@ read_lease(const struct interface *iface) return dhcp; } -#ifdef ENABLE_INFO /* Create a malloced string of cstr, changing ' to '\'' * so the contents work in a shell */ char * @@ -854,4 +845,3 @@ write_options(FILE *f, const struct dhcp_message *dhcp) } return retval; } -#endif diff --git a/dhcp.h b/dhcp.h index 5b53b2fe..1aa38ecd 100644 --- a/dhcp.h +++ b/dhcp.h @@ -186,8 +186,6 @@ 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); -#ifdef ENABLE_INFO char *clean_metas(const char *cstr); ssize_t write_options(FILE *f, const struct dhcp_message *dhcp); #endif -#endif diff --git a/dhcpcd.c b/dhcpcd.c index 1ad739ca..490ebc2f 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -170,9 +170,8 @@ main(int argc, char **argv) snprintf(options->classid, CLASS_ID_MAX_LEN, "%s %s", PACKAGE, VERSION); - options->options |= DHCPCD_ARP | DHCPCD_DNS | DHCPCD_MTU | - DHCPCD_NIS | DHCPCD_NTP | DHCPCD_GATEWAY | - DHCPCD_DAEMONISE | DHCPCD_IPV4LL | DHCPCD_DUID; + options->options |= DHCPCD_GATEWAY | DHCPCD_IPV4LL | DHCPCD_DUID | + DHCPCD_DAEMONISE; options->timeout = DEFAULT_TIMEOUT; gethostname(options->hostname, sizeof(options->hostname)); @@ -180,6 +179,11 @@ main(int argc, char **argv) strcmp(options->hostname, "localhost") == 0) *options->hostname = '\0'; + setenv("PEERDNS", "yes", 1); + setenv("PEERHOSTNAME", "no", 1); + setenv("PEERNIS", "yes", 1); + setenv("PEERNTP", "yes", 1); + /* Don't set any optional arguments here so we retain POSIX * compatibility with getopt */ while ((opt = getopt_long(argc, argv, EXTRA_OPTS @@ -340,10 +344,6 @@ main(int argc, char **argv) options->options &= ~DHCPCD_IPV4LL; break; case 'E': -#ifndef ENABLE_INFO - logger (LOG_ERR, "info not compiled into dhcpcd"); - goto abort; -#endif options->options |= DHCPCD_LASTLEASE; break; case 'F': @@ -367,7 +367,7 @@ main(int argc, char **argv) options->options &= ~DHCPCD_GATEWAY; break; case 'H': - options->options |= DHCPCD_HOSTNAME; + setenv("PEERHOSTNAME", "yes", 1); break; case 'I': if (optarg) { @@ -394,23 +394,19 @@ main(int argc, char **argv) options->options &= ~DHCPCD_MTU; break; case 'N': - options->options &= ~DHCPCD_NTP; + setenv("PEERNTP", "no", 1); break; case 'R': - options->options &= ~DHCPCD_DNS; + setenv("PEERDNS", "no", 1); break; case 'S': options->domscsr++; break; case 'T': -#ifndef ENABLE_INFO - logger(LOG_ERR, "info support not compiled into dhcpcd"); - goto abort; -#endif options->options |= DHCPCD_TEST | DHCPCD_PERSISTENT; break; case 'Y': - options->options &= ~DHCPCD_NIS; + setenv("PEERNIS", "no", 1); break; case '?': usage(); @@ -429,27 +425,12 @@ main(int argc, char **argv) #ifdef ENABLE_DUID " DUID" #endif -#ifdef ENABLE_INFO - " INFO" -#endif #ifdef ENABLE_INFO_COMPAT " INFO_COMPAT" #endif #ifdef ENABLE_IPV4LL " IPV4LL" #endif -#ifdef ENABLE_NIS - " NIS" -#endif -#ifdef ENABLE_NTP - " NTP" -#endif -#ifdef SERVICE - " " SERVICE -#endif -#ifdef ENABLE_RESOLVCONF - " RESOLVCONF" -#endif #ifdef THERE_IS_NO_FORK " THERE_IS_NO_FORK" #endif @@ -603,7 +584,7 @@ main(int argc, char **argv) /* Seed random */ srandomdev(); -#ifdef __linux +#ifdef __linux__ /* Massage our filters per platform */ setup_packet_filters(); #endif diff --git a/dhcpcd.h b/dhcpcd.h index 325a1a57..d3b6bb3b 100644 --- a/dhcpcd.h +++ b/dhcpcd.h @@ -53,12 +53,9 @@ extern char *dhcpcd_skiproutes; #endif #define DHCPCD_ARP (1 << 0) -#define DHCPCD_DNS (1 << 1) #define DHCPCD_DOMAIN (1 << 2) #define DHCPCD_GATEWAY (1 << 3) #define DHCPCD_MTU (1 << 4) -#define DHCPCD_NIS (1 << 5) -#define DHCPCD_NTP (1 << 6) #define DHCPCD_LASTLEASE (1 << 7) #define DHCPCD_INFORM (1 << 8) #define DHCPCD_REQUEST (1 << 9) diff --git a/dhcpcd.sh b/dhcpcd.sh index 8c86aac6..12e90e4d 100755 --- a/dhcpcd.sh +++ b/dhcpcd.sh @@ -1,46 +1,256 @@ #!/bin/sh +# +# dhcpcd - DHCP client daemon +# Copyright 2006-2008 Roy Marples +# All rights reserved # -# This is a sample /etc/dhcpcd.sh script. -# /etc/dhcpcd.sh script is executed by dhcpcd daemon -# any time it configures or shuts down interface. -# The following parameters are passed to dhcpcd.exe script: -# $1 = HostInfoFilePath, e.g "/var/lib/dhcpcd/dhcpcd-eth0.info" -# $2 = "up" if interface has been configured with the same -# IP address as before reboot; -# $2 = "down" if interface has been shut down; -# $2 = "new" if interface has been configured with new IP address; +# 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. # -# Sanity checks +# 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. -if [ $# -lt 2 ]; then - logger -s -p local0.err -t dhcpcd.sh "wrong usage" - exit 1 +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_nis_conf() { + yesno "${PEERNIS}" || return 0 + [ -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() +{ + yesno "${PEERNIS}" || return 0 + restore_conf /etc/yp.conf || return 0 + pidfile="$(service_pidfile ypbind)" + if [ -s "${pidfile}" ]; then + kill -HUP "${pidfile}" + fi +} + +make_ntp_conf() +{ + yesno "${PEERNTP}" || return 0 + [ -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 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() +{ + yesno "${PEERNTP}" || return 0 + restore_conf /etc/ntp.conf || return 0 + do_service ntp restart +} + +make_resolv_conf() +{ + yesno "${PEERDNS}" || return 0 + 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() +{ + yesno "${PEERDNS}" || return 0 + 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 +} + +make_hostname() +{ + [ -z "${HOSTNAME}" ] && return 0 + if need_hostname || yesno "${PEERHOSTNAME}"; then + hostname "${HOSTNAME}" + 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 -hostinfo="$1" -state="$2" +make_resolv_conf +make_hostname +make_nis_conf +make_ntp_conf -# Reading HostInfo file for configuration parameters -[ -e "${hostinfo}" ] && . "${hostinfo}" - -case "${state}" in - up) - logger -s -p local0.info -t dhcpcd.sh \ - "interface ${INTERFACE} has been configured with old IP=${IPADDR}" - # Put your code here for when the interface has been brought up with an - # old IP address here - ;; - - new) - logger -s -p local0.info -t dhcpcd.sh \ - "interface ${INTERFACE} has been configured with new IP=${IPADDR}" - # Put your code here for when the interface has been brought up with a - # new IP address - ;; - - down) logger -s -p local0.info -t dhcpcd.sh \ - "interface ${INTERFACE} has been brought down" - # Put your code here for the when the interface has been shut down - ;; -esac -exit 0 +do_hooks exit diff --git a/mk/prog.mk b/mk/prog.mk index ccbb81db..61c1a8a2 100644 --- a/mk/prog.mk +++ b/mk/prog.mk @@ -31,11 +31,15 @@ _proginstall: ${PROG} ${INSTALL} -m ${BINMODE} ${PROG} ${DESTDIR}${BINDIR} ${INSTALL} -d ${DESTDIR}${INFODIR} +_scriptinstall: ${SCRIPT} + ${INSTALL} -d ${DESTDIR}${SCRIPTDIR} + ${INSTALL} -m ${BINMODE} ${SCRIPT} ${DESTDIR}${SCRIPTDIR} + include ${MK}/depend.mk include ${MK}/man.mk include ${MK}/dist.mk -install: _proginstall maninstall +install: _proginstall _scriptinstall maninstall clean: rm -f ${OBJS} ${PROG} _${PROG}.c _${PROG}.o ${CLEANFILES} diff --git a/net.c b/net.c index a0de374b..5f7e363b 100644 --- a/net.c +++ b/net.c @@ -358,9 +358,7 @@ 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); -#ifdef ENABLE_INFO snprintf(iface->infofile, PATH_MAX, INFOFILE, ifname); -#endif memcpy(&iface->hwaddr, hwaddr, hwlen); iface->hwlen = hwlen; diff --git a/signal.c b/signal.c index d6f29617..ea036d6e 100644 --- a/signal.c +++ b/signal.c @@ -122,8 +122,6 @@ signal_read(struct pollfd *fd) int signal_init(void) { - struct sigaction sa; - if (pipe(signal_pipe) == -1) return -1; @@ -131,14 +129,6 @@ signal_init(void) close_on_exec(signal_pipe[0]); close_on_exec(signal_pipe[1]); - /* Ignore child signals and don't make zombies. - * Because we do this, we don't need to be in signal_setup */ - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - sa.sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT; - if (sigaction(SIGCHLD, &sa, NULL) == -1) - return -1; - memset(signals, 0, sizeof(signals)); return 0; }