Mercurial > hg > dhcpcd
changeset 78:3e35e39a5fa3 draft
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.
| author | Roy Marples <roy@marples.name> |
|---|---|
| date | Tue, 03 Apr 2007 07:03:04 +0000 |
| parents | 0d143e90c3cb |
| children | ee2c527a6b84 |
| files | ChangeLog Makefile client.c configure.c configure.h dhcp.c dhcpcd.8 dhcpcd.c dhcpcd.h pathnames.h signals.c |
| diffstat | 11 files changed, 193 insertions(+), 95 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Fri Mar 23 10:32:11 2007 +0000 +++ b/ChangeLog Tue Apr 03 07:03:04 2007 +0000 @@ -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.
--- a/Makefile Fri Mar 23 10:32:11 2007 +0000 +++ b/Makefile Tue Apr 03 07:03:04 2007 +0000 @@ -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 @@ # 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
--- a/client.c Fri Mar 23 10:32:11 2007 +0000 +++ b/client.c Tue Apr 03 07:03:04 2007 +0000 @@ -21,7 +21,6 @@ #include <sys/types.h> #include <sys/select.h> -#include <sys/wait.h> #include <arpa/inet.h> #ifdef __linux__ #include <netinet/ether.h> @@ -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 @@ { 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ goto eexit; } - if (! daemonised) + if (! daemonised && options->daemonise) { if ((daemonise (options->pidfile)) < 0 ) { @@ -627,12 +617,7 @@ 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)
--- a/configure.c Fri Mar 23 10:32:11 2007 +0000 +++ b/configure.c Tue Apr 03 07:03:04 2007 +0000 @@ -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 @@ 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 @@ { 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 @@ 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 @@ 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 @@ logger (LOG_ERR, "popen: %s", strerror (errno)); } else +#endif { logger (LOG_DEBUG, "writing "RESOLVFILE); if (! (f = fopen(RESOLVFILE, "w"))) @@ -185,6 +169,7 @@ static void restore_resolv(const char *ifname) { +#ifdef RESOLVCONF struct stat buf; if (stat (RESOLVCONF, &buf) < 0) @@ -192,9 +177,11 @@ 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 @@ 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 @@ /* 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 @@ 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 @@ fclose (f); return 0; } +#endif int configure (const options_t *options, interface_t *iface, const dhcp_t *dhcp) @@ -567,11 +636,15 @@ 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 @@ } } +#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)
--- a/configure.h Fri Mar 23 10:32:11 2007 +0000 +++ b/configure.h Tue Apr 03 07:03:04 2007 +0000 @@ -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"
--- a/dhcp.c Fri Mar 23 10:32:11 2007 +0000 +++ b/dhcp.c Tue Apr 03 07:03:04 2007 +0000 @@ -80,10 +80,9 @@ 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 @@ 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));
--- a/dhcpcd.8 Fri Mar 23 10:32:11 2007 +0000 +++ b/dhcpcd.8 Tue Apr 03 07:03:04 2007 +0000 @@ -61,6 +61,7 @@ .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
--- a/dhcpcd.c Fri Mar 23 10:32:11 2007 +0000 +++ b/dhcpcd.c Tue Apr 03 07:03:04 2007 +0000 @@ -110,6 +110,7 @@ int option_index = 0; char prefix[IF_NAMESIZE + 3]; pid_t pid; + int debug = 0; const struct option longopts[] = { @@ -158,6 +159,7 @@ 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 @@ 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 @@ 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 @@ } break; case 'm': - STRINGINT(optarg, options.metric); + STRINGINT (optarg, options.metric); break; case 'n': options.signal = SIGALRM;
--- a/dhcpcd.h Fri Mar 23 10:32:11 2007 +0000 +++ b/dhcpcd.h Tue Apr 03 07:03:04 2007 +0000 @@ -59,6 +59,7 @@ bool dodomainname; int signal; bool persistent; + bool daemonise; char *script; char pidfile[PATH_MAX];
--- a/pathnames.h Fri Mar 23 10:32:11 2007 +0000 +++ b/pathnames.h Tue Apr 03 07:03:04 2007 +0000 @@ -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"
--- a/signals.c Fri Mar 23 10:32:11 2007 +0000 +++ b/signals.c Tue Apr 03 07:03:04 2007 +0000 @@ -21,6 +21,7 @@ #include <sys/socket.h> #include <sys/select.h> +#include <sys/wait.h> #include <errno.h> #include <fcntl.h> #include <signal.h> @@ -34,6 +35,15 @@ 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)); }
