From: Roy Marples Date: Thu, 12 Jul 2007 12:52:27 +0000 (+0000) Subject: Added -T test option. This just sends a DHCP_DISCOVER message and then X-Git-Tag: v3.2.3~238 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d358684f8257f0f2c1569f49ded2c911af4c10ab;p=thirdparty%2Fdhcpcd.git Added -T test option. This just sends a DHCP_DISCOVER message and then prints the configuration data to stdout - we don't request a lease, configure the interface or write the info file. --- diff --git a/ChangeLog b/ChangeLog index 733aeeee..2b273bfa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +Added -T test option. This just sends a DHCP_DISCOVER message and then +prints the configuration data to stdout - we don't request a lease, +configure the interface or write the info file. Fix adding of routes on the BSDs. ROOTPATH should work correctly again, thanks to danhien. We now have 6 hostname options, which should satisfy everyone. diff --git a/client.c b/client.c index b66f2cd9..5904337b 100644 --- a/client.c +++ b/client.c @@ -49,6 +49,7 @@ #include "configure.h" #include "dhcp.h" #include "dhcpcd.h" +#include "info.h" #include "interface.h" #include "logger.h" #include "signals.h" @@ -258,16 +259,18 @@ int dhcp_run (const options_t *options, int *pidfd) After all, we ARE a DHCP client whose job it is to configure the interface. We only do this on start, so persistent addresses can be added afterwards by the user if needed. */ - if (! options->doinform) - flush_addresses (iface->name); - else { - /* The inform address HAS to be configured for it to work with most - * DHCP servers */ - if (options->doinform && has_address (iface->name, dhcp->address) < 1) { - add_address (iface->name, dhcp->address, dhcp->netmask, - dhcp->broadcast); - iface->previous_address = dhcp->address; - iface->previous_netmask = dhcp->netmask; + if (! options->test) { + if (! options->doinform) + flush_addresses (iface->name); + else { + /* The inform address HAS to be configured for it to work with most + * DHCP servers */ + if (options->doinform && has_address (iface->name, dhcp->address) < 1) { + add_address (iface->name, dhcp->address, dhcp->netmask, + dhcp->broadcast); + iface->previous_address = dhcp->address; + iface->previous_netmask = dhcp->netmask; + } } } @@ -579,6 +582,13 @@ int dhcp_run (const options_t *options, int *pidfd) addr, inet_ntoa (dhcp->serveraddress)); free (addr); +#ifdef ENABLE_INFO + if (options->test) { + write_info (iface, dhcp, options, false); + goto eexit; + } +#endif + SEND_MESSAGE (DHCP_REQUEST); state = STATE_REQUESTING; } diff --git a/dhcpcd.8 b/dhcpcd.8 index eebf1875..6db1c718 100644 --- a/dhcpcd.8 +++ b/dhcpcd.8 @@ -1,6 +1,6 @@ .\" $Id$ .\" -.TH DHCPCD 8 "15 May 2007" "dhcpcd 3.1" +.TH DHCPCD 8 "12 Jul 2007" "dhcpcd 3.1" .SH NAME dhcpcd \- DHCP client daemon @@ -9,7 +9,7 @@ dhcpcd \- DHCP client daemon .in +.5i .ti -.5i dhcpcd -\%[\-adknpGHMNRTY] +\%[\-adknpEGHMNRTY] \%[\-c\ script] \%[\-h\ hostname] \%[\-i\ vendorClassID] @@ -87,7 +87,7 @@ process associated with the specified interface if one is currently running. If receives .B SIGHUP it will send -.B DCHP_RELEASE +.B DHCP_RELEASE message to the server and destroy dhcpcd cache. In a case .B dhcpcd receives @@ -187,6 +187,45 @@ fixed hardware addresses. You can specify more than one user class, but the total length must be less than 255 characters, -1 character for each user class. .TP +.BI \-E +Will read +.I /var/lib/dhcpcd/dhcpcd-.info +file and use last known good lease if +.B dhcpcd +is unable to reach the DHCP server and the lease has not expired. +This puts \fBdhcpcd\fR into the BOUND or REBINDING state depending on +how long the lease has until expiry. +.TP +.BI \-F \ none | ptr | both +Forces +.B dhcpcd +to request the DHCP server update the DNS using the FQDN option +instead of the Hostname option. The name used by this option +is specified with the \fB-h\fP switch, which must be present. If +the \fB-h\fP switch is not present, the FQDN option is ignored. +The name should be fully qualified, although servers usually +accept a simple name. +.I both +requests that the DHCP server update both the A and PTR +records in the DNS. +.I ptr +requests that the DHCP server updates only the PTR record in +the DNS. +.I none +requests that the DHCP server perform no updates. +.B dhcpcd +does not perform any DNS update, even when the server is +requested to perform no updates. This can be easily +implemented outside the client; all the necessary +information is recorded in the +.I /var/lib/dhcpcd/dhcpcd-.info +file. +.TP +.BI \-G +Prevents +.B dhcpcd +from installing default routes provided by DHCP server. +.TP .BI \-H Forces .B dhcpcd @@ -217,31 +256,6 @@ same as above, but strip the domain if it matches .BI \-HHHHHH same as above, but strip the domain regardless .TP -.BI \-F \ none | ptr | both -Forces -.B dhcpcd -to request the DHCP server update the DNS using the FQDN option -instead of the Hostname option. The name used by this option -is specified with the \fB-h\fP switch, which must be present. If -the \fB-h\fP switch is not present, the FQDN option is ignored. -The name should be fully qualified, although servers usually -accept a simple name. -.I both -requests that the DHCP server update both the A and PTR -records in the DNS. -.I ptr -requests that the DHCP server updates only the PTR record in -the DNS. -.I none -requests that the DHCP server perform no updates. -.B dhcpcd -does not perform any DNS update, even when the server is -requested to perform no updates. This can be easily -implemented outside the client; all the necessary -information is recorded in the -.I /var/lib/dhcpcd/dhcpcd-.info -file. -.TP .BI \-I \ clientID Specifies the client identifier string. If not specified then .B dhcpcd @@ -271,40 +285,14 @@ from replacing or using resolvconf. .TP .BI \-T -Will read -.I /var/lib/dhcpcd/dhcpcd-.info -file and use last known good lease if -.B dhcpcd -is unable to reach the DHCP server and the lease has not expired. -This puts \fBdhcpcd\fR into the BOUND or REBINDING state depending on -how long the lease has until expiry. +dhcpcd sends out a DHCP_DISCOVER message and then prints the values returned to +stdout. It does not configure the interface or touch the .info files. .TP .BI \-Y Prevents .B dhcpcd from replacing .I /etc/yp.conf -.TP -.BI \-G -Prevents -.B dhcpcd -from installing default routes provided by DHCP server. -.SH NOTES -.TP -.B dhcpcd -uses -.I LOCAL0 -syslog facility for all logging. To catch -.B dhcpcd -debugging output add the following line to -.I /etc/syslog.conf -file: - -local0.* /var/log/dhcpcd.log - -and then refresh syslogd daemon: - -kill -1 `cat /var/run/syslogd.pid` .SH FILES .PD 0 @@ -363,9 +351,6 @@ to which is attached. .SH SEE ALSO -.BR dig (1), -.BR nslookup (8), -.BR nsupdate (8) .LP .I Dynamic Host Configuration Protocol, RFC2132 @@ -373,11 +358,11 @@ RFC2132 .I DHCP Options and BOOTP Vendor Extensions, RFC2132 .LP -.I Draft DHC FQDN Option specification, -draft-ietf-dhc-fqdn-option +.I DHCP FQDN Option specification, +RFC4702 .SH BUGS -Please report them to http://bugs.gentoo.org. +Please report them to http://dhcpcd.berlios.de or http://bugs.gentoo.org. .PD 0 .SH AUTHORS diff --git a/dhcpcd.c b/dhcpcd.c index aa3f89d1..55ce5280 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -79,7 +79,7 @@ static pid_t read_pid(const char *pidfile) static void usage () { - printf ("usage: "PACKAGE" [-adknpEGHMNRSY] [-c script] [-h hostame] [-i classID]\n" + printf ("usage: "PACKAGE" [-adknpEGHMNRTY] [-c script] [-h hostame] [-i classID]\n" " [-l leasetime] [-m metric] [-s ipaddress] [-t timeout]\n" " [-u userclass] [-F none | ptr | both] [-I clientID]\n"); } @@ -96,7 +96,7 @@ int main(int argc, char **argv) pid_t pid; int debug = 0; int i; - int pidfd; + int pidfd = -1; const struct option longopts[] = { {"arp", no_argument, NULL, 'a'}, @@ -121,6 +121,7 @@ int main(int argc, char **argv) {"nomtu", no_argument, NULL, 'M'}, {"nontp", no_argument, NULL, 'N'}, {"nodns", no_argument, NULL, 'R'}, + {"test", no_argument, NULL, 'T'}, {"nonis", no_argument, NULL, 'Y'}, {"help", no_argument, &dohelp, 1}, {"version", no_argument, &doversion, 1}, @@ -155,7 +156,7 @@ int main(int argc, char **argv) /* Don't set any optional arguments here so we retain POSIX * compatibility with getopt */ - while ((opt = getopt_long(argc, argv, "ac:dh:i:kl:m:npr:s:t:u:EF:GHI:MNRY", + while ((opt = getopt_long(argc, argv, "ac:dh:i:kl:m:npr:s:t:u:EF:GHI:MNRTY", longopts, &option_index)) != -1) { switch (opt) { @@ -168,6 +169,10 @@ int main(int argc, char **argv) break; case 'a': +#ifndef ENABLE_ARP + logger (LOG_ERR, "arp support not compiled into dhcpcd"); + exit (EXIT_FAILURE); +#endif options.doarp = true; break; case 'c': @@ -279,6 +284,10 @@ int main(int argc, char **argv) } break; case 'E': +#ifndef ENABLE_INFO + logger (LOG_ERR, "info support not compiled into dhcpcd"); + exit (EXIT_FAILURE); +#endif options.dolastlease = true; break; case 'F': @@ -325,6 +334,14 @@ int main(int argc, char **argv) case 'R': options.dodns = false; break; + case 'T': +#ifndef ENABLE_INFO + logger (LOG_ERR, "info support not compiled into dhcpcd"); + exit (EXIT_FAILURE); +#endif + options.test = true; + options.persistent = true; + break; case 'Y': options.donis = false; break; @@ -380,25 +397,6 @@ int main(int argc, char **argv) snprintf (options.pidfile, sizeof (options.pidfile), PIDFILE, options.interface); - if (options.signal != 0) { - int killed = -1; - pid = read_pid (options.pidfile); - if (pid != 0) - logger (LOG_INFO, "sending signal %d to pid %d", options.signal, pid); - - if (! pid || (killed = kill (pid, options.signal))) - logger (options.signal == SIGALRM ? LOG_INFO : LOG_ERR, ""PACKAGE" not running"); - - if (pid != 0 && (options.signal != SIGALRM || killed != 0)) - unlink (options.pidfile); - - if (killed == 0) - exit (EXIT_SUCCESS); - - if (options.signal != SIGALRM) - exit (EXIT_FAILURE); - } - chdir ("/"); umask (022); @@ -416,30 +414,69 @@ int main(int argc, char **argv) exit (EXIT_FAILURE); } - if ((pid = read_pid (options.pidfile)) > 0 && kill (pid, 0) == 0) { - logger (LOG_ERR, ""PACKAGE" already running on pid %d (%s)", - pid, options.pidfile); - exit (EXIT_FAILURE); - } + if (options.test) { + if (options.dorequest || options.doinform) { + logger (LOG_ERR, "cannot test with --inform or --request"); + exit (EXIT_FAILURE); + } - pidfd = open (options.pidfile, O_WRONLY | O_CREAT | O_NONBLOCK, 0660); - if (pidfd == -1) { - logger (LOG_ERR, "open `%s': %s", options.pidfile, strerror (errno)); - exit (EXIT_FAILURE); + if (options.dolastlease) { + logger (LOG_ERR, "cannot test with --lastlease"); + exit (EXIT_FAILURE); + } + + if (options.signal != 0) { + logger (LOG_ERR, "cannot test with --release or --renew"); + exit (EXIT_FAILURE); + } } - /* Lock the file so that only one instance of dhcpcd runs on an interface */ - if (flock (pidfd, LOCK_EX | LOCK_NB) == -1) { - logger (LOG_ERR, "flock `%s': %s", options.pidfile, strerror (errno)); - exit (EXIT_FAILURE); + if (options.signal != 0 ) { + int killed = -1; + pid = read_pid (options.pidfile); + if (pid != 0) + logger (LOG_INFO, "sending signal %d to pid %d", options.signal, pid); + + if (! pid || (killed = kill (pid, options.signal))) + logger (options.signal == SIGALRM ? LOG_INFO : LOG_ERR, ""PACKAGE" not running"); + + if (pid != 0 && (options.signal != SIGALRM || killed != 0)) + unlink (options.pidfile); + + if (killed == 0) + exit (EXIT_SUCCESS); + + if (options.signal != SIGALRM) + exit (EXIT_FAILURE); } - /* dhcpcd.sh should not interhit this fd */ - if ((i = fcntl (pidfd, F_GETFD, 0)) < 0 || - fcntl (pidfd, F_SETFD, i | FD_CLOEXEC) < 0) + if (! options.test) { + if ((pid = read_pid (options.pidfile)) > 0 && kill (pid, 0) == 0) { + logger (LOG_ERR, ""PACKAGE" already running on pid %d (%s)", + pid, options.pidfile); + exit (EXIT_FAILURE); + } + + pidfd = open (options.pidfile, O_WRONLY | O_CREAT | O_NONBLOCK, 0660); + if (pidfd == -1) { + logger (LOG_ERR, "open `%s': %s", options.pidfile, strerror (errno)); + exit (EXIT_FAILURE); + } + + /* Lock the file so that only one instance of dhcpcd runs on an interface */ + if (flock (pidfd, LOCK_EX | LOCK_NB) == -1) { + logger (LOG_ERR, "flock `%s': %s", options.pidfile, strerror (errno)); + exit (EXIT_FAILURE); + } + + /* dhcpcd.sh should not interhit this fd */ + if ((i = fcntl (pidfd, F_GETFD, 0)) < 0 || + fcntl (pidfd, F_SETFD, i | FD_CLOEXEC) < 0) logger (LOG_ERR, "fcntl: %s", strerror (errno)); - logger (LOG_INFO, PACKAGE " " VERSION " starting"); + logger (LOG_INFO, PACKAGE " " VERSION " starting"); + } + if (dhcp_run (&options, &pidfd)) { if (pidfd > -1) close (pidfd); diff --git a/dhcpcd.h b/dhcpcd.h index b3a08d6d..065943db 100644 --- a/dhcpcd.h +++ b/dhcpcd.h @@ -69,6 +69,7 @@ typedef struct options_t { bool persistent; bool keep_address; bool daemonise; + bool test; char *script; char pidfile[PATH_MAX]; diff --git a/info.c b/info.c index 0caadfde..6726a289 100644 --- a/info.c +++ b/info.c @@ -72,13 +72,17 @@ bool write_info(const interface_t *iface, const dhcp_t *dhcp, address_t *address; struct stat sb; - if (! overwrite && stat (iface->infofile, &sb) == 0) - return (true); - - logger (LOG_DEBUG, "writing %s", iface->infofile); - if ((f = fopen (iface->infofile, "w")) == NULL) { - logger (LOG_ERR, "fopen `%s': %s", iface->infofile, strerror (errno)); - return (false); + if (options->test) + f = stdout; + else { + if (! overwrite && stat (iface->infofile, &sb) == 0) + return (true); + + logger (LOG_DEBUG, "writing %s", iface->infofile); + if ((f = fopen (iface->infofile, "w")) == NULL) { + logger (LOG_ERR, "fopen `%s': %s", iface->infofile, strerror (errno)); + return (false); + } } if (dhcp->address.s_addr) { @@ -174,7 +178,8 @@ bool write_info(const interface_t *iface, const dhcp_t *dhcp, if (dhcp->servername[0]) fprintf (f, "DHCPSNAME='%s'\n", cleanmetas (dhcp->servername)); if (! options->doinform && dhcp->address.s_addr) { - fprintf (f, "LEASEDFROM='%u'\n", dhcp->leasedfrom); + if (! options->test) + fprintf (f, "LEASEDFROM='%u'\n", dhcp->leasedfrom); fprintf (f, "LEASETIME='%u'\n", dhcp->leasetime); fprintf (f, "RENEWALTIME='%u'\n", dhcp->renewaltime); fprintf (f, "REBINDTIME='%u'\n", dhcp->rebindtime); @@ -240,7 +245,8 @@ bool write_info(const interface_t *iface, const dhcp_t *dhcp, } #endif - fclose (f); + if (! options->test) + fclose (f); return (true); }