From: Roy Marples Date: Tue, 3 Apr 2007 07:03:04 +0000 (+0000) Subject: You can now build dhcpcd without support for writing ntp, nis and info files X-Git-Tag: v3.2.3~296 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=522a128c7236125dd42840ea3e588bcf5b224f84;p=thirdparty%2Fdhcpcd.git You can now build dhcpcd without support for writing ntp, nis and info files which makes the binary a few k smaller. Support OpenNTP as well as NTP. Re-work the state engine a little, so we renew and rebind correctly. Subsequent debug options stop dhcpcd from daemonising. --- diff --git a/ChangeLog b/ChangeLog index a0b86fe4..298d94a9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +You can now build dhcpcd without support for writing ntp, nis and info files +which makes the binary a few k smaller. +Support OpenNTP as well as NTP. +Re-work the state engine a little, so we renew and rebind correctly. +Subsequent debug options stop dhcpcd from daemonising. When we get an invalid length for a DHCP option, try and continue anyway. When MTU is less than 576 we now ignore it instead of setting the MTU to 576. Build correctly on dietlibc, thanks to d00mer. diff --git a/Makefile b/Makefile index 544e8259..578b521d 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # Should work for both GNU make and BSD make -VERSION = 3.0.16 +VERSION = 3.0.17_pre2 CFLAGS ?= -O2 -pipe @@ -8,7 +8,7 @@ CFLAGS ?= -O2 -pipe # IMPORTANT: We should be using c99 instead of gnu99 but for some reason # generic linux headers as of 2.6.19 don't allow this in asm/types.h CFLAGS += -pedantic -std=gnu99 \ - -Wall -Wunused -Wimplicit -Wshadow -Wformat=2 \ + -Wall -Wextra -Wunused -Wimplicit -Wshadow -Wformat=2 \ -Wmissing-declarations -Wno-missing-prototypes -Wwrite-strings \ -Wbad-function-cast -Wnested-externs -Wcomment -Winline \ -Wchar-subscripts -Wcast-align -Wno-format-nonliteral diff --git a/client.c b/client.c index d780358e..afdc4f56 100644 --- a/client.c +++ b/client.c @@ -21,7 +21,6 @@ #include #include -#include #include #ifdef __linux__ #include @@ -86,6 +85,15 @@ send_message (iface, dhcp, xid, _type, options); \ } +#define DROP_CONFIG \ +{ \ + memset (&dhcp->address, 0, sizeof (struct in_addr)); \ + if (iface->previous_address.s_addr != 0 && ! options->persistent) \ + configure (options, iface, dhcp); \ + free_dhcp (dhcp); \ + memset (dhcp, 0, sizeof (dhcp_t)); \ +} + static int daemonise (const char *pidfile) { logger (LOG_DEBUG, "forking to background"); @@ -240,10 +248,6 @@ int dhcp_run (const options_t *options) { switch (sig) { - case SIGCHLD: - /* Silently ignore this signal and wait for it - This stops zombies */ - wait (0); break; case SIGINT: logger (LOG_INFO, "received SIGINT, stopping"); @@ -311,17 +315,7 @@ int dhcp_run (const options_t *options) xid = 0; SOCKET_MODE (SOCKET_CLOSED); if (! options->persistent) - { - free_dhcp (dhcp); - memset (dhcp, 0, sizeof (dhcp_t)); - configure (options, iface, dhcp); - } - if (! daemonised) - { - retval = -1; - goto eexit; - } - break; + DROP_CONFIG; } if (xid == 0) @@ -368,22 +362,25 @@ int dhcp_run (const options_t *options) break; case STATE_REBINDING: logger (LOG_ERR, "lost lease, attemping to rebind"); + memset (&dhcp->address, 0, sizeof (struct in_addr)); SOCKET_MODE (SOCKET_OPEN); - SEND_MESSAGE (DHCP_DISCOVER); + SEND_MESSAGE (DHCP_REQUEST); timeout = dhcp->leasetime - dhcp->rebindtime; - state = STATE_INIT; + state = STATE_REQUESTING; break; case STATE_REQUESTING: - logger (LOG_ERR, "timed out"); - if (! daemonised) + if (iface->previous_address.s_addr != 0) + logger (LOG_ERR, "lost lease"); + else + logger (LOG_ERR, "timed out"); + if (! daemonised && options->daemonise) goto eexit; state = STATE_INIT; SOCKET_MODE (SOCKET_CLOSED); timeout = 0; xid = 0; - free_dhcp (dhcp); - memset (dhcp, 0, sizeof (dhcp_t)); + DROP_CONFIG; break; case STATE_RELEASED: @@ -420,12 +417,12 @@ int dhcp_run (const options_t *options) if (xid != message.xid) { logger (LOG_ERR, - "ignoring packet with xid %d as it's not ours (%d)", + "ignoring packet with xid 0x%x as it's not ours (0x%x)", message.xid, xid); continue; } - logger (LOG_DEBUG, "got a packet with xid %d", message.xid); + logger (LOG_DEBUG, "got a packet with xid 0x%x", message.xid); memset (new_dhcp, 0, sizeof (dhcp_t)); if ((type = parse_dhcpmessage (new_dhcp, &message)) < 0) { @@ -461,9 +458,7 @@ int dhcp_run (const options_t *options) state = STATE_INIT; timeout = 0; xid = 0; - free_dhcp (dhcp); - memset (dhcp, 0, sizeof (dhcp_t)); - configure (options, iface, dhcp); + DROP_CONFIG; continue; } @@ -502,12 +497,7 @@ int dhcp_run (const options_t *options) SOCKET_MODE (SOCKET_OPEN); SEND_MESSAGE (DHCP_DECLINE); SOCKET_MODE (SOCKET_CLOSED); - - free_dhcp (dhcp); - memset (dhcp, 0, sizeof (dhcp_t)); - - if (daemonised) - configure (options, iface, dhcp); + DROP_CONFIG; xid = 0; timeout = 0; @@ -592,7 +582,7 @@ int dhcp_run (const options_t *options) goto eexit; } - if (! daemonised) + if (! daemonised && options->daemonise) { if ((daemonise (options->pidfile)) < 0 ) { @@ -627,12 +617,7 @@ int dhcp_run (const options_t *options) eexit: SOCKET_MODE (SOCKET_CLOSED); - - /* Remove our config if we need to */ - free_dhcp (dhcp); - memset (dhcp, 0, sizeof (dhcp_t)); - if (iface->previous_address.s_addr != 0 && ! options->persistent && daemonised) - configure (options, iface, dhcp); + DROP_CONFIG; free (dhcp); if (iface) diff --git a/configure.c b/configure.c index 21e07387..ce43d015 100644 --- a/configure.c +++ b/configure.c @@ -47,34 +47,6 @@ #include "logger.h" #include "socket.h" -static char *cleanmetas (const char *cstr) -{ - /* The largest single element we can have is 256 bytes according to the RFC, - so this buffer size should be safe even if it's all ' */ - static char buffer[1024]; - char *b = buffer; - - memset (buffer, 0, sizeof (buffer)); - if (cstr == NULL || strlen (cstr) == 0) - return b; - - do - if (*cstr == 39) - { - *b++ = '\''; - *b++ = '\\'; - *b++ = '\''; - *b++ = '\''; - } - else - *b++ = *cstr; - while (*cstr++); - - *b++ = 0; - b = buffer; - - return b; -} /* IMPORTANT: Ensure that the last parameter is NULL when calling */ static int exec_cmd (const char *cmd, const char *args, ...) @@ -105,7 +77,7 @@ static int exec_cmd (const char *cmd, const char *args, ...) if ((pid = fork ()) == 0) { - if (execve (cmd, argv, NULL) && errno != ENOENT) + if (execv (cmd, argv) && errno != ENOENT) logger (LOG_ERR, "error executing \"%s\": %s", cmd, strerror (errno)); exit (0); @@ -121,8 +93,13 @@ static void exec_script (const char *script, const char *infofile, { struct stat buf; +#ifdef ENABLE_INFO if (! script || ! infofile || ! arg) return; +#else + if (! script || ! arg) + return ; +#endif if (stat (script, &buf) < 0) { @@ -131,8 +108,13 @@ static void exec_script (const char *script, const char *infofile, return; } +#ifdef ENABLE_INFO logger (LOG_DEBUG, "exec \"%s %s %s\"", script, infofile, arg); exec_cmd (script, infofile, arg, NULL); +#else + logger (LOG_DEBUG, "exec \"%s \"\" %s\"", script, infofile, arg); + exec_cmd (script, infofile, "", arg, NULL); +#endif } static int make_resolv (const char *ifname, const dhcp_t *dhcp) @@ -142,6 +124,7 @@ static int make_resolv (const char *ifname, const dhcp_t *dhcp) char resolvconf[PATH_MAX] = {0}; address_t *address; +#ifdef RESOLVCONF if (stat (RESOLVCONF, &buf) == 0) { logger (LOG_DEBUG, "sending DNS information to resolvconf"); @@ -152,6 +135,7 @@ static int make_resolv (const char *ifname, const dhcp_t *dhcp) logger (LOG_ERR, "popen: %s", strerror (errno)); } else +#endif { logger (LOG_DEBUG, "writing "RESOLVFILE); if (! (f = fopen(RESOLVFILE, "w"))) @@ -185,6 +169,7 @@ static int make_resolv (const char *ifname, const dhcp_t *dhcp) static void restore_resolv(const char *ifname) { +#ifdef RESOLVCONF struct stat buf; if (stat (RESOLVCONF, &buf) < 0) @@ -192,9 +177,11 @@ static void restore_resolv(const char *ifname) logger (LOG_DEBUG, "removing information from resolvconf"); exec_cmd (RESOLVCONF, "-d", ifname, NULL); +#endif } -static int make_ntp (const char *ifname, const dhcp_t *dhcp) +#ifdef ENABLE_NTP +static int _make_ntp (const char *file, const char *ifname, const dhcp_t *dhcp) { FILE *f; address_t *address; @@ -202,17 +189,18 @@ static int make_ntp (const char *ifname, const dhcp_t *dhcp) char buffer[1024]; int tomatch = 0; char *token; + bool ntp = false; for (address = dhcp->ntpservers; address; address = address->next) tomatch++; /* 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(NTPFILE, "r"))) + if (! (f = fopen (file, "r"))) { if (errno != ENOENT) { - logger (LOG_ERR, "fopen `%s': %s", NTPFILE, strerror (errno)); + logger (LOG_ERR, "fopen `%s': %s", file, strerror (errno)); return -1; } } @@ -244,36 +232,85 @@ static int make_ntp (const char *ifname, const dhcp_t *dhcp) /* File has the same name servers that we do, so no need to restart ntp */ if (tomatch == 0) { - logger (LOG_DEBUG, "ntp already configured, skipping"); + logger (LOG_DEBUG, "%s already configured, skipping", file); return 0; } } - logger (LOG_DEBUG, "writing "NTPFILE); - if (! (f = fopen(NTPFILE, "w"))) + logger (LOG_DEBUG, "writing %s", file); + if (! (f = fopen (file, "w"))) { - logger (LOG_ERR, "fopen `%s': %s", NTPFILE, strerror (errno)); + logger (LOG_ERR, "fopen `%s': %s", file, strerror (errno)); return -1; } fprintf (f, "# Generated by dhcpcd for interface %s\n", ifname); - fprintf (f, "restrict default noquery notrust nomodify\n"); - fprintf (f, "restrict 127.0.0.1\n"); +#ifdef NTPFILE + if (strcmp (file, NTPFILE) == 0) + { + ntp = true; + fprintf (f, "restrict default noquery notrust nomodify\n"); + fprintf (f, "restrict 127.0.0.1\n"); + } +#endif for (address = dhcp->ntpservers; address; address = address->next) { a = inet_ntoa (address->address); - fprintf (f, "restrict %s nomodify notrap noquery\nserver %s\n", a, a); + if (ntp) + fprintf (f, "restrict %s nomodify notrap noquery\n", a); + fprintf (f, "server %s\n", a); } - fprintf (f, "driftfile " NTPDRIFTFILE "\n"); - fprintf (f, "logfile " NTPLOGFILE "\n"); + if (ntp) + { + fprintf (f, "driftfile " NTPDRIFTFILE "\n"); + fprintf (f, "logfile " NTPLOGFILE "\n"); + } fclose (f); - exec_cmd (NTPSERVICE, NTPRESTARTARGS, NULL); - return 0; + return 1; +} + +static int make_ntp (const char *ifname, const dhcp_t *dhcp) +{ + /* On some systems we have only have one ntp service, but we don't know + which configuration file we're using. So we need to write to both and + restart accordingly. */ + + bool restart_ntp = false; + bool restart_openntp = false; + int retval = 0; + +#ifdef NTPFILE + if (_make_ntp (NTPFILE, ifname, dhcp) > 0) + restart_ntp = true; +#endif + +#ifdef OPENNTPFILE + if (_make_ntp (OPENNTPFILE, ifname, dhcp) > 0) + restart_openntp = true; +#endif + +#ifdef NTPSERVICE + if (restart_ntp) + retval += exec_cmd (NTPSERVICE, NTPRESTARTARGS, NULL); +#endif + +#if defined (NTPSERVICE) && defined (OPENNTPSERVICE) + if (restart_openntp && + (strcmp (NTPSERVICE, OPENNTPSERVICE) != 0 || ! restart_ntp)) + retval += exec_cmd (OPENNTPSERVICE, OPENNTPRESTARTARGS, NULL); +#elif defined (OPENNTPSERVICE) && ! defined (NTPSERVICE) + if (restart_openntp) + retval += exec_cmd (OPENNTPSERVICE, OPENNTPRESTARTARGS, NULL); +#endif + + return retval; } +#endif +#ifdef ENABLE_NIS static int make_nis (const char *ifname, const dhcp_t *dhcp) { FILE *f; @@ -308,6 +345,37 @@ static int make_nis (const char *ifname, const dhcp_t *dhcp) exec_cmd (NISSERVICE, NISRESTARTARGS, NULL); return 0; } +#endif + +#ifdef ENABLE_INFO +static char *cleanmetas (const char *cstr) +{ + /* The largest single element we can have is 256 bytes according to the RFC, + so this buffer size should be safe even if it's all ' */ + static char buffer[1024]; + char *b = buffer; + + memset (buffer, 0, sizeof (buffer)); + if (cstr == NULL || strlen (cstr) == 0) + return b; + + do + if (*cstr == 39) + { + *b++ = '\''; + *b++ = '\\'; + *b++ = '\''; + *b++ = '\''; + } + else + *b++ = *cstr; + while (*cstr++); + + *b++ = 0; + b = buffer; + + return b; +} static int write_info(const interface_t *iface, const dhcp_t *dhcp, const options_t *options) @@ -417,6 +485,7 @@ static int write_info(const interface_t *iface, const dhcp_t *dhcp, fclose (f); return 0; } +#endif int configure (const options_t *options, interface_t *iface, const dhcp_t *dhcp) @@ -567,11 +636,15 @@ int configure (const options_t *options, interface_t *iface, else logger (LOG_DEBUG, "no dns information to write"); +#ifdef ENABLE_NTP if (options->dontp && dhcp->ntpservers) make_ntp(iface->name, dhcp); +#endif +#ifdef ENABLE_NIS if (options->donis && (dhcp->nisservers || dhcp->nisdomain)) make_nis(iface->name, dhcp); +#endif /* Now we have made a resolv.conf we can obtain a hostname if we need one */ if (options->dohostname && ! dhcp->hostname) @@ -606,7 +679,9 @@ int configure (const options_t *options, interface_t *iface, } } +#ifdef ENABLE_INFO write_info (iface, dhcp, options); +#endif if (iface->previous_address.s_addr != dhcp->address.s_addr || iface->previous_netmask.s_addr != dhcp->netmask.s_addr) diff --git a/configure.h b/configure.h index a7e54632..4d766d26 100644 --- a/configure.h +++ b/configure.h @@ -22,6 +22,13 @@ #ifndef DHCPCONFIG_H #define DHCPCONFIG_H +/* If you disable all 3 options you can shrink the binary by around 5-10k + unstripped depending on platform and CFLAGS +*/ +#define ENABLE_NTP +#define ENABLE_NIS +#define ENABLE_INFO + #include "dhcpcd.h" #include "interface.h" #include "dhcp.h" diff --git a/dhcp.c b/dhcp.c index d1c42201..efe016a7 100644 --- a/dhcp.c +++ b/dhcp.c @@ -80,10 +80,9 @@ size_t send_message (const interface_t *iface, const dhcp_t *dhcp, memset (&message, 0, sizeof (dhcpmessage_t)); - if (iface->previous_address.s_addr != 0 - && (type == DHCP_INFORM || type == DHCP_RELEASE - || (type == DHCP_REQUEST - && iface->previous_address.s_addr == dhcp->address.s_addr))) + if (type == DHCP_INFORM || + type == DHCP_RELEASE || + type == DHCP_REQUEST) { message.ciaddr = iface->previous_address.s_addr; from.s_addr = iface->previous_address.s_addr; @@ -272,7 +271,7 @@ size_t send_message (const interface_t *iface, const dhcp_t *dhcp, make_dhcp_packet (&packet, (unsigned char *) &message, message_length, from, to); - logger (LOG_DEBUG, "sending %s with xid %d", dhcp_message[(int) type], xid); + logger (LOG_DEBUG, "sending %s with xid 0x%x", dhcp_message[(int) type], xid); return send_packet (iface, ETHERTYPE_IP, (unsigned char *) &packet, message_length + sizeof (struct ip) + sizeof (struct udphdr)); diff --git a/dhcpcd.8 b/dhcpcd.8 index 0f0c4543..a9388769 100644 --- a/dhcpcd.8 +++ b/dhcpcd.8 @@ -61,6 +61,7 @@ section below. .TP .BI \-d Echos debugging and information messages to the console. +Subsequent debug options stop \fBdhcpcd\fR from daemonising. .TP .BI \-h \ hostname specifies a string used for the hostname option field when diff --git a/dhcpcd.c b/dhcpcd.c index 24c5c160..2e3280d6 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -110,6 +110,7 @@ int main(int argc, char **argv) int option_index = 0; char prefix[IF_NAMESIZE + 3]; pid_t pid; + int debug = 0; const struct option longopts[] = { @@ -158,6 +159,7 @@ int main(int argc, char **argv) options.donis = true; options.dontp = true; options.dogateway = true; + options.daemonise = true; gethostname (options.hostname, sizeof (options.hostname)); if (strcmp (options.hostname, "(none)") == 0 || strcmp (options.hostname, "localhost") == 0) @@ -183,12 +185,21 @@ int main(int argc, char **argv) options.script = optarg; break; case 'd': - setloglevel(LOG_DEBUG); + debug++; + switch (debug) + { + case 1: + setloglevel(LOG_DEBUG); + break; + case 2: + options.daemonise = false; + break; + } break; case 'h': if (strlen (optarg) > HOSTNAME_MAX_LEN) { - logger(LOG_ERR, "`%s' too long for HostName string, max is %d", + logger (LOG_ERR, "`%s' too long for HostName string, max is %d", optarg, HOSTNAME_MAX_LEN); exit (EXIT_FAILURE); } @@ -196,14 +207,14 @@ int main(int argc, char **argv) strcpy (options.hostname, optarg); break; case 'i': - if (strlen(optarg) > CLASS_ID_MAX_LEN) + if (strlen (optarg) > CLASS_ID_MAX_LEN) { logger (LOG_ERR, "`%s' too long for ClassID string, max is %d", optarg, CLASS_ID_MAX_LEN); exit (EXIT_FAILURE); } else - sprintf(options.classid, "%s", optarg); + sprintf (options.classid, "%s", optarg); break; case 'k': options.signal = SIGHUP; @@ -217,7 +228,7 @@ int main(int argc, char **argv) } break; case 'm': - STRINGINT(optarg, options.metric); + STRINGINT (optarg, options.metric); break; case 'n': options.signal = SIGALRM; diff --git a/dhcpcd.h b/dhcpcd.h index 25e7ef97..fc77f381 100644 --- a/dhcpcd.h +++ b/dhcpcd.h @@ -59,6 +59,7 @@ typedef struct options_t { bool dodomainname; int signal; bool persistent; + bool daemonise; char *script; char pidfile[PATH_MAX]; diff --git a/pathnames.h b/pathnames.h index b80a9e15..c8b5710a 100644 --- a/pathnames.h +++ b/pathnames.h @@ -39,6 +39,10 @@ #define NTPSERVICE ETCDIR "/init.d/ntpd" #define NTPRESTARTARGS "--quiet", "conditionalrestart" +#define OPENNTPFILE ETCDIR "/ntpd.conf" +#define OPENNTPSERVICE ETCDIR "/init.d/ntpd" +#define OPENNTPRESTARTARGS "--quiet", "conditionalrestart" + #define DEFAULT_SCRIPT ETCDIR "/" PACKAGE ".sh" #define STATEDIR "/var" diff --git a/signals.c b/signals.c index 5aa29e91..0a50ed36 100644 --- a/signals.c +++ b/signals.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -34,6 +35,15 @@ static int signal_pipe[2]; static void signal_handler (int sig) { + /* Silently ignore this signal and wait for it. This stops zombies. + We do this here instead of client.c so that we don't spam the log file + with "waiting on select messages" */ + if (sig == SIGCHLD) + { + wait (0); + return; + } + if (send (signal_pipe[1], &sig, sizeof (sig), MSG_DONTWAIT) < 0) logger (LOG_ERR, "Could not send signal: %s", strerror (errno)); }