+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.
#include "configure.h"
#include "dhcp.h"
#include "dhcpcd.h"
+#include "info.h"
#include "interface.h"
#include "logger.h"
#include "signals.h"
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;
+ }
}
}
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;
}
.\" $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
.in +.5i
.ti -.5i
dhcpcd
-\%[\-adknpGHMNRTY]
+\%[\-adknpEGHMNRTY]
\%[\-c\ script]
\%[\-h\ hostname]
\%[\-i\ vendorClassID]
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
total length must be less than 255 characters, -1 character for each user
class.
.TP
+.BI \-E
+Will read
+.I /var/lib/dhcpcd/dhcpcd-<interface>.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-<interface>.info
+file.
+.TP
+.BI \-G
+Prevents
+.B dhcpcd
+from installing default routes provided by DHCP server.
+.TP
.BI \-H
Forces
.B dhcpcd
.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-<interface>.info
-file.
-.TP
.BI \-I \ clientID
Specifies the client identifier string. If not specified then
.B dhcpcd
or using resolvconf.
.TP
.BI \-T
-Will read
-.I /var/lib/dhcpcd/dhcpcd-<interface>.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
is attached.
.SH SEE ALSO
-.BR dig (1),
-.BR nslookup (8),
-.BR nsupdate (8)
.LP
.I Dynamic Host Configuration Protocol,
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
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");
}
pid_t pid;
int debug = 0;
int i;
- int pidfd;
+ int pidfd = -1;
const struct option longopts[] = {
{"arp", no_argument, NULL, 'a'},
{"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},
/* 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) {
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':
}
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':
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;
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);
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);
bool persistent;
bool keep_address;
bool daemonise;
+ bool test;
char *script;
char pidfile[PATH_MAX];
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) {
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);
}
#endif
- fclose (f);
+ if (! options->test)
+ fclose (f);
return (true);
}