summaryrefslogtreecommitdiffstats
path: root/src/customdhcpcd
diff options
context:
space:
mode:
authorSebastian Schmelzer2011-12-03 13:31:09 +0100
committerSebastian Schmelzer2011-12-03 13:31:09 +0100
commit1b48532c662470f5dd4090d47e1e2c333e967caf (patch)
tree8c23d3eca5fa088b91887d528138b9e0462382fb /src/customdhcpcd
parentlet cmake find qxt (diff)
downloadfbgui-1b48532c662470f5dd4090d47e1e2c333e967caf.tar.gz
fbgui-1b48532c662470f5dd4090d47e1e2c333e967caf.tar.xz
fbgui-1b48532c662470f5dd4090d47e1e2c333e967caf.zip
codeformating, change to log4cxx
Diffstat (limited to 'src/customdhcpcd')
-rw-r--r--src/customdhcpcd/arp.c421
-rw-r--r--src/customdhcpcd/arp.h2
-rw-r--r--src/customdhcpcd/client.c1973
-rw-r--r--src/customdhcpcd/client.h2
-rw-r--r--src/customdhcpcd/common.c285
-rw-r--r--src/customdhcpcd/common.h2
-rw-r--r--src/customdhcpcd/configure.c1267
-rw-r--r--src/customdhcpcd/configure.h4
-rw-r--r--src/customdhcpcd/dhcp.c1480
-rw-r--r--src/customdhcpcd/dhcp.h191
-rw-r--r--src/customdhcpcd/dhcpcd.c1237
-rw-r--r--src/customdhcpcd/dhcpcd.h89
-rw-r--r--src/customdhcpcd/duid.c147
-rw-r--r--src/customdhcpcd/duid.h2
-rw-r--r--src/customdhcpcd/info.c799
-rw-r--r--src/customdhcpcd/info.h4
-rw-r--r--src/customdhcpcd/interface.c1615
-rw-r--r--src/customdhcpcd/interface.h60
-rw-r--r--src/customdhcpcd/ipv4ll.c50
-rw-r--r--src/customdhcpcd/ipv4ll.h2
-rw-r--r--src/customdhcpcd/logger.c189
-rw-r--r--src/customdhcpcd/logger.h2
-rw-r--r--src/customdhcpcd/logwriter.c436
-rw-r--r--src/customdhcpcd/logwriter.h11
-rw-r--r--src/customdhcpcd/signal.c216
-rw-r--r--src/customdhcpcd/signal.h2
-rw-r--r--src/customdhcpcd/socket.c1064
-rw-r--r--src/customdhcpcd/socket.h10
28 files changed, 6026 insertions, 5536 deletions
diff --git a/src/customdhcpcd/arp.c b/src/customdhcpcd/arp.c
index 794850c..29a22f2 100644
--- a/src/customdhcpcd/arp.c
+++ b/src/customdhcpcd/arp.c
@@ -1,4 +1,4 @@
-/*
+/*
* dhcpcd - DHCP client daemon
* Copyright 2006-2008 Roy Marples <roy@marples.name>
* All rights reserved
@@ -74,211 +74,232 @@
#ifdef ENABLE_ARP
static int send_arp (const interface_t *iface, int op, struct in_addr sip,
- const unsigned char *taddr, struct in_addr tip)
+ const unsigned char *taddr, struct in_addr tip)
{
- struct arphdr *arp;
- size_t arpsize = arphdr_len2 (iface->hwlen, sizeof (sip));
- caddr_t tha;
- int retval;
-
- arp = xzalloc (arpsize);
- arp->ar_hrd = htons (iface->family);
- arp->ar_pro = htons (ETHERTYPE_IP);
- arp->ar_hln = iface->hwlen;
- arp->ar_pln = sizeof (sip);
- arp->ar_op = htons (op);
- memcpy (ar_sha (arp), iface->hwaddr, (size_t) arp->ar_hln);
- memcpy (ar_spa (arp), &sip, (size_t) arp->ar_pln);
- if (taddr) {
- /* NetBSD can return NULL from ar_tha, which is probably wrong
- * but we still need to deal with it */
- if (! (tha = ar_tha (arp))) {
- free (arp);
- errno = EINVAL;
- return (-1);
- }
- memcpy (tha, taddr, (size_t) arp->ar_hln);
- }
- memcpy (ar_tpa (arp), &tip, (size_t) arp->ar_pln);
-
- retval = send_packet (iface, ETHERTYPE_ARP,
- (unsigned char *) arp, arphdr_len (arp));
- free (arp);
- return (retval);
+ struct arphdr *arp;
+ size_t arpsize = arphdr_len2 (iface->hwlen, sizeof (sip));
+ caddr_t tha;
+ int retval;
+
+ arp = xzalloc (arpsize);
+ arp->ar_hrd = htons (iface->family);
+ arp->ar_pro = htons (ETHERTYPE_IP);
+ arp->ar_hln = iface->hwlen;
+ arp->ar_pln = sizeof (sip);
+ arp->ar_op = htons (op);
+ memcpy (ar_sha (arp), iface->hwaddr, (size_t) arp->ar_hln);
+ memcpy (ar_spa (arp), &sip, (size_t) arp->ar_pln);
+ if (taddr)
+ {
+ /* NetBSD can return NULL from ar_tha, which is probably wrong
+ * but we still need to deal with it */
+ if (! (tha = ar_tha (arp)))
+ {
+ free (arp);
+ errno = EINVAL;
+ return (-1);
+ }
+ memcpy (tha, taddr, (size_t) arp->ar_hln);
+ }
+ memcpy (ar_tpa (arp), &tip, (size_t) arp->ar_pln);
+
+ retval = send_packet (iface, ETHERTYPE_ARP,
+ (unsigned char *) arp, arphdr_len (arp));
+ free (arp);
+ return (retval);
}
int arp_claim (interface_t *iface, struct in_addr address)
{
- struct arphdr *reply = NULL;
- long timeout = 0;
- unsigned char *buffer;
- int retval = -1;
- int nprobes = 0;
- int nclaims = 0;
- struct in_addr null_address;
- struct pollfd fds[] = {
- { -1, POLLIN, 0 },
- { -1, POLLIN, 0 }
- };
-
- if (! iface)
- return (-1);
-
- if (! iface->arpable) {
- logger (LOG_DEBUG, "interface `%s' is not ARPable", iface->name);
- return (0);
- }
-
- if (! IN_LINKLOCAL (ntohl (iface->previous_address.s_addr)) &&
- ! IN_LINKLOCAL (ntohl (address.s_addr)))
- logger (LOG_INFO,
- "checking %s is available on attached networks",
- inet_ntoa (address));
-
- if (! open_socket (iface, ETHERTYPE_ARP))
- return (-1);
-
- fds[0].fd = signal_fd ();
- fds[1].fd = iface->fd;
-
- memset (&null_address, 0, sizeof (null_address));
-
- buffer = xmalloc (iface->buffer_length);
- reply = xmalloc (iface->buffer_length);
-
- for (;;) {
- size_t bufpos = 0;
- size_t buflen = iface->buffer_length;
- int bytes;
- int s = 0;
- struct timeval stopat;
- struct timeval now;
-
- /* Only poll if we have a timeout */
- if (timeout > 0) {
- s = poll (fds, 2, timeout);
- if (s == -1) {
- if (errno == EINTR) {
- if (signal_exists (NULL) == -1) {
- errno = 0;
- continue;
- } else
- break;
- }
-
- logger (LOG_ERR, "poll: `%s'",
- strerror (errno));
- break;
- }
- }
-
- /* Timed out */
- if (s == 0) {
- if (nprobes < NPROBES) {
- nprobes ++;
- timeout = PROBE_INTERVAL;
- logger (LOG_DEBUG, "sending ARP probe #%d",
- nprobes);
- if (send_arp (iface, ARPOP_REQUEST,
- null_address, NULL,
- address) == -1)
- break;
-
- /* IEEE1394 cannot set ARP target address
- * according to RFC2734 */
- if (nprobes >= NPROBES &&
- iface->family == ARPHRD_IEEE1394)
- nclaims = NCLAIMS;
- } else if (nclaims < NCLAIMS) {
- nclaims ++;
- timeout = CLAIM_INTERVAL;
- logger (LOG_DEBUG, "sending ARP claim #%d",
- nclaims);
- if (send_arp (iface, ARPOP_REQUEST,
- address, iface->hwaddr,
- address) == -1)
- break;
- } else {
- /* No replies, so done */
- retval = 0;
- break;
- }
-
- /* Setup our stop time */
- if (get_time (&stopat) != 0)
- break;
- stopat.tv_usec += timeout;
-
- continue;
- }
-
- /* We maybe ARP flooded, so check our time */
- if (get_time (&now) != 0)
- break;
- if (timercmp (&now, &stopat, >)) {
- timeout = 0;
- continue;
- }
-
- if (! fds[1].revents & POLLIN)
- continue;
-
- memset (buffer, 0, buflen);
- do {
- union {
- unsigned char *c;
- struct in_addr *a;
- } rp;
- union {
- unsigned char *c;
- struct ether_addr *a;
- } rh;
-
- memset (reply, 0, iface->buffer_length);
- if ((bytes = get_packet (iface, (unsigned char *) reply,
- buffer,
- &buflen, &bufpos)) == -1)
- break;
-
- /* Only these types are recognised */
- if (reply->ar_op != htons (ARPOP_REPLY))
- continue;
-
- /* Protocol must be IP. */
- if (reply->ar_pro != htons (ETHERTYPE_IP))
- continue;
- if (reply->ar_pln != sizeof (address))
- continue;
- if ((unsigned) bytes < sizeof (reply) +
- 2 * (4 + reply->ar_hln))
- continue;
-
- rp.c = (unsigned char *) ar_spa (reply);
- rh.c = (unsigned char *) ar_sha (reply);
-
- /* Ensure the ARP reply is for the our address */
- if (rp.a->s_addr != address.s_addr)
- continue;
-
- /* Some systems send a reply back from our hwaddress,
- * which is wierd */
- if (reply->ar_hln == iface->hwlen &&
- memcmp (rh.c, iface->hwaddr, iface->hwlen) == 0)
- continue;
-
- logger (LOG_ERR, "ARPOP_REPLY received from %s (%s)",
- inet_ntoa (*rp.a),
- hwaddr_ntoa (rh.c, (size_t) reply->ar_hln));
- retval = -1;
- goto eexit;
- } while (bufpos != 0);
- }
+ struct arphdr *reply = NULL;
+ long timeout = 0;
+ unsigned char *buffer;
+ int retval = -1;
+ int nprobes = 0;
+ int nclaims = 0;
+ struct in_addr null_address;
+ struct pollfd fds[] =
+ {
+ { -1, POLLIN, 0 },
+ { -1, POLLIN, 0 }
+ };
+
+ if (! iface)
+ return (-1);
+
+ if (! iface->arpable)
+ {
+ logger (LOG_DEBUG, "interface `%s' is not ARPable", iface->name);
+ return (0);
+ }
+
+ if (! IN_LINKLOCAL (ntohl (iface->previous_address.s_addr)) &&
+ ! IN_LINKLOCAL (ntohl (address.s_addr)))
+ logger (LOG_INFO,
+ "checking %s is available on attached networks",
+ inet_ntoa (address));
+
+ if (! open_socket (iface, ETHERTYPE_ARP))
+ return (-1);
+
+ fds[0].fd = signal_fd ();
+ fds[1].fd = iface->fd;
+
+ memset (&null_address, 0, sizeof (null_address));
+
+ buffer = xmalloc (iface->buffer_length);
+ reply = xmalloc (iface->buffer_length);
+
+ for (;;)
+ {
+ size_t bufpos = 0;
+ size_t buflen = iface->buffer_length;
+ int bytes;
+ int s = 0;
+ struct timeval stopat;
+ struct timeval now;
+
+ /* Only poll if we have a timeout */
+ if (timeout > 0)
+ {
+ s = poll (fds, 2, timeout);
+ if (s == -1)
+ {
+ if (errno == EINTR)
+ {
+ if (signal_exists (NULL) == -1)
+ {
+ errno = 0;
+ continue;
+ }
+ else
+ break;
+ }
+
+ logger (LOG_ERR, "poll: `%s'",
+ strerror (errno));
+ break;
+ }
+ }
+
+ /* Timed out */
+ if (s == 0)
+ {
+ if (nprobes < NPROBES)
+ {
+ nprobes ++;
+ timeout = PROBE_INTERVAL;
+ logger (LOG_DEBUG, "sending ARP probe #%d",
+ nprobes);
+ if (send_arp (iface, ARPOP_REQUEST,
+ null_address, NULL,
+ address) == -1)
+ break;
+
+ /* IEEE1394 cannot set ARP target address
+ * according to RFC2734 */
+ if (nprobes >= NPROBES &&
+ iface->family == ARPHRD_IEEE1394)
+ nclaims = NCLAIMS;
+ }
+ else if (nclaims < NCLAIMS)
+ {
+ nclaims ++;
+ timeout = CLAIM_INTERVAL;
+ logger (LOG_DEBUG, "sending ARP claim #%d",
+ nclaims);
+ if (send_arp (iface, ARPOP_REQUEST,
+ address, iface->hwaddr,
+ address) == -1)
+ break;
+ }
+ else
+ {
+ /* No replies, so done */
+ retval = 0;
+ break;
+ }
+
+ /* Setup our stop time */
+ if (get_time (&stopat) != 0)
+ break;
+ stopat.tv_usec += timeout;
+
+ continue;
+ }
+
+ /* We maybe ARP flooded, so check our time */
+ if (get_time (&now) != 0)
+ break;
+ if (timercmp (&now, &stopat, > ))
+ {
+ timeout = 0;
+ continue;
+ }
+
+ if (! fds[1].revents & POLLIN)
+ continue;
+
+ memset (buffer, 0, buflen);
+ do
+ {
+ union
+ {
+ unsigned char *c;
+ struct in_addr *a;
+ } rp;
+ union
+ {
+ unsigned char *c;
+ struct ether_addr *a;
+ } rh;
+
+ memset (reply, 0, iface->buffer_length);
+ if ((bytes = get_packet (iface, (unsigned char *) reply,
+ buffer,
+ &buflen, &bufpos)) == -1)
+ break;
+
+ /* Only these types are recognised */
+ if (reply->ar_op != htons (ARPOP_REPLY))
+ continue;
+
+ /* Protocol must be IP. */
+ if (reply->ar_pro != htons (ETHERTYPE_IP))
+ continue;
+ if (reply->ar_pln != sizeof (address))
+ continue;
+ if ((unsigned) bytes < sizeof (reply) +
+ 2 * (4 + reply->ar_hln))
+ continue;
+
+ rp.c = (unsigned char *) ar_spa (reply);
+ rh.c = (unsigned char *) ar_sha (reply);
+
+ /* Ensure the ARP reply is for the our address */
+ if (rp.a->s_addr != address.s_addr)
+ continue;
+
+ /* Some systems send a reply back from our hwaddress,
+ * which is wierd */
+ if (reply->ar_hln == iface->hwlen &&
+ memcmp (rh.c, iface->hwaddr, iface->hwlen) == 0)
+ continue;
+
+ logger (LOG_ERR, "ARPOP_REPLY received from %s (%s)",
+ inet_ntoa (*rp.a),
+ hwaddr_ntoa (rh.c, (size_t) reply->ar_hln));
+ retval = -1;
+ goto eexit;
+ }
+ while (bufpos != 0);
+ }
eexit:
- close (iface->fd);
- iface->fd = -1;
- free (buffer);
- free (reply);
- return (retval);
+ close (iface->fd);
+ iface->fd = -1;
+ free (buffer);
+ free (reply);
+ return (retval);
}
#endif
diff --git a/src/customdhcpcd/arp.h b/src/customdhcpcd/arp.h
index 3b7e8ef..bb99e48 100644
--- a/src/customdhcpcd/arp.h
+++ b/src/customdhcpcd/arp.h
@@ -1,4 +1,4 @@
-/*
+/*
* dhcpcd - DHCP client daemon
* Copyright 2006-2008 Roy Marples <roy@marples.name>
* All rights reserved
diff --git a/src/customdhcpcd/client.c b/src/customdhcpcd/client.c
index b007fd6..cb22d24 100644
--- a/src/customdhcpcd/client.c
+++ b/src/customdhcpcd/client.c
@@ -1,4 +1,4 @@
-/*
+/*
* dhcpcd - DHCP client daemon
* Copyright 2006-2008 Roy Marples <roy@marples.name>
* All rights reserved
@@ -72,7 +72,7 @@
#ifdef THERE_IS_NO_FORK
# ifndef ENABLE_INFO
- # error "Non MMU requires ENABLE_INFO to work"
+# error "Non MMU requires ENABLE_INFO to work"
# endif
#endif
@@ -97,7 +97,7 @@
#define STATE_RENEW_REQUESTED 6
#define STATE_RELEASED 7
-/* We should define a maximum for the NAK exponential backoff */
+/* We should define a maximum for the NAK exponential backoff */
#define NAKOFF_MAX 60
#define SOCKET_CLOSED 0
@@ -105,1045 +105,1140 @@
/* Indexes for pollfds */
#define POLLFD_SIGNAL 0
-#define POLLFD_IFACE 1
-
-typedef struct _state {
- int *pidfd;
- bool forked;
- int state;
- uint32_t xid;
- dhcp_t *dhcp;
- int socket;
- interface_t *interface;
- time_t start;
- time_t last_sent;
- time_t last_type;
- long timeout;
- time_t nakoff;
- bool daemonised;
- bool persistent;
- unsigned char *buffer;
- size_t buffer_len;
- size_t buffer_pos;
+#define POLLFD_IFACE 1
+
+typedef struct _state
+{
+ int *pidfd;
+ bool forked;
+ int state;
+ uint32_t xid;
+ dhcp_t *dhcp;
+ int socket;
+ interface_t *interface;
+ time_t start;
+ time_t last_sent;
+ time_t last_type;
+ long timeout;
+ time_t nakoff;
+ bool daemonised;
+ bool persistent;
+ unsigned char *buffer;
+ size_t buffer_len;
+ size_t buffer_pos;
} state_t;
static pid_t daemonise (int *pidfd)
{
- pid_t pid;
- sigset_t full;
- sigset_t old;
+ pid_t pid;
+ sigset_t full;
+ sigset_t old;
#ifdef THERE_IS_NO_FORK
- char **argv;
- int i;
+ char **argv;
+ int i;
#endif
- sigfillset (&full);
- sigprocmask (SIG_SETMASK, &full, &old);
+ sigfillset (&full);
+ sigprocmask (SIG_SETMASK, &full, &old);
#ifndef THERE_IS_NO_FORK
- logger (LOG_DEBUG, "forking to background");
- switch (pid = fork()) {
- case -1:
- logger (LOG_ERR, "fork: %s", strerror (errno));
- exit (EXIT_FAILURE);
- /* NOT REACHED */
- case 0:
- setsid ();
- close_fds ();
- break;
- default:
- /* Reset our signals as we're the parent about to exit. */
- signal_reset ();
- break;
- }
+ logger (LOG_DEBUG, "forking to background");
+ switch (pid = fork())
+ {
+ case -1:
+ logger (LOG_ERR, "fork: %s", strerror (errno));
+ exit (EXIT_FAILURE);
+ /* NOT REACHED */
+ case 0:
+ setsid ();
+ close_fds ();
+ break;
+ default:
+ /* Reset our signals as we're the parent about to exit. */
+ signal_reset ();
+ break;
+ }
#else
- logger (LOG_INFO, "forking to background");
-
- /* We need to add --daemonise to our options */
- argv = xmalloc (sizeof (char *) * (dhcpcd_argc + 4));
- argv[0] = dhcpcd;
- for (i = 1; i < dhcpcd_argc; i++)
- argv[i] = dhcpcd_argv[i];
- argv[i] = (char *) "--daemonised";
- if (dhcpcd_skiproutes) {
- argv[++i] = (char *) "--skiproutes";
- argv[++i] = dhcpcd_skiproutes;
- }
- argv[i + 1] = NULL;
-
- switch (pid = vfork ()) {
- case -1:
- logger (LOG_ERR, "vfork: %s", strerror (errno));
- _exit (EXIT_FAILURE);
- case 0:
- signal_reset ();
- sigprocmask (SIG_SETMASK, &old, NULL);
- execvp (dhcpcd, argv);
- logger (LOG_ERR, "execl `%s': %s", dhcpcd,
- strerror (errno));
- _exit (EXIT_FAILURE);
- }
-
- free (argv);
+ logger (LOG_INFO, "forking to background");
+
+ /* We need to add --daemonise to our options */
+ argv = xmalloc (sizeof (char *) * (dhcpcd_argc + 4));
+ argv[0] = dhcpcd;
+ for (i = 1; i < dhcpcd_argc; i++)
+ argv[i] = dhcpcd_argv[i];
+ argv[i] = (char *) "--daemonised";
+ if (dhcpcd_skiproutes)
+ {
+ argv[++i] = (char *) "--skiproutes";
+ argv[++i] = dhcpcd_skiproutes;
+ }
+ argv[i + 1] = NULL;
+
+ switch (pid = vfork ())
+ {
+ case -1:
+ logger (LOG_ERR, "vfork: %s", strerror (errno));
+ _exit (EXIT_FAILURE);
+ case 0:
+ signal_reset ();
+ sigprocmask (SIG_SETMASK, &old, NULL);
+ execvp (dhcpcd, argv);
+ logger (LOG_ERR, "execl `%s': %s", dhcpcd,
+ strerror (errno));
+ _exit (EXIT_FAILURE);
+ }
+
+ free (argv);
#endif
- /* Done with the fd now */
- if (pid != 0) {
- writepid (*pidfd, pid);
- close (*pidfd);
- *pidfd = -1;
+ /* Done with the fd now */
+ if (pid != 0)
+ {
+ writepid (*pidfd, pid);
+ close (*pidfd);
+ *pidfd = -1;
- }
+ }
- sigprocmask (SIG_SETMASK, &old, NULL);
- return (pid);
+ sigprocmask (SIG_SETMASK, &old, NULL);
+ return (pid);
}
#ifdef ENABLE_INFO
static bool get_old_lease (state_t *state, const options_t *options)
{
- interface_t *iface = state->interface;
- dhcp_t *dhcp = state->dhcp;
- struct timeval tv;
- unsigned int offset = 0;
+ interface_t *iface = state->interface;
+ dhcp_t *dhcp = state->dhcp;
+ struct timeval tv;
+ unsigned int offset = 0;
- if (! IN_LINKLOCAL (ntohl (iface->previous_address.s_addr)))
- logger (LOG_INFO, "trying to use old lease in `%s'",
- iface->infofile);
- if (! read_info (iface, dhcp))
- return (false);
+ if (! IN_LINKLOCAL (ntohl (iface->previous_address.s_addr)))
+ logger (LOG_INFO, "trying to use old lease in `%s'",
+ iface->infofile);
+ if (! read_info (iface, dhcp))
+ return (false);
- /* Vitaly important we remove the server information here */
- memset (&dhcp->serveraddress, 0, sizeof (dhcp->serveraddress));
- memset (dhcp->servername, 0, sizeof (dhcp->servername));
+ /* Vitaly important we remove the server information here */
+ memset (&dhcp->serveraddress, 0, sizeof (dhcp->serveraddress));
+ memset (dhcp->servername, 0, sizeof (dhcp->servername));
#ifdef ENABLE_ARP
- /* Check that no-one is using the address */
- if ((options->dolastlease ||
- (IN_LINKLOCAL (ntohl (dhcp->address.s_addr)) &&
- (! options->doipv4ll ||
- arp_claim (iface, dhcp->address)))))
- {
- memset (&dhcp->address, 0, sizeof (dhcp->address));
- memset (&dhcp->netmask, 0, sizeof (dhcp->netmask));
- memset (&dhcp->broadcast, 0, sizeof (dhcp->broadcast));
- return (false);
- }
-
- /* Ok, lets use this */
- if (IN_LINKLOCAL (dhcp->address.s_addr))
- return (true);
+ /* Check that no-one is using the address */
+ if ((options->dolastlease ||
+ (IN_LINKLOCAL (ntohl (dhcp->address.s_addr)) &&
+ (! options->doipv4ll ||
+ arp_claim (iface, dhcp->address)))))
+ {
+ memset (&dhcp->address, 0, sizeof (dhcp->address));
+ memset (&dhcp->netmask, 0, sizeof (dhcp->netmask));
+ memset (&dhcp->broadcast, 0, sizeof (dhcp->broadcast));
+ return (false);
+ }
+
+ /* Ok, lets use this */
+ if (IN_LINKLOCAL (dhcp->address.s_addr))
+ return (true);
#endif
- /* Ensure that we can still use the lease */
- if (gettimeofday (&tv, NULL) == -1) {
- logger (LOG_ERR, "gettimeofday: %s", strerror (errno));
- return (false);
- }
-
- offset = tv.tv_sec - dhcp->leasedfrom;
- if (dhcp->leasedfrom &&
- tv.tv_sec - dhcp->leasedfrom > dhcp->leasetime)
- {
- logger (LOG_ERR, "lease expired %u seconds ago",
- offset + dhcp->leasetime);
- return (false);
- }
-
- if (dhcp->leasedfrom == 0)
- offset = 0;
- state->timeout = dhcp->renewaltime - offset;
- iface->start_uptime = uptime ();
- return (true);
+ /* Ensure that we can still use the lease */
+ if (gettimeofday (&tv, NULL) == -1)
+ {
+ logger (LOG_ERR, "gettimeofday: %s", strerror (errno));
+ return (false);
+ }
+
+ offset = tv.tv_sec - dhcp->leasedfrom;
+ if (dhcp->leasedfrom &&
+ tv.tv_sec - dhcp->leasedfrom > dhcp->leasetime)
+ {
+ logger (LOG_ERR, "lease expired %u seconds ago",
+ offset + dhcp->leasetime);
+ return (false);
+ }
+
+ if (dhcp->leasedfrom == 0)
+ offset = 0;
+ state->timeout = dhcp->renewaltime - offset;
+ iface->start_uptime = uptime ();
+ return (true);
}
#endif
#ifdef THERE_IS_NO_FORK
static void remove_skiproutes (dhcp_t *dhcp, interface_t *iface)
{
- int i = -1;
- route_t *route;
- route_t *newroute;
-
- free_route (iface->previous_routes);
- iface->previous_routes = NULL;
-
- NSTAILQ_FOREACH (route, dhcp->routes, entries) {
- i++;
-
- /* Check that we did add this route or not */
- if (dhcpcd_skiproutes) {
- char *sk = xstrdup (dhcpcd_skiproutes);
- char *skp = sk;
- char *token;
- bool found = false;
-
- while ((token = strsep (&skp, ","))) {
- if (isdigit (*token) && atoi (token) == i) {
- found = true;
- break;
- }
- }
- free (sk);
- if (found)
- continue;
- }
-
- if (! iface->previous_routes) {
- iface->previous_routes = xmalloc (sizeof (*iface->previous_routes));
- STAILQ_INIT (iface->previous_routes);
- }
-
- newroute = xmalloc (sizeof (*newroute));
- memcpy (newroute, route, sizeof (*newroute));
- STAILQ_INSERT_TAIL (iface->previous_routes, newroute, entries);
- }
-
- /* We no longer need this argument */
- free (dhcpcd_skiproutes);
- dhcpcd_skiproutes = NULL;
+ int i = -1;
+ route_t *route;
+ route_t *newroute;
+
+ free_route (iface->previous_routes);
+ iface->previous_routes = NULL;
+
+ NSTAILQ_FOREACH (route, dhcp->routes, entries)
+ {
+ i++;
+
+ /* Check that we did add this route or not */
+ if (dhcpcd_skiproutes)
+ {
+ char *sk = xstrdup (dhcpcd_skiproutes);
+ char *skp = sk;
+ char *token;
+ bool found = false;
+
+ while ((token = strsep (&skp, ",")))
+ {
+ if (isdigit (*token) && atoi (token) == i)
+ {
+ found = true;
+ break;
+ }
+ }
+ free (sk);
+ if (found)
+ continue;
+ }
+
+ if (! iface->previous_routes)
+ {
+ iface->previous_routes = xmalloc (sizeof (*iface->previous_routes));
+ STAILQ_INIT (iface->previous_routes);
+ }
+
+ newroute = xmalloc (sizeof (*newroute));
+ memcpy (newroute, route, sizeof (*newroute));
+ STAILQ_INSERT_TAIL (iface->previous_routes, newroute, entries);
+ }
+
+ /* We no longer need this argument */
+ free (dhcpcd_skiproutes);
+ dhcpcd_skiproutes = NULL;
}
#endif
static bool client_setup (state_t *state, const options_t *options)
{
- dhcp_t *dhcp = state->dhcp;
- interface_t *iface = state->interface;
-
- state->state = STATE_INIT;
- state->last_type = DHCP_DISCOVER;
- state->nakoff = 1;
- state->daemonised = options->daemonised;
- state->persistent = options->persistent;
-
- if (options->request_address.s_addr == 0 &&
- (options->doinform || options->dorequest || options->daemonised))
- {
+ dhcp_t *dhcp = state->dhcp;
+ interface_t *iface = state->interface;
+
+ state->state = STATE_INIT;
+ state->last_type = DHCP_DISCOVER;
+ state->nakoff = 1;
+ state->daemonised = options->daemonised;
+ state->persistent = options->persistent;
+
+ if (options->request_address.s_addr == 0 &&
+ (options->doinform || options->dorequest || options->daemonised))
+ {
#ifdef ENABLE_INFO
- if (! get_old_lease (state, options))
+ if (! get_old_lease (state, options))
#endif
- {
- free (dhcp);
- return (false);
- }
- state->timeout = 0;
-
- if (! options->daemonised &&
- IN_LINKLOCAL (ntohl (dhcp->address.s_addr)))
- {
- logger (LOG_ERR, "cannot request a link local address");
- return (false);
- }
+ {
+ free (dhcp);
+ return (false);
+ }
+ state->timeout = 0;
+
+ if (! options->daemonised &&
+ IN_LINKLOCAL (ntohl (dhcp->address.s_addr)))
+ {
+ logger (LOG_ERR, "cannot request a link local address");
+ return (false);
+ }
#ifdef THERE_IS_NO_FORK
- if (options->daemonised) {
- state->state = STATE_BOUND;
- state->timeout = dhcp->renewaltime;
- iface->previous_address = dhcp->address;
- iface->previous_netmask = dhcp->netmask;
- remove_skiproutes (dhcp, iface);
- }
+ if (options->daemonised)
+ {
+ state->state = STATE_BOUND;
+ state->timeout = dhcp->renewaltime;
+ iface->previous_address = dhcp->address;
+ iface->previous_netmask = dhcp->netmask;
+ remove_skiproutes (dhcp, iface);
+ }
#endif
- } else {
- dhcp->address = options->request_address;
- dhcp->netmask = options->request_netmask;
- if (dhcp->netmask.s_addr == 0)
- dhcp->netmask.s_addr = get_netmask (dhcp->address.s_addr);
- dhcp->broadcast.s_addr = dhcp->address.s_addr |
- ~dhcp->netmask.s_addr;
- }
-
- /* Remove all existing addresses.
- * 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->test && ! options->daemonised) {
- 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->clientid) {
- /* Attempt to see if the ClientID is a hardware address */
- iface->clientid_len = hwaddr_aton (NULL, options->clientid);
- if (iface->clientid_len) {
- iface->clientid = xmalloc (iface->clientid_len);
- hwaddr_aton (iface->clientid, options->clientid);
- } else {
- /* Nope, so mark it as-is */
- iface->clientid_len = strlen (options->clientid) + 1;
- iface->clientid = xmalloc (iface->clientid_len);
- *iface->clientid = '\0';
- memcpy (iface->clientid + 1,
- options->clientid, iface->clientid_len - 1);
- }
- } else {
+ }
+ else
+ {
+ dhcp->address = options->request_address;
+ dhcp->netmask = options->request_netmask;
+ if (dhcp->netmask.s_addr == 0)
+ dhcp->netmask.s_addr = get_netmask (dhcp->address.s_addr);
+ dhcp->broadcast.s_addr = dhcp->address.s_addr |
+ ~dhcp->netmask.s_addr;
+ }
+
+ /* Remove all existing addresses.
+ * 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->test && ! options->daemonised)
+ {
+ 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->clientid)
+ {
+ /* Attempt to see if the ClientID is a hardware address */
+ iface->clientid_len = hwaddr_aton (NULL, options->clientid);
+ if (iface->clientid_len)
+ {
+ iface->clientid = xmalloc (iface->clientid_len);
+ hwaddr_aton (iface->clientid, options->clientid);
+ }
+ else
+ {
+ /* Nope, so mark it as-is */
+ iface->clientid_len = strlen (options->clientid) + 1;
+ iface->clientid = xmalloc (iface->clientid_len);
+ *iface->clientid = '\0';
+ memcpy (iface->clientid + 1,
+ options->clientid, iface->clientid_len - 1);
+ }
+ }
+ else
+ {
#ifdef ENABLE_DUID
- unsigned char *duid = NULL;
- size_t duid_len = 0;
-
- if (options->doduid) {
- duid = xmalloc (DUID_LEN);
- duid_len = get_duid (duid, iface);
- }
-
- if (duid_len > 0) {
- logger (LOG_INFO, "DUID = %s", hwaddr_ntoa (duid, duid_len));
-
- iface->clientid_len = duid_len + 5;
- iface->clientid = xmalloc (iface->clientid_len);
- *iface->clientid = 255; /* RFC 4361 */
-
- /* IAID is 4 bytes, so if the iface name is 4 bytes use it */
- if (strlen (iface->name) == 4) {
- memcpy (iface->clientid + 1, iface->name, 4);
- } else {
- /* Name isn't 4 bytes, so use the index */
- uint32_t ul = htonl (if_nametoindex (iface->name));
- memcpy (iface->clientid + 1, &ul, 4);
- }
-
- memcpy (iface->clientid + 5, duid, duid_len);
- free (duid);
- } else {
+ unsigned char *duid = NULL;
+ size_t duid_len = 0;
+
+ if (options->doduid)
+ {
+ duid = xmalloc (DUID_LEN);
+ duid_len = get_duid (duid, iface);
+ }
+
+ if (duid_len > 0)
+ {
+ logger (LOG_INFO, "DUID = %s", hwaddr_ntoa (duid, duid_len));
+
+ iface->clientid_len = duid_len + 5;
+ iface->clientid = xmalloc (iface->clientid_len);
+ *iface->clientid = 255; /* RFC 4361 */
+
+ /* IAID is 4 bytes, so if the iface name is 4 bytes use it */
+ if (strlen (iface->name) == 4)
+ {
+ memcpy (iface->clientid + 1, iface->name, 4);
+ }
+ else
+ {
+ /* Name isn't 4 bytes, so use the index */
+ uint32_t ul = htonl (if_nametoindex (iface->name));
+ memcpy (iface->clientid + 1, &ul, 4);
+ }
+
+ memcpy (iface->clientid + 5, duid, duid_len);
+ free (duid);
+ }
+ else
+ {
#else
- {
+ {
#endif
- iface->clientid_len = iface->hwlen + 1;
- iface->clientid = xmalloc (iface->clientid_len);
- *iface->clientid = iface->family;
- memcpy (iface->clientid + 1, iface->hwaddr, iface->hwlen);
- }
- }
-
- return (true);
+ iface->clientid_len = iface->hwlen + 1;
+ iface->clientid = xmalloc (iface->clientid_len);
+ *iface->clientid = iface->family;
+ memcpy (iface->clientid + 1, iface->hwaddr, iface->hwlen);
+ }
+ }
+
+ return (true);
}
static bool do_socket (state_t *state, int mode)
{
- if (state->interface->fd >= 0)
- close (state->interface->fd);
+ if (state->interface->fd >= 0)
+ close (state->interface->fd);
#ifdef __linux
- if (mode == SOCKET_CLOSED && state->interface->listen_fd >= 0) {
- close (state->interface->listen_fd);
- state->interface->listen_fd = -1;
- }
+ if (mode == SOCKET_CLOSED && state->interface->listen_fd >= 0)
+ {
+ close (state->interface->listen_fd);
+ state->interface->listen_fd = -1;
+ }
#endif
- state->interface->fd = -1;
- if (mode == SOCKET_OPEN)
- if (open_socket (state->interface, ETHERTYPE_IP) == -1)
- return (false);
- state->socket = mode;
- return (true);
+ state->interface->fd = -1;
+ if (mode == SOCKET_OPEN)
+ if (open_socket (state->interface, ETHERTYPE_IP) == -1)
+ return (false);
+ state->socket = mode;
+ return (true);
}
static bool _send_message (state_t *state, int type, const options_t *options)
{
- ssize_t retval;
-
- state->last_type = type;
- state->last_sent = uptime ();
- logSendToQt(type);
- retval = send_message (state->interface, state->dhcp, state->xid,
- type, options);
- return (retval == -1 ? false : true);
+ ssize_t retval;
+
+ state->last_type = type;
+ state->last_sent = uptime ();
+ logSendToQt(type);
+ retval = send_message (state->interface, state->dhcp, state->xid,
+ type, options);
+ return (retval == -1 ? false : true);
}
static void drop_config (state_t *state, const options_t *options)
{
- if (! state->persistent)
- configure (options, state->interface, state->dhcp, false);
+ if (! state->persistent)
+ configure (options, state->interface, state->dhcp, false);
- free_dhcp (state->dhcp);
- memset (state->dhcp, 0, sizeof (*state->dhcp));
+ free_dhcp (state->dhcp);
+ memset (state->dhcp, 0, sizeof (*state->dhcp));
}
static int wait_for_packet (struct pollfd *fds, state_t *state,
- const options_t *options)
+ const options_t *options)
{
- dhcp_t *dhcp = state->dhcp;
- interface_t *iface = state->interface;
- int timeout = 0;
- int retval = 0;
-
- if (! (state->timeout > 0 ||
- (options->timeout == 0 &&
- (state->state != STATE_INIT || state->xid)))) {
- /* We need to zero our signal fd, otherwise we will block
- * trying to read a signal. */
- fds[POLLFD_SIGNAL].revents = 0;
- return (0);
- }
-
- fds[POLLFD_IFACE].fd = iface->fd;
-
- if ((options->timeout == 0 && state->xid) ||
- (dhcp->leasetime == (unsigned) -1 &&
- state->state == STATE_BOUND))
- {
- logger (LOG_DEBUG, "waiting for infinity");
- while (retval == 0) {
- if (iface->fd == -1)
- retval = poll (fds, 1, INFTIM);
- else {
- /* Slow down our requests */
- if (timeout < TIMEOUT_MINI_INF)
- timeout += TIMEOUT_MINI;
- else if (timeout > TIMEOUT_MINI_INF)
- timeout = TIMEOUT_MINI_INF;
-
- retval = poll (fds, 2, timeout * 1000);
- if (retval == -1 && errno == EINTR) {
- /* If interupted, continue as normal as
- * the signal will be delivered down
- * the pipe */
- retval = 0;
- continue;
- }
- if (retval == 0)
- _send_message (state, state->last_type,
- options);
- }
- }
-
- return (retval);
- }
-
- /* Resend our message if we're getting loads of packets.
- * As we use BPF or LPF, we shouldn't hit this as much, but it's
- * still nice to have. */
- if (iface->fd > -1 && uptime () - state->last_sent >= TIMEOUT_MINI)
- _send_message (state, state->last_type, options);
-
- logger (LOG_DEBUG, "waiting for %ld seconds",
- (unsigned long) state->timeout);
- /* If we're waiting for a reply, then we re-send the last
- * DHCP request periodically in-case of a bad line */
- retval = 0;
- while (state->timeout > 0 && retval == 0) {
- if (iface->fd == -1)
- timeout = (int) state->timeout;
- else {
- timeout = TIMEOUT_MINI;
- if (state->timeout < timeout)
- timeout = (int) state->timeout;
- }
- timeout *= 1000;
- state->start = uptime ();
- retval = poll (fds, iface->fd == -1 ? 1 : 2, timeout);
- state->timeout -= uptime () - state->start;
- if (retval == -1 && errno == EINTR) {
- /* If interupted, continue as normal as the signal
- * will be delivered down the pipe */
- retval = 0;
- continue;
- }
- if (retval == 0 && iface->fd != -1 && state->timeout > 0)
- _send_message (state, state->last_type, options);
- }
-
- return (retval);
+ dhcp_t *dhcp = state->dhcp;
+ interface_t *iface = state->interface;
+ int timeout = 0;
+ int retval = 0;
+
+ if (! (state->timeout > 0 ||
+ (options->timeout == 0 &&
+ (state->state != STATE_INIT || state->xid))))
+ {
+ /* We need to zero our signal fd, otherwise we will block
+ * trying to read a signal. */
+ fds[POLLFD_SIGNAL].revents = 0;
+ return (0);
+ }
+
+ fds[POLLFD_IFACE].fd = iface->fd;
+
+ if ((options->timeout == 0 && state->xid) ||
+ (dhcp->leasetime == (unsigned) - 1 &&
+ state->state == STATE_BOUND))
+ {
+ logger (LOG_DEBUG, "waiting for infinity");
+ while (retval == 0)
+ {
+ if (iface->fd == -1)
+ retval = poll (fds, 1, INFTIM);
+ else
+ {
+ /* Slow down our requests */
+ if (timeout < TIMEOUT_MINI_INF)
+ timeout += TIMEOUT_MINI;
+ else if (timeout > TIMEOUT_MINI_INF)
+ timeout = TIMEOUT_MINI_INF;
+
+ retval = poll (fds, 2, timeout * 1000);
+ if (retval == -1 && errno == EINTR)
+ {
+ /* If interupted, continue as normal as
+ * the signal will be delivered down
+ * the pipe */
+ retval = 0;
+ continue;
+ }
+ if (retval == 0)
+ _send_message (state, state->last_type,
+ options);
+ }
+ }
+
+ return (retval);
+ }
+
+ /* Resend our message if we're getting loads of packets.
+ * As we use BPF or LPF, we shouldn't hit this as much, but it's
+ * still nice to have. */
+ if (iface->fd > -1 && uptime () - state->last_sent >= TIMEOUT_MINI)
+ _send_message (state, state->last_type, options);
+
+ logger (LOG_DEBUG, "waiting for %ld seconds",
+ (unsigned long) state->timeout);
+ /* If we're waiting for a reply, then we re-send the last
+ * DHCP request periodically in-case of a bad line */
+ retval = 0;
+ while (state->timeout > 0 && retval == 0)
+ {
+ if (iface->fd == -1)
+ timeout = (int) state->timeout;
+ else
+ {
+ timeout = TIMEOUT_MINI;
+ if (state->timeout < timeout)
+ timeout = (int) state->timeout;
+ }
+ timeout *= 1000;
+ state->start = uptime ();
+ retval = poll (fds, iface->fd == -1 ? 1 : 2, timeout);
+ state->timeout -= uptime () - state->start;
+ if (retval == -1 && errno == EINTR)
+ {
+ /* If interupted, continue as normal as the signal
+ * will be delivered down the pipe */
+ retval = 0;
+ continue;
+ }
+ if (retval == 0 && iface->fd != -1 && state->timeout > 0)
+ _send_message (state, state->last_type, options);
+ }
+
+ return (retval);
}
static bool handle_signal (int sig, state_t *state, const options_t *options)
{
- switch (sig) {
- case SIGINT:
- logger (LOG_INFO, "received SIGINT, stopping");
- return (false);
- case SIGTERM:
- logger (LOG_INFO, "received SIGTERM, stopping");
- return (false);
-
- case SIGALRM:
- logger (LOG_INFO, "received SIGALRM, renewing lease");
- switch (state->state) {
- case STATE_BOUND:
- case STATE_RENEWING:
- case STATE_REBINDING:
- state->state = STATE_RENEW_REQUESTED;
- break;
- case STATE_RENEW_REQUESTED:
- case STATE_REQUESTING:
- case STATE_RELEASED:
- state->state = STATE_INIT;
- break;
- }
- state->timeout = 0;
- state->xid = 0;
- return (true);
-
- case SIGHUP:
- if (state->state != STATE_BOUND &&
- state->state != STATE_RENEWING &&
- state->state != STATE_REBINDING)
- {
- logger (LOG_ERR,
- "received SIGHUP, but we no have lease to release");
- return (false);
- }
-
- logger (LOG_INFO, "received SIGHUP, releasing lease");
- if (! IN_LINKLOCAL (ntohl (state->dhcp->address.s_addr))) {
- do_socket (state, SOCKET_OPEN);
- state->xid = (uint32_t) random ();
- if ((open_socket (state->interface, false)) >= 0) {
- _send_message (state, DHCP_RELEASE, options);
- }
- do_socket (state, SOCKET_CLOSED);
- }
- unlink (state->interface->infofile);
- return (false);
-
- default:
- logger (LOG_ERR,
- "received signal %d, but don't know what to do with it",
- sig);
- }
-
- return (false);
+ switch (sig)
+ {
+ case SIGINT:
+ logger (LOG_INFO, "received SIGINT, stopping");
+ return (false);
+ case SIGTERM:
+ logger (LOG_INFO, "received SIGTERM, stopping");
+ return (false);
+
+ case SIGALRM:
+ logger (LOG_INFO, "received SIGALRM, renewing lease");
+ switch (state->state)
+ {
+ case STATE_BOUND:
+ case STATE_RENEWING:
+ case STATE_REBINDING:
+ state->state = STATE_RENEW_REQUESTED;
+ break;
+ case STATE_RENEW_REQUESTED:
+ case STATE_REQUESTING:
+ case STATE_RELEASED:
+ state->state = STATE_INIT;
+ break;
+ }
+ state->timeout = 0;
+ state->xid = 0;
+ return (true);
+
+ case SIGHUP:
+ if (state->state != STATE_BOUND &&
+ state->state != STATE_RENEWING &&
+ state->state != STATE_REBINDING)
+ {
+ logger (LOG_ERR,
+ "received SIGHUP, but we no have lease to release");
+ return (false);
+ }
+
+ logger (LOG_INFO, "received SIGHUP, releasing lease");
+ if (! IN_LINKLOCAL (ntohl (state->dhcp->address.s_addr)))
+ {
+ do_socket (state, SOCKET_OPEN);
+ state->xid = (uint32_t) random ();
+ if ((open_socket (state->interface, false)) >= 0)
+ {
+ _send_message (state, DHCP_RELEASE, options);
+ }
+ do_socket (state, SOCKET_CLOSED);
+ }
+ unlink (state->interface->infofile);
+ return (false);
+
+ default:
+ logger (LOG_ERR,
+ "received signal %d, but don't know what to do with it",
+ sig);
+ }
+
+ return (false);
}
static int handle_timeout (state_t *state, const options_t *options)
{
- dhcp_t *dhcp = state->dhcp;
- interface_t *iface = state->interface;
-
- /* No NAK, so reset the backoff */
- state->nakoff = 1;
-
- if (state->state == STATE_INIT && state->xid != 0) {
- if (iface->previous_address.s_addr != 0 &&
- ! IN_LINKLOCAL (ntohl (iface->previous_address.s_addr)) &&
- ! options->doinform)
- {
- logger (LOG_ERR, "lost lease");
- if (! options->persistent)
- drop_config (state, options);
- } else if (! IN_LINKLOCAL (ntohl (iface->previous_address.s_addr)))
- logger (LOG_ERR, "timed out");
-
- do_socket (state, SOCKET_CLOSED);
- free_dhcp (dhcp);
- memset (dhcp, 0, sizeof (*dhcp));
+ dhcp_t *dhcp = state->dhcp;
+ interface_t *iface = state->interface;
+
+ /* No NAK, so reset the backoff */
+ state->nakoff = 1;
+
+ if (state->state == STATE_INIT && state->xid != 0)
+ {
+ if (iface->previous_address.s_addr != 0 &&
+ ! IN_LINKLOCAL (ntohl (iface->previous_address.s_addr)) &&
+ ! options->doinform)
+ {
+ logger (LOG_ERR, "lost lease");
+ if (! options->persistent)
+ drop_config (state, options);
+ }
+ else if (! IN_LINKLOCAL (ntohl (iface->previous_address.s_addr)))
+ logger (LOG_ERR, "timed out");
+
+ do_socket (state, SOCKET_CLOSED);
+ free_dhcp (dhcp);
+ memset (dhcp, 0, sizeof (*dhcp));
#ifdef ENABLE_INFO
- if (! options->test &&
- (options->doipv4ll || options->dolastlease))
- {
- errno = 0;
- if (! get_old_lease (state, options))
- {
- if (errno == EINTR)
- return (0);
- if (options->dolastlease)
- return (-1);
- free_dhcp (dhcp);
- memset (dhcp, 0, sizeof (*dhcp));
- } else if (errno == EINTR)
- return (0);
- }
+ if (! options->test &&
+ (options->doipv4ll || options->dolastlease))
+ {
+ errno = 0;
+ if (! get_old_lease (state, options))
+ {
+ if (errno == EINTR)
+ return (0);
+ if (options->dolastlease)
+ return (-1);
+ free_dhcp (dhcp);
+ memset (dhcp, 0, sizeof (*dhcp));
+ }
+ else if (errno == EINTR)
+ return (0);
+ }
#endif
#ifdef ENABLE_IPV4LL
- if (! options->test && options->doipv4ll &&
- (! dhcp->address.s_addr ||
- (! IN_LINKLOCAL (ntohl (dhcp->address.s_addr)) &&
- ! options->dolastlease)))
- {
- logger (LOG_INFO, "probing for an IPV4LL address");
- free_dhcp (dhcp);
- memset (dhcp, 0, sizeof (*dhcp));
- if (ipv4ll_get_address (iface, dhcp) == -1) {
- if (! state->daemonised)
- return (-1);
-
- /* start over */
- state->xid = 0;
- return (0);
- }
- state->timeout = dhcp->renewaltime;
- }
+ if (! options->test && options->doipv4ll &&
+ (! dhcp->address.s_addr ||
+ (! IN_LINKLOCAL (ntohl (dhcp->address.s_addr)) &&
+ ! options->dolastlease)))
+ {
+ logger (LOG_INFO, "probing for an IPV4LL address");
+ free_dhcp (dhcp);
+ memset (dhcp, 0, sizeof (*dhcp));
+ if (ipv4ll_get_address (iface, dhcp) == -1)
+ {
+ if (! state->daemonised)
+ return (-1);
+
+ /* start over */
+ state->xid = 0;
+ return (0);
+ }
+ state->timeout = dhcp->renewaltime;
+ }
#endif
#if defined (ENABLE_INFO) || defined (ENABLE_IPV4LL)
- if (dhcp->address.s_addr) {
- if (! state->daemonised &&
- IN_LINKLOCAL (ntohl (dhcp->address.s_addr)))
- logger (LOG_WARNING, "using IPV4LL address %s",
- inet_ntoa (dhcp->address));
- if (configure (options, iface, dhcp, true) == -1 &&
- ! state->daemonised)
- return (-1);
-
- state->state = STATE_BOUND;
- if (! state->daemonised && options->daemonise) {
- switch (daemonise (state->pidfd)) {
- case -1:
- return (-1);
- case 0:
- state->daemonised = true;
- return (0);
- default:
- state->persistent = true;
- state->forked = true;
- return (-1);
- }
- }
-
- state->timeout = dhcp->renewaltime;
- state->xid = 0;
- return (0);
- }
+ if (dhcp->address.s_addr)
+ {
+ if (! state->daemonised &&
+ IN_LINKLOCAL (ntohl (dhcp->address.s_addr)))
+ logger (LOG_WARNING, "using IPV4LL address %s",
+ inet_ntoa (dhcp->address));
+ if (configure (options, iface, dhcp, true) == -1 &&
+ ! state->daemonised)
+ return (-1);
+
+ state->state = STATE_BOUND;
+ if (! state->daemonised && options->daemonise)
+ {
+ switch (daemonise (state->pidfd))
+ {
+ case -1:
+ return (-1);
+ case 0:
+ state->daemonised = true;
+ return (0);
+ default:
+ state->persistent = true;
+ state->forked = true;
+ return (-1);
+ }
+ }
+
+ state->timeout = dhcp->renewaltime;
+ state->xid = 0;
+ return (0);
+ }
#endif
- if (! state->daemonised)
- return (-1);
- }
-
- switch (state->state) {
- case STATE_INIT:
- state->xid = (uint32_t) random ();
- do_socket (state, SOCKET_OPEN);
- state->timeout = options->timeout;
- iface->start_uptime = uptime ();
- if (dhcp->address.s_addr == 0) {
- if (! IN_LINKLOCAL (ntohl (iface->previous_address.s_addr)))
- logger (LOG_INFO, "broadcasting for a lease");
- _send_message (state, DHCP_DISCOVER, options);
- } else if (options->doinform) {
- logger (LOG_INFO, "broadcasting inform for %s",
- inet_ntoa (dhcp->address));
- _send_message (state, DHCP_INFORM, options);
- state->state = STATE_REQUESTING;
- } else {
- logger (LOG_INFO, "broadcasting for a lease of %s",
- inet_ntoa (dhcp->address));
- _send_message (state, DHCP_REQUEST, options);
- state->state = STATE_REQUESTING;
- }
-
- break;
- case STATE_BOUND:
- case STATE_RENEW_REQUESTED:
- if (IN_LINKLOCAL (ntohl (dhcp->address.s_addr))) {
- memset (&dhcp->address, 0, sizeof (dhcp->address));
- state->state = STATE_INIT;
- state->xid = 0;
- break;
- }
- state->state = STATE_RENEWING;
- state->xid = (uint32_t) random ();
- /* FALLTHROUGH */
- case STATE_RENEWING:
- iface->start_uptime = uptime ();
- logger (LOG_INFO, "renewing lease of %s", inet_ntoa
- (dhcp->address));
- do_socket (state, SOCKET_OPEN);
- _send_message (state, DHCP_REQUEST, options);
- state->timeout = dhcp->rebindtime - dhcp->renewaltime;
- state->state = STATE_REBINDING;
- break;
- case STATE_REBINDING:
- logger (LOG_ERR, "lost lease, attemping to rebind");
- memset (&dhcp->address, 0, sizeof (dhcp->address));
- do_socket (state, SOCKET_OPEN);
- if (state->xid == 0)
- state->xid = (uint32_t) random ();
- dhcp->serveraddress.s_addr = 0;
- _send_message (state, DHCP_REQUEST, options);
- state->timeout = dhcp->leasetime - dhcp->rebindtime;
- state->state = STATE_REQUESTING;
- break;
- case STATE_REQUESTING:
- state->state = STATE_INIT;
- do_socket (state, SOCKET_CLOSED);
- state->timeout = 0;
- break;
-
- case STATE_RELEASED:
- dhcp->leasetime = 0;
- break;
- }
-
- return (0);
+ if (! state->daemonised)
+ return (-1);
+ }
+
+ switch (state->state)
+ {
+ case STATE_INIT:
+ state->xid = (uint32_t) random ();
+ do_socket (state, SOCKET_OPEN);
+ state->timeout = options->timeout;
+ iface->start_uptime = uptime ();
+ if (dhcp->address.s_addr == 0)
+ {
+ if (! IN_LINKLOCAL (ntohl (iface->previous_address.s_addr)))
+ logger (LOG_INFO, "broadcasting for a lease");
+ _send_message (state, DHCP_DISCOVER, options);
+ }
+ else if (options->doinform)
+ {
+ logger (LOG_INFO, "broadcasting inform for %s",
+ inet_ntoa (dhcp->address));
+ _send_message (state, DHCP_INFORM, options);
+ state->state = STATE_REQUESTING;
+ }
+ else
+ {
+ logger (LOG_INFO, "broadcasting for a lease of %s",
+ inet_ntoa (dhcp->address));
+ _send_message (state, DHCP_REQUEST, options);
+ state->state = STATE_REQUESTING;
+ }
+
+ break;
+ case STATE_BOUND:
+ case STATE_RENEW_REQUESTED:
+ if (IN_LINKLOCAL (ntohl (dhcp->address.s_addr)))
+ {
+ memset (&dhcp->address, 0, sizeof (dhcp->address));
+ state->state = STATE_INIT;
+ state->xid = 0;
+ break;
+ }
+ state->state = STATE_RENEWING;
+ state->xid = (uint32_t) random ();
+ /* FALLTHROUGH */
+ case STATE_RENEWING:
+ iface->start_uptime = uptime ();
+ logger (LOG_INFO, "renewing lease of %s", inet_ntoa
+ (dhcp->address));
+ do_socket (state, SOCKET_OPEN);
+ _send_message (state, DHCP_REQUEST, options);
+ state->timeout = dhcp->rebindtime - dhcp->renewaltime;
+ state->state = STATE_REBINDING;
+ break;
+ case STATE_REBINDING:
+ logger (LOG_ERR, "lost lease, attemping to rebind");
+ memset (&dhcp->address, 0, sizeof (dhcp->address));
+ do_socket (state, SOCKET_OPEN);
+ if (state->xid == 0)
+ state->xid = (uint32_t) random ();
+ dhcp->serveraddress.s_addr = 0;
+ _send_message (state, DHCP_REQUEST, options);
+ state->timeout = dhcp->leasetime - dhcp->rebindtime;
+ state->state = STATE_REQUESTING;
+ break;
+ case STATE_REQUESTING:
+ state->state = STATE_INIT;
+ do_socket (state, SOCKET_CLOSED);
+ state->timeout = 0;
+ break;
+
+ case STATE_RELEASED:
+ dhcp->leasetime = 0;
+ break;
+ }
+
+ return (0);
}
static int handle_dhcp (state_t *state, int type, const options_t *options)
{
- struct timespec ts;
- interface_t *iface = state->interface;
- dhcp_t *dhcp = state->dhcp;
-
- /* We should restart on a NAK */
- if (type == DHCP_NAK) {
- logger (LOG_INFO, "received NAK: %s", dhcp->message);
- logToQt(LOG_INFO, DHCP_NAK, "");
- state->state = STATE_INIT;
- state->timeout = 0;
- state->xid = 0;
- free_dhcp (dhcp);
- memset (dhcp, 0, sizeof (*dhcp));
-
- /* If we constantly get NAKS then we should slowly back off */
- if (state->nakoff > 0) {
- logger (LOG_DEBUG, "sleeping for %ld seconds",
- (long) state->nakoff);
- ts.tv_sec = state->nakoff;
- ts.tv_nsec = 0;
- state->nakoff *= 2;
- if (state->nakoff > NAKOFF_MAX)
- state->nakoff = NAKOFF_MAX;
- nanosleep (&ts, NULL);
- }
-
- return (0);
- }
-
- /* No NAK, so reset the backoff */
- state->nakoff = 1;
-
- if (type == DHCP_OFFER && state->state == STATE_INIT) {
- char *addr = strdup (inet_ntoa (dhcp->address));
- if (dhcp->servername[0])
- logger (LOG_INFO, "offered %s from %s `%s'",
- addr, inet_ntoa (dhcp->serveraddress),
- dhcp->servername);
- else
- logger (LOG_INFO, "offered %s from %s",
- addr, inet_ntoa (dhcp->serveraddress));
- free (addr);
-
- logToQt(LOG_INFO, DHCP_OFFER, "");
+ struct timespec ts;
+ interface_t *iface = state->interface;
+ dhcp_t *dhcp = state->dhcp;
+
+ /* We should restart on a NAK */
+ if (type == DHCP_NAK)
+ {
+ logger (LOG_INFO, "received NAK: %s", dhcp->message);
+ logToQt(LOG_INFO, DHCP_NAK, "");
+ state->state = STATE_INIT;
+ state->timeout = 0;
+ state->xid = 0;
+ free_dhcp (dhcp);
+ memset (dhcp, 0, sizeof (*dhcp));
+
+ /* If we constantly get NAKS then we should slowly back off */
+ if (state->nakoff > 0)
+ {
+ logger (LOG_DEBUG, "sleeping for %ld seconds",
+ (long) state->nakoff);
+ ts.tv_sec = state->nakoff;
+ ts.tv_nsec = 0;
+ state->nakoff *= 2;
+ if (state->nakoff > NAKOFF_MAX)
+ state->nakoff = NAKOFF_MAX;
+ nanosleep (&ts, NULL);
+ }
+
+ return (0);
+ }
+
+ /* No NAK, so reset the backoff */
+ state->nakoff = 1;
+
+ if (type == DHCP_OFFER && state->state == STATE_INIT)
+ {
+ char *addr = strdup (inet_ntoa (dhcp->address));
+ if (dhcp->servername[0])
+ logger (LOG_INFO, "offered %s from %s `%s'",
+ addr, inet_ntoa (dhcp->serveraddress),
+ dhcp->servername);
+ else
+ logger (LOG_INFO, "offered %s from %s",
+ addr, inet_ntoa (dhcp->serveraddress));
+ free (addr);
+
+ logToQt(LOG_INFO, DHCP_OFFER, "");
#ifdef ENABLE_INFO
- if (options->test) {
- write_info (iface, dhcp, options, false);
- errno = 0;
- return (-1);
- }
+ if (options->test)
+ {
+ write_info (iface, dhcp, options, false);
+ errno = 0;
+ return (-1);
+ }
#endif
- _send_message (state, DHCP_REQUEST, options);
- state->state = STATE_REQUESTING;
-
- return (0);
- }
-
- if (type == DHCP_OFFER) {
- logger (LOG_INFO, "got subsequent offer of %s, ignoring ",
- inet_ntoa (dhcp->address));
- return (0);
- }
-
- /* We should only be dealing with acks */
- if (type != DHCP_ACK) {
- logger (LOG_ERR, "%d not an ACK or OFFER", type);
- return (0);
- }
-
- /* if we are here, than we received an ACK and can go on with configuration */
- logToQt(LOG_INFO, DHCP_ACK, "");
-
- switch (state->state) {
- case STATE_RENEW_REQUESTED:
- case STATE_REQUESTING:
- case STATE_RENEWING:
- case STATE_REBINDING:
- break;
- default:
- logger (LOG_ERR, "wrong state %d", state->state);
- }
-
- do_socket (state, SOCKET_CLOSED);
+ _send_message (state, DHCP_REQUEST, options);
+ state->state = STATE_REQUESTING;
+
+ return (0);
+ }
+
+ if (type == DHCP_OFFER)
+ {
+ logger (LOG_INFO, "got subsequent offer of %s, ignoring ",
+ inet_ntoa (dhcp->address));
+ return (0);
+ }
+
+ /* We should only be dealing with acks */
+ if (type != DHCP_ACK)
+ {
+ logger (LOG_ERR, "%d not an ACK or OFFER", type);
+ return (0);
+ }
+
+ /* if we are here, than we received an ACK and can go on with configuration */
+ logToQt(LOG_INFO, DHCP_ACK, "");
+
+ switch (state->state)
+ {
+ case STATE_RENEW_REQUESTED:
+ case STATE_REQUESTING:
+ case STATE_RENEWING:
+ case STATE_REBINDING:
+ break;
+ default:
+ logger (LOG_ERR, "wrong state %d", state->state);
+ }
+
+ do_socket (state, SOCKET_CLOSED);
#ifdef ENABLE_ARP
- if (options->doarp && iface->previous_address.s_addr !=
- dhcp->address.s_addr)
- {
- errno = 0;
- logToQt(LOG_INFO, DHCPCD_ARP_TEST, "");
- if (arp_claim (iface, dhcp->address)) {
- do_socket (state, SOCKET_OPEN);
- _send_message (state, DHCP_DECLINE, options);
- do_socket (state, SOCKET_CLOSED);
-
- free_dhcp (dhcp);
- memset (dhcp, 0, sizeof (*dhcp));
- state->xid = 0;
- state->timeout = 0;
- state->state = STATE_INIT;
-
- /* RFC 2131 says that we should wait for 10 seconds
- * before doing anything else */
- logger (LOG_INFO, "sleeping for 10 seconds");
- ts.tv_sec = 10;
- ts.tv_nsec = 0;
- nanosleep (&ts, NULL);
- return (0);
- } else if (errno == EINTR)
- return (0);
- }
+ if (options->doarp && iface->previous_address.s_addr !=
+ dhcp->address.s_addr)
+ {
+ errno = 0;
+ logToQt(LOG_INFO, DHCPCD_ARP_TEST, "");
+ if (arp_claim (iface, dhcp->address))
+ {
+ do_socket (state, SOCKET_OPEN);
+ _send_message (state, DHCP_DECLINE, options);
+ do_socket (state, SOCKET_CLOSED);
+
+ free_dhcp (dhcp);
+ memset (dhcp, 0, sizeof (*dhcp));
+ state->xid = 0;
+ state->timeout = 0;
+ state->state = STATE_INIT;
+
+ /* RFC 2131 says that we should wait for 10 seconds
+ * before doing anything else */
+ logger (LOG_INFO, "sleeping for 10 seconds");
+ ts.tv_sec = 10;
+ ts.tv_nsec = 0;
+ nanosleep (&ts, NULL);
+ return (0);
+ }
+ else if (errno == EINTR)
+ return (0);
+ }
#endif
- if (options->doinform) {
- if (options->request_address.s_addr != 0)
- dhcp->address = options->request_address;
- else
- dhcp->address = iface->previous_address;
-
- logger (LOG_INFO, "received approval for %s",
- inet_ntoa (dhcp->address));
- if (iface->previous_netmask.s_addr != dhcp->netmask.s_addr) {
- add_address (iface->name, dhcp->address,
- dhcp->netmask, dhcp->broadcast);
- iface->previous_netmask.s_addr = dhcp->netmask.s_addr;
- }
- state->timeout = options->leasetime;
- if (state->timeout == 0)
- state->timeout = DEFAULT_LEASETIME;
- state->state = STATE_INIT;
- } else if (dhcp->leasetime == (unsigned) -1) {
- dhcp->renewaltime = dhcp->rebindtime = dhcp->leasetime;
- state->timeout = 1; /* So we wait for infinity */
- logger (LOG_INFO, "leased %s for infinity",
- inet_ntoa (dhcp->address));
- state->state = STATE_BOUND;
- } else {
- if (! dhcp->leasetime) {
- dhcp->leasetime = DEFAULT_LEASETIME;
- logger(LOG_INFO,
- "no lease time supplied, assuming %d seconds",
- dhcp->leasetime);
- }
- logger (LOG_INFO, "leased %s for %u seconds",
- inet_ntoa (dhcp->address), dhcp->leasetime);
-
- if (dhcp->rebindtime >= dhcp->leasetime) {
- dhcp->rebindtime = (dhcp->leasetime * 0.875);
- logger (LOG_ERR,
- "rebind time greater than lease "
- "time, forcing to %u seconds",
- dhcp->rebindtime);
- }
-
- if (dhcp->renewaltime > dhcp->rebindtime) {
- dhcp->renewaltime = (dhcp->leasetime * 0.5);
- logger (LOG_ERR,
- "renewal time greater than rebind time, "
- "forcing to %u seconds",
- dhcp->renewaltime);
- }
-
- if (! dhcp->renewaltime) {
- dhcp->renewaltime = (dhcp->leasetime * 0.5);
- logger (LOG_INFO,
- "no renewal time supplied, assuming %d seconds",
- dhcp->renewaltime);
- } else
- logger (LOG_DEBUG, "renew in %u seconds",
- dhcp->renewaltime);
-
- if (! dhcp->rebindtime) {
- dhcp->rebindtime = (dhcp->leasetime * 0.875);
- logger (LOG_INFO,
- "no rebind time supplied, assuming %d seconds",
- dhcp->rebindtime);
- } else
- logger (LOG_DEBUG, "rebind in %u seconds",
- dhcp->rebindtime);
-
- state->timeout = dhcp->renewaltime;
- state->state = STATE_BOUND;
- }
-
- state->xid = 0;
-
- logToQt(LOG_INFO, DHCPCD_CONFIGURE, "");
- if (configure (options, iface, dhcp, true) == -1 &&
- ! state->daemonised)
- return (-1);
-
- if (! state->daemonised && options->daemonise) {
- switch (daemonise (state->pidfd)) {
- case 0:
- state->daemonised = true;
- return (0);
- case -1:
- return (-1);
- default:
- state->persistent = true;
- state->forked = true;
- return (-1);
- }
- }
-
- return (0);
+ if (options->doinform)
+ {
+ if (options->request_address.s_addr != 0)
+ dhcp->address = options->request_address;
+ else
+ dhcp->address = iface->previous_address;
+
+ logger (LOG_INFO, "received approval for %s",
+ inet_ntoa (dhcp->address));
+ if (iface->previous_netmask.s_addr != dhcp->netmask.s_addr)
+ {
+ add_address (iface->name, dhcp->address,
+ dhcp->netmask, dhcp->broadcast);
+ iface->previous_netmask.s_addr = dhcp->netmask.s_addr;
+ }
+ state->timeout = options->leasetime;
+ if (state->timeout == 0)
+ state->timeout = DEFAULT_LEASETIME;
+ state->state = STATE_INIT;
+ }
+ else if (dhcp->leasetime == (unsigned) - 1)
+ {
+ dhcp->renewaltime = dhcp->rebindtime = dhcp->leasetime;
+ state->timeout = 1; /* So we wait for infinity */
+ logger (LOG_INFO, "leased %s for infinity",
+ inet_ntoa (dhcp->address));
+ state->state = STATE_BOUND;
+ }
+ else
+ {
+ if (! dhcp->leasetime)
+ {
+ dhcp->leasetime = DEFAULT_LEASETIME;
+ logger(LOG_INFO,
+ "no lease time supplied, assuming %d seconds",
+ dhcp->leasetime);
+ }
+ logger (LOG_INFO, "leased %s for %u seconds",
+ inet_ntoa (dhcp->address), dhcp->leasetime);
+
+ if (dhcp->rebindtime >= dhcp->leasetime)
+ {
+ dhcp->rebindtime = (dhcp->leasetime * 0.875);
+ logger (LOG_ERR,
+ "rebind time greater than lease "
+ "time, forcing to %u seconds",
+ dhcp->rebindtime);
+ }
+
+ if (dhcp->renewaltime > dhcp->rebindtime)
+ {
+ dhcp->renewaltime = (dhcp->leasetime * 0.5);
+ logger (LOG_ERR,
+ "renewal time greater than rebind time, "
+ "forcing to %u seconds",
+ dhcp->renewaltime);
+ }
+
+ if (! dhcp->renewaltime)
+ {
+ dhcp->renewaltime = (dhcp->leasetime * 0.5);
+ logger (LOG_INFO,
+ "no renewal time supplied, assuming %d seconds",
+ dhcp->renewaltime);
+ }
+ else
+ logger (LOG_DEBUG, "renew in %u seconds",
+ dhcp->renewaltime);
+
+ if (! dhcp->rebindtime)
+ {
+ dhcp->rebindtime = (dhcp->leasetime * 0.875);
+ logger (LOG_INFO,
+ "no rebind time supplied, assuming %d seconds",
+ dhcp->rebindtime);
+ }
+ else
+ logger (LOG_DEBUG, "rebind in %u seconds",
+ dhcp->rebindtime);
+
+ state->timeout = dhcp->renewaltime;
+ state->state = STATE_BOUND;
+ }
+
+ state->xid = 0;
+
+ logToQt(LOG_INFO, DHCPCD_CONFIGURE, "");
+ if (configure (options, iface, dhcp, true) == -1 &&
+ ! state->daemonised)
+ return (-1);
+
+ if (! state->daemonised && options->daemonise)
+ {
+ switch (daemonise (state->pidfd))
+ {
+ case 0:
+ state->daemonised = true;
+ return (0);
+ case -1:
+ return (-1);
+ default:
+ state->persistent = true;
+ state->forked = true;
+ return (-1);
+ }
+ }
+
+ return (0);
}
static int handle_packet (state_t *state, const options_t *options)
{
- interface_t *iface = state->interface;
- bool valid = false;
- int type;
- struct dhcp_t *new_dhcp;
- dhcpmessage_t message;
-
- /* Allocate our buffer space for BPF.
- * We cannot do this until we have opened our socket as we don't
- * know how much of a buffer we need until then. */
- if (! state->buffer)
- state->buffer = xmalloc (iface->buffer_length);
- state->buffer_len = iface->buffer_length;
- state->buffer_pos = 0;
-
- /* We loop through until our buffer is empty.
- * The benefit is that if we get >1 DHCP packet in our buffer and
- * the first one fails for any reason, we can use the next. */
-
- memset (&message, 0, sizeof (message));
- new_dhcp = xmalloc (sizeof (*new_dhcp));
-
- do {
- if (get_packet (iface, (unsigned char *) &message,
- state->buffer,
- &state->buffer_len, &state->buffer_pos) == -1)
- break;
-
- if (state->xid != message.xid) {
- logger (LOG_DEBUG,
- "ignoring packet with xid 0x%x as it's not ours (0x%x)",
- message.xid, state->xid);
- continue;
- }
-
- logger (LOG_DEBUG, "got a packet with xid 0x%x", message.xid);
- memset (new_dhcp, 0, sizeof (*new_dhcp));
- type = parse_dhcpmessage (new_dhcp, &message);
- if (type == -1) {
- logger (LOG_ERR, "failed to parse packet");
- free_dhcp (new_dhcp);
- /* We don't abort on this, so return zero */
- return (0);
- }
-
- /* If we got here then the DHCP packet is valid and appears to
- * be for us, so let's clear the buffer as we don't care about
- * any more DHCP packets at this point. */
- valid = true;
- break;
- } while (state->buffer_pos != 0);
-
- /* No packets for us, so wait until we get one */
- if (! valid) {
- free (new_dhcp);
- return (0);
- }
-
- /* new_dhcp is now our master DHCP message */
- free_dhcp (state->dhcp);
- free (state->dhcp);
- state->dhcp = new_dhcp;
- new_dhcp = NULL;
-
- return (handle_dhcp (state, type, options));
+ interface_t *iface = state->interface;
+ bool valid = false;
+ int type;
+ struct dhcp_t *new_dhcp;
+ dhcpmessage_t message;
+
+ /* Allocate our buffer space for BPF.
+ * We cannot do this until we have opened our socket as we don't
+ * know how much of a buffer we need until then. */
+ if (! state->buffer)
+ state->buffer = xmalloc (iface->buffer_length);
+ state->buffer_len = iface->buffer_length;
+ state->buffer_pos = 0;
+
+ /* We loop through until our buffer is empty.
+ * The benefit is that if we get >1 DHCP packet in our buffer and
+ * the first one fails for any reason, we can use the next. */
+
+ memset (&message, 0, sizeof (message));
+ new_dhcp = xmalloc (sizeof (*new_dhcp));
+
+ do
+ {
+ if (get_packet (iface, (unsigned char *) &message,
+ state->buffer,
+ &state->buffer_len, &state->buffer_pos) == -1)
+ break;
+
+ if (state->xid != message.xid)
+ {
+ logger (LOG_DEBUG,
+ "ignoring packet with xid 0x%x as it's not ours (0x%x)",
+ message.xid, state->xid);
+ continue;
+ }
+
+ logger (LOG_DEBUG, "got a packet with xid 0x%x", message.xid);
+ memset (new_dhcp, 0, sizeof (*new_dhcp));
+ type = parse_dhcpmessage (new_dhcp, &message);
+ if (type == -1)
+ {
+ logger (LOG_ERR, "failed to parse packet");
+ free_dhcp (new_dhcp);
+ /* We don't abort on this, so return zero */
+ return (0);
+ }
+
+ /* If we got here then the DHCP packet is valid and appears to
+ * be for us, so let's clear the buffer as we don't care about
+ * any more DHCP packets at this point. */
+ valid = true;
+ break;
+ }
+ while (state->buffer_pos != 0);
+
+ /* No packets for us, so wait until we get one */
+ if (! valid)
+ {
+ free (new_dhcp);
+ return (0);
+ }
+
+ /* new_dhcp is now our master DHCP message */
+ free_dhcp (state->dhcp);
+ free (state->dhcp);
+ state->dhcp = new_dhcp;
+ new_dhcp = NULL;
+
+ return (handle_dhcp (state, type, options));
}
int dhcp_run (const options_t *options, int *pidfd)
{
- interface_t *iface;
- state_t *state = NULL;
- struct pollfd fds[] = {
- { -1, POLLIN, 0 },
- { -1, POLLIN, 0 }
- };
- int retval = -1;
- int sig;
-
- if (! options)
- return (-1);
-
- /*read_interface : defined in interface.c*/
- iface = read_interface (options->interface, options->metric);
- if (! iface)
- goto eexit;
-
- state = xzalloc (sizeof (*state));
- state->dhcp = xzalloc (sizeof (*state->dhcp));
- state->pidfd = pidfd;
- state->interface = iface;
-
- if (! client_setup (state, options))
- goto eexit;
-
- if (signal_init () == -1)
- goto eexit;
- if (signal_setup () == -1)
- goto eexit;
-
- fds[POLLFD_SIGNAL].fd = signal_fd ();
-
- for (;;) {
- retval = wait_for_packet (fds, state, options);
-
- /* We should always handle our signals first */
- if ((sig = (signal_read (&fds[POLLFD_SIGNAL]))) != -1) {
- if (handle_signal (sig, state, options))
- retval = 0;
- else
- retval = -1;
- } else if (retval == 0)
- retval = handle_timeout (state, options);
- else if (retval > 0 &&
- state->socket != SOCKET_CLOSED &&
- fds[POLLFD_IFACE].revents & POLLIN)
- retval = handle_packet (state, options);
- else if (retval == -1 && errno == EINTR) {
- /* The interupt will be handled above */
- retval = 0;
- } else {
- logger (LOG_ERR, "poll: %s", strerror (errno));
- retval = -1;
- }
-
- if (retval != 0)
- break;
- }
+ interface_t *iface;
+ state_t *state = NULL;
+ struct pollfd fds[] =
+ {
+ { -1, POLLIN, 0 },
+ { -1, POLLIN, 0 }
+ };
+ int retval = -1;
+ int sig;
+
+ if (! options)
+ return (-1);
+
+ /*read_interface : defined in interface.c*/
+ iface = read_interface (options->interface, options->metric);
+ if (! iface)
+ goto eexit;
+
+ state = xzalloc (sizeof (*state));
+ state->dhcp = xzalloc (sizeof (*state->dhcp));
+ state->pidfd = pidfd;
+ state->interface = iface;
+
+ if (! client_setup (state, options))
+ goto eexit;
+
+ if (signal_init () == -1)
+ goto eexit;
+ if (signal_setup () == -1)
+ goto eexit;
+
+ fds[POLLFD_SIGNAL].fd = signal_fd ();
+
+ for (;;)
+ {
+ retval = wait_for_packet (fds, state, options);
+
+ /* We should always handle our signals first */
+ if ((sig = (signal_read (&fds[POLLFD_SIGNAL]))) != -1)
+ {
+ if (handle_signal (sig, state, options))
+ retval = 0;
+ else
+ retval = -1;
+ }
+ else if (retval == 0)
+ retval = handle_timeout (state, options);
+ else if (retval > 0 &&
+ state->socket != SOCKET_CLOSED &&
+ fds[POLLFD_IFACE].revents & POLLIN)
+ retval = handle_packet (state, options);
+ else if (retval == -1 && errno == EINTR)
+ {
+ /* The interupt will be handled above */
+ retval = 0;
+ }
+ else
+ {
+ logger (LOG_ERR, "poll: %s", strerror (errno));
+ retval = -1;
+ }
+
+ if (retval != 0)
+ break;
+ }
eexit:
- if (iface) {
- do_socket (state, SOCKET_CLOSED);
- drop_config (state, options);
- free_route (iface->previous_routes);
- free (iface->clientid);
- free (iface);
- }
-
- if (state) {
- if (state->forked)
- retval = 0;
-
- if (state->daemonised)
- unlink (options->pidfile);
-
- free_dhcp (state->dhcp);
- free (state->dhcp);
- free (state->buffer);
- free (state);
- }
-
- return (retval);
+ if (iface)
+ {
+ do_socket (state, SOCKET_CLOSED);
+ drop_config (state, options);
+ free_route (iface->previous_routes);
+ free (iface->clientid);
+ free (iface);
+ }
+
+ if (state)
+ {
+ if (state->forked)
+ retval = 0;
+
+ if (state->daemonised)
+ unlink (options->pidfile);
+
+ free_dhcp (state->dhcp);
+ free (state->dhcp);
+ free (state->buffer);
+ free (state);
+ }
+
+ return (retval);
}
diff --git a/src/customdhcpcd/client.h b/src/customdhcpcd/client.h
index fa6ea9b..247abe9 100644
--- a/src/customdhcpcd/client.h
+++ b/src/customdhcpcd/client.h
@@ -1,4 +1,4 @@
-/*
+/*
* dhcpcd - DHCP client daemon
* Copyright 2006-2008 Roy Marples <roy@marples.name>
* All rights reserved
diff --git a/src/customdhcpcd/common.c b/src/customdhcpcd/common.c
index 99471bc..707ea32 100644
--- a/src/customdhcpcd/common.c
+++ b/src/customdhcpcd/common.c
@@ -1,4 +1,4 @@
-/*
+/*
* dhcpcd - DHCP client daemon
* Copyright 2006-2008 Roy Marples <roy@marples.name>
* All rights reserved
@@ -41,28 +41,30 @@
* This means we read the whole line and avoid any nasty buffer overflows. */
char *get_line (FILE *fp)
{
- char *line = NULL;
- char *p;
- size_t len = 0;
- size_t last = 0;
-
- if (feof (fp))
- return (NULL);
-
- do {
- len += BUFSIZ;
- line = xrealloc (line, sizeof (char) * len);
- p = line + last;
- memset (p, 0, BUFSIZ);
- fgets (p, BUFSIZ, fp);
- last += strlen (p);
- } while (! feof (fp) && line[last - 1] != '\n');
-
- /* Trim the trailing newline */
- if (*line && line[--last] == '\n')
- line[last] = '\0';
-
- return (line);
+ char *line = NULL;
+ char *p;
+ size_t len = 0;
+ size_t last = 0;
+
+ if (feof (fp))
+ return (NULL);
+
+ do
+ {
+ len += BUFSIZ;
+ line = xrealloc (line, sizeof (char) * len);
+ p = line + last;
+ memset (p, 0, BUFSIZ);
+ fgets (p, BUFSIZ, fp);
+ last += strlen (p);
+ }
+ while (! feof (fp) && line[last - 1] != '\n');
+
+ /* Trim the trailing newline */
+ if (*line && line[--last] == '\n')
+ line[last] = '\0';
+
+ return (line);
}
/* OK, this should be in dhcpcd.c
@@ -70,19 +72,20 @@ char *get_line (FILE *fp)
#ifndef HAVE_SRANDOMDEV
void srandomdev (void)
{
- int fd;
- unsigned long seed;
-
- fd = open ("/dev/urandom", 0);
- if (fd == -1 || read (fd, &seed, sizeof (seed)) == -1) {
- logger (LOG_WARNING, "Could not read from /dev/urandom: %s",
- strerror (errno));
- seed = time (0);
- }
- if (fd >= 0)
- close(fd);
-
- srandom (seed);
+ int fd;
+ unsigned long seed;
+
+ fd = open ("/dev/urandom", 0);
+ if (fd == -1 || read (fd, &seed, sizeof (seed)) == -1)
+ {
+ logger (LOG_WARNING, "Could not read from /dev/urandom: %s",
+ strerror (errno));
+ seed = time (0);
+ }
+ if (fd >= 0)
+ close(fd);
+
+ srandom (seed);
}
#endif
@@ -90,54 +93,58 @@ void srandomdev (void)
#ifndef HAVE_STRLCPY
size_t strlcpy (char *dst, const char *src, size_t size)
{
- const char *s = src;
- size_t n = size;
-
- if (n && --n)
- do {
- if (! (*dst++ = *src++))
- break;
- } while (--n);
-
- if (! n) {
- if (size)
- *dst = '\0';
- while (*src++);
- }
-
- return (src - s - 1);
+ const char *s = src;
+ size_t n = size;
+
+ if (n && --n)
+ do
+ {
+ if (! (*dst++ = *src++))
+ break;
+ }
+ while (--n);
+
+ if (! n)
+ {
+ if (size)
+ *dst = '\0';
+ while (*src++);
+ }
+
+ return (src - s - 1);
}
#endif
/* Close our fd's */
int close_fds (void)
{
- int fd;
-
- if ((fd = open ("/dev/null", O_RDWR)) == -1) {
- logger (LOG_ERR, "open `/dev/null': %s", strerror (errno));
- return (-1);
- }
-
- dup2 (fd, fileno (stdin));
- dup2 (fd, fileno (stdout));
- dup2 (fd, fileno (stderr));
- if (fd > 2)
- close (fd);
- return (0);
+ int fd;
+
+ if ((fd = open ("/dev/null", O_RDWR)) == -1)
+ {
+ logger (LOG_ERR, "open `/dev/null': %s", strerror (errno));
+ return (-1);
+ }
+
+ dup2 (fd, fileno (stdin));
+ dup2 (fd, fileno (stdout));
+ dup2 (fd, fileno (stderr));
+ if (fd > 2)
+ close (fd);
+ return (0);
}
int close_on_exec (int fd)
{
- int flags;
-
- if ((flags = fcntl (fd, F_GETFD, 0)) == -1
- || fcntl (fd, F_SETFD, flags | FD_CLOEXEC) == -1)
- {
- logger (LOG_ERR, "fcntl: %s", strerror (errno));
- return (-1);
- }
- return (0);
+ int flags;
+
+ if ((flags = fcntl (fd, F_GETFD, 0)) == -1
+ || fcntl (fd, F_SETFD, flags | FD_CLOEXEC) == -1)
+ {
+ logger (LOG_ERR, "fcntl: %s", strerror (errno));
+ return (-1);
+ }
+ return (0);
}
/* Handy function to get the time.
@@ -148,102 +155,108 @@ int close_on_exec (int fd)
int get_time (struct timeval *tp)
{
#if defined(_POSIX_MONOTONIC_CLOCK) && defined(CLOCK_MONOTONIC)
- struct timespec ts;
- static clockid_t posix_clock;
- static int posix_clock_set = 0;
-
- if (! posix_clock_set) {
- if (sysconf (_SC_MONOTONIC_CLOCK) >= 0)
- posix_clock = CLOCK_MONOTONIC;
- else
- posix_clock = CLOCK_REALTIME;
- posix_clock_set = 1;
- }
-
- if (clock_gettime (posix_clock, &ts) == -1) {
- logger (LOG_ERR, "clock_gettime: %s", strerror (errno));
- return (-1);
- }
-
- tp->tv_sec = ts.tv_sec;
- tp->tv_usec = ts.tv_nsec / 1000;
- return (0);
+ struct timespec ts;
+ static clockid_t posix_clock;
+ static int posix_clock_set = 0;
+
+ if (! posix_clock_set)
+ {
+ if (sysconf (_SC_MONOTONIC_CLOCK) >= 0)
+ posix_clock = CLOCK_MONOTONIC;
+ else
+ posix_clock = CLOCK_REALTIME;
+ posix_clock_set = 1;
+ }
+
+ if (clock_gettime (posix_clock, &ts) == -1)
+ {
+ logger (LOG_ERR, "clock_gettime: %s", strerror (errno));
+ return (-1);
+ }
+
+ tp->tv_sec = ts.tv_sec;
+ tp->tv_usec = ts.tv_nsec / 1000;
+ return (0);
#else
- if (gettimeofday (tp, NULL) == -1) {
- logger (LOG_ERR, "gettimeofday: %s", strerror (errno));
- return (-1);
- }
- return (0);
+ if (gettimeofday (tp, NULL) == -1)
+ {
+ logger (LOG_ERR, "gettimeofday: %s", strerror (errno));
+ return (-1);
+ }
+ return (0);
#endif
}
time_t uptime (void)
{
- struct timeval tp;
+ struct timeval tp;
- if (get_time (&tp) == -1)
- return (-1);
+ if (get_time (&tp) == -1)
+ return (-1);
- return (tp.tv_sec);
+ return (tp.tv_sec);
}
void writepid (int fd, pid_t pid)
{
- char spid[16];
- if (ftruncate (fd, (off_t) 0) == -1) {
- logger (LOG_ERR, "ftruncate: %s", strerror (errno));
- } else {
- ssize_t len;
- snprintf (spid, sizeof (spid), "%u", pid);
- len = pwrite (fd, spid, strlen (spid), (off_t) 0);
- if (len != (ssize_t) strlen (spid))
- logger (LOG_ERR, "pwrite: %s", strerror (errno));
- }
+ char spid[16];
+ if (ftruncate (fd, (off_t) 0) == -1)
+ {
+ logger (LOG_ERR, "ftruncate: %s", strerror (errno));
+ }
+ else
+ {
+ ssize_t len;
+ snprintf (spid, sizeof (spid), "%u", pid);
+ len = pwrite (fd, spid, strlen (spid), (off_t) 0);
+ if (len != (ssize_t) strlen (spid))
+ logger (LOG_ERR, "pwrite: %s", strerror (errno));
+ }
}
void *xmalloc (size_t s)
{
- void *value = malloc (s);
+ void *value = malloc (s);
- if (value)
- return (value);
+ if (value)
+ return (value);
- logger (LOG_ERR, "memory exhausted");
+ logger (LOG_ERR, "memory exhausted");
- exit (EXIT_FAILURE);
- /* NOTREACHED */
+ exit (EXIT_FAILURE);
+ /* NOTREACHED */
}
void *xzalloc (size_t s)
{
- void *value = xmalloc (s);
- memset (value, 0, s);
- return (value);
+ void *value = xmalloc (s);
+ memset (value, 0, s);
+ return (value);
}
void *xrealloc (void *ptr, size_t s)
{
- void *value = realloc (ptr, s);
+ void *value = realloc (ptr, s);
- if (value)
- return (value);
+ if (value)
+ return (value);
- logger (LOG_ERR, "memory exhausted");
- exit (EXIT_FAILURE);
- /* NOTREACHED */
+ logger (LOG_ERR, "memory exhausted");
+ exit (EXIT_FAILURE);
+ /* NOTREACHED */
}
char *xstrdup (const char *str)
{
- char *value;
+ char *value;
- if (! str)
- return (NULL);
+ if (! str)
+ return (NULL);
- if ((value = strdup (str)))
- return (value);
+ if ((value = strdup (str)))
+ return (value);
- logger (LOG_ERR, "memory exhausted");
- exit (EXIT_FAILURE);
- /* NOTREACHED */
+ logger (LOG_ERR, "memory exhausted");
+ exit (EXIT_FAILURE);
+ /* NOTREACHED */
}
diff --git a/src/customdhcpcd/common.h b/src/customdhcpcd/common.h
index 46f1886..5d68f7f 100644
--- a/src/customdhcpcd/common.h
+++ b/src/customdhcpcd/common.h
@@ -1,4 +1,4 @@
-/*
+/*
* dhcpcd - DHCP client daemon
* Copyright 2006-2008 Roy Marples <roy@marples.name>
* All rights reserved
diff --git a/src/customdhcpcd/configure.c b/src/customdhcpcd/configure.c
index b69ccdc..00d75d0 100644
--- a/src/customdhcpcd/configure.c
+++ b/src/customdhcpcd/configure.c
@@ -1,4 +1,4 @@
-/*
+/*
* dhcpcd - DHCP client daemon
* Copyright 2006-2008 Roy Marples <roy@marples.name>
* All rights reserved
@@ -63,340 +63,360 @@
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);
+ 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);
}
/* IMPORTANT: Ensure that the last parameter is NULL when calling */
static int exec_cmd (const char *cmd, const char *args, ...)
{
- va_list va;
- char **argv;
- int n = 1;
- int ret = 0;
- pid_t pid;
- sigset_t full;
- sigset_t old;
-
- va_start (va, args);
- while (va_arg (va, char *) != NULL)
- n++;
- va_end (va);
- argv = xmalloc (sizeof (char *) * (n + 2));
-
- va_start (va, args);
- n = 2;
- argv[0] = (char *) cmd;
- argv[1] = (char *) args;
- while ((argv[n] = va_arg (va, char *)) != NULL)
- n++;
- va_end (va);
-
- /* OK, we need to block signals */
- sigfillset (&full);
- sigprocmask (SIG_SETMASK, &full, &old);
+ va_list va;
+ char **argv;
+ int n = 1;
+ int ret = 0;
+ pid_t pid;
+ sigset_t full;
+ sigset_t old;
+
+ va_start (va, args);
+ while (va_arg (va, char *) != NULL)
+ n++;
+ va_end (va);
+ argv = xmalloc (sizeof (char *) * (n + 2));
+
+ va_start (va, args);
+ n = 2;
+ argv[0] = (char *) cmd;
+ argv[1] = (char *) args;
+ while ((argv[n] = va_arg (va, char *)) != NULL)
+ n++;
+ va_end (va);
+
+ /* OK, we need to block signals */
+ sigfillset (&full);
+ sigprocmask (SIG_SETMASK, &full, &old);
#ifdef THERE_IS_NO_FORK
- signal_reset ();
- pid = vfork ();
+ signal_reset ();
+ pid = vfork ();
#else
- pid = fork();
+ pid = fork();
#endif
- switch (pid) {
- case -1:
- logger (LOG_ERR, "vfork: %s", strerror (errno));
- ret = -1;
- break;
- case 0:
+ switch (pid)
+ {
+ case -1:
+ logger (LOG_ERR, "vfork: %s", strerror (errno));
+ ret = -1;
+ break;
+ case 0:
#ifndef THERE_IS_NO_FORK
- signal_reset ();
+ signal_reset ();
#endif
- sigprocmask (SIG_SETMASK, &old, NULL);
- if (execvp (cmd, argv) && errno != ENOENT)
- logger (LOG_ERR, "error executing \"%s\": %s",
- cmd, strerror (errno));
- _exit (111);
- /* NOTREACHED */
- }
+ sigprocmask (SIG_SETMASK, &old, NULL);
+ if (execvp (cmd, argv) && errno != ENOENT)
+ logger (LOG_ERR, "error executing \"%s\": %s",
+ cmd, strerror (errno));
+ _exit (111);
+ /* NOTREACHED */
+ }
#ifdef THERE_IS_NO_FORK
- signal_setup ();
+ signal_setup ();
#endif
- /* Restore our signals */
- sigprocmask (SIG_SETMASK, &old, NULL);
+ /* Restore our signals */
+ sigprocmask (SIG_SETMASK, &old, NULL);
- free (argv);
- return (ret);
+ free (argv);
+ return (ret);
}
static void exec_script (const char *script, const char *infofile,
- const char *arg)
+ const char *arg)
{
- struct stat buf;
+ struct stat buf;
- if (! script || ! infofile || ! arg)
- return;
+ if (! script || ! infofile || ! arg)
+ return;
- if (stat (script, &buf) == -1) {
- if (strcmp (script, DEFAULT_SCRIPT) != 0)
- logger (LOG_ERR, "`%s': %s", script, strerror (ENOENT));
- return;
- }
+ if (stat (script, &buf) == -1)
+ {
+ if (strcmp (script, DEFAULT_SCRIPT) != 0)
+ logger (LOG_ERR, "`%s': %s", script, strerror (ENOENT));
+ return;
+ }
#ifdef ENABLE_INFO
- logger (LOG_DEBUG, "exec \"%s\" \"%s\" \"%s\"", script, infofile, arg);
- exec_cmd (script, infofile, arg, (char *) NULL);
+ 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);
+ logger (LOG_DEBUG, "exec \"%s\" \"\" \"%s\"", script, arg);
+ exec_cmd (script, "", arg, (char *) NULL);
#endif
}
static int make_resolv (const char *ifname, const dhcp_t *dhcp)
{
- FILE *f = NULL;
- address_t *address;
+ FILE *f = NULL;
+ address_t *address;
#ifdef ENABLE_RESOLVCONF
- char *resolvconf = NULL;
-
- if (file_in_path ("resolvconf") == 0) {
- size_t len = strlen ("resolvconf -a ") + strlen (ifname) + 1;
- resolvconf = xmalloc (sizeof (char) * len);
- snprintf (resolvconf, len, "resolvconf -a %s", ifname);
- if ((f = popen (resolvconf , "w")))
- logger (LOG_DEBUG,
- "sending DNS information to resolvconf");
- else if (errno == EEXIST)
- logger (LOG_ERR, "popen: %s", strerror (errno));
-
- if (ferror (f))
- logger (LOG_ERR, "ferror");
- free (resolvconf);
- }
-#endif
- if (! f) {
- logger (LOG_DEBUG, "writing "RESOLVFILE);
- if (! (f = fopen(RESOLVFILE, "w")))
- logger (LOG_ERR, "fopen `%s': %s", RESOLVFILE, strerror (errno));
- }
-
- if (! f)
- return (-1);
-
- fprintf (f, "# Generated by dhcpcd for interface %s\n", ifname);
- if (dhcp->dnssearch)
- fprintf (f, "search %s\n", dhcp->dnssearch);
- else if (dhcp->dnsdomain) {
- fprintf (f, "search %s\n", dhcp->dnsdomain);
- }
-
- STAILQ_FOREACH (address, dhcp->dnsservers, entries)
- fprintf (f, "nameserver %s\n", inet_ntoa (address->address));
+ char *resolvconf = NULL;
+
+ if (file_in_path ("resolvconf") == 0)
+ {
+ size_t len = strlen ("resolvconf -a ") + strlen (ifname) + 1;
+ resolvconf = xmalloc (sizeof (char) * len);
+ snprintf (resolvconf, len, "resolvconf -a %s", ifname);
+ if ((f = popen (resolvconf , "w")))
+ logger (LOG_DEBUG,
+ "sending DNS information to resolvconf");
+ else if (errno == EEXIST)
+ logger (LOG_ERR, "popen: %s", strerror (errno));
+
+ if (ferror (f))
+ logger (LOG_ERR, "ferror");
+ free (resolvconf);
+ }
+#endif
+ if (! f)
+ {
+ logger (LOG_DEBUG, "writing "RESOLVFILE);
+ if (! (f = fopen(RESOLVFILE, "w")))
+ logger (LOG_ERR, "fopen `%s': %s", RESOLVFILE, strerror (errno));
+ }
+
+ if (! f)
+ return (-1);
+
+ fprintf (f, "# Generated by dhcpcd for interface %s\n", ifname);
+ if (dhcp->dnssearch)
+ fprintf (f, "search %s\n", dhcp->dnssearch);
+ else if (dhcp->dnsdomain)
+ {
+ fprintf (f, "search %s\n", dhcp->dnsdomain);
+ }
+
+ STAILQ_FOREACH (address, dhcp->dnsservers, entries)
+ fprintf (f, "nameserver %s\n", inet_ntoa (address->address));
#ifdef ENABLE_RESOLVCONF
- if (resolvconf)
- pclose (f);
- else
+ if (resolvconf)
+ pclose (f);
+ else
#endif
- fclose (f);
+ fclose (f);
- /* Refresh the local resolver */
- res_init ();
- return (0);
+ /* Refresh the local resolver */
+ res_init ();
+ return (0);
}
static void restore_resolv (const char *ifname)
{
#ifdef ENABLE_RESOLVCONF
- if (file_in_path ("resolvconf") == 0) {
- logger (LOG_DEBUG, "removing information from resolvconf");
- exec_cmd("resolvconf", "-d", ifname, (char *) NULL);
- }
+ if (file_in_path ("resolvconf") == 0)
+ {
+ logger (LOG_DEBUG, "removing information from resolvconf");
+ exec_cmd("resolvconf", "-d", ifname, (char *) NULL);
+ }
#endif
}
static bool in_addresses (const struct address_head *addresses,
- struct in_addr address)
+ struct in_addr address)
{
- const address_t *addr;
+ const address_t *addr;
- STAILQ_FOREACH (addr, addresses, entries)
- if (addr->address.s_addr == address.s_addr)
- return (true);
+ STAILQ_FOREACH (addr, addresses, entries)
+ if (addr->address.s_addr == address.s_addr)
+ return (true);
- return (false);
+ return (false);
}
static bool in_routes (const struct route_head *routes, route_t *route)
{
- const route_t *r;
-
- if (! routes)
- return (false);
-
- STAILQ_FOREACH (r, routes, entries)
- if (r->destination.s_addr == route->destination.s_addr &&
- r->netmask.s_addr == route->netmask.s_addr &&
- r->gateway.s_addr == route->gateway.s_addr)
- return (true);
-
- return (false);
+ const route_t *r;
+
+ if (! routes)
+ return (false);
+
+ STAILQ_FOREACH (r, routes, entries)
+ if (r->destination.s_addr == route->destination.s_addr &&
+ r->netmask.s_addr == route->netmask.s_addr &&
+ r->gateway.s_addr == route->gateway.s_addr)
+ return (true);
+
+ return (false);
}
#ifdef ENABLE_NTP
static int _make_ntp (const char *file, const char *ifname, const dhcp_t *dhcp)
{
- FILE *f;
- address_t *address;
- char *a;
- char *line;
- int tomatch = 0;
- char *token;
- bool ntp = false;
-
- STAILQ_FOREACH (address, dhcp->ntpservers, entries)
- 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 (file, "r"))) {
- if (errno != ENOENT) {
- logger (LOG_ERR, "fopen `%s': %s",
- file, strerror (errno));
- return (-1);
- }
- } else {
- while (tomatch != 0 && (line = get_line (f))) {
- struct in_addr addr;
-
- a = line;
- token = strsep (&a, " ");
- if (! token || strcmp (token, "server") != 0)
- goto next;
-
- if ((token = strsep (&a, " \n")) == NULL)
- goto next;
-
- if (inet_aton (token, &addr) == 1 &&
- in_addresses (dhcp->ntpservers, addr))
- tomatch--;
+ FILE *f;
+ address_t *address;
+ char *a;
+ char *line;
+ int tomatch = 0;
+ char *token;
+ bool ntp = false;
+
+ STAILQ_FOREACH (address, dhcp->ntpservers, entries)
+ 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 (file, "r")))
+ {
+ if (errno != ENOENT)
+ {
+ logger (LOG_ERR, "fopen `%s': %s",
+ file, strerror (errno));
+ return (-1);
+ }
+ }
+ else
+ {
+ while (tomatch != 0 && (line = get_line (f)))
+ {
+ struct in_addr addr;
+
+ a = line;
+ token = strsep (&a, " ");
+ if (! token || strcmp (token, "server") != 0)
+ goto next;
+
+ if ((token = strsep (&a, " \n")) == NULL)
+ goto next;
+
+ if (inet_aton (token, &addr) == 1 &&
+ in_addresses (dhcp->ntpservers, addr))
+ tomatch--;
next:
- free (line);
- }
- fclose (f);
-
- /* File has the same name servers that we do,
- * so no need to restart ntp */
- if (tomatch == 0) {
- logger (LOG_DEBUG, "%s already configured, skipping",
- file);
- return (0);
- }
- }
-
- logger (LOG_DEBUG, "writing %s", file);
- if (! (f = fopen (file, "w"))) {
- logger (LOG_ERR, "fopen `%s': %s", file, strerror (errno));
- return (-1);
- }
-
- fprintf (f, "# Generated by dhcpcd for interface %s\n", ifname);
+ free (line);
+ }
+ fclose (f);
+
+ /* File has the same name servers that we do,
+ * so no need to restart ntp */
+ if (tomatch == 0)
+ {
+ logger (LOG_DEBUG, "%s already configured, skipping",
+ file);
+ return (0);
+ }
+ }
+
+ logger (LOG_DEBUG, "writing %s", file);
+ if (! (f = fopen (file, "w")))
+ {
+ logger (LOG_ERR, "fopen `%s': %s", file, strerror (errno));
+ return (-1);
+ }
+
+ fprintf (f, "# Generated by dhcpcd for interface %s\n", ifname);
#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
-
- STAILQ_FOREACH (address, dhcp->ntpservers, entries) {
- a = inet_ntoa (address->address);
- if (ntp)
- fprintf (f, "restrict %s nomodify notrap noquery\n", a);
- fprintf (f, "server %s\n", a);
- }
- fclose (f);
-
- return (1);
+ if (strcmp (file, NTPFILE) == 0)
+ {
+ ntp = true;
+ fprintf (f, "restrict default noquery notrust nomodify\n");
+ fprintf (f, "restrict 127.0.0.1\n");
+ }
+#endif
+
+ STAILQ_FOREACH (address, dhcp->ntpservers, entries)
+ {
+ a = inet_ntoa (address->address);
+ if (ntp)
+ fprintf (f, "restrict %s nomodify notrap noquery\n", a);
+ fprintf (f, "server %s\n", a);
+ }
+ fclose (f);
+
+ 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. */
+ /* 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;
+ bool restart_ntp = false;
+ bool restart_openntp = false;
+ int retval = 0;
#ifdef NTPFILE
- if (_make_ntp (NTPFILE, ifname, dhcp) > 0)
- restart_ntp = true;
+ if (_make_ntp (NTPFILE, ifname, dhcp) > 0)
+ restart_ntp = true;
#endif
#ifdef OPENNTPFILE
- if (_make_ntp (OPENNTPFILE, ifname, dhcp) > 0)
- restart_openntp = true;
+ if (_make_ntp (OPENNTPFILE, ifname, dhcp) > 0)
+ restart_openntp = true;
#endif
#ifdef NTPSERVICE
- if (restart_ntp) {
+ if (restart_ntp)
+ {
#ifdef NTPCHECK
- if (system (NTPCHECK) == 0)
+ if (system (NTPCHECK) == 0)
#endif
- retval += exec_cmd (NTPSERVICE, NTPRESTARTARGS,
- (char *) NULL);
- }
+ retval += exec_cmd (NTPSERVICE, NTPRESTARTARGS,
+ (char *) NULL);
+ }
#endif
#if defined (NTPSERVICE) && defined (OPENNTPSERVICE)
- if (restart_openntp &&
- (strcmp (NTPSERVICE, OPENNTPSERVICE) != 0 || ! restart_ntp))
- {
+ if (restart_openntp &&
+ (strcmp (NTPSERVICE, OPENNTPSERVICE) != 0 || ! restart_ntp))
+ {
#ifdef OPENNTPCHECK
- if (system (OPENNTPCHECK) == 0)
+ if (system (OPENNTPCHECK) == 0)
#endif
- retval += exec_cmd (OPENNTPSERVICE,
- OPENNTPRESTARTARGS, (char *) NULL);
- }
+ retval += exec_cmd (OPENNTPSERVICE,
+ OPENNTPRESTARTARGS, (char *) NULL);
+ }
#elif defined (OPENNTPSERVICE) && ! defined (NTPSERVICE)
- if (restart_openntp) {
+ if (restart_openntp)
+ {
#ifdef OPENNTPCHECK
- if (system (OPENNTPCHECK) == 0)
+ if (system (OPENNTPCHECK) == 0)
#endif
- retval += exec_cmd (OPENNTPSERVICE,
- OPENNTPRESTARTARGS, (char *) NULL);
- }
+ retval += exec_cmd (OPENNTPSERVICE,
+ OPENNTPRESTARTARGS, (char *) NULL);
+ }
#endif
- return (retval);
+ return (retval);
}
#endif
@@ -404,411 +424,438 @@ static int make_ntp (const char *ifname, const dhcp_t *dhcp)
#define PREFIXSIZE 256
static int make_nis (const char *ifname, const dhcp_t *dhcp)
{
- FILE *f;
- address_t *address;
- char *prefix;
-
- logger (LOG_DEBUG, "writing "NISFILE);
- if (! (f = fopen(NISFILE, "w"))) {
- logger (LOG_ERR, "fopen `%s': %s", NISFILE, strerror (errno));
- return (-1);
- }
-
- prefix = xmalloc (sizeof (char) * PREFIXSIZE);
- *prefix = '\0';
- fprintf (f, "# Generated by dhcpcd for interface %s\n", ifname);
-
- if (dhcp->nisdomain) {
- setdomainname (dhcp->nisdomain, (int) strlen (dhcp->nisdomain));
-
- if (dhcp->nisservers)
- snprintf (prefix, PREFIXSIZE, "domain %s server",
- dhcp->nisdomain);
- else
- fprintf (f, "domain %s broadcast\n", dhcp->nisdomain);
- }
- else
- snprintf (prefix, PREFIXSIZE, "%s", "ypserver");
-
- NSTAILQ_FOREACH (address, dhcp->nisservers, entries)
- fprintf (f, "%s %s\n", prefix, inet_ntoa (address->address));
-
- free (prefix);
- fclose (f);
+ FILE *f;
+ address_t *address;
+ char *prefix;
+
+ logger (LOG_DEBUG, "writing "NISFILE);
+ if (! (f = fopen(NISFILE, "w")))
+ {
+ logger (LOG_ERR, "fopen `%s': %s", NISFILE, strerror (errno));
+ return (-1);
+ }
+
+ prefix = xmalloc (sizeof (char) * PREFIXSIZE);
+ *prefix = '\0';
+ fprintf (f, "# Generated by dhcpcd for interface %s\n", ifname);
+
+ if (dhcp->nisdomain)
+ {
+ setdomainname (dhcp->nisdomain, (int) strlen (dhcp->nisdomain));
+
+ if (dhcp->nisservers)
+ snprintf (prefix, PREFIXSIZE, "domain %s server",
+ dhcp->nisdomain);
+ else
+ fprintf (f, "domain %s broadcast\n", dhcp->nisdomain);
+ }
+ else
+ snprintf (prefix, PREFIXSIZE, "%s", "ypserver");
+
+ NSTAILQ_FOREACH (address, dhcp->nisservers, entries)
+ fprintf (f, "%s %s\n", prefix, inet_ntoa (address->address));
+
+ free (prefix);
+ fclose (f);
#ifdef NISCHECK
- if (system (NISCHECK) == 0)
+ if (system (NISCHECK) == 0)
#endif
- exec_cmd (NISSERVICE, NISRESTARTARGS, (char *) NULL);
- return (0);
+ exec_cmd (NISSERVICE, NISRESTARTARGS, (char *) NULL);
+ return (0);
}
#endif
static char *lookuphostname (char *hostname, const dhcp_t *dhcp,
- const options_t *options)
+ const options_t *options)
{
- union {
- struct sockaddr sa;
- struct sockaddr_in sin;
- } su;
- socklen_t salen;
- char *addr;
- struct addrinfo hints;
- struct addrinfo *res = NULL;
- int result;
- char *p;
-
- logger (LOG_DEBUG, "Looking up hostname via DNS");
- addr = xmalloc (sizeof (char) * NI_MAXHOST);
- salen = sizeof (su.sa);
- memset (&su.sa, 0, salen);
- su.sin.sin_family = AF_INET;
- memcpy (&su.sin.sin_addr, &dhcp->address, sizeof (su.sin.sin_addr));
-
- if ((result = getnameinfo (&su.sa, salen, addr, NI_MAXHOST,
- NULL, 0, NI_NAMEREQD)) != 0) {
- logger (LOG_ERR,
- "Failed to lookup hostname via DNS: %s",
- gai_strerror (result));
- free (addr);
- return (NULL);
- }
-
- /* Check for a malicious PTR record */
- memset (&hints, 0, sizeof (hints));
- hints.ai_socktype = SOCK_DGRAM;
- hints.ai_flags = AI_NUMERICHOST;
- result = getaddrinfo (addr, "0", &hints, &res);
- if (res)
- freeaddrinfo (res);
- if (result == 0)
- logger (LOG_ERR, "malicious PTR record detected");
- if (result == 0 || ! *addr) {
- free (addr);
- return (NULL);
- }
-
- p = strchr (addr, '.');
- if (p) {
- switch (options->dohostname) {
- case 1: /* -H */
- case 4: /* -HHHH */
- break;
- case 2: /* -HH */
- case 5: /* -HHHHH */
- /* Strip out the domain if it matches */
- p++;
- if (*p && dhcp->dnssearch) {
- char *s = xstrdup (dhcp->dnssearch);
- char *sp = s;
- char *t;
-
- while ((t = strsep (&sp, " ")))
- if (strcmp (t, p) == 0) {
- *--p = '\0';
- break;
- }
- free (s);
- } else if (dhcp->dnsdomain) {
- if (strcmp (dhcp->dnsdomain, p) == 0)
- *--p = '\0';
- }
- break;
- case 3: /* -HHH */
- case 6: /* -HHHHHH */
- /* Just strip the domain */
- *p = '\0';
- break;
- default: /* Too many H! */
- break;
- }
- }
-
- strlcpy (hostname, addr, MAXHOSTNAMELEN);
- free (addr);
- return (hostname);
+ union
+ {
+ struct sockaddr sa;
+ struct sockaddr_in sin;
+ } su;
+ socklen_t salen;
+ char *addr;
+ struct addrinfo hints;
+ struct addrinfo *res = NULL;
+ int result;
+ char *p;
+
+ logger (LOG_DEBUG, "Looking up hostname via DNS");
+ addr = xmalloc (sizeof (char) * NI_MAXHOST);
+ salen = sizeof (su.sa);
+ memset (&su.sa, 0, salen);
+ su.sin.sin_family = AF_INET;
+ memcpy (&su.sin.sin_addr, &dhcp->address, sizeof (su.sin.sin_addr));
+
+ if ((result = getnameinfo (&su.sa, salen, addr, NI_MAXHOST,
+ NULL, 0, NI_NAMEREQD)) != 0)
+ {
+ logger (LOG_ERR,
+ "Failed to lookup hostname via DNS: %s",
+ gai_strerror (result));
+ free (addr);
+ return (NULL);
+ }
+
+ /* Check for a malicious PTR record */
+ memset (&hints, 0, sizeof (hints));
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_flags = AI_NUMERICHOST;
+ result = getaddrinfo (addr, "0", &hints, &res);
+ if (res)
+ freeaddrinfo (res);
+ if (result == 0)
+ logger (LOG_ERR, "malicious PTR record detected");
+ if (result == 0 || ! *addr)
+ {
+ free (addr);
+ return (NULL);
+ }
+
+ p = strchr (addr, '.');
+ if (p)
+ {
+ switch (options->dohostname)
+ {
+ case 1: /* -H */
+ case 4: /* -HHHH */
+ break;
+ case 2: /* -HH */
+ case 5: /* -HHHHH */
+ /* Strip out the domain if it matches */
+ p++;
+ if (*p && dhcp->dnssearch)
+ {
+ char *s = xstrdup (dhcp->dnssearch);
+ char *sp = s;
+ char *t;
+
+ while ((t = strsep (&sp, " ")))
+ if (strcmp (t, p) == 0)
+ {
+ *--p = '\0';
+ break;
+ }
+ free (s);
+ }
+ else if (dhcp->dnsdomain)
+ {
+ if (strcmp (dhcp->dnsdomain, p) == 0)
+ *--p = '\0';
+ }
+ break;
+ case 3: /* -HHH */
+ case 6: /* -HHHHHH */
+ /* Just strip the domain */
+ *p = '\0';
+ break;
+ default: /* Too many H! */
+ break;
+ }
+ }
+
+ strlcpy (hostname, addr, MAXHOSTNAMELEN);
+ free (addr);
+ return (hostname);
}
int configure (const options_t *options, interface_t *iface,
- const dhcp_t *dhcp, bool up)
+ const dhcp_t *dhcp, bool up)
{
- route_t *route = NULL;
- struct route_head *new_routes = NULL;
- route_t *new_route = NULL;
- char *newhostname = NULL;
- char *curhostname = NULL;
- int remember;
+ route_t *route = NULL;
+ struct route_head *new_routes = NULL;
+ route_t *new_route = NULL;
+ char *newhostname = NULL;
+ char *curhostname = NULL;
+ int remember;
#ifdef ENABLE_IPV4LL
- bool haslinklocal = false;
+ bool haslinklocal = false;
#endif
#ifdef THERE_IS_NO_FORK
- int skip = 0;
- size_t skiplen;
- char *skipp;
-#endif
-
- if (! options || ! iface || ! dhcp)
- return (-1);
-
- if (dhcp->address.s_addr == 0)
- up = 0;
-
- logGatewayToFile(iface, dhcp);
-
- /* Remove old routes.
- * Always do this as the interface may have >1 address not added by us
- * so the routes we added may still exist. */
- NSTAILQ_FOREACH (route, iface->previous_routes, entries)
- if ((route->destination.s_addr || options->dogateway) &&
- (! up || ! in_routes (dhcp->routes, route)))
- del_route (iface->name, route->destination,
- route->netmask, route->gateway,
- options->metric);
- /* If we aren't up, then reset the interface as much as we can */
- if (! up) {
- if (iface->previous_routes) {
- free_route (iface->previous_routes);
- iface->previous_routes = NULL;
- }
-
- /* Restore the original MTU value */
- if (iface->mtu && iface->previous_mtu != iface->mtu) {
- set_mtu (iface->name, iface->mtu);
- iface->previous_mtu = iface->mtu;
- }
+ int skip = 0;
+ size_t skiplen;
+ char *skipp;
+#endif
+
+ if (! options || ! iface || ! dhcp)
+ return (-1);
+
+ if (dhcp->address.s_addr == 0)
+ up = 0;
+
+ logGatewayToFile(iface, dhcp);
+
+ /* Remove old routes.
+ * Always do this as the interface may have >1 address not added by us
+ * so the routes we added may still exist. */
+ NSTAILQ_FOREACH (route, iface->previous_routes, entries)
+ if ((route->destination.s_addr || options->dogateway) &&
+ (! up || ! in_routes (dhcp->routes, route)))
+ del_route (iface->name, route->destination,
+ route->netmask, route->gateway,
+ options->metric);
+ /* If we aren't up, then reset the interface as much as we can */
+ if (! up)
+ {
+ if (iface->previous_routes)
+ {
+ free_route (iface->previous_routes);
+ iface->previous_routes = NULL;
+ }
+
+ /* Restore the original MTU value */
+ if (iface->mtu && iface->previous_mtu != iface->mtu)
+ {
+ set_mtu (iface->name, iface->mtu);
+ iface->previous_mtu = iface->mtu;
+ }
#ifdef ENABLE_INFO
- /* If we haven't created an info file, do so now */
- if (! dhcp->frominfo)
- write_info (iface, dhcp, options, false);
-#endif
-
- /* Only reset things if we had set them before */
- if (iface->previous_address.s_addr != 0) {
- if (! options->keep_address) {
- del_address (iface->name,
- iface->previous_address,
- iface->previous_netmask);
- memset (&iface->previous_address,
- 0, sizeof (iface->previous_address));
- memset (&iface->previous_netmask,
- 0, sizeof (iface->previous_netmask));
- }
- }
-
- restore_resolv (iface->name);
- exec_script (options->script, iface->infofile, "down");
-
- return (0);
- }
-
- /* Set the MTU requested.
- * If the DHCP server no longer sends one OR it's invalid then
- * we restore the original MTU */
- if (options->domtu) {
- unsigned short mtu = iface->mtu;
- if (dhcp->mtu)
- mtu = dhcp->mtu;
-
- if (mtu != iface->previous_mtu) {
- if (set_mtu (iface->name, mtu) == 0)
- iface->previous_mtu = mtu;
- }
- }
-
- /* This also changes netmask */
- if (! options->doinform || ! has_address (iface->name, dhcp->address))
- if (add_address (iface->name, dhcp->address, dhcp->netmask,
- dhcp->broadcast) == -1 && errno != EEXIST)
- return (false);
-
- /* Now delete the old address if different */
- if (iface->previous_address.s_addr != dhcp->address.s_addr &&
- iface->previous_address.s_addr != 0 &&
- ! options->keep_address)
- del_address (iface->name,
- iface->previous_address, iface->previous_netmask);
+ /* If we haven't created an info file, do so now */
+ if (! dhcp->frominfo)
+ write_info (iface, dhcp, options, false);
+#endif
+
+ /* Only reset things if we had set them before */
+ if (iface->previous_address.s_addr != 0)
+ {
+ if (! options->keep_address)
+ {
+ del_address (iface->name,
+ iface->previous_address,
+ iface->previous_netmask);
+ memset (&iface->previous_address,
+ 0, sizeof (iface->previous_address));
+ memset (&iface->previous_netmask,
+ 0, sizeof (iface->previous_netmask));
+ }
+ }
+
+ restore_resolv (iface->name);
+ exec_script (options->script, iface->infofile, "down");
+
+ return (0);
+ }
+
+ /* Set the MTU requested.
+ * If the DHCP server no longer sends one OR it's invalid then
+ * we restore the original MTU */
+ if (options->domtu)
+ {
+ unsigned short mtu = iface->mtu;
+ if (dhcp->mtu)
+ mtu = dhcp->mtu;
+
+ if (mtu != iface->previous_mtu)
+ {
+ if (set_mtu (iface->name, mtu) == 0)
+ iface->previous_mtu = mtu;
+ }
+ }
+
+ /* This also changes netmask */
+ if (! options->doinform || ! has_address (iface->name, dhcp->address))
+ if (add_address (iface->name, dhcp->address, dhcp->netmask,
+ dhcp->broadcast) == -1 && errno != EEXIST)
+ return (false);
+
+ /* Now delete the old address if different */
+ if (iface->previous_address.s_addr != dhcp->address.s_addr &&
+ iface->previous_address.s_addr != 0 &&
+ ! options->keep_address)
+ del_address (iface->name,
+ iface->previous_address, iface->previous_netmask);
#ifdef __linux__
- /* On linux, we need to change the subnet route to have our metric. */
- if (iface->previous_address.s_addr != dhcp->address.s_addr &&
- options->metric > 0 &&
- dhcp->netmask.s_addr != INADDR_BROADCAST)
- {
- struct in_addr td;
- struct in_addr tg;
- memset (&td, 0, sizeof (td));
- memset (&tg, 0, sizeof (tg));
- td.s_addr = dhcp->address.s_addr & dhcp->netmask.s_addr;
- add_route (iface->name, td, dhcp->netmask, tg, options->metric);
- del_route (iface->name, td, dhcp->netmask, tg, 0);
- }
+ /* On linux, we need to change the subnet route to have our metric. */
+ if (iface->previous_address.s_addr != dhcp->address.s_addr &&
+ options->metric > 0 &&
+ dhcp->netmask.s_addr != INADDR_BROADCAST)
+ {
+ struct in_addr td;
+ struct in_addr tg;
+ memset (&td, 0, sizeof (td));
+ memset (&tg, 0, sizeof (tg));
+ td.s_addr = dhcp->address.s_addr & dhcp->netmask.s_addr;
+ add_route (iface->name, td, dhcp->netmask, tg, options->metric);
+ del_route (iface->name, td, dhcp->netmask, tg, 0);
+ }
#endif
#ifdef THERE_IS_NO_FORK
- free (dhcpcd_skiproutes);
- /* We can never have more than 255 routes. So we need space
- * for 255 3 digit numbers and commas */
- skiplen = 255 * 4 + 1;
- skipp = dhcpcd_skiproutes = xmalloc (sizeof (char) * skiplen);
- *skipp = '\0';
+ free (dhcpcd_skiproutes);
+ /* We can never have more than 255 routes. So we need space
+ * for 255 3 digit numbers and commas */
+ skiplen = 255 * 4 + 1;
+ skipp = dhcpcd_skiproutes = xmalloc (sizeof (char) * skiplen);
+ *skipp = '\0';
#endif
- /* Remember added routes */
- NSTAILQ_FOREACH (route, dhcp->routes, entries) {
+ /* Remember added routes */
+ NSTAILQ_FOREACH (route, dhcp->routes, entries)
+ {
#ifdef ENABLE_IPV4LL
- /* Check if we have already got a link locale route dished
- * out by the DHCP server */
- if (route->destination.s_addr == htonl (LINKLOCAL_ADDR) &&
- route->netmask.s_addr == htonl (LINKLOCAL_MASK))
- haslinklocal = true;
-#endif
- /* Don't set default routes if not asked to */
- if (route->destination.s_addr == 0 &&
- route->netmask.s_addr == 0 &&
- ! options->dogateway)
- continue;
-
- remember = add_route (iface->name, route->destination,
- route->netmask, route->gateway,
- options->metric);
- /* If we failed to add the route, we may have already added it
- ourselves. If so, remember it again. */
- if (remember < 0 && in_routes (iface->previous_routes, route))
- remember = 1;
-
- if (remember >= 0) {
- if (! new_routes) {
- new_routes = xmalloc (sizeof (*new_routes));
- STAILQ_INIT (new_routes);
- }
- new_route = xmalloc (sizeof (route_t));
- memcpy (new_route, route, sizeof (*new_route));
- STAILQ_INSERT_TAIL (new_routes, new_route, entries);
- }
+ /* Check if we have already got a link locale route dished
+ * out by the DHCP server */
+ if (route->destination.s_addr == htonl (LINKLOCAL_ADDR) &&
+ route->netmask.s_addr == htonl (LINKLOCAL_MASK))
+ haslinklocal = true;
+#endif
+ /* Don't set default routes if not asked to */
+ if (route->destination.s_addr == 0 &&
+ route->netmask.s_addr == 0 &&
+ ! options->dogateway)
+ continue;
+
+ remember = add_route (iface->name, route->destination,
+ route->netmask, route->gateway,
+ options->metric);
+ /* If we failed to add the route, we may have already added it
+ ourselves. If so, remember it again. */
+ if (remember < 0 && in_routes (iface->previous_routes, route))
+ remember = 1;
+
+ if (remember >= 0)
+ {
+ if (! new_routes)
+ {
+ new_routes = xmalloc (sizeof (*new_routes));
+ STAILQ_INIT (new_routes);
+ }
+ new_route = xmalloc (sizeof (route_t));
+ memcpy (new_route, route, sizeof (*new_route));
+ STAILQ_INSERT_TAIL (new_routes, new_route, entries);
+ }
#ifdef THERE_IS_NO_FORK
- /* If we have daemonised yet we need to record which routes
- * we failed to add so we can skip them */
- else if (! options->daemonised) {
- /* We can never have more than 255 / 4 routes,
- * so 3 chars is plently */
- if (*skipp)
- *skipp++ = ',';
- skipp += snprintf (skipp,
- dhcpcd_skiproutes + skiplen - skipp,
- "%d", skip);
- }
- skip++;
-#endif
- }
+ /* If we have daemonised yet we need to record which routes
+ * we failed to add so we can skip them */
+ else if (! options->daemonised)
+ {
+ /* We can never have more than 255 / 4 routes,
+ * so 3 chars is plently */
+ if (*skipp)
+ *skipp++ = ',';
+ skipp += snprintf (skipp,
+ dhcpcd_skiproutes + skiplen - skipp,
+ "%d", skip);
+ }
+ skip++;
+#endif
+ }
#ifdef THERE_IS_NO_FORK
- if (*dhcpcd_skiproutes)
- *skipp = '\0';
- else {
- free (dhcpcd_skiproutes);
- dhcpcd_skiproutes = NULL;
- }
+ if (*dhcpcd_skiproutes)
+ *skipp = '\0';
+ else
+ {
+ free (dhcpcd_skiproutes);
+ dhcpcd_skiproutes = NULL;
+ }
#endif
#ifdef ENABLE_IPV4LL
- /* Ensure we always add the link local route if we got a private
- * address and isn't link local itself */
- if (options->doipv4ll &&
- ! haslinklocal &&
- IN_PRIVATE (ntohl (dhcp->address.s_addr)))
- {
- struct in_addr dest;
- struct in_addr mask;
- struct in_addr gate;
-
- dest.s_addr = htonl (LINKLOCAL_ADDR);
- mask.s_addr = htonl (LINKLOCAL_MASK);
- gate.s_addr = 0;
- remember = add_route (iface->name, dest, mask, gate,
- options->metric);
-
- if (remember >= 0) {
- if (! new_routes) {
- new_routes = xmalloc (sizeof (*new_routes));
- STAILQ_INIT (new_routes);
- }
- new_route = xmalloc (sizeof (*new_route));
- new_route->destination.s_addr = dest.s_addr;
- new_route->netmask.s_addr = mask.s_addr;
- new_route->gateway.s_addr = gate.s_addr;
- STAILQ_INSERT_TAIL (new_routes, new_route, entries);
- }
- }
-#endif
-
- if (iface->previous_routes)
- free_route (iface->previous_routes);
- iface->previous_routes = new_routes;
-
- logToQt(LOG_INFO, DHCPCD_WRITE, "");
- if (options->dodns && dhcp->dnsservers)
- make_resolv(iface->name, dhcp);
- else
- logger (LOG_DEBUG, "no dns information to write");
+ /* Ensure we always add the link local route if we got a private
+ * address and isn't link local itself */
+ if (options->doipv4ll &&
+ ! haslinklocal &&
+ IN_PRIVATE (ntohl (dhcp->address.s_addr)))
+ {
+ struct in_addr dest;
+ struct in_addr mask;
+ struct in_addr gate;
+
+ dest.s_addr = htonl (LINKLOCAL_ADDR);
+ mask.s_addr = htonl (LINKLOCAL_MASK);
+ gate.s_addr = 0;
+ remember = add_route (iface->name, dest, mask, gate,
+ options->metric);
+
+ if (remember >= 0)
+ {
+ if (! new_routes)
+ {
+ new_routes = xmalloc (sizeof (*new_routes));
+ STAILQ_INIT (new_routes);
+ }
+ new_route = xmalloc (sizeof (*new_route));
+ new_route->destination.s_addr = dest.s_addr;
+ new_route->netmask.s_addr = mask.s_addr;
+ new_route->gateway.s_addr = gate.s_addr;
+ STAILQ_INSERT_TAIL (new_routes, new_route, entries);
+ }
+ }
+#endif
+
+ if (iface->previous_routes)
+ free_route (iface->previous_routes);
+ iface->previous_routes = new_routes;
+
+ logToQt(LOG_INFO, DHCPCD_WRITE, "");
+ if (options->dodns && dhcp->dnsservers)
+ make_resolv(iface->name, dhcp);
+ else
+ logger (LOG_DEBUG, "no dns information to write");
#ifdef ENABLE_NTP
- if (options->dontp && dhcp->ntpservers)
- make_ntp(iface->name, dhcp);
+ 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);
+ if (options->donis && (dhcp->nisservers || dhcp->nisdomain))
+ make_nis(iface->name, dhcp);
#endif
- curhostname = xmalloc (sizeof (char) * MAXHOSTNAMELEN);
- *curhostname = '\0';
+ curhostname = xmalloc (sizeof (char) * MAXHOSTNAMELEN);
+ *curhostname = '\0';
- gethostname (curhostname, MAXHOSTNAMELEN);
- if (options->dohostname ||
- strlen (curhostname) == 0 ||
- strcmp (curhostname, "(none)") == 0 ||
- strcmp (curhostname, "localhost") == 0)
- {
- newhostname = xmalloc (sizeof (char) * MAXHOSTNAMELEN);
+ gethostname (curhostname, MAXHOSTNAMELEN);
+ if (options->dohostname ||
+ strlen (curhostname) == 0 ||
+ strcmp (curhostname, "(none)") == 0 ||
+ strcmp (curhostname, "localhost") == 0)
+ {
+ newhostname = xmalloc (sizeof (char) * MAXHOSTNAMELEN);
- if (dhcp->hostname)
- strlcpy (newhostname, dhcp->hostname, MAXHOSTNAMELEN);
- else
- *newhostname = '\0';
+ if (dhcp->hostname)
+ strlcpy (newhostname, dhcp->hostname, MAXHOSTNAMELEN);
+ else
+ *newhostname = '\0';
- /* Now we have made a resolv.conf we can obtain a hostname
- * if we need it */
- if (! *newhostname || options->dohostname > 3)
- lookuphostname (newhostname, dhcp, options);
+ /* Now we have made a resolv.conf we can obtain a hostname
+ * if we need it */
+ if (! *newhostname || options->dohostname > 3)
+ lookuphostname (newhostname, dhcp, options);
- if (*newhostname) {
- logger (LOG_INFO, "setting hostname to `%s'",
- newhostname);
- sethostname (newhostname, (int) strlen (newhostname));
- }
+ if (*newhostname)
+ {
+ logger (LOG_INFO, "setting hostname to `%s'",
+ newhostname);
+ sethostname (newhostname, (int) strlen (newhostname));
+ }
- free (newhostname);
- }
+ free (newhostname);
+ }
- free (curhostname);
+ free (curhostname);
#ifdef ENABLE_INFO
- if (! dhcp->frominfo)
- write_info (iface, dhcp, options, true);
-#endif
-
- if (iface->previous_address.s_addr != dhcp->address.s_addr ||
- iface->previous_netmask.s_addr != dhcp->netmask.s_addr)
- {
- memcpy (&iface->previous_address,
- &dhcp->address, sizeof (iface->previous_address));
- memcpy (&iface->previous_netmask,
- &dhcp->netmask, sizeof (iface->previous_netmask));
- exec_script (options->script, iface->infofile, "new");
- } else
- exec_script (options->script, iface->infofile, "up");
-
- return (0);
+ if (! dhcp->frominfo)
+ write_info (iface, dhcp, options, true);
+#endif
+
+ if (iface->previous_address.s_addr != dhcp->address.s_addr ||
+ iface->previous_netmask.s_addr != dhcp->netmask.s_addr)
+ {
+ memcpy (&iface->previous_address,
+ &dhcp->address, sizeof (iface->previous_address));
+ memcpy (&iface->previous_netmask,
+ &dhcp->netmask, sizeof (iface->previous_netmask));
+ exec_script (options->script, iface->infofile, "new");
+ }
+ else
+ exec_script (options->script, iface->infofile, "up");
+
+ return (0);
}
diff --git a/src/customdhcpcd/configure.h b/src/customdhcpcd/configure.h
index 3166947..09ab1e0 100644
--- a/src/customdhcpcd/configure.h
+++ b/src/customdhcpcd/configure.h
@@ -1,4 +1,4 @@
-/*
+/*
* dhcpcd - DHCP client daemon
* Copyright 2006-2008 Roy Marples <roy@marples.name>
* All rights reserved
@@ -33,6 +33,6 @@
#include "dhcp.h"
int configure (const options_t *options, interface_t *iface,
- const dhcp_t *dhcp, bool up);
+ const dhcp_t *dhcp, bool up);
#endif
diff --git a/src/customdhcpcd/dhcp.c b/src/customdhcpcd/dhcp.c
index f625e8f..7c41ad2 100644
--- a/src/customdhcpcd/dhcp.c
+++ b/src/customdhcpcd/dhcp.c
@@ -1,4 +1,4 @@
-/*
+/*
* dhcpcd - DHCP client daemon
* Copyright 2006-2008 Roy Marples <roy@marples.name>
* All rights reserved
@@ -61,492 +61,528 @@
} while (0)
#endif
-typedef struct message {
- int value;
- const char *name;
+typedef struct message
+{
+ int value;
+ const char *name;
} dhcp_message_t;
-static dhcp_message_t dhcp_messages[] = {
- { DHCP_DISCOVER, "DHCP_DISCOVER" },
- { DHCP_OFFER, "DHCP_OFFER" },
- { DHCP_REQUEST, "DHCP_REQUEST" },
- { DHCP_DECLINE, "DHCP_DECLINE" },
- { DHCP_ACK, "DHCP_ACK" },
- { DHCP_NAK, "DHCP_NAK" },
- { DHCP_RELEASE, "DHCP_RELEASE" },
- { DHCP_INFORM, "DHCP_INFORM" },
- { -1, NULL }
+static dhcp_message_t dhcp_messages[] =
+{
+ { DHCP_DISCOVER, "DHCP_DISCOVER" },
+ { DHCP_OFFER, "DHCP_OFFER" },
+ { DHCP_REQUEST, "DHCP_REQUEST" },
+ { DHCP_DECLINE, "DHCP_DECLINE" },
+ { DHCP_ACK, "DHCP_ACK" },
+ { DHCP_NAK, "DHCP_NAK" },
+ { DHCP_RELEASE, "DHCP_RELEASE" },
+ { DHCP_INFORM, "DHCP_INFORM" },
+ { -1, NULL }
};
static const char *dhcp_message (int type)
{
- dhcp_message_t *d;
- for (d = dhcp_messages; d->name; d++)
- if (d->value == type)
- return (d->name);
+ dhcp_message_t *d;
+ for (d = dhcp_messages; d->name; d++)
+ if (d->value == type)
+ return (d->name);
- return (NULL);
+ return (NULL);
}
ssize_t send_message (const interface_t *iface, const dhcp_t *dhcp,
- uint32_t xid, char type, const options_t *options)
+ uint32_t xid, char type, const options_t *options)
{
- struct udp_dhcp_packet *packet;
- dhcpmessage_t *message;
- unsigned char *m;
- unsigned char *p;
- unsigned char *n_params = NULL;
- size_t l;
- struct in_addr from;
- struct in_addr to;
- time_t up = uptime() - iface->start_uptime;
- uint32_t ul;
- uint16_t sz;
- size_t message_length;
- ssize_t retval;
-
- if (!iface || !options || !dhcp)
- return -1;
-
- memset (&from, 0, sizeof (from));
- memset (&to, 0, sizeof (to));
-
- if (type == DHCP_RELEASE)
- to.s_addr = dhcp->serveraddress.s_addr;
-
- message = xzalloc (sizeof (*message));
- m = (unsigned char *) message;
- p = (unsigned char *) &message->options;
-
- if ((type == DHCP_INFORM ||
- type == DHCP_RELEASE ||
- type == DHCP_REQUEST) &&
- ! IN_LINKLOCAL (ntohl (iface->previous_address.s_addr)))
- {
- message->ciaddr = iface->previous_address.s_addr;
- from.s_addr = iface->previous_address.s_addr;
-
- /* Just incase we haven't actually configured the address yet */
- if (type == DHCP_INFORM && iface->previous_address.s_addr == 0)
- message->ciaddr = dhcp->address.s_addr;
-
- /* Zero the address if we're currently on a different subnet */
- if (type == DHCP_REQUEST &&
- iface->previous_netmask.s_addr != dhcp->netmask.s_addr)
- message->ciaddr = from.s_addr = 0;
-
- if (from.s_addr != 0)
- to.s_addr = dhcp->serveraddress.s_addr;
- }
-
- message->op = DHCP_BOOTREQUEST;
- message->hwtype = iface->family;
- switch (iface->family) {
- case ARPHRD_ETHER:
- case ARPHRD_IEEE802:
- message->hwlen = ETHER_ADDR_LEN;
- memcpy (&message->chaddr, &iface->hwaddr,
- ETHER_ADDR_LEN);
- break;
- case ARPHRD_IEEE1394:
- case ARPHRD_INFINIBAND:
- message->hwlen = 0;
- if (message->ciaddr == 0)
- message->flags = htons (BROADCAST_FLAG);
- break;
- default:
- logger (LOG_ERR, "dhcp: unknown hardware type %d",
- iface->family);
- }
-
- if (up < 0 || up > (time_t) UINT16_MAX)
- message->secs = htons ((uint16_t) UINT16_MAX);
- else
- message->secs = htons (up);
- message->xid = xid;
- message->cookie = htonl (MAGIC_COOKIE);
-
- *p++ = DHCP_MESSAGETYPE;
- *p++ = 1;
- *p++ = type;
-
- if (type == DHCP_REQUEST) {
- *p++ = DHCP_MAXMESSAGESIZE;
- *p++ = 2;
- sz = get_mtu (iface->name);
- if (sz < MTU_MIN) {
- if (set_mtu (iface->name, MTU_MIN) == 0)
- sz = MTU_MIN;
- }
- sz = htons (sz);
- memcpy (p, &sz, 2);
- p += 2;
- }
-
- *p++ = DHCP_CLIENTID;
- *p++ = iface->clientid_len;
- memcpy (p, iface->clientid, iface->clientid_len);
- p+= iface->clientid_len;
-
- if (type != DHCP_DECLINE && type != DHCP_RELEASE) {
- if (options->userclass_len > 0) {
- *p++ = DHCP_USERCLASS;
- *p++ = options->userclass_len;
- memcpy (p, &options->userclass, options->userclass_len);
- p += options->userclass_len;
- }
-
- if (*options->classid > 0) {
- *p++ = DHCP_CLASSID;
- *p++ = l = strlen (options->classid);
- memcpy (p, options->classid, l);
- p += l;
- }
- }
-
- if (type == DHCP_DISCOVER || type == DHCP_REQUEST) {
+ struct udp_dhcp_packet *packet;
+ dhcpmessage_t *message;
+ unsigned char *m;
+ unsigned char *p;
+ unsigned char *n_params = NULL;
+ size_t l;
+ struct in_addr from;
+ struct in_addr to;
+ time_t up = uptime() - iface->start_uptime;
+ uint32_t ul;
+ uint16_t sz;
+ size_t message_length;
+ ssize_t retval;
+
+ if (!iface || !options || !dhcp)
+ return -1;
+
+ memset (&from, 0, sizeof (from));
+ memset (&to, 0, sizeof (to));
+
+ if (type == DHCP_RELEASE)
+ to.s_addr = dhcp->serveraddress.s_addr;
+
+ message = xzalloc (sizeof (*message));
+ m = (unsigned char *) message;
+ p = (unsigned char *) &message->options;
+
+ if ((type == DHCP_INFORM ||
+ type == DHCP_RELEASE ||
+ type == DHCP_REQUEST) &&
+ ! IN_LINKLOCAL (ntohl (iface->previous_address.s_addr)))
+ {
+ message->ciaddr = iface->previous_address.s_addr;
+ from.s_addr = iface->previous_address.s_addr;
+
+ /* Just incase we haven't actually configured the address yet */
+ if (type == DHCP_INFORM && iface->previous_address.s_addr == 0)
+ message->ciaddr = dhcp->address.s_addr;
+
+ /* Zero the address if we're currently on a different subnet */
+ if (type == DHCP_REQUEST &&
+ iface->previous_netmask.s_addr != dhcp->netmask.s_addr)
+ message->ciaddr = from.s_addr = 0;
+
+ if (from.s_addr != 0)
+ to.s_addr = dhcp->serveraddress.s_addr;
+ }
+
+ message->op = DHCP_BOOTREQUEST;
+ message->hwtype = iface->family;
+ switch (iface->family)
+ {
+ case ARPHRD_ETHER:
+ case ARPHRD_IEEE802:
+ message->hwlen = ETHER_ADDR_LEN;
+ memcpy (&message->chaddr, &iface->hwaddr,
+ ETHER_ADDR_LEN);
+ break;
+ case ARPHRD_IEEE1394:
+ case ARPHRD_INFINIBAND:
+ message->hwlen = 0;
+ if (message->ciaddr == 0)
+ message->flags = htons (BROADCAST_FLAG);
+ break;
+ default:
+ logger (LOG_ERR, "dhcp: unknown hardware type %d",
+ iface->family);
+ }
+
+ if (up < 0 || up > (time_t) UINT16_MAX)
+ message->secs = htons ((uint16_t) UINT16_MAX);
+ else
+ message->secs = htons (up);
+ message->xid = xid;
+ message->cookie = htonl (MAGIC_COOKIE);
+
+ *p++ = DHCP_MESSAGETYPE;
+ *p++ = 1;
+ *p++ = type;
+
+ if (type == DHCP_REQUEST)
+ {
+ *p++ = DHCP_MAXMESSAGESIZE;
+ *p++ = 2;
+ sz = get_mtu (iface->name);
+ if (sz < MTU_MIN)
+ {
+ if (set_mtu (iface->name, MTU_MIN) == 0)
+ sz = MTU_MIN;
+ }
+ sz = htons (sz);
+ memcpy (p, &sz, 2);
+ p += 2;
+ }
+
+ *p++ = DHCP_CLIENTID;
+ *p++ = iface->clientid_len;
+ memcpy (p, iface->clientid, iface->clientid_len);
+ p += iface->clientid_len;
+
+ if (type != DHCP_DECLINE && type != DHCP_RELEASE)
+ {
+ if (options->userclass_len > 0)
+ {
+ *p++ = DHCP_USERCLASS;
+ *p++ = options->userclass_len;
+ memcpy (p, &options->userclass, options->userclass_len);
+ p += options->userclass_len;
+ }
+
+ if (*options->classid > 0)
+ {
+ *p++ = DHCP_CLASSID;
+ *p++ = l = strlen (options->classid);
+ memcpy (p, options->classid, l);
+ p += l;
+ }
+ }
+
+ if (type == DHCP_DISCOVER || type == DHCP_REQUEST)
+ {
#define PUTADDR(_type, _val) { \
*p++ = _type; \
*p++ = 4; \
memcpy (p, &_val.s_addr, 4); \
p += 4; \
}
- if (IN_LINKLOCAL (ntohl (dhcp->address.s_addr)))
- logger (LOG_ERR,
- "cannot request a link local address");
- else {
- if (dhcp->address.s_addr &&
- dhcp->address.s_addr !=
- iface->previous_address.s_addr)
- {
- PUTADDR (DHCP_ADDRESS, dhcp->address);
- if (dhcp->serveraddress.s_addr)
- PUTADDR (DHCP_SERVERIDENTIFIER,
- dhcp->serveraddress);
- }
- }
+ if (IN_LINKLOCAL (ntohl (dhcp->address.s_addr)))
+ logger (LOG_ERR,
+ "cannot request a link local address");
+ else
+ {
+ if (dhcp->address.s_addr &&
+ dhcp->address.s_addr !=
+ iface->previous_address.s_addr)
+ {
+ PUTADDR (DHCP_ADDRESS, dhcp->address);
+ if (dhcp->serveraddress.s_addr)
+ PUTADDR (DHCP_SERVERIDENTIFIER,
+ dhcp->serveraddress);
+ }
+ }
#undef PUTADDR
- if (options->leasetime != 0) {
- *p++ = DHCP_LEASETIME;
- *p++ = 4;
- ul = htonl (options->leasetime);
- memcpy (p, &ul, 4);
- p += 4;
- }
- }
-
- if (type == DHCP_DISCOVER ||
- type == DHCP_INFORM ||
- type == DHCP_REQUEST)
- {
- if (options->hostname[0]) {
- if (options->fqdn == FQDN_DISABLE) {
- *p++ = DHCP_HOSTNAME;
- *p++ = l = strlen (options->hostname);
- memcpy (p, options->hostname, l);
- p += l;
- } else {
- /* Draft IETF DHC-FQDN option (81) */
- *p++ = DHCP_FQDN;
- *p++ = (l = strlen (options->hostname)) + 3;
- /* Flags: 0000NEOS
- * S: 1 => Client requests Server to update
- * a RR in DNS as well as PTR
- * O: 1 => Server indicates to client that
- * DNS has been updated
- * E: 1 => Name data is DNS format
- * N: 1 => Client requests Server to not
- * update DNS
- */
- *p++ = options->fqdn & 0x9;
- *p++ = 0; /* from server for PTR RR */
- *p++ = 0; /* from server for A RR if S=1 */
- memcpy (p, options->hostname, l);
- p += l;
- }
- }
-
- *p++ = DHCP_PARAMETERREQUESTLIST;
- n_params = p;
- *p++ = 0;
- /* Only request DNSSERVER in discover to keep the packets small.
- * RFC2131 Section 3.5 states that the REQUEST must include the
- * list from the DISCOVER message, so I think this is ok. */
-
- if (type == DHCP_DISCOVER && ! options->test)
- *p++ = DHCP_DNSSERVER;
- else {
- if (type != DHCP_INFORM) {
- *p++ = DHCP_RENEWALTIME;
- *p++ = DHCP_REBINDTIME;
- }
- *p++ = DHCP_NETMASK;
- *p++ = DHCP_BROADCAST;
-
- /* -S means request CSR and MSCSR
- * -SS means only request MSCSR incase DHCP message
- * is too big */
- if (options->domscsr < 2)
- *p++ = DHCP_CSR;
- if (options->domscsr > 0)
- *p++ = DHCP_MSCSR;
- /* RFC 3442 states classless static routes should be
- * before routers and static routes as classless static
- * routes override them both */
- *p++ = DHCP_STATICROUTE;
- *p++ = DHCP_ROUTERS;
- *p++ = DHCP_HOSTNAME;
- *p++ = DHCP_DNSSEARCH;
- *p++ = DHCP_DNSDOMAIN;
- *p++ = DHCP_DNSSERVER;
+ if (options->leasetime != 0)
+ {
+ *p++ = DHCP_LEASETIME;
+ *p++ = 4;
+ ul = htonl (options->leasetime);
+ memcpy (p, &ul, 4);
+ p += 4;
+ }
+ }
+
+ if (type == DHCP_DISCOVER ||
+ type == DHCP_INFORM ||
+ type == DHCP_REQUEST)
+ {
+ if (options->hostname[0])
+ {
+ if (options->fqdn == FQDN_DISABLE)
+ {
+ *p++ = DHCP_HOSTNAME;
+ *p++ = l = strlen (options->hostname);
+ memcpy (p, options->hostname, l);
+ p += l;
+ }
+ else
+ {
+ /* Draft IETF DHC-FQDN option (81) */
+ *p++ = DHCP_FQDN;
+ *p++ = (l = strlen (options->hostname)) + 3;
+ /* Flags: 0000NEOS
+ * S: 1 => Client requests Server to update
+ * a RR in DNS as well as PTR
+ * O: 1 => Server indicates to client that
+ * DNS has been updated
+ * E: 1 => Name data is DNS format
+ * N: 1 => Client requests Server to not
+ * update DNS
+ */
+ *p++ = options->fqdn & 0x9;
+ *p++ = 0; /* from server for PTR RR */
+ *p++ = 0; /* from server for A RR if S=1 */
+ memcpy (p, options->hostname, l);
+ p += l;
+ }
+ }
+
+ *p++ = DHCP_PARAMETERREQUESTLIST;
+ n_params = p;
+ *p++ = 0;
+ /* Only request DNSSERVER in discover to keep the packets small.
+ * RFC2131 Section 3.5 states that the REQUEST must include the
+ * list from the DISCOVER message, so I think this is ok. */
+
+ if (type == DHCP_DISCOVER && ! options->test)
+ *p++ = DHCP_DNSSERVER;
+ else
+ {
+ if (type != DHCP_INFORM)
+ {
+ *p++ = DHCP_RENEWALTIME;
+ *p++ = DHCP_REBINDTIME;
+ }
+ *p++ = DHCP_NETMASK;
+ *p++ = DHCP_BROADCAST;
+
+ /* -S means request CSR and MSCSR
+ * -SS means only request MSCSR incase DHCP message
+ * is too big */
+ if (options->domscsr < 2)
+ *p++ = DHCP_CSR;
+ if (options->domscsr > 0)
+ *p++ = DHCP_MSCSR;
+ /* RFC 3442 states classless static routes should be
+ * before routers and static routes as classless static
+ * routes override them both */
+ *p++ = DHCP_STATICROUTE;
+ *p++ = DHCP_ROUTERS;
+ *p++ = DHCP_HOSTNAME;
+ *p++ = DHCP_DNSSEARCH;
+ *p++ = DHCP_DNSDOMAIN;
+ *p++ = DHCP_DNSSERVER;
#ifdef ENABLE_NIS
- *p++ = DHCP_NISDOMAIN;
- *p++ = DHCP_NISSERVER;
+ *p++ = DHCP_NISDOMAIN;
+ *p++ = DHCP_NISSERVER;
#endif
#ifdef ENABLE_NTP
- *p++ = DHCP_NTPSERVER;
+ *p++ = DHCP_NTPSERVER;
#endif
- *p++ = DHCP_MTU;
+ *p++ = DHCP_MTU;
#ifdef ENABLE_INFO
- *p++ = DHCP_ROOTPATH;
- *p++ = DHCP_SIPSERVER;
+ *p++ = DHCP_ROOTPATH;
+ *p++ = DHCP_SIPSERVER;
#endif
- }
+ }
- *n_params = p - n_params - 1;
- }
- *p++ = DHCP_END;
+ *n_params = p - n_params - 1;
+ }
+ *p++ = DHCP_END;
#ifdef BOOTP_MESSAGE_LENTH_MIN
- /* Some crappy DHCP servers think they have to obey the BOOTP minimum
- * message length.
- * They are wrong, but we should still cater for them. */
- while (p - m < BOOTP_MESSAGE_LENTH_MIN)
- *p++ = DHCP_PAD;
+ /* Some crappy DHCP servers think they have to obey the BOOTP minimum
+ * message length.
+ * They are wrong, but we should still cater for them. */
+ while (p - m < BOOTP_MESSAGE_LENTH_MIN)
+ *p++ = DHCP_PAD;
#endif
- message_length = p - m;
+ message_length = p - m;
- packet = xzalloc (sizeof (*packet));
- make_dhcp_packet (packet, (unsigned char *) message, message_length,
- from, to);
- free (message);
+ packet = xzalloc (sizeof (*packet));
+ make_dhcp_packet (packet, (unsigned char *) message, message_length,
+ from, to);
+ free (message);
- logger (LOG_DEBUG, "sending %s with xid 0x%x",
- dhcp_message (type), xid);
- retval = send_packet (iface, ETHERTYPE_IP, (unsigned char *) packet,
- message_length +
- sizeof (packet->ip) + sizeof (packet->udp));
- free (packet);
- return (retval);
+ logger (LOG_DEBUG, "sending %s with xid 0x%x",
+ dhcp_message (type), xid);
+ retval = send_packet (iface, ETHERTYPE_IP, (unsigned char *) packet,
+ message_length +
+ sizeof (packet->ip) + sizeof (packet->udp));
+ free (packet);
+ return (retval);
}
/* Decode an RFC3397 DNS search order option into a space
- * seperated string. Returns length of string (including
+ * seperated string. Returns length of string (including
* terminating zero) or zero on error. out may be NULL
* to just determine output length. */
static unsigned int decode_search (const unsigned char *p, int len, char *out)
{
- const unsigned char *r, *q = p;
- unsigned int count = 0, l, hops;
-
- while (q - p < len) {
- r = NULL;
- hops = 0;
- while ((l = *q++)) {
- unsigned int label_type = l & 0xc0;
- if (label_type == 0x80 || label_type == 0x40)
- return 0;
- else if (label_type == 0xc0) { /* pointer */
- l = (l & 0x3f) << 8;
- l |= *q++;
-
- /* save source of first jump. */
- if (!r)
- r = q;
-
- hops++;
- if (hops > 255)
- return 0;
-
- q = p + l;
- if (q - p >= len)
- return 0;
- } else {
- /* straightforward name segment, add with '.' */
- count += l + 1;
- if (out) {
- memcpy (out, q, l);
- out += l;
- *out++ = '.';
- }
- q += l;
- }
- }
-
- /* change last dot to space */
- if (out)
- *(out - 1) = ' ';
-
- if (r)
- q = r;
- }
-
- /* change last space to zero terminator */
- if (out)
- *(out - 1) = 0;
-
- return count;
+ const unsigned char *r, *q = p;
+ unsigned int count = 0, l, hops;
+
+ while (q - p < len)
+ {
+ r = NULL;
+ hops = 0;
+ while ((l = *q++))
+ {
+ unsigned int label_type = l & 0xc0;
+ if (label_type == 0x80 || label_type == 0x40)
+ return 0;
+ else if (label_type == 0xc0) /* pointer */
+ {
+ l = (l & 0x3f) << 8;
+ l |= *q++;
+
+ /* save source of first jump. */
+ if (!r)
+ r = q;
+
+ hops++;
+ if (hops > 255)
+ return 0;
+
+ q = p + l;
+ if (q - p >= len)
+ return 0;
+ }
+ else
+ {
+ /* straightforward name segment, add with '.' */
+ count += l + 1;
+ if (out)
+ {
+ memcpy (out, q, l);
+ out += l;
+ *out++ = '.';
+ }
+ q += l;
+ }
+ }
+
+ /* change last dot to space */
+ if (out)
+ *(out - 1) = ' ';
+
+ if (r)
+ q = r;
+ }
+
+ /* change last space to zero terminator */
+ if (out)
+ *(out - 1) = 0;
+
+ return count;
}
/* Add our classless static routes to the routes variable
* and return the last route set */
static struct route_head *decode_CSR (const unsigned char *p, int len)
{
- const unsigned char *q = p;
- unsigned int cidr;
- unsigned int ocets;
- struct route_head *routes = NULL;
- route_t *route;
-
- /* Minimum is 5 -first is CIDR and a router length of 4 */
- if (len < 5)
- return NULL;
-
- while (q - p < len) {
- if (! routes) {
- routes = xmalloc (sizeof (*routes));
- STAILQ_INIT (routes);
- }
-
- route = xzalloc (sizeof (*route));
-
- cidr = *q++;
- if (cidr > 32) {
- logger (LOG_ERR,
- "invalid CIDR of %d in classless static route",
- cidr);
- free_route (routes);
- return (NULL);
- }
- ocets = (cidr + 7) / 8;
-
- if (ocets > 0) {
- memcpy (&route->destination.s_addr, q, (size_t) ocets);
- q += ocets;
- }
-
- /* Now enter the netmask */
- if (ocets > 0) {
- memset (&route->netmask.s_addr, 255, (size_t) ocets - 1);
- memset ((unsigned char *) &route->netmask.s_addr +
- (ocets - 1),
- (256 - (1 << (32 - cidr) % 8)), 1);
- }
-
- /* Finally, snag the router */
- memcpy (&route->gateway.s_addr, q, 4);
- q += 4;
-
- STAILQ_INSERT_TAIL (routes, route, entries);
- }
-
- return (routes);
+ const unsigned char *q = p;
+ unsigned int cidr;
+ unsigned int ocets;
+ struct route_head *routes = NULL;
+ route_t *route;
+
+ /* Minimum is 5 -first is CIDR and a router length of 4 */
+ if (len < 5)
+ return NULL;
+
+ while (q - p < len)
+ {
+ if (! routes)
+ {
+ routes = xmalloc (sizeof (*routes));
+ STAILQ_INIT (routes);
+ }
+
+ route = xzalloc (sizeof (*route));
+
+ cidr = *q++;
+ if (cidr > 32)
+ {
+ logger (LOG_ERR,
+ "invalid CIDR of %d in classless static route",
+ cidr);
+ free_route (routes);
+ return (NULL);
+ }
+ ocets = (cidr + 7) / 8;
+
+ if (ocets > 0)
+ {
+ memcpy (&route->destination.s_addr, q, (size_t) ocets);
+ q += ocets;
+ }
+
+ /* Now enter the netmask */
+ if (ocets > 0)
+ {
+ memset (&route->netmask.s_addr, 255, (size_t) ocets - 1);
+ memset ((unsigned char *) &route->netmask.s_addr +
+ (ocets - 1),
+ (256 - (1 << (32 - cidr) % 8)), 1);
+ }
+
+ /* Finally, snag the router */
+ memcpy (&route->gateway.s_addr, q, 4);
+ q += 4;
+
+ STAILQ_INSERT_TAIL (routes, route, entries);
+ }
+
+ return (routes);
}
void free_dhcp (dhcp_t *dhcp)
{
- if (! dhcp)
- return;
-
- free_route (dhcp->routes);
- free (dhcp->hostname);
- free_address (dhcp->dnsservers);
- free (dhcp->dnsdomain);
- free (dhcp->dnssearch);
- free_address (dhcp->ntpservers);
- free (dhcp->nisdomain);
- free_address (dhcp->nisservers);
- free (dhcp->rootpath);
- free (dhcp->sipservers);
- if (dhcp->fqdn) {
- free (dhcp->fqdn->name);
- free (dhcp->fqdn);
- }
+ if (! dhcp)
+ return;
+
+ free_route (dhcp->routes);
+ free (dhcp->hostname);
+ free_address (dhcp->dnsservers);
+ free (dhcp->dnsdomain);
+ free (dhcp->dnssearch);
+ free_address (dhcp->ntpservers);
+ free (dhcp->nisdomain);
+ free_address (dhcp->nisservers);
+ free (dhcp->rootpath);
+ free (dhcp->sipservers);
+ if (dhcp->fqdn)
+ {
+ free (dhcp->fqdn->name);
+ free (dhcp->fqdn);
+ }
}
static bool dhcp_add_address (struct address_head **addresses,
- const unsigned char *data,
- int length)
+ const unsigned char *data,
+ int length)
{
- int i;
- address_t *address;
-
- for (i = 0; i < length; i += 4) {
- /* Sanity check */
- if (i + 4 > length) {
- logger (LOG_ERR, "invalid address length");
- return (false);
- }
-
- if (*addresses == NULL) {
- *addresses = xmalloc (sizeof (**addresses));
- STAILQ_INIT (*addresses);
- }
- address = xzalloc (sizeof (*address));
- memcpy (&address->address.s_addr, data + i, 4);
- STAILQ_INSERT_TAIL (*addresses, address, entries);
- }
-
- return (true);
+ int i;
+ address_t *address;
+
+ for (i = 0; i < length; i += 4)
+ {
+ /* Sanity check */
+ if (i + 4 > length)
+ {
+ logger (LOG_ERR, "invalid address length");
+ return (false);
+ }
+
+ if (*addresses == NULL)
+ {
+ *addresses = xmalloc (sizeof (**addresses));
+ STAILQ_INIT (*addresses);
+ }
+ address = xzalloc (sizeof (*address));
+ memcpy (&address->address.s_addr, data + i, 4);
+ STAILQ_INSERT_TAIL (*addresses, address, entries);
+ }
+
+ return (true);
}
#ifdef ENABLE_INFO
static char *decode_sipservers (const unsigned char *data, int length)
{
- char *sip = NULL;
- char *p;
- const char encoding = *data++;
- struct in_addr addr;
- size_t len;
-
- length--;
-
- switch (encoding) {
- case 0:
- if ((len = decode_search (data, length, NULL)) > 0) {
- sip = xmalloc (len);
- decode_search (data, length, sip);
- }
- break;
-
- case 1:
- if (length == 0 || length % 4 != 0) {
- logger (LOG_ERR,
- "invalid length %d for option 120",
- length + 1);
- break;
- }
- len = ((length / 4) * (4 * 4)) + 1;
- sip = p = xmalloc (len);
- while (length != 0) {
- memcpy (&addr.s_addr, data, 4);
- data += 4;
- p += snprintf (p, len - (p - sip),
- "%s ", inet_ntoa (addr));
- length -= 4;
- }
- *--p = '\0';
- break;
-
- default:
- logger (LOG_ERR, "unknown sip encoding %d", encoding);
- break;
- }
-
- return (sip);
+ char *sip = NULL;
+ char *p;
+ const char encoding = *data++;
+ struct in_addr addr;
+ size_t len;
+
+ length--;
+
+ switch (encoding)
+ {
+ case 0:
+ if ((len = decode_search (data, length, NULL)) > 0)
+ {
+ sip = xmalloc (len);
+ decode_search (data, length, sip);
+ }
+ break;
+
+ case 1:
+ if (length == 0 || length % 4 != 0)
+ {
+ logger (LOG_ERR,
+ "invalid length %d for option 120",
+ length + 1);
+ break;
+ }
+ len = ((length / 4) * (4 * 4)) + 1;
+ sip = p = xmalloc (len);
+ while (length != 0)
+ {
+ memcpy (&addr.s_addr, data, 4);
+ data += 4;
+ p += snprintf (p, len - (p - sip),
+ "%s ", inet_ntoa (addr));
+ length -= 4;
+ }
+ *--p = '\0';
+ break;
+
+ default:
+ logger (LOG_ERR, "unknown sip encoding %d", encoding);
+ break;
+ }
+
+ return (sip);
}
#endif
@@ -555,100 +591,107 @@ static char *decode_sipservers (const unsigned char *data, int length)
* for an interface address. */
static uint32_t route_netmask (uint32_t ip_in)
{
- /* used to be unsigned long - check if error */
- uint32_t p = ntohl (ip_in);
- uint32_t t;
-
- if (IN_CLASSA (p))
- t = ~IN_CLASSA_NET;
- else {
- if (IN_CLASSB (p))
- t = ~IN_CLASSB_NET;
- else {
- if (IN_CLASSC (p))
- t = ~IN_CLASSC_NET;
- else
- t = 0;
- }
- }
-
- while (t & p)
- t >>= 1;
-
- return (htonl (~t));
+ /* used to be unsigned long - check if error */
+ uint32_t p = ntohl (ip_in);
+ uint32_t t;
+
+ if (IN_CLASSA (p))
+ t = ~IN_CLASSA_NET;
+ else
+ {
+ if (IN_CLASSB (p))
+ t = ~IN_CLASSB_NET;
+ else
+ {
+ if (IN_CLASSC (p))
+ t = ~IN_CLASSC_NET;
+ else
+ t = 0;
+ }
+ }
+
+ while (t & p)
+ t >>= 1;
+
+ return (htonl (~t));
}
static struct route_head *decode_routes (const unsigned char *data, int length)
{
- int i;
- struct route_head *head = NULL;
- route_t *route;
-
- for (i = 0; i < length; i += 8) {
- if (! head) {
- head = xmalloc (sizeof (*head));
- STAILQ_INIT (head);
- }
- route = xzalloc (sizeof (*route));
- memcpy (&route->destination.s_addr, data + i, 4);
- memcpy (&route->gateway.s_addr, data + i + 4, 4);
- route->netmask.s_addr =
- route_netmask (route->destination.s_addr);
- STAILQ_INSERT_TAIL (head, route, entries);
- }
-
- return (head);
+ int i;
+ struct route_head *head = NULL;
+ route_t *route;
+
+ for (i = 0; i < length; i += 8)
+ {
+ if (! head)
+ {
+ head = xmalloc (sizeof (*head));
+ STAILQ_INIT (head);
+ }
+ route = xzalloc (sizeof (*route));
+ memcpy (&route->destination.s_addr, data + i, 4);
+ memcpy (&route->gateway.s_addr, data + i + 4, 4);
+ route->netmask.s_addr =
+ route_netmask (route->destination.s_addr);
+ STAILQ_INSERT_TAIL (head, route, entries);
+ }
+
+ return (head);
}
static struct route_head *decode_routers (const unsigned char *data, int length)
{
- int i;
- struct route_head *head = NULL;
- route_t *route = NULL;
-
- for (i = 0; i < length; i += 4) {
- if (! head) {
- head = xmalloc (sizeof (*head));
- STAILQ_INIT (head);
- }
- route = xzalloc (sizeof (*route));
- memcpy (&route->gateway.s_addr, data + i, 4);
- STAILQ_INSERT_TAIL (head, route, entries);
- }
-
- return (head);
+ int i;
+ struct route_head *head = NULL;
+ route_t *route = NULL;
+
+ for (i = 0; i < length; i += 4)
+ {
+ if (! head)
+ {
+ head = xmalloc (sizeof (*head));
+ STAILQ_INIT (head);
+ }
+ route = xzalloc (sizeof (*route));
+ memcpy (&route->gateway.s_addr, data + i, 4);
+ STAILQ_INSERT_TAIL (head, route, entries);
+ }
+
+ return (head);
}
int parse_dhcpmessage (dhcp_t *dhcp, const dhcpmessage_t *message)
{
- const unsigned char *p = message->options;
- const unsigned char *end = p; /* Add size later for gcc-3 issue */
- unsigned char option;
- unsigned char length;
- unsigned int len = 0;
- int retval = -1;
- struct timeval tv;
- struct route_head *routers = NULL;
- struct route_head *routes = NULL;
- struct route_head *csr = NULL;
- struct route_head *mscsr = NULL;
- bool in_overload = false;
- bool parse_sname = false;
- bool parse_file = false;
-
- end += sizeof (message->options);
-
- if (gettimeofday (&tv, NULL) == -1) {
- logger (LOG_ERR, "gettimeofday: %s", strerror (errno));
- return (-1);
- }
-
- dhcp->address.s_addr = message->yiaddr;
- dhcp->leasedfrom = tv.tv_sec;
- dhcp->frominfo = false;
- dhcp->address.s_addr = message->yiaddr;
- strlcpy (dhcp->servername, (char *) message->servername,
- sizeof (dhcp->servername));
+ const unsigned char *p = message->options;
+ const unsigned char *end = p; /* Add size later for gcc-3 issue */
+ unsigned char option;
+ unsigned char length;
+ unsigned int len = 0;
+ int retval = -1;
+ struct timeval tv;
+ struct route_head *routers = NULL;
+ struct route_head *routes = NULL;
+ struct route_head *csr = NULL;
+ struct route_head *mscsr = NULL;
+ bool in_overload = false;
+ bool parse_sname = false;
+ bool parse_file = false;
+
+ end += sizeof (message->options);
+
+ if (gettimeofday (&tv, NULL) == -1)
+ {
+ logger (LOG_ERR, "gettimeofday: %s", strerror (errno));
+ return (-1);
+ }
+
+ dhcp->address.s_addr = message->yiaddr;
+ dhcp->leasedfrom = tv.tv_sec;
+ dhcp->frominfo = false;
+ dhcp->address.s_addr = message->yiaddr;
+ strlcpy (dhcp->servername, (char *) message->servername,
+ sizeof (dhcp->servername));
#define LEN_ERR \
{ \
@@ -659,42 +702,47 @@ int parse_dhcpmessage (dhcp_t *dhcp, const dhcpmessage_t *message)
}
parse_start:
- while (p < end) {
- option = *p++;
- if (! option)
- continue;
-
- if (option == DHCP_END)
- goto eexit;
-
- length = *p++;
-
- if (option != DHCP_PAD && length == 0) {
- logger (LOG_ERR, "option %d has zero length", option);
- retval = -1;
- goto eexit;
- }
-
- if (p + length >= end) {
- logger (LOG_ERR, "dhcp option exceeds message length");
- retval = -1;
- goto eexit;
- }
-
- switch (option) {
- case DHCP_MESSAGETYPE:
- retval = (int) *p;
- p += length;
- continue;
-
- default:
- if (length == 0) {
- logger (LOG_DEBUG,
- "option %d has zero length, skipping",
- option);
- continue;
- }
- }
+ while (p < end)
+ {
+ option = *p++;
+ if (! option)
+ continue;
+
+ if (option == DHCP_END)
+ goto eexit;
+
+ length = *p++;
+
+ if (option != DHCP_PAD && length == 0)
+ {
+ logger (LOG_ERR, "option %d has zero length", option);
+ retval = -1;
+ goto eexit;
+ }
+
+ if (p + length >= end)
+ {
+ logger (LOG_ERR, "dhcp option exceeds message length");
+ retval = -1;
+ goto eexit;
+ }
+
+ switch (option)
+ {
+ case DHCP_MESSAGETYPE:
+ retval = (int) * p;
+ p += length;
+ continue;
+
+ default:
+ if (length == 0)
+ {
+ logger (LOG_DEBUG,
+ "option %d has zero length, skipping",
+ option);
+ continue;
+ }
+ }
#define LENGTH(_length) \
if (length != _length) \
@@ -721,40 +769,42 @@ parse_start:
GET_UINT32 (_val); \
_val = ntohl (_val);
- switch (option) {
- case DHCP_ADDRESS:
- GET_UINT32 (dhcp->address.s_addr);
- break;
- case DHCP_NETMASK:
- GET_UINT32 (dhcp->netmask.s_addr);
- break;
- case DHCP_BROADCAST:
- GET_UINT32 (dhcp->broadcast.s_addr);
- break;
- case DHCP_SERVERIDENTIFIER:
- GET_UINT32 (dhcp->serveraddress.s_addr);
- break;
- case DHCP_LEASETIME:
- GET_UINT32_H (dhcp->leasetime);
- break;
- case DHCP_RENEWALTIME:
- GET_UINT32_H (dhcp->renewaltime);
- break;
- case DHCP_REBINDTIME:
- GET_UINT32_H (dhcp->rebindtime);
- break;
- case DHCP_MTU:
- GET_UINT16_H (dhcp->mtu);
- /* Minimum legal mtu is 68 accoridng to
- * RFC 2132. In practise it's 576 which is the
- * minimum maximum message size. */
- if (dhcp->mtu < MTU_MIN) {
- logger (LOG_DEBUG,
- "MTU %d is too low, minimum is %d; ignoring",
- dhcp->mtu, MTU_MIN);
- dhcp->mtu = 0;
- }
- break;
+ switch (option)
+ {
+ case DHCP_ADDRESS:
+ GET_UINT32 (dhcp->address.s_addr);
+ break;
+ case DHCP_NETMASK:
+ GET_UINT32 (dhcp->netmask.s_addr);
+ break;
+ case DHCP_BROADCAST:
+ GET_UINT32 (dhcp->broadcast.s_addr);
+ break;
+ case DHCP_SERVERIDENTIFIER:
+ GET_UINT32 (dhcp->serveraddress.s_addr);
+ break;
+ case DHCP_LEASETIME:
+ GET_UINT32_H (dhcp->leasetime);
+ break;
+ case DHCP_RENEWALTIME:
+ GET_UINT32_H (dhcp->renewaltime);
+ break;
+ case DHCP_REBINDTIME:
+ GET_UINT32_H (dhcp->rebindtime);
+ break;
+ case DHCP_MTU:
+ GET_UINT16_H (dhcp->mtu);
+ /* Minimum legal mtu is 68 accoridng to
+ * RFC 2132. In practise it's 576 which is the
+ * minimum maximum message size. */
+ if (dhcp->mtu < MTU_MIN)
+ {
+ logger (LOG_DEBUG,
+ "MTU %d is too low, minimum is %d; ignoring",
+ dhcp->mtu, MTU_MIN);
+ dhcp->mtu = 0;
+ }
+ break;
#undef GET_UINT32_H
#undef GET_UINT32
@@ -769,24 +819,24 @@ parse_start:
memcpy (_var, p, (size_t) length); \
memset (_var + length, 0, 1); \
}
- case DHCP_HOSTNAME:
- GETSTR (dhcp->hostname);
- break;
- case DHCP_DNSDOMAIN:
- GETSTR (dhcp->dnsdomain);
- break;
- case DHCP_MESSAGE:
- GETSTR (dhcp->message);
- break;
+ case DHCP_HOSTNAME:
+ GETSTR (dhcp->hostname);
+ break;
+ case DHCP_DNSDOMAIN:
+ GETSTR (dhcp->dnsdomain);
+ break;
+ case DHCP_MESSAGE:
+ GETSTR (dhcp->message);
+ break;
#ifdef ENABLE_INFO
- case DHCP_ROOTPATH:
- GETSTR (dhcp->rootpath);
- break;
+ case DHCP_ROOTPATH:
+ GETSTR (dhcp->rootpath);
+ break;
#endif
#ifdef ENABLE_NIS
- case DHCP_NISDOMAIN:
- GETSTR (dhcp->nisdomain);
- break;
+ case DHCP_NISDOMAIN:
+ GETSTR (dhcp->nisdomain);
+ break;
#endif
#undef GETSTR
@@ -797,137 +847,147 @@ parse_start:
retval = -1; \
goto eexit; \
}
- case DHCP_DNSSERVER:
- GETADDR (dhcp->dnsservers);
- break;
+ case DHCP_DNSSERVER:
+ GETADDR (dhcp->dnsservers);
+ break;
#ifdef ENABLE_NTP
- case DHCP_NTPSERVER:
- GETADDR (dhcp->ntpservers);
- break;
+ case DHCP_NTPSERVER:
+ GETADDR (dhcp->ntpservers);
+ break;
#endif
#ifdef ENABLE_NIS
- case DHCP_NISSERVER:
- GETADDR (dhcp->nisservers);
- break;
+ case DHCP_NISSERVER:
+ GETADDR (dhcp->nisservers);
+ break;
#endif
#undef GETADDR
- case DHCP_DNSSEARCH:
- MIN_LENGTH (1);
- free (dhcp->dnssearch);
- len = decode_search (p, length, NULL);
- if (len > 0) {
- dhcp->dnssearch = xmalloc (len);
- decode_search (p, length,
- dhcp->dnssearch);
- }
- break;
-
- case DHCP_CSR:
- MIN_LENGTH (5);
- free_route (csr);
- csr = decode_CSR (p, length);
- break;
-
- case DHCP_MSCSR:
- MIN_LENGTH (5);
- free_route (mscsr);
- mscsr = decode_CSR (p, length);
- break;
+ case DHCP_DNSSEARCH:
+ MIN_LENGTH (1);
+ free (dhcp->dnssearch);
+ len = decode_search (p, length, NULL);
+ if (len > 0)
+ {
+ dhcp->dnssearch = xmalloc (len);
+ decode_search (p, length,
+ dhcp->dnssearch);
+ }
+ break;
+
+ case DHCP_CSR:
+ MIN_LENGTH (5);
+ free_route (csr);
+ csr = decode_CSR (p, length);
+ break;
+
+ case DHCP_MSCSR:
+ MIN_LENGTH (5);
+ free_route (mscsr);
+ mscsr = decode_CSR (p, length);
+ break;
#ifdef ENABLE_INFO
- case DHCP_SIPSERVER:
- free (dhcp->sipservers);
- dhcp->sipservers = decode_sipservers (p,length);
- break;
+ case DHCP_SIPSERVER:
+ free (dhcp->sipservers);
+ dhcp->sipservers = decode_sipservers (p, length);
+ break;
#endif
- case DHCP_STATICROUTE:
- MULT_LENGTH (8);
- free_route (routes);
- routes = decode_routes (p, length);
- break;
-
- case DHCP_ROUTERS:
- MULT_LENGTH (4);
- free_route (routers);
- routers = decode_routers (p, length);
- break;
-
- case DHCP_OPTIONSOVERLOADED:
- LENGTH (1);
- /* The overloaded option in an overloaded option
- * should be ignored, overwise we may get an
- * infinite loop */
- if (! in_overload) {
- if (*p & 1)
- parse_file = true;
- if (*p & 2)
- parse_sname = true;
- }
- break;
-
- case DHCP_FQDN:
- /* We ignore replies about FQDN */
- break;
+ case DHCP_STATICROUTE:
+ MULT_LENGTH (8);
+ free_route (routes);
+ routes = decode_routes (p, length);
+ break;
+
+ case DHCP_ROUTERS:
+ MULT_LENGTH (4);
+ free_route (routers);
+ routers = decode_routers (p, length);
+ break;
+
+ case DHCP_OPTIONSOVERLOADED:
+ LENGTH (1);
+ /* The overloaded option in an overloaded option
+ * should be ignored, overwise we may get an
+ * infinite loop */
+ if (! in_overload)
+ {
+ if (*p & 1)
+ parse_file = true;
+ if (*p & 2)
+ parse_sname = true;
+ }
+ break;
+
+ case DHCP_FQDN:
+ /* We ignore replies about FQDN */
+ break;
#undef LENGTH
#undef MIN_LENGTH
#undef MULT_LENGTH
- default:
- logger (LOG_DEBUG,
- "no facility to parse DHCP code %u",
- option);
- break;
- }
+ default:
+ logger (LOG_DEBUG,
+ "no facility to parse DHCP code %u",
+ option);
+ break;
+ }
- p += length;
- }
+ p += length;
+ }
eexit:
- /* We may have options overloaded, so go back and grab them */
- if (parse_file) {
- parse_file = false;
- p = message->bootfile;
- end = p + sizeof (message->bootfile);
- in_overload = true;
- goto parse_start;
- } else if (parse_sname) {
- parse_sname = false;
- p = message->servername;
- end = p + sizeof (message->servername);
- memset (dhcp->servername, 0, sizeof (dhcp->servername));
- in_overload = true;
- goto parse_start;
- }
-
- /* Fill in any missing fields */
- if (! dhcp->netmask.s_addr)
- dhcp->netmask.s_addr = get_netmask (dhcp->address.s_addr);
- if (! dhcp->broadcast.s_addr)
- dhcp->broadcast.s_addr = dhcp->address.s_addr |
- ~dhcp->netmask.s_addr;
-
- /* If we have classess static routes then we discard
- * static routes and routers according to RFC 3442 */
- if (csr) {
- dhcp->routes = csr;
- free_route (mscsr);
- free_route (routers);
- free_route (routes);
- } else if (mscsr) {
- dhcp->routes = mscsr;
- free_route (routers);
- free_route (routes);
- } else {
- /* Ensure that we apply static routes before routers */
- if (! routes)
- routes = routers;
- else if (routers)
- STAILQ_CONCAT (routes, routers);
- dhcp->routes = routes;
- }
-
- return (retval);
+ /* We may have options overloaded, so go back and grab them */
+ if (parse_file)
+ {
+ parse_file = false;
+ p = message->bootfile;
+ end = p + sizeof (message->bootfile);
+ in_overload = true;
+ goto parse_start;
+ }
+ else if (parse_sname)
+ {
+ parse_sname = false;
+ p = message->servername;
+ end = p + sizeof (message->servername);
+ memset (dhcp->servername, 0, sizeof (dhcp->servername));
+ in_overload = true;
+ goto parse_start;
+ }
+
+ /* Fill in any missing fields */
+ if (! dhcp->netmask.s_addr)
+ dhcp->netmask.s_addr = get_netmask (dhcp->address.s_addr);
+ if (! dhcp->broadcast.s_addr)
+ dhcp->broadcast.s_addr = dhcp->address.s_addr |
+ ~dhcp->netmask.s_addr;
+
+ /* If we have classess static routes then we discard
+ * static routes and routers according to RFC 3442 */
+ if (csr)
+ {
+ dhcp->routes = csr;
+ free_route (mscsr);
+ free_route (routers);
+ free_route (routes);
+ }
+ else if (mscsr)
+ {
+ dhcp->routes = mscsr;
+ free_route (routers);
+ free_route (routes);
+ }
+ else
+ {
+ /* Ensure that we apply static routes before routers */
+ if (! routes)
+ routes = routers;
+ else if (routers)
+ STAILQ_CONCAT (routes, routers);
+ dhcp->routes = routes;
+ }
+
+ return (retval);
}
diff --git a/src/customdhcpcd/dhcp.h b/src/customdhcpcd/dhcp.h
index ef97b75..019d3b3 100644
--- a/src/customdhcpcd/dhcp.h
+++ b/src/customdhcpcd/dhcp.h
@@ -1,4 +1,4 @@
-/*
+/*
* dhcpcd - DHCP client daemon
* Copyright 2006-2008 Roy Marples <roy@marples.name>
* All rights reserved
@@ -65,105 +65,106 @@
/* DHCP options */
enum DHCP_OPTIONS
{
- DHCP_PAD = 0,
- DHCP_NETMASK = 1,
- DHCP_TIMEROFFSET = 2,
- DHCP_ROUTERS = 3,
- DHCP_TIMESERVER = 4,
- DHCP_NAMESERVER = 5,
- DHCP_DNSSERVER = 6,
- DHCP_LOGSERVER = 7,
- DHCP_COOKIESERVER = 8,
- DHCP_HOSTNAME = 12,
- DHCP_DNSDOMAIN = 15,
- DHCP_ROOTPATH = 17,
- DHCP_DEFAULTIPTTL = 23,
- DHCP_MTU = 26,
- DHCP_BROADCAST = 28,
- DHCP_MASKDISCOVERY = 29,
- DHCP_ROUTERDISCOVERY = 31,
- DHCP_STATICROUTE = 33,
- DHCP_NISDOMAIN = 40,
- DHCP_NISSERVER = 41,
- DHCP_NTPSERVER = 42,
- DHCP_ADDRESS = 50,
- DHCP_LEASETIME = 51,
- DHCP_OPTIONSOVERLOADED = 52,
- DHCP_MESSAGETYPE = 53,
- DHCP_SERVERIDENTIFIER = 54,
- DHCP_PARAMETERREQUESTLIST = 55,
- DHCP_MESSAGE = 56,
- DHCP_MAXMESSAGESIZE = 57,
- DHCP_RENEWALTIME = 58,
- DHCP_REBINDTIME = 59,
- DHCP_CLASSID = 60,
- DHCP_CLIENTID = 61,
- DHCP_USERCLASS = 77, /* RFC 3004 */
- DHCP_FQDN = 81,
- DHCP_DNSSEARCH = 119, /* RFC 3397 */
- DHCP_SIPSERVER = 120, /* RFC 3361 */
- DHCP_CSR = 121, /* RFC 3442 */
- DHCP_MSCSR = 249, /* MS code for RFC 3442 */
- DHCP_END = 255
+ DHCP_PAD = 0,
+ DHCP_NETMASK = 1,
+ DHCP_TIMEROFFSET = 2,
+ DHCP_ROUTERS = 3,
+ DHCP_TIMESERVER = 4,
+ DHCP_NAMESERVER = 5,
+ DHCP_DNSSERVER = 6,
+ DHCP_LOGSERVER = 7,
+ DHCP_COOKIESERVER = 8,
+ DHCP_HOSTNAME = 12,
+ DHCP_DNSDOMAIN = 15,
+ DHCP_ROOTPATH = 17,
+ DHCP_DEFAULTIPTTL = 23,
+ DHCP_MTU = 26,
+ DHCP_BROADCAST = 28,
+ DHCP_MASKDISCOVERY = 29,
+ DHCP_ROUTERDISCOVERY = 31,
+ DHCP_STATICROUTE = 33,
+ DHCP_NISDOMAIN = 40,
+ DHCP_NISSERVER = 41,
+ DHCP_NTPSERVER = 42,
+ DHCP_ADDRESS = 50,
+ DHCP_LEASETIME = 51,
+ DHCP_OPTIONSOVERLOADED = 52,
+ DHCP_MESSAGETYPE = 53,
+ DHCP_SERVERIDENTIFIER = 54,
+ DHCP_PARAMETERREQUESTLIST = 55,
+ DHCP_MESSAGE = 56,
+ DHCP_MAXMESSAGESIZE = 57,
+ DHCP_RENEWALTIME = 58,
+ DHCP_REBINDTIME = 59,
+ DHCP_CLASSID = 60,
+ DHCP_CLIENTID = 61,
+ DHCP_USERCLASS = 77, /* RFC 3004 */
+ DHCP_FQDN = 81,
+ DHCP_DNSSEARCH = 119, /* RFC 3397 */
+ DHCP_SIPSERVER = 120, /* RFC 3361 */
+ DHCP_CSR = 121, /* RFC 3442 */
+ DHCP_MSCSR = 249, /* MS code for RFC 3442 */
+ DHCP_END = 255
};
/* SetFQDNHostName values - lsnybble used in flags
* byte (see buildmsg.c), hsnybble to create order
* and to allow 0x00 to mean disable
*/
-enum FQQN {
- FQDN_DISABLE = 0x00,
- FQDN_NONE = 0x18,
- FQDN_PTR = 0x20,
- FQDN_BOTH = 0x31
+enum FQQN
+{
+ FQDN_DISABLE = 0x00,
+ FQDN_NONE = 0x18,
+ FQDN_PTR = 0x20,
+ FQDN_BOTH = 0x31
};
typedef struct fqdn_t
{
- uint8_t flags;
- uint8_t r1;
- uint8_t r2;
- char *name;
+ uint8_t flags;
+ uint8_t r1;
+ uint8_t r2;
+ char *name;
} fqdn_t;
typedef struct dhcp_t
{
- char version[11];
+ char version[11];
- struct in_addr serveraddress;
- char serverhw[IF_NAMESIZE];
- char servername[64];
+ struct in_addr serveraddress;
+ char serverhw[IF_NAMESIZE];
+ char servername[64];
- struct in_addr address;
- struct in_addr netmask;
- struct in_addr broadcast;
- unsigned short mtu;
+ struct in_addr address;
+ struct in_addr netmask;
+ struct in_addr broadcast;
+ unsigned short mtu;
- uint32_t leasedfrom;
- uint32_t leasetime;
- uint32_t renewaltime;
- uint32_t rebindtime;
+ uint32_t leasedfrom;
+ uint32_t leasetime;
+ uint32_t renewaltime;
+ uint32_t rebindtime;
- struct route_head *routes;
+ struct route_head *routes;
- char *hostname;
- fqdn_t *fqdn;
+ char *hostname;
+ fqdn_t *fqdn;
- struct address_head *dnsservers;
- char *dnsdomain;
- char *dnssearch;
+ struct address_head *dnsservers;
+ char *dnsdomain;
+ char *dnssearch;
- struct address_head *ntpservers;
+ struct address_head *ntpservers;
- struct address_head *nisservers;
- char *nisdomain;
+ struct address_head *nisservers;
+ char *nisdomain;
- char *sipservers;
+ char *sipservers;
- char *message;
- char *rootpath;
+ char *message;
+ char *rootpath;
- bool frominfo;
+ bool frominfo;
} dhcp_t;
/* Sizes for DHCP options */
@@ -183,33 +184,33 @@ typedef struct dhcp_t
typedef struct dhcpmessage_t
{
- unsigned char op; /* message type */
- unsigned char hwtype; /* hardware address type */
- unsigned char hwlen; /* hardware address length */
- unsigned char hwopcount; /* should be zero in client message */
- uint32_t xid; /* transaction id */
- uint16_t secs; /* elapsed time in sec. from boot */
- uint16_t flags;
- uint32_t ciaddr; /* (previously allocated) client IP */
- uint32_t yiaddr; /* 'your' client IP address */
- uint32_t siaddr; /* should be zero in client's messages */
- uint32_t giaddr; /* should be zero in client's messages */
- unsigned char chaddr[DHCP_CHADDR_LEN]; /* client's hardware address */
- unsigned char servername[SERVERNAME_LEN]; /* server host name */
- unsigned char bootfile[BOOTFILE_LEN]; /* boot file name */
- uint32_t cookie;
- unsigned char options[DHCP_OPTION_LEN]; /* message options - cookie */
+ unsigned char op; /* message type */
+ unsigned char hwtype; /* hardware address type */
+ unsigned char hwlen; /* hardware address length */
+ unsigned char hwopcount; /* should be zero in client message */
+ uint32_t xid; /* transaction id */
+ uint16_t secs; /* elapsed time in sec. from boot */
+ uint16_t flags;
+ uint32_t ciaddr; /* (previously allocated) client IP */
+ uint32_t yiaddr; /* 'your' client IP address */
+ uint32_t siaddr; /* should be zero in client's messages */
+ uint32_t giaddr; /* should be zero in client's messages */
+ unsigned char chaddr[DHCP_CHADDR_LEN]; /* client's hardware address */
+ unsigned char servername[SERVERNAME_LEN]; /* server host name */
+ unsigned char bootfile[BOOTFILE_LEN]; /* boot file name */
+ uint32_t cookie;
+ unsigned char options[DHCP_OPTION_LEN]; /* message options - cookie */
} dhcpmessage_t;
struct udp_dhcp_packet
{
- struct ip ip;
- struct udphdr udp;
- dhcpmessage_t dhcp;
+ struct ip ip;
+ struct udphdr udp;
+ dhcpmessage_t dhcp;
};
ssize_t send_message (const interface_t *iface, const dhcp_t *dhcp,
- uint32_t xid, char type, const options_t *options);
+ uint32_t xid, char type, const options_t *options);
void free_dhcp (dhcp_t *dhcp);
int parse_dhcpmessage (dhcp_t *dhcp, const dhcpmessage_t *message);
#endif
diff --git a/src/customdhcpcd/dhcpcd.c b/src/customdhcpcd/dhcpcd.c
index d0ad5e7..31bfdcb 100644
--- a/src/customdhcpcd/dhcpcd.c
+++ b/src/customdhcpcd/dhcpcd.c
@@ -1,28 +1,28 @@
- /* dhcpcd - DHCP client daemon
- * Copyright 2006-2008 Roy Marples <roy@marples.name>
- * All rights reserved
-
- * 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.
- *
- * 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.
- */
+/* dhcpcd - DHCP client daemon
+* Copyright 2006-2008 Roy Marples <roy@marples.name>
+* All rights reserved
+
+* 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.
+*
+* 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.
+*/
const char copyright[] = "Copyright (c) 2006-2008 Roy Marples";
@@ -55,42 +55,43 @@ const char copyright[] = "Copyright (c) 2006-2008 Roy Marples";
static int doversion = 0;
static int dohelp = 0;
#define EXTRA_OPTS
-static const struct option longopts[] = {
- {"arp", no_argument, NULL, 'a'},
- {"script", required_argument, NULL, 'c'},
- {"debug", no_argument, NULL, 'd'},
- {"hostname", optional_argument, NULL, 'h'},
- {"classid", optional_argument, NULL, 'i'},
- {"release", no_argument, NULL, 'k'},
- {"leasetime", required_argument, NULL, 'l'},
- {"metric", required_argument, NULL, 'm'},
- {"renew", no_argument, NULL, 'n'},
- {"persistent", no_argument, NULL, 'p'},
- {"qtsocketaddress", required_argument, NULL, 'q'},
- {"inform", optional_argument, NULL, 's'},
- {"request", optional_argument, NULL, 'r'},
- {"timeout", required_argument, NULL, 't'},
- {"userclass", required_argument, NULL, 'u'},
- {"exit", no_argument, NULL, 'x'},
- {"lastlease", no_argument, NULL, 'E'},
- {"fqdn", required_argument, NULL, 'F'},
- {"nogateway", no_argument, NULL, 'G'},
- {"sethostname", no_argument, NULL, 'H'},
- {"clientid", optional_argument, NULL, 'I'},
- {"noipv4ll", no_argument, NULL, 'L'},
- {"nomtu", no_argument, NULL, 'M'},
- {"nontp", no_argument, NULL, 'N'},
- {"nodns", no_argument, NULL, 'R'},
- {"msscr", no_argument, NULL, 'S'},
- {"test", no_argument, NULL, 'T'},
- {"nonis", no_argument, NULL, 'Y'},
- {"help", no_argument, &dohelp, 1},
- {"version", no_argument, &doversion, 1},
+static const struct option longopts[] =
+{
+ {"arp", no_argument, NULL, 'a'},
+ {"script", required_argument, NULL, 'c'},
+ {"debug", no_argument, NULL, 'd'},
+ {"hostname", optional_argument, NULL, 'h'},
+ {"classid", optional_argument, NULL, 'i'},
+ {"release", no_argument, NULL, 'k'},
+ {"leasetime", required_argument, NULL, 'l'},
+ {"metric", required_argument, NULL, 'm'},
+ {"renew", no_argument, NULL, 'n'},
+ {"persistent", no_argument, NULL, 'p'},
+ {"qtsocketaddress", required_argument, NULL, 'q'},
+ {"inform", optional_argument, NULL, 's'},
+ {"request", optional_argument, NULL, 'r'},
+ {"timeout", required_argument, NULL, 't'},
+ {"userclass", required_argument, NULL, 'u'},
+ {"exit", no_argument, NULL, 'x'},
+ {"lastlease", no_argument, NULL, 'E'},
+ {"fqdn", required_argument, NULL, 'F'},
+ {"nogateway", no_argument, NULL, 'G'},
+ {"sethostname", no_argument, NULL, 'H'},
+ {"clientid", optional_argument, NULL, 'I'},
+ {"noipv4ll", no_argument, NULL, 'L'},
+ {"nomtu", no_argument, NULL, 'M'},
+ {"nontp", no_argument, NULL, 'N'},
+ {"nodns", no_argument, NULL, 'R'},
+ {"msscr", no_argument, NULL, 'S'},
+ {"test", no_argument, NULL, 'T'},
+ {"nonis", no_argument, NULL, 'Y'},
+ {"help", no_argument, &dohelp, 1},
+ {"version", no_argument, &doversion, 1},
#ifdef THERE_IS_NO_FORK
- {"daemonised", no_argument, NULL, 'f'},
- {"skiproutes", required_argument, NULL, 'g'},
+ {"daemonised", no_argument, NULL, 'f'},
+ {"skiproutes", required_argument, NULL, 'g'},
#endif
- {NULL, 0, NULL, 0}
+ {NULL, 0, NULL, 0}
};
#ifdef THERE_IS_NO_FORK
@@ -104,568 +105,616 @@ char *dhcpcd_skiproutes = NULL;
static int atoint (const char *s)
{
- char *t;
- long n;
-
- errno = 0;
- n = strtol (s, &t, 0);
- if ((errno != 0 && n == 0) || s == t ||
- (errno == ERANGE && (n == LONG_MAX || n == LONG_MIN)))
- {
- logger (LOG_ERR, "`%s' out of range", s);
- return (-1);
- }
-
- return ((int) n);
+ char *t;
+ long n;
+
+ errno = 0;
+ n = strtol (s, &t, 0);
+ if ((errno != 0 && n == 0) || s == t ||
+ (errno == ERANGE && (n == LONG_MAX || n == LONG_MIN)))
+ {
+ logger (LOG_ERR, "`%s' out of range", s);
+ return (-1);
+ }
+
+ return ((int) n);
}
static pid_t read_pid (const char *pidfile)
{
- FILE *fp;
- pid_t pid = 0;
+ FILE *fp;
+ pid_t pid = 0;
- if ((fp = fopen (pidfile, "r")) == NULL) {
- errno = ENOENT;
- return 0;
- }
+ if ((fp = fopen (pidfile, "r")) == NULL)
+ {
+ errno = ENOENT;
+ return 0;
+ }
- fscanf (fp, "%d", &pid);
- fclose (fp);
+ fscanf (fp, "%d", &pid);
+ fclose (fp);
- return (pid);
+ return (pid);
}
static void usage (void)
{
- printf ("usage: "PACKAGE" [-adknpEGHMNRSTY] [-c script] [-h hostname] [-i classID]\n"
- " [-l leasetime] [-m metric] [-r ipaddress] [-s ipaddress]\n"
- " [-t timeout] [-u userclass] [-F none | ptr | both]\n"
- " [-I clientID] [-q qtsocketaddress] <interface>\n");
+ printf ("usage: "PACKAGE" [-adknpEGHMNRSTY] [-c script] [-h hostname] [-i classID]\n"
+ " [-l leasetime] [-m metric] [-r ipaddress] [-s ipaddress]\n"
+ " [-t timeout] [-u userclass] [-F none | ptr | both]\n"
+ " [-I clientID] [-q qtsocketaddress] <interface>\n");
}
int main (int argc, char **argv)
{
- options_t *options;
- int userclasses = 0;
- int opt;
- int option_index = 0;
- char *prefix;
- pid_t pid;
- int debug = 0;
- int i;
- int pidfd = -1;
- int sig = 0;
- int retval = EXIT_FAILURE;
-
- /* Close any un-needed fd's */
- for (i = getdtablesize() - 1; i >= 3; --i)
- close (i);
-
- openlog (PACKAGE, LOG_PID, LOG_LOCAL0);
-
- options = xzalloc (sizeof (*options));
- options->script = (char *) DEFAULT_SCRIPT;
- snprintf (options->classid, CLASS_ID_MAX_LEN, "%s %s",
- PACKAGE, VERSION);
-
- options->doarp = true;
- options->dodns = true;
- options->domtu = true;
- options->donis = true;
- options->dontp = true;
- options->dogateway = true;
- options->daemonise = true;
- options->doinform = false;
- options->doipv4ll = true;
- options->doduid = true;
- options->timeout = DEFAULT_TIMEOUT;
- /* added by Niklas Goby, additional field, storing the socket address path for
- * communicating with Qt "server"
- * defined in dhcpcd.h */
- strcpy(options->qtsocketaddress, DEFAULT_QTSOCKETADDRESS);
-
- gethostname (options->hostname, sizeof (options->hostname));
- if (strcmp (options->hostname, "(none)") == 0 ||
- strcmp (options->hostname, "localhost") == 0)
- memset (options->hostname, 0, sizeof (options->hostname));
-
-
- /* Don't set any optional arguments here so we retain POSIX
- * compatibility with getopt */
- while ((opt = getopt_long(argc, argv, EXTRA_OPTS
- "c:dh:i:kl:m:npq:r:s:t:u:xAEF:GHI:LMNRSTY",
- longopts, &option_index)) != -1)
- {
- switch (opt) {
- case 0:
- if (longopts[option_index].flag)
- break;
- logger (LOG_ERR,
- "option `%s' should set a flag",
- longopts[option_index].name);
- goto abort;
- case 'c':
- options->script = optarg;
- break;
- case 'd':
- debug++;
- switch (debug) {
- case 1:
- setloglevel (LOG_DEBUG);
- break;
- case 2:
- options->daemonise = false;
- break;
- }
- break;
- #ifdef THERE_IS_NO_FORK
- case 'f':
- options->daemonised = true;
- close_fds ();
- break;
- case 'g':
- dhcpcd_skiproutes = xstrdup (optarg);
- break;
- #endif
- case 'h':
- if (! optarg)
- *options->hostname = '\0';
- else if (strlen (optarg) > MAXHOSTNAMELEN) {
- logger (LOG_ERR,
- "`%s' too long for HostName string, max is %d",
- optarg, MAXHOSTNAMELEN);
- goto abort;
- } else
- strlcpy (options->hostname, optarg,
- sizeof (options->hostname));
- break;
- case 'i':
- if (! optarg) {
- *options->classid = '\0';
- } else if (strlen (optarg) > CLASS_ID_MAX_LEN) {
- logger (LOG_ERR,
- "`%s' too long for ClassID string, max is %d",
- optarg, CLASS_ID_MAX_LEN);
- goto abort;
- } else
- strlcpy (options->classid, optarg,
- sizeof (options->classid));
- break;
- case 'k':
- sig = SIGHUP;
- break;
- case 'l':
- if (*optarg == '-') {
- logger (LOG_ERR,
- "leasetime must be a positive value");
- goto abort;
- }
- errno = 0;
- options->leasetime = (uint32_t) strtol (optarg, NULL, 0);
- if (errno == EINVAL || errno == ERANGE) {
- logger (LOG_ERR, "`%s' out of range", optarg);
- goto abort;
- }
- break;
- case 'm':
- options->metric = atoint (optarg);
- if (options->metric < 0) {
- logger (LOG_ERR,
- "metric must be a positive value");
- goto abort;
- }
- break;
- case 'n':
- sig = SIGALRM;
- break;
- case 'p':
- options->persistent = true;
- break;
- case 'q':
- if (strlen(optarg) > QTSOCKETADDRESSLENGTH) {
- logger(LOG_ERR, "`%s' too long for an socket address path (max=%d)",
- optarg, QTSOCKETADDRESSLENGTH);
- goto abort;
- }
- strlcpy(options->qtsocketaddress, optarg, sizeof(options->qtsocketaddress));
- break;
- case 's':
- options->doinform = true;
- options->doarp = false;
- if (! optarg || strlen (optarg) == 0) {
- options->request_address.s_addr = 0;
- break;
- } else {
- char *slash = strchr (optarg, '/');
- if (slash) {
- int cidr;
- /* nullify the slash, so the -r option can read the
- * address */
- *slash++ = '\0';
- if (sscanf (slash, "%d", &cidr) != 1 ||
- inet_cidrtoaddr (cidr, &options->request_netmask) != 0) {
- logger (LOG_ERR, "`%s' is not a valid CIDR", slash);
- goto abort;
- }
- }
- }
- /* FALLTHROUGH */
- case 'r':
- if (! options->doinform)
- options->dorequest = true;
- if (strlen (optarg) > 0 &&
- ! inet_aton (optarg, &options->request_address))
- {
- logger (LOG_ERR, "`%s' is not a valid IP address", optarg);
- goto abort;
- }
- break;
- case 't':
- options->timeout = atoint (optarg);
- if (options->timeout < 0) {
- logger (LOG_ERR, "timeout must be a positive value");
- goto abort;
- }
- break;
- case 'u':
- {
- int offset = 0;
- for (i = 0; i < userclasses; i++)
- offset += (int) options->userclass[offset] + 1;
- if (offset + 1 + strlen (optarg) > USERCLASS_MAX_LEN) {
- logger (LOG_ERR, "userclass overrun, max is %d",
- USERCLASS_MAX_LEN);
- goto abort;
- }
- userclasses++;
- memcpy (options->userclass + offset + 1 , optarg, strlen (optarg));
- options->userclass[offset] = strlen (optarg);
- options->userclass_len += (strlen (optarg)) + 1;
- }
- break;
- case 'x':
- sig = SIGTERM;
- break;
- case 'A':
- #ifndef ENABLE_ARP
- logger (LOG_ERR,
- "arp not compiled into dhcpcd");
- goto abort;
- #endif
- options->doarp = false;
- break;
- case 'E':
- #ifndef ENABLE_INFO
- logger (LOG_ERR,
- "info not compiled into dhcpcd");
- goto abort;
- #endif
- options->dolastlease = true;
- break;
- case 'F':
- if (strncmp (optarg, "none", strlen (optarg)) == 0)
- options->fqdn = FQDN_NONE;
- else if (strncmp (optarg, "ptr", strlen (optarg)) == 0)
- options->fqdn = FQDN_PTR;
- else if (strncmp (optarg, "both", strlen (optarg)) == 0)
- options->fqdn = FQDN_BOTH;
- else {
- logger (LOG_ERR, "invalid value `%s' for FQDN", optarg);
- goto abort;
- }
- break;
- case 'G':
- options->dogateway = false;
- break;
- case 'H':
- options->dohostname++;
- break;
- case 'I':
- if (optarg) {
- if (strlen (optarg) > CLIENT_ID_MAX_LEN) {
- logger (LOG_ERR, "`%s' is too long for ClientID, max is %d",
- optarg, CLIENT_ID_MAX_LEN);
- goto abort;
- }
- if (strlcpy (options->clientid, optarg,
- sizeof (options->clientid)) == 0)
- /* empty string disabled duid */
- options->doduid = false;
-
- } else {
- memset (options->clientid, 0, sizeof (options->clientid));
- options->doduid = false;
- }
- break;
- case 'L':
- options->doipv4ll = false;
- break;
- case 'M':
- options->domtu = false;
- break;
- case 'N':
- options->dontp = false;
- break;
- case 'R':
- options->dodns = false;
- break;
- case 'S':
- options->domscsr++;
- break;
- case 'T':
- #ifndef ENABLE_INFO
- logger (LOG_ERR, "info support not compiled into dhcpcd");
- goto abort;
- #endif
- options->test = true;
- options->persistent = true;
- break;
- case 'Y':
- options->donis = false;
- break;
- case '?':
- usage ();
- goto abort;
- default:
- usage ();
- goto abort;
- }
- }
- if (doversion) {
- printf (""PACKAGE" "VERSION"\n");
- printf ("Compile time options:"
- #ifdef ENABLE_ARP
- " ARP"
- #endif
- #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
- "\n");
- }
-
- if (dohelp)
- usage ();
+ options_t *options;
+ int userclasses = 0;
+ int opt;
+ int option_index = 0;
+ char *prefix;
+ pid_t pid;
+ int debug = 0;
+ int i;
+ int pidfd = -1;
+ int sig = 0;
+ int retval = EXIT_FAILURE;
+
+ /* Close any un-needed fd's */
+ for (i = getdtablesize() - 1; i >= 3; --i)
+ close (i);
+
+ openlog (PACKAGE, LOG_PID, LOG_LOCAL0);
+
+ options = xzalloc (sizeof (*options));
+ options->script = (char *) DEFAULT_SCRIPT;
+ snprintf (options->classid, CLASS_ID_MAX_LEN, "%s %s",
+ PACKAGE, VERSION);
+
+ options->doarp = true;
+ options->dodns = true;
+ options->domtu = true;
+ options->donis = true;
+ options->dontp = true;
+ options->dogateway = true;
+ options->daemonise = true;
+ options->doinform = false;
+ options->doipv4ll = true;
+ options->doduid = true;
+ options->timeout = DEFAULT_TIMEOUT;
+ /* added by Niklas Goby, additional field, storing the socket address path for
+ * communicating with Qt "server"
+ * defined in dhcpcd.h */
+ strcpy(options->qtsocketaddress, DEFAULT_QTSOCKETADDRESS);
+
+ gethostname (options->hostname, sizeof (options->hostname));
+ if (strcmp (options->hostname, "(none)") == 0 ||
+ strcmp (options->hostname, "localhost") == 0)
+ memset (options->hostname, 0, sizeof (options->hostname));
+
+
+ /* Don't set any optional arguments here so we retain POSIX
+ * compatibility with getopt */
+ while ((opt = getopt_long(argc, argv, EXTRA_OPTS
+ "c:dh:i:kl:m:npq:r:s:t:u:xAEF:GHI:LMNRSTY",
+ longopts, &option_index)) != -1)
+ {
+ switch (opt)
+ {
+ case 0:
+ if (longopts[option_index].flag)
+ break;
+ logger (LOG_ERR,
+ "option `%s' should set a flag",
+ longopts[option_index].name);
+ goto abort;
+ case 'c':
+ options->script = optarg;
+ break;
+ case 'd':
+ debug++;
+ switch (debug)
+ {
+ case 1:
+ setloglevel (LOG_DEBUG);
+ break;
+ case 2:
+ options->daemonise = false;
+ break;
+ }
+ break;
+#ifdef THERE_IS_NO_FORK
+ case 'f':
+ options->daemonised = true;
+ close_fds ();
+ break;
+ case 'g':
+ dhcpcd_skiproutes = xstrdup (optarg);
+ break;
+#endif
+ case 'h':
+ if (! optarg)
+ *options->hostname = '\0';
+ else if (strlen (optarg) > MAXHOSTNAMELEN)
+ {
+ logger (LOG_ERR,
+ "`%s' too long for HostName string, max is %d",
+ optarg, MAXHOSTNAMELEN);
+ goto abort;
+ }
+ else
+ strlcpy (options->hostname, optarg,
+ sizeof (options->hostname));
+ break;
+ case 'i':
+ if (! optarg)
+ {
+ *options->classid = '\0';
+ }
+ else if (strlen (optarg) > CLASS_ID_MAX_LEN)
+ {
+ logger (LOG_ERR,
+ "`%s' too long for ClassID string, max is %d",
+ optarg, CLASS_ID_MAX_LEN);
+ goto abort;
+ }
+ else
+ strlcpy (options->classid, optarg,
+ sizeof (options->classid));
+ break;
+ case 'k':
+ sig = SIGHUP;
+ break;
+ case 'l':
+ if (*optarg == '-')
+ {
+ logger (LOG_ERR,
+ "leasetime must be a positive value");
+ goto abort;
+ }
+ errno = 0;
+ options->leasetime = (uint32_t) strtol (optarg, NULL, 0);
+ if (errno == EINVAL || errno == ERANGE)
+ {
+ logger (LOG_ERR, "`%s' out of range", optarg);
+ goto abort;
+ }
+ break;
+ case 'm':
+ options->metric = atoint (optarg);
+ if (options->metric < 0)
+ {
+ logger (LOG_ERR,
+ "metric must be a positive value");
+ goto abort;
+ }
+ break;
+ case 'n':
+ sig = SIGALRM;
+ break;
+ case 'p':
+ options->persistent = true;
+ break;
+ case 'q':
+ if (strlen(optarg) > QTSOCKETADDRESSLENGTH)
+ {
+ logger(LOG_ERR, "`%s' too long for an socket address path (max=%d)",
+ optarg, QTSOCKETADDRESSLENGTH);
+ goto abort;
+ }
+ strlcpy(options->qtsocketaddress, optarg, sizeof(options->qtsocketaddress));
+ break;
+ case 's':
+ options->doinform = true;
+ options->doarp = false;
+ if (! optarg || strlen (optarg) == 0)
+ {
+ options->request_address.s_addr = 0;
+ break;
+ }
+ else
+ {
+ char *slash = strchr (optarg, '/');
+ if (slash)
+ {
+ int cidr;
+ /* nullify the slash, so the -r option can read the
+ * address */
+ *slash++ = '\0';
+ if (sscanf (slash, "%d", &cidr) != 1 ||
+ inet_cidrtoaddr (cidr, &options->request_netmask) != 0)
+ {
+ logger (LOG_ERR, "`%s' is not a valid CIDR", slash);
+ goto abort;
+ }
+ }
+ }
+ /* FALLTHROUGH */
+ case 'r':
+ if (! options->doinform)
+ options->dorequest = true;
+ if (strlen (optarg) > 0 &&
+ ! inet_aton (optarg, &options->request_address))
+ {
+ logger (LOG_ERR, "`%s' is not a valid IP address", optarg);
+ goto abort;
+ }
+ break;
+ case 't':
+ options->timeout = atoint (optarg);
+ if (options->timeout < 0)
+ {
+ logger (LOG_ERR, "timeout must be a positive value");
+ goto abort;
+ }
+ break;
+ case 'u':
+ {
+ int offset = 0;
+ for (i = 0; i < userclasses; i++)
+ offset += (int) options->userclass[offset] + 1;
+ if (offset + 1 + strlen (optarg) > USERCLASS_MAX_LEN)
+ {
+ logger (LOG_ERR, "userclass overrun, max is %d",
+ USERCLASS_MAX_LEN);
+ goto abort;
+ }
+ userclasses++;
+ memcpy (options->userclass + offset + 1 , optarg, strlen (optarg));
+ options->userclass[offset] = strlen (optarg);
+ options->userclass_len += (strlen (optarg)) + 1;
+ }
+ break;
+ case 'x':
+ sig = SIGTERM;
+ break;
+ case 'A':
+#ifndef ENABLE_ARP
+ logger (LOG_ERR,
+ "arp not compiled into dhcpcd");
+ goto abort;
+#endif
+ options->doarp = false;
+ break;
+ case 'E':
+#ifndef ENABLE_INFO
+ logger (LOG_ERR,
+ "info not compiled into dhcpcd");
+ goto abort;
+#endif
+ options->dolastlease = true;
+ break;
+ case 'F':
+ if (strncmp (optarg, "none", strlen (optarg)) == 0)
+ options->fqdn = FQDN_NONE;
+ else if (strncmp (optarg, "ptr", strlen (optarg)) == 0)
+ options->fqdn = FQDN_PTR;
+ else if (strncmp (optarg, "both", strlen (optarg)) == 0)
+ options->fqdn = FQDN_BOTH;
+ else
+ {
+ logger (LOG_ERR, "invalid value `%s' for FQDN", optarg);
+ goto abort;
+ }
+ break;
+ case 'G':
+ options->dogateway = false;
+ break;
+ case 'H':
+ options->dohostname++;
+ break;
+ case 'I':
+ if (optarg)
+ {
+ if (strlen (optarg) > CLIENT_ID_MAX_LEN)
+ {
+ logger (LOG_ERR, "`%s' is too long for ClientID, max is %d",
+ optarg, CLIENT_ID_MAX_LEN);
+ goto abort;
+ }
+ if (strlcpy (options->clientid, optarg,
+ sizeof (options->clientid)) == 0)
+ /* empty string disabled duid */
+ options->doduid = false;
+
+ }
+ else
+ {
+ memset (options->clientid, 0, sizeof (options->clientid));
+ options->doduid = false;
+ }
+ break;
+ case 'L':
+ options->doipv4ll = false;
+ break;
+ case 'M':
+ options->domtu = false;
+ break;
+ case 'N':
+ options->dontp = false;
+ break;
+ case 'R':
+ options->dodns = false;
+ break;
+ case 'S':
+ options->domscsr++;
+ break;
+ case 'T':
+#ifndef ENABLE_INFO
+ logger (LOG_ERR, "info support not compiled into dhcpcd");
+ goto abort;
+#endif
+ options->test = true;
+ options->persistent = true;
+ break;
+ case 'Y':
+ options->donis = false;
+ break;
+ case '?':
+ usage ();
+ goto abort;
+ default:
+ usage ();
+ goto abort;
+ }
+ }
+ if (doversion)
+ {
+ printf (""PACKAGE" "VERSION"\n");
+ printf ("Compile time options:"
+#ifdef ENABLE_ARP
+ " ARP"
+#endif
+#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
+ "\n");
+ }
+
+ if (dohelp)
+ usage ();
#ifdef THERE_IS_NO_FORK
- dhcpcd_argv = argv;
- dhcpcd_argc = argc;
- if (! realpath (argv[0], dhcpcd)) {
- logger (LOG_ERR, "unable to resolve the path `%s': %s",
- argv[0], strerror (errno));
- goto abort;
- }
+ dhcpcd_argv = argv;
+ dhcpcd_argc = argc;
+ if (! realpath (argv[0], dhcpcd))
+ {
+ logger (LOG_ERR, "unable to resolve the path `%s': %s",
+ argv[0], strerror (errno));
+ goto abort;
+ }
#endif
- /* initializations for the ipc connection to qt*/
- setSocketName(options->qtsocketaddress);
- if (initQtLoggerSocket() < 0) {
- logger(LOG_ERR, "initialization Qt Logger failed: %s ", strerror (errno));
- goto abort;
- }
-
-
- if (optind < argc) {
- if (strlen(argv[optind]) > IF_NAMESIZE) {
- logger(LOG_ERR, "`%s' too long for an interface name (max=%d)",
- argv[optind], IF_NAMESIZE);
- goto abort;
- }
- strlcpy(options->interface, argv[optind], sizeof(options->interface));
- setInterfaceName(options->interface);
- } else {
- /* If only version was requested then exit now */
- if (doversion || dohelp) {
- retval = 0;
- goto abort;
- }
-
- logger(LOG_ERR, "no interface specified");
- setInterfaceName("no_if");
- goto abort;
- }
-
- if (strchr(options->hostname, '.')) {
- if (options->fqdn == FQDN_DISABLE)
- options->fqdn = FQDN_BOTH;
- } else
- options->fqdn = FQDN_DISABLE;
-
- if (options->request_address.s_addr == 0 && options->doinform) {
- if ((options->request_address.s_addr = get_address(options->interface))
- != 0)
- options->keep_address = true;
- }
-
- if (IN_LINKLOCAL (ntohl (options->request_address.s_addr))) {
- logger (LOG_ERR,
- "you are not allowed to request a link local address");
- logToQt(LOG_ERR, -1, "you are not allowed to request a link local address");
- goto abort;
- }
-
- if (geteuid ()) {
- logger (LOG_WARNING, PACKAGE " will not work correctly unless"
- " run as root");
- }
-
- prefix = xmalloc (sizeof (char) * (IF_NAMESIZE + 3));
- snprintf (prefix, IF_NAMESIZE, "%s: ", options->interface);
- setlogprefix (prefix);
- snprintf (options->pidfile, sizeof (options->pidfile), PIDFILE,
- options->interface);
- free (prefix);
-
- chdir ("/");
- umask (022);
-
- if (mkdir (INFODIR, S_IRUSR | S_IWUSR |S_IXUSR | S_IRGRP | S_IXGRP
- | S_IROTH | S_IXOTH) && errno != EEXIST)
- {
- logger (LOG_ERR,
- "mkdir(\"%s\",0): %s\n", INFODIR, strerror (errno));
- goto abort;
- }
-
- if (mkdir (ETCDIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP
- | S_IROTH | S_IXOTH) && errno != EEXIST)
- {
- logger (LOG_ERR,
- "mkdir(\"%s\",0): %s\n", ETCDIR, strerror (errno));
- goto abort;
- }
-
- if (options->test) {
- if (options->dorequest || options->doinform) {
- logger (LOG_ERR,
- "cannot test with --inform or --request");
- goto abort;
- }
-
- if (options->dolastlease) {
- logger (LOG_ERR, "cannot test with --lastlease");
- goto abort;
- }
-
- if (sig != 0) {
- logger (LOG_ERR,
- "cannot test with --release or --renew");
- goto abort;
- }
- }
-
- if (sig != 0) {
- int killed = -1;
- pid = read_pid (options->pidfile);
- if (pid != 0)
- logger (LOG_INFO, "sending signal %d to pid %d",
- sig, pid);
-
- if (! pid || (killed = kill (pid, sig)))
- logger (sig == SIGALRM ? LOG_INFO : LOG_ERR,
- ""PACKAGE" not running");
-
- if (pid != 0 && (sig != SIGALRM || killed != 0))
- unlink (options->pidfile);
-
- if (killed == 0) {
- retval = EXIT_SUCCESS;
- goto abort;
- }
-
- if (sig != SIGALRM)
- goto abort;
- }
-
- if (! options->test && ! options->daemonised) {
- if ((pid = read_pid (options->pidfile)) > 0 &&
- kill (pid, 0) == 0)
- {
- logger (LOG_ERR, ""PACKAGE
- " already running on pid %d (%s)",
- pid, options->pidfile);
- goto abort;
- }
-
- pidfd = open (options->pidfile,
- O_WRONLY | O_CREAT | O_NONBLOCK, 0664);
- if (pidfd == -1) {
- logger (LOG_ERR, "open `%s': %s",
- options->pidfile, strerror (errno));
- goto abort;
- }
-
- /* 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));
- goto abort;
- }
-
- /* dhcpcd.sh should not interhit this fd */
- if ((i = fcntl (pidfd, F_GETFD, 0)) == -1 ||
- fcntl (pidfd, F_SETFD, i | FD_CLOEXEC) == -1)
- logger (LOG_ERR, "fcntl: %s", strerror (errno));
-
- writepid (pidfd, getpid ());
- logger (LOG_INFO, PACKAGE " " VERSION " starting");
- }
-
- /* Seed random */
- srandomdev ();
-
- /* Massage our filters per platform */
- setup_packet_filters ();
-
- /* dhcp_run : defined in client.c */
- if (dhcp_run (options, &pidfd) == 0)
- retval = EXIT_SUCCESS;
+ /* initializations for the ipc connection to qt*/
+ setSocketName(options->qtsocketaddress);
+ if (initQtLoggerSocket() < 0)
+ {
+ logger(LOG_ERR, "initialization Qt Logger failed: %s ", strerror (errno));
+ goto abort;
+ }
+
+
+ if (optind < argc)
+ {
+ if (strlen(argv[optind]) > IF_NAMESIZE)
+ {
+ logger(LOG_ERR, "`%s' too long for an interface name (max=%d)",
+ argv[optind], IF_NAMESIZE);
+ goto abort;
+ }
+ strlcpy(options->interface, argv[optind], sizeof(options->interface));
+ setInterfaceName(options->interface);
+ }
+ else
+ {
+ /* If only version was requested then exit now */
+ if (doversion || dohelp)
+ {
+ retval = 0;
+ goto abort;
+ }
+
+ logger(LOG_ERR, "no interface specified");
+ setInterfaceName("no_if");
+ goto abort;
+ }
+
+ if (strchr(options->hostname, '.'))
+ {
+ if (options->fqdn == FQDN_DISABLE)
+ options->fqdn = FQDN_BOTH;
+ }
+ else
+ options->fqdn = FQDN_DISABLE;
+
+ if (options->request_address.s_addr == 0 && options->doinform)
+ {
+ if ((options->request_address.s_addr = get_address(options->interface))
+ != 0)
+ options->keep_address = true;
+ }
+
+ if (IN_LINKLOCAL (ntohl (options->request_address.s_addr)))
+ {
+ logger (LOG_ERR,
+ "you are not allowed to request a link local address");
+ logToQt(LOG_ERR, -1, "you are not allowed to request a link local address");
+ goto abort;
+ }
+
+ if (geteuid ())
+ {
+ logger (LOG_WARNING, PACKAGE " will not work correctly unless"
+ " run as root");
+ }
+
+ prefix = xmalloc (sizeof (char) * (IF_NAMESIZE + 3));
+ snprintf (prefix, IF_NAMESIZE, "%s: ", options->interface);
+ setlogprefix (prefix);
+ snprintf (options->pidfile, sizeof (options->pidfile), PIDFILE,
+ options->interface);
+ free (prefix);
+
+ chdir ("/");
+ umask (022);
+
+ if (mkdir (INFODIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP
+ | S_IROTH | S_IXOTH) && errno != EEXIST)
+ {
+ logger (LOG_ERR,
+ "mkdir(\"%s\",0): %s\n", INFODIR, strerror (errno));
+ goto abort;
+ }
+
+ if (mkdir (ETCDIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP
+ | S_IROTH | S_IXOTH) && errno != EEXIST)
+ {
+ logger (LOG_ERR,
+ "mkdir(\"%s\",0): %s\n", ETCDIR, strerror (errno));
+ goto abort;
+ }
+
+ if (options->test)
+ {
+ if (options->dorequest || options->doinform)
+ {
+ logger (LOG_ERR,
+ "cannot test with --inform or --request");
+ goto abort;
+ }
+
+ if (options->dolastlease)
+ {
+ logger (LOG_ERR, "cannot test with --lastlease");
+ goto abort;
+ }
+
+ if (sig != 0)
+ {
+ logger (LOG_ERR,
+ "cannot test with --release or --renew");
+ goto abort;
+ }
+ }
+
+ if (sig != 0)
+ {
+ int killed = -1;
+ pid = read_pid (options->pidfile);
+ if (pid != 0)
+ logger (LOG_INFO, "sending signal %d to pid %d",
+ sig, pid);
+
+ if (! pid || (killed = kill (pid, sig)))
+ logger (sig == SIGALRM ? LOG_INFO : LOG_ERR,
+ ""PACKAGE" not running");
+
+ if (pid != 0 && (sig != SIGALRM || killed != 0))
+ unlink (options->pidfile);
+
+ if (killed == 0)
+ {
+ retval = EXIT_SUCCESS;
+ goto abort;
+ }
+
+ if (sig != SIGALRM)
+ goto abort;
+ }
+
+ if (! options->test && ! options->daemonised)
+ {
+ if ((pid = read_pid (options->pidfile)) > 0 &&
+ kill (pid, 0) == 0)
+ {
+ logger (LOG_ERR, ""PACKAGE
+ " already running on pid %d (%s)",
+ pid, options->pidfile);
+ goto abort;
+ }
+
+ pidfd = open (options->pidfile,
+ O_WRONLY | O_CREAT | O_NONBLOCK, 0664);
+ if (pidfd == -1)
+ {
+ logger (LOG_ERR, "open `%s': %s",
+ options->pidfile, strerror (errno));
+ goto abort;
+ }
+
+ /* 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));
+ goto abort;
+ }
+
+ /* dhcpcd.sh should not interhit this fd */
+ if ((i = fcntl (pidfd, F_GETFD, 0)) == -1 ||
+ fcntl (pidfd, F_SETFD, i | FD_CLOEXEC) == -1)
+ logger (LOG_ERR, "fcntl: %s", strerror (errno));
+
+ writepid (pidfd, getpid ());
+ logger (LOG_INFO, PACKAGE " " VERSION " starting");
+ }
+
+ /* Seed random */
+ srandomdev ();
+
+ /* Massage our filters per platform */
+ setup_packet_filters ();
+
+ /* dhcp_run : defined in client.c */
+ if (dhcp_run (options, &pidfd) == 0)
+ retval = EXIT_SUCCESS;
abort:
- /* If we didn't daemonise then we need to punt the pidfile now */
- if (pidfd > -1) {
- close (pidfd);
- unlink (options->pidfile);
- }
+ /* If we didn't daemonise then we need to punt the pidfile now */
+ if (pidfd > -1)
+ {
+ close (pidfd);
+ unlink (options->pidfile);
+ }
- free (options);
+ free (options);
#ifdef THERE_IS_NO_FORK
- /* There may have been an error before the dhcp_run function
- * clears this, so just do it here to be safe */
- free (dhcpcd_skiproutes);
+ /* There may have been an error before the dhcp_run function
+ * clears this, so just do it here to be safe */
+ free (dhcpcd_skiproutes);
#endif
- logger (LOG_INFO, "exiting");
- logToQt(LOG_INFO, DHCPCD_EXIT, "exiting due abort");
- closeQtLoggerSocket();
- exit (retval);
- /* NOTREACHED */
+ logger (LOG_INFO, "exiting");
+ logToQt(LOG_INFO, DHCPCD_EXIT, "exiting due abort");
+ closeQtLoggerSocket();
+ exit (retval);
+ /* NOTREACHED */
}
diff --git a/src/customdhcpcd/dhcpcd.h b/src/customdhcpcd/dhcpcd.h
index 9219446..a600a8c 100644
--- a/src/customdhcpcd/dhcpcd.h
+++ b/src/customdhcpcd/dhcpcd.h
@@ -1,4 +1,4 @@
-/*
+/*
* dhcpcd - DHCP client daemon
* Copyright 2006-2008 Roy Marples <roy@marples.name>
* All rights reserved
@@ -52,55 +52,56 @@
#define CLIENT_ID_MAX_LEN 48
#define USERCLASS_MAX_LEN 255
-#ifdef THERE_IS_NO_FORK
+#ifdef THERE_IS_NO_FORK
extern char dhcpcd[PATH_MAX];
extern char **dhcpcd_argv;
extern int dhcpcd_argc;
extern char *dhcpcd_skiproutes;
#endif
-typedef struct options_t {
- /* added by Niklas Goby, additional field, storing the socket address path for
- * communicating with Qt "server" */
- char qtsocketaddress[QTSOCKETADDRESSLENGTH];
- /*----*/
- char interface[IF_NAMESIZE];
- char hostname[MAXHOSTNAMELEN];
- int fqdn;
- char classid[CLASS_ID_MAX_LEN];
- char clientid[CLIENT_ID_MAX_LEN];
- char userclass[USERCLASS_MAX_LEN];
- size_t userclass_len;
- uint32_t leasetime;
- time_t timeout;
- int metric;
-
- bool doarp;
- bool dodns;
- bool dodomainname;
- bool dogateway;
- int dohostname;
- bool domtu;
- bool donis;
- bool dontp;
- bool dolastlease;
- bool doinform;
- bool dorequest;
- bool doipv4ll;
- bool doduid;
- int domscsr;
-
- struct in_addr request_address;
- struct in_addr request_netmask;
-
- bool persistent;
- bool keep_address;
- bool daemonise;
- bool daemonised;
- bool test;
-
- char *script;
- char pidfile[PATH_MAX];
+typedef struct options_t
+{
+ /* added by Niklas Goby, additional field, storing the socket address path for
+ * communicating with Qt "server" */
+ char qtsocketaddress[QTSOCKETADDRESSLENGTH];
+ /*----*/
+ char interface[IF_NAMESIZE];
+ char hostname[MAXHOSTNAMELEN];
+ int fqdn;
+ char classid[CLASS_ID_MAX_LEN];
+ char clientid[CLIENT_ID_MAX_LEN];
+ char userclass[USERCLASS_MAX_LEN];
+ size_t userclass_len;
+ uint32_t leasetime;
+ time_t timeout;
+ int metric;
+
+ bool doarp;
+ bool dodns;
+ bool dodomainname;
+ bool dogateway;
+ int dohostname;
+ bool domtu;
+ bool donis;
+ bool dontp;
+ bool dolastlease;
+ bool doinform;
+ bool dorequest;
+ bool doipv4ll;
+ bool doduid;
+ int domscsr;
+
+ struct in_addr request_address;
+ struct in_addr request_netmask;
+
+ bool persistent;
+ bool keep_address;
+ bool daemonise;
+ bool daemonised;
+ bool test;
+
+ char *script;
+ char pidfile[PATH_MAX];
} options_t;
int nd_main (char *ifname);
diff --git a/src/customdhcpcd/duid.c b/src/customdhcpcd/duid.c
index e4dd83b..c51503d 100644
--- a/src/customdhcpcd/duid.c
+++ b/src/customdhcpcd/duid.c
@@ -1,4 +1,4 @@
-/*
+/*
* dhcpcd - DHCP client daemon
* Copyright 2006-2008 Roy Marples <roy@marples.name>
* All rights reserved
@@ -45,74 +45,81 @@
size_t get_duid (unsigned char *duid, const interface_t *iface)
{
- FILE *f;
- uint16_t type = 0;
- uint16_t hw = 0;
- uint32_t ul;
- time_t t;
- int x = 0;
- unsigned char *p = duid;
- size_t len = 0;
-
- if (! iface)
- return (0);
-
- /* If we already have a DUID then use it as it's never supposed
- * to change once we have one even if the interfaces do */
- if ((f = fopen (DUIDFILE, "r"))) {
- char *line = get_line (f);
- if (line) {
- len = hwaddr_aton (NULL, line);
- if (len && len <= DUID_LEN)
- hwaddr_aton (duid, line);
- free (line);
- }
- fclose (f);
- if (len)
- return (len);
- } else {
- if (errno != ENOENT) {
- logger (LOG_ERR, "fopen `%s': %s",
- DUIDFILE, strerror (errno));
- return (0);
- }
- }
-
- /* No file? OK, lets make one based on our interface */
- type = htons (1); /* DUI-D-LLT */
- memcpy (p, &type, 2);
- p += 2;
-
- hw = htons (iface->family);
- memcpy (p, &hw, 2);
- p += 2;
-
- /* time returns seconds from jan 1 1970, but DUID-LLT is
- * seconds from jan 1 2000 modulo 2^32 */
- t = time (NULL) - THIRTY_YEARS_IN_SECONDS;
- ul = htonl (t & 0xffffffff);
- memcpy (p, &ul, 4);
- p += 4;
-
- /* Finally, add the MAC address of the interface */
- memcpy (p, iface->hwaddr, iface->hwlen);
- p += iface->hwlen;
-
- len = p - duid;
-
- if (! (f = fopen (DUIDFILE, "w")))
- logger (LOG_ERR, "fopen `%s': %s", DUIDFILE, strerror (errno));
- else {
- x = fprintf (f, "%s\n", hwaddr_ntoa (duid, len));
- fclose (f);
- }
-
- /* Failed to write the duid? scrub it, we cannot use it */
- if (x < 1) {
- len = 0;
- unlink (DUIDFILE);
- }
-
- return (len);
+ FILE *f;
+ uint16_t type = 0;
+ uint16_t hw = 0;
+ uint32_t ul;
+ time_t t;
+ int x = 0;
+ unsigned char *p = duid;
+ size_t len = 0;
+
+ if (! iface)
+ return (0);
+
+ /* If we already have a DUID then use it as it's never supposed
+ * to change once we have one even if the interfaces do */
+ if ((f = fopen (DUIDFILE, "r")))
+ {
+ char *line = get_line (f);
+ if (line)
+ {
+ len = hwaddr_aton (NULL, line);
+ if (len && len <= DUID_LEN)
+ hwaddr_aton (duid, line);
+ free (line);
+ }
+ fclose (f);
+ if (len)
+ return (len);
+ }
+ else
+ {
+ if (errno != ENOENT)
+ {
+ logger (LOG_ERR, "fopen `%s': %s",
+ DUIDFILE, strerror (errno));
+ return (0);
+ }
+ }
+
+ /* No file? OK, lets make one based on our interface */
+ type = htons (1); /* DUI-D-LLT */
+ memcpy (p, &type, 2);
+ p += 2;
+
+ hw = htons (iface->family);
+ memcpy (p, &hw, 2);
+ p += 2;
+
+ /* time returns seconds from jan 1 1970, but DUID-LLT is
+ * seconds from jan 1 2000 modulo 2^32 */
+ t = time (NULL) - THIRTY_YEARS_IN_SECONDS;
+ ul = htonl (t & 0xffffffff);
+ memcpy (p, &ul, 4);
+ p += 4;
+
+ /* Finally, add the MAC address of the interface */
+ memcpy (p, iface->hwaddr, iface->hwlen);
+ p += iface->hwlen;
+
+ len = p - duid;
+
+ if (! (f = fopen (DUIDFILE, "w")))
+ logger (LOG_ERR, "fopen `%s': %s", DUIDFILE, strerror (errno));
+ else
+ {
+ x = fprintf (f, "%s\n", hwaddr_ntoa (duid, len));
+ fclose (f);
+ }
+
+ /* Failed to write the duid? scrub it, we cannot use it */
+ if (x < 1)
+ {
+ len = 0;
+ unlink (DUIDFILE);
+ }
+
+ return (len);
}
#endif
diff --git a/src/customdhcpcd/duid.h b/src/customdhcpcd/duid.h
index 1492990..f264c26 100644
--- a/src/customdhcpcd/duid.h
+++ b/src/customdhcpcd/duid.h
@@ -1,4 +1,4 @@
-/*
+/*
* dhcpcd - DHCP client daemon
* Copyright 2006-2008 Roy Marples <roy@marples.name>
* All rights reserved
diff --git a/src/customdhcpcd/info.c b/src/customdhcpcd/info.c
index 8369b43..5d933dc 100644
--- a/src/customdhcpcd/info.c
+++ b/src/customdhcpcd/info.c
@@ -1,4 +1,4 @@
-/*
+/*
* dhcpcd - DHCP client daemon
* Copyright 2006-2008 Roy Marples <roy@marples.name>
* All rights reserved
@@ -48,424 +48,469 @@
* so the contents work in a shell */
static char *cleanmetas (const char *cstr)
{
- const char *p = cstr;
- char *new;
- char *n;
- size_t len;
-
- if (cstr == NULL || (len = strlen (cstr)) == 0)
- return (xstrdup (""));
-
- n = new = xmalloc (sizeof (char) * len + 2);
- do
- if (*p == '\'') {
- size_t pos = n - new;
- len += 4;
- new = xrealloc (new, sizeof (char) * len + 1);
- n = new + pos;
- *n++ = '\'';
- *n++ = '\\';
- *n++ = '\'';
- *n++ = '\'';
- } else
- *n++ = *p;
- while (*p++);
-
- /* Terminate the sucker */
- *n = '\0';
-
- return (new);
+ const char *p = cstr;
+ char *new;
+ char *n;
+ size_t len;
+
+ if (cstr == NULL || (len = strlen (cstr)) == 0)
+ return (xstrdup (""));
+
+ n = new = xmalloc (sizeof (char) * len + 2);
+ do
+ if (*p == '\'')
+ {
+ size_t pos = n - new;
+ len += 4;
+ new = xrealloc (new, sizeof (char) * len + 1);
+ n = new + pos;
+ *n++ = '\'';
+ *n++ = '\\';
+ *n++ = '\'';
+ *n++ = '\'';
+ }
+ else
+ *n++ = *p;
+ while (*p++);
+
+ /* Terminate the sucker */
+ *n = '\0';
+
+ return (new);
}
static void print_addresses (FILE *f, const struct address_head *addresses)
{
- const address_t *addr;
-
- STAILQ_FOREACH (addr, addresses, entries) {
- fprintf (f, "%s", inet_ntoa (addr->address));
- if (STAILQ_NEXT (addr, entries))
- fprintf (f, " ");
- }
+ const address_t *addr;
+
+ STAILQ_FOREACH (addr, addresses, entries)
+ {
+ fprintf (f, "%s", inet_ntoa (addr->address));
+ if (STAILQ_NEXT (addr, entries))
+ fprintf (f, " ");
+ }
}
static void print_clean (FILE *f, const char *name, const char *value)
{
- char *clean;
+ char *clean;
- if (! value)
- return;
+ if (! value)
+ return;
- clean = cleanmetas (value);
- fprintf (f, "%s='%s'\n", name, clean);
- free (clean);
+ clean = cleanmetas (value);
+ fprintf (f, "%s='%s'\n", name, clean);
+ free (clean);
}
bool write_info(const interface_t *iface, const dhcp_t *dhcp,
- const options_t *options, bool overwrite)
+ const options_t *options, bool overwrite)
{
- FILE *f;
- route_t *route;
- struct stat sb;
-
- 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) {
- struct in_addr n;
- n.s_addr = dhcp->address.s_addr & dhcp->netmask.s_addr;
- fprintf (f, "IPADDR='%s'\n", inet_ntoa (dhcp->address));
- fprintf (f, "NETMASK='%s'\n", inet_ntoa (dhcp->netmask));
- fprintf (f, "NETWORK='%s'\n", inet_ntoa (n));
- fprintf (f, "BROADCAST='%s'\n", inet_ntoa (dhcp->broadcast));
- }
- if (dhcp->mtu > 0)
- fprintf (f, "MTU='%d'\n", dhcp->mtu);
-
- if (dhcp->routes) {
- bool doneone = false;
- fprintf (f, "ROUTES='");
- STAILQ_FOREACH (route, dhcp->routes, entries) {
- if (route->destination.s_addr != 0) {
- if (doneone)
- fprintf (f, " ");
- fprintf (f, "%s", inet_ntoa (route->destination));
- fprintf (f, ",%s", inet_ntoa (route->netmask));
- fprintf (f, ",%s", inet_ntoa (route->gateway));
- doneone = true;
- }
- }
- fprintf (f, "'\n");
-
- doneone = false;
- fprintf (f, "GATEWAYS='");
- STAILQ_FOREACH (route, dhcp->routes, entries) {
- if (route->destination.s_addr == 0) {
- if (doneone)
- fprintf (f, " ");
- fprintf (f, "%s", inet_ntoa (route->gateway));
- doneone = true;
- }
- }
- fprintf (f, "'\n");
- }
-
- print_clean (f, "HOSTNAME", dhcp->hostname);
- print_clean (f, "DNSDOMAIN", dhcp->dnsdomain);
- print_clean (f, "DNSSEARCH", dhcp->dnssearch);
-
- if (dhcp->dnsservers) {
- fprintf (f, "DNSSERVERS='");
- print_addresses (f, dhcp->dnsservers);
- fprintf (f, "'\n");
- }
-
- if (dhcp->fqdn) {
- fprintf (f, "FQDNFLAGS='%u'\n", dhcp->fqdn->flags);
- fprintf (f, "FQDNRCODE1='%u'\n", dhcp->fqdn->r1);
- fprintf (f, "FQDNRCODE2='%u'\n", dhcp->fqdn->r2);
- print_clean (f, "FQDNHOSTNAME", dhcp->fqdn->name);
- }
-
- if (dhcp->ntpservers) {
- fprintf (f, "NTPSERVERS='");
- print_addresses (f, dhcp->ntpservers);
- fprintf (f, "'\n");
- }
-
- print_clean (f, "NISDOMAIN", dhcp->nisdomain);
- if (dhcp->nisservers) {
- fprintf (f, "NISSERVERS='");
- print_addresses (f, dhcp->nisservers);
- fprintf (f, "'\n");
- }
-
- print_clean (f, "ROOTPATH", dhcp->rootpath);
- print_clean (f, "SIPSERVERS", dhcp->sipservers);
-
- if (dhcp->serveraddress.s_addr)
- fprintf (f, "DHCPSID='%s'\n", inet_ntoa (dhcp->serveraddress));
- if (dhcp->servername[0])
- print_clean (f, "DHCPSNAME", dhcp->servername);
-
- if (! options->doinform && dhcp->address.s_addr) {
- 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);
- }
- print_clean (f, "INTERFACE", iface->name);
- print_clean (f, "CLASSID", options->classid);
- if (iface->clientid_len > 0) {
- fprintf (f, "CLIENTID='%s'\n",
- hwaddr_ntoa (iface->clientid, iface->clientid_len));
- }
- fprintf (f, "DHCPCHADDR='%s'\n", hwaddr_ntoa (iface->hwaddr,
- iface->hwlen));
+ FILE *f;
+ route_t *route;
+ struct stat sb;
+
+ 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)
+ {
+ struct in_addr n;
+ n.s_addr = dhcp->address.s_addr & dhcp->netmask.s_addr;
+ fprintf (f, "IPADDR='%s'\n", inet_ntoa (dhcp->address));
+ fprintf (f, "NETMASK='%s'\n", inet_ntoa (dhcp->netmask));
+ fprintf (f, "NETWORK='%s'\n", inet_ntoa (n));
+ fprintf (f, "BROADCAST='%s'\n", inet_ntoa (dhcp->broadcast));
+ }
+ if (dhcp->mtu > 0)
+ fprintf (f, "MTU='%d'\n", dhcp->mtu);
+
+ if (dhcp->routes)
+ {
+ bool doneone = false;
+ fprintf (f, "ROUTES='");
+ STAILQ_FOREACH (route, dhcp->routes, entries)
+ {
+ if (route->destination.s_addr != 0)
+ {
+ if (doneone)
+ fprintf (f, " ");
+ fprintf (f, "%s", inet_ntoa (route->destination));
+ fprintf (f, ",%s", inet_ntoa (route->netmask));
+ fprintf (f, ",%s", inet_ntoa (route->gateway));
+ doneone = true;
+ }
+ }
+ fprintf (f, "'\n");
+
+ doneone = false;
+ fprintf (f, "GATEWAYS='");
+ STAILQ_FOREACH (route, dhcp->routes, entries)
+ {
+ if (route->destination.s_addr == 0)
+ {
+ if (doneone)
+ fprintf (f, " ");
+ fprintf (f, "%s", inet_ntoa (route->gateway));
+ doneone = true;
+ }
+ }
+ fprintf (f, "'\n");
+ }
+
+ print_clean (f, "HOSTNAME", dhcp->hostname);
+ print_clean (f, "DNSDOMAIN", dhcp->dnsdomain);
+ print_clean (f, "DNSSEARCH", dhcp->dnssearch);
+
+ if (dhcp->dnsservers)
+ {
+ fprintf (f, "DNSSERVERS='");
+ print_addresses (f, dhcp->dnsservers);
+ fprintf (f, "'\n");
+ }
+
+ if (dhcp->fqdn)
+ {
+ fprintf (f, "FQDNFLAGS='%u'\n", dhcp->fqdn->flags);
+ fprintf (f, "FQDNRCODE1='%u'\n", dhcp->fqdn->r1);
+ fprintf (f, "FQDNRCODE2='%u'\n", dhcp->fqdn->r2);
+ print_clean (f, "FQDNHOSTNAME", dhcp->fqdn->name);
+ }
+
+ if (dhcp->ntpservers)
+ {
+ fprintf (f, "NTPSERVERS='");
+ print_addresses (f, dhcp->ntpservers);
+ fprintf (f, "'\n");
+ }
+
+ print_clean (f, "NISDOMAIN", dhcp->nisdomain);
+ if (dhcp->nisservers)
+ {
+ fprintf (f, "NISSERVERS='");
+ print_addresses (f, dhcp->nisservers);
+ fprintf (f, "'\n");
+ }
+
+ print_clean (f, "ROOTPATH", dhcp->rootpath);
+ print_clean (f, "SIPSERVERS", dhcp->sipservers);
+
+ if (dhcp->serveraddress.s_addr)
+ fprintf (f, "DHCPSID='%s'\n", inet_ntoa (dhcp->serveraddress));
+ if (dhcp->servername[0])
+ print_clean (f, "DHCPSNAME", dhcp->servername);
+
+ if (! options->doinform && dhcp->address.s_addr)
+ {
+ 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);
+ }
+ print_clean (f, "INTERFACE", iface->name);
+ print_clean (f, "CLASSID", options->classid);
+ if (iface->clientid_len > 0)
+ {
+ fprintf (f, "CLIENTID='%s'\n",
+ hwaddr_ntoa (iface->clientid, iface->clientid_len));
+ }
+ fprintf (f, "DHCPCHADDR='%s'\n", hwaddr_ntoa (iface->hwaddr,
+ iface->hwlen));
#ifdef ENABLE_INFO_COMPAT
- /* Support the old .info settings if we need to */
- fprintf (f, "\n# dhcpcd-1.x and 2.x compatible variables\n");
- if (dhcp->dnsservers) {
- address_t *addr;
-
- fprintf (f, "DNS='");
- STAILQ_FOREACH (addr, dhcp->dnsservers, entries) {
- fprintf (f, "%s", inet_ntoa (addr->address));
- if (STAILQ_NEXT (addr, entries))
- fprintf (f, ",");
- }
- fprintf (f, "'\n");
- }
-
- if (dhcp->routes) {
- bool doneone = false;
- fprintf (f, "GATEWAY='");
- STAILQ_FOREACH (route, dhcp->routes, entries) {
- if (route->destination.s_addr == 0) {
- if (doneone)
- fprintf (f, ",");
- fprintf (f, "%s", inet_ntoa (route->gateway));
- doneone = true;
- }
- }
- fprintf (f, "'\n");
- }
+ /* Support the old .info settings if we need to */
+ fprintf (f, "\n# dhcpcd-1.x and 2.x compatible variables\n");
+ if (dhcp->dnsservers)
+ {
+ address_t *addr;
+
+ fprintf (f, "DNS='");
+ STAILQ_FOREACH (addr, dhcp->dnsservers, entries)
+ {
+ fprintf (f, "%s", inet_ntoa (addr->address));
+ if (STAILQ_NEXT (addr, entries))
+ fprintf (f, ",");
+ }
+ fprintf (f, "'\n");
+ }
+
+ if (dhcp->routes)
+ {
+ bool doneone = false;
+ fprintf (f, "GATEWAY='");
+ STAILQ_FOREACH (route, dhcp->routes, entries)
+ {
+ if (route->destination.s_addr == 0)
+ {
+ if (doneone)
+ fprintf (f, ",");
+ fprintf (f, "%s", inet_ntoa (route->gateway));
+ doneone = true;
+ }
+ }
+ fprintf (f, "'\n");
+ }
#endif
- if (! options->test)
- fclose (f);
- return (true);
+ if (! options->test)
+ fclose (f);
+ return (true);
}
static bool parse_address (struct in_addr *addr,
- const char *value, const char *var)
+ const char *value, const char *var)
{
- if (inet_aton (value, addr) == 0) {
- logger (LOG_ERR, "%s `%s': %s", var, value,
- strerror (errno));
- return (false);
- }
- return (true);
+ if (inet_aton (value, addr) == 0)
+ {
+ logger (LOG_ERR, "%s `%s': %s", var, value,
+ strerror (errno));
+ return (false);
+ }
+ return (true);
}
static bool parse_uint (unsigned int *i,
- const char *value, const char *var)
+ const char *value, const char *var)
{
- if (sscanf (value, "%u", i) != 1) {
- logger (LOG_ERR, "%s `%s': not a valid number",
- var, value);
- return (false);
- }
- return (true);
+ if (sscanf (value, "%u", i) != 1)
+ {
+ logger (LOG_ERR, "%s `%s': not a valid number",
+ var, value);
+ return (false);
+ }
+ return (true);
}
static bool parse_ushort (unsigned short *s,
- const char *value, const char *var)
+ const char *value, const char *var)
{
- if (sscanf (value, "%hu", s) != 1) {
- logger (LOG_ERR, "%s `%s': not a valid number",
- var, value);
- return (false);
- }
- return (true);
+ if (sscanf (value, "%hu", s) != 1)
+ {
+ logger (LOG_ERR, "%s `%s': not a valid number",
+ var, value);
+ return (false);
+ }
+ return (true);
}
static struct address_head *parse_addresses (char *value, const char *var)
{
- char *token;
- char *p = value;
- struct address_head *head = NULL;
-
- while ((token = strsep (&p, " "))) {
- address_t *a = xzalloc (sizeof (*a));
-
- if (inet_aton (token, &a->address) == 0) {
- logger (LOG_ERR, "%s: invalid address `%s'", var, token);
- free_address (head);
- free (a);
- return (NULL);
- }
-
- if (! head) {
- head = xmalloc (sizeof (*head));
- STAILQ_INIT (head);
- }
- STAILQ_INSERT_TAIL (head, a, entries);
- }
-
- return (head);
+ char *token;
+ char *p = value;
+ struct address_head *head = NULL;
+
+ while ((token = strsep (&p, " ")))
+ {
+ address_t *a = xzalloc (sizeof (*a));
+
+ if (inet_aton (token, &a->address) == 0)
+ {
+ logger (LOG_ERR, "%s: invalid address `%s'", var, token);
+ free_address (head);
+ free (a);
+ return (NULL);
+ }
+
+ if (! head)
+ {
+ head = xmalloc (sizeof (*head));
+ STAILQ_INIT (head);
+ }
+ STAILQ_INSERT_TAIL (head, a, entries);
+ }
+
+ return (head);
}
bool read_info (const interface_t *iface, dhcp_t *dhcp)
{
- FILE *fp;
- char *line;
- char *var;
- char *value;
- char *p;
- struct stat sb;
-
- if (stat (iface->infofile, &sb) != 0) {
- logger (LOG_ERR, "lease information file `%s' does not exist",
- iface->infofile);
- return (false);
- }
-
- if (! (fp = fopen (iface->infofile, "r"))) {
- logger (LOG_ERR, "fopen `%s': %s",
- iface->infofile, strerror (errno));
- return (false);
- }
-
- dhcp->frominfo = true;
-
- while ((line = get_line (fp))) {
- var = line;
-
- /* Strip leading spaces/tabs */
- while ((*var == ' ') || (*var == '\t'))
- var++;
-
- /* Trim trailing \n */
- p = var + strlen (var) - 1;
- if (*p == '\n')
- *p = 0;
-
- /* Skip comments */
- if (*var == '#')
- goto next;
-
- /* If we don't have an equals sign then skip it */
- if (! (p = strchr (var, '=')))
- goto next;
-
- /* Terminate the = so we have two strings */
- *p = 0;
-
- value = p + 1;
- /* Strip leading and trailing quotes if present */
- if (*value == '\'' || *value == '"')
- value++;
- p = value + strlen (value) - 1;
- if (*p == '\'' || *p == '"')
- *p = 0;
-
- /* Don't process null vars or values */
- if (! *var || ! *value)
- goto next;
-
- if (strcmp (var, "IPADDR") == 0)
- parse_address (&dhcp->address, value, "IPADDR");
- else if (strcmp (var, "NETMASK") == 0)
- parse_address (&dhcp->netmask, value, "NETMASK");
- else if (strcmp (var, "BROADCAST") == 0)
- parse_address (&dhcp->broadcast, value, "BROADCAST");
- else if (strcmp (var, "MTU") == 0)
- parse_ushort (&dhcp->mtu, value, "MTU");
- else if (strcmp (var, "ROUTES") == 0) {
- p = value;
- while ((value = strsep (&p, " "))) {
- char *pp = value;
- char *dest = strsep (&pp, ",");
- char *net = strsep (&pp, ",");
- char *gate = strsep (&pp, ",");
- route_t *route;
-
- if (! dest || ! net || ! gate) {
- logger (LOG_ERR, "read_info ROUTES `%s,%s,%s': invalid route",
- dest, net, gate);
- goto next;
- }
-
- /* See if we can create a route */
- route = xzalloc (sizeof (*route));
- if (inet_aton (dest, &route->destination) == 0) {
- logger (LOG_ERR, "read_info ROUTES `%s': not a valid destination address",
- dest);
- free (route);
- goto next;
- }
- if (inet_aton (dest, &route->netmask) == 0) {
- logger (LOG_ERR, "read_info ROUTES `%s': not a valid netmask address",
- net);
- free (route);
- goto next;
- }
- if (inet_aton (dest, &route->gateway) == 0) {
- logger (LOG_ERR, "read_info ROUTES `%s': not a valid gateway address",
- gate);
- free (route);
- goto next;
- }
-
- /* OK, now add our route */
- if (! dhcp->routes) {
- dhcp->routes = xmalloc (sizeof (*dhcp->routes));
- STAILQ_INIT (dhcp->routes);
- }
- STAILQ_INSERT_TAIL (dhcp->routes, route, entries);
- }
- } else if (strcmp (var, "GATEWAYS") == 0) {
- p = value;
- while ((value = strsep (&p, " "))) {
- route_t *route = xzalloc (sizeof (*route));
- if (parse_address (&route->gateway, value, "GATEWAYS")) {
- if (! dhcp->routes) {
- dhcp->routes = xmalloc (sizeof (*dhcp->routes));
- STAILQ_INIT (dhcp->routes);
- }
- STAILQ_INSERT_TAIL (dhcp->routes, route, entries);
- } else
- free (route);
- }
- } else if (strcmp (var, "HOSTNAME") == 0)
- dhcp->hostname = xstrdup (value);
- else if (strcmp (var, "DNSDOMAIN") == 0)
- dhcp->dnsdomain = xstrdup (value);
- else if (strcmp (var, "DNSSEARCH") == 0)
- dhcp->dnssearch = xstrdup (value);
- else if (strcmp (var, "DNSSERVERS") == 0)
- dhcp->dnsservers = parse_addresses (value, "DNSSERVERS");
- else if (strcmp (var, "NTPSERVERS") == 0)
- dhcp->ntpservers = parse_addresses (value, "NTPSERVERS");
- else if (strcmp (var, "NISDOMAIN") == 0)
- dhcp->nisdomain = xstrdup (value);
- else if (strcmp (var, "NISSERVERS") == 0)
- dhcp->nisservers = parse_addresses (value, "NISSERVERS");
- else if (strcmp (var, "ROOTPATH") == 0)
- dhcp->rootpath = xstrdup (value);
- else if (strcmp (var, "DHCPSID") == 0)
- parse_address (&dhcp->serveraddress, value, "DHCPSID");
- else if (strcmp (var, "DHCPSNAME") == 0)
- strlcpy (dhcp->servername, value, sizeof (dhcp->servername));
- else if (strcmp (var, "LEASEDFROM") == 0)
- parse_uint (&dhcp->leasedfrom, value, "LEASEDFROM");
- else if (strcmp (var, "LEASETIME") == 0)
- parse_uint (&dhcp->leasetime, value, "LEASETIME");
- else if (strcmp (var, "RENEWALTIME") == 0)
- parse_uint (&dhcp->renewaltime, value, "RENEWALTIME");
- else if (strcmp (var, "REBINDTIME") == 0)
- parse_uint (&dhcp->rebindtime, value, "REBINDTIME");
+ FILE *fp;
+ char *line;
+ char *var;
+ char *value;
+ char *p;
+ struct stat sb;
+
+ if (stat (iface->infofile, &sb) != 0)
+ {
+ logger (LOG_ERR, "lease information file `%s' does not exist",
+ iface->infofile);
+ return (false);
+ }
+
+ if (! (fp = fopen (iface->infofile, "r")))
+ {
+ logger (LOG_ERR, "fopen `%s': %s",
+ iface->infofile, strerror (errno));
+ return (false);
+ }
+
+ dhcp->frominfo = true;
+
+ while ((line = get_line (fp)))
+ {
+ var = line;
+
+ /* Strip leading spaces/tabs */
+ while ((*var == ' ') || (*var == '\t'))
+ var++;
+
+ /* Trim trailing \n */
+ p = var + strlen (var) - 1;
+ if (*p == '\n')
+ *p = 0;
+
+ /* Skip comments */
+ if (*var == '#')
+ goto next;
+
+ /* If we don't have an equals sign then skip it */
+ if (! (p = strchr (var, '=')))
+ goto next;
+
+ /* Terminate the = so we have two strings */
+ *p = 0;
+
+ value = p + 1;
+ /* Strip leading and trailing quotes if present */
+ if (*value == '\'' || *value == '"')
+ value++;
+ p = value + strlen (value) - 1;
+ if (*p == '\'' || *p == '"')
+ *p = 0;
+
+ /* Don't process null vars or values */
+ if (! *var || ! *value)
+ goto next;
+
+ if (strcmp (var, "IPADDR") == 0)
+ parse_address (&dhcp->address, value, "IPADDR");
+ else if (strcmp (var, "NETMASK") == 0)
+ parse_address (&dhcp->netmask, value, "NETMASK");
+ else if (strcmp (var, "BROADCAST") == 0)
+ parse_address (&dhcp->broadcast, value, "BROADCAST");
+ else if (strcmp (var, "MTU") == 0)
+ parse_ushort (&dhcp->mtu, value, "MTU");
+ else if (strcmp (var, "ROUTES") == 0)
+ {
+ p = value;
+ while ((value = strsep (&p, " ")))
+ {
+ char *pp = value;
+ char *dest = strsep (&pp, ",");
+ char *net = strsep (&pp, ",");
+ char *gate = strsep (&pp, ",");
+ route_t *route;
+
+ if (! dest || ! net || ! gate)
+ {
+ logger (LOG_ERR, "read_info ROUTES `%s,%s,%s': invalid route",
+ dest, net, gate);
+ goto next;
+ }
+
+ /* See if we can create a route */
+ route = xzalloc (sizeof (*route));
+ if (inet_aton (dest, &route->destination) == 0)
+ {
+ logger (LOG_ERR, "read_info ROUTES `%s': not a valid destination address",
+ dest);
+ free (route);
+ goto next;
+ }
+ if (inet_aton (dest, &route->netmask) == 0)
+ {
+ logger (LOG_ERR, "read_info ROUTES `%s': not a valid netmask address",
+ net);
+ free (route);
+ goto next;
+ }
+ if (inet_aton (dest, &route->gateway) == 0)
+ {
+ logger (LOG_ERR, "read_info ROUTES `%s': not a valid gateway address",
+ gate);
+ free (route);
+ goto next;
+ }
+
+ /* OK, now add our route */
+ if (! dhcp->routes)
+ {
+ dhcp->routes = xmalloc (sizeof (*dhcp->routes));
+ STAILQ_INIT (dhcp->routes);
+ }
+ STAILQ_INSERT_TAIL (dhcp->routes, route, entries);
+ }
+ }
+ else if (strcmp (var, "GATEWAYS") == 0)
+ {
+ p = value;
+ while ((value = strsep (&p, " ")))
+ {
+ route_t *route = xzalloc (sizeof (*route));
+ if (parse_address (&route->gateway, value, "GATEWAYS"))
+ {
+ if (! dhcp->routes)
+ {
+ dhcp->routes = xmalloc (sizeof (*dhcp->routes));
+ STAILQ_INIT (dhcp->routes);
+ }
+ STAILQ_INSERT_TAIL (dhcp->routes, route, entries);
+ }
+ else
+ free (route);
+ }
+ }
+ else if (strcmp (var, "HOSTNAME") == 0)
+ dhcp->hostname = xstrdup (value);
+ else if (strcmp (var, "DNSDOMAIN") == 0)
+ dhcp->dnsdomain = xstrdup (value);
+ else if (strcmp (var, "DNSSEARCH") == 0)
+ dhcp->dnssearch = xstrdup (value);
+ else if (strcmp (var, "DNSSERVERS") == 0)
+ dhcp->dnsservers = parse_addresses (value, "DNSSERVERS");
+ else if (strcmp (var, "NTPSERVERS") == 0)
+ dhcp->ntpservers = parse_addresses (value, "NTPSERVERS");
+ else if (strcmp (var, "NISDOMAIN") == 0)
+ dhcp->nisdomain = xstrdup (value);
+ else if (strcmp (var, "NISSERVERS") == 0)
+ dhcp->nisservers = parse_addresses (value, "NISSERVERS");
+ else if (strcmp (var, "ROOTPATH") == 0)
+ dhcp->rootpath = xstrdup (value);
+ else if (strcmp (var, "DHCPSID") == 0)
+ parse_address (&dhcp->serveraddress, value, "DHCPSID");
+ else if (strcmp (var, "DHCPSNAME") == 0)
+ strlcpy (dhcp->servername, value, sizeof (dhcp->servername));
+ else if (strcmp (var, "LEASEDFROM") == 0)
+ parse_uint (&dhcp->leasedfrom, value, "LEASEDFROM");
+ else if (strcmp (var, "LEASETIME") == 0)
+ parse_uint (&dhcp->leasetime, value, "LEASETIME");
+ else if (strcmp (var, "RENEWALTIME") == 0)
+ parse_uint (&dhcp->renewaltime, value, "RENEWALTIME");
+ else if (strcmp (var, "REBINDTIME") == 0)
+ parse_uint (&dhcp->rebindtime, value, "REBINDTIME");
next:
- free (line);
- }
+ free (line);
+ }
- fclose (fp);
- return (true);
+ fclose (fp);
+ return (true);
}
#endif
diff --git a/src/customdhcpcd/info.h b/src/customdhcpcd/info.h
index 22966db..2b4a90e 100644
--- a/src/customdhcpcd/info.h
+++ b/src/customdhcpcd/info.h
@@ -1,4 +1,4 @@
-/*
+/*
* dhcpcd - DHCP client daemon
* Copyright 2006-2008 Roy Marples <roy@marples.name>
* All rights reserved
@@ -34,7 +34,7 @@
#ifdef ENABLE_INFO
bool write_info (const interface_t *iface, const dhcp_t *dhcp,
- const options_t *options, bool overwrite);
+ const options_t *options, bool overwrite);
bool read_info (const interface_t *iface, dhcp_t *dhcp);
#endif
diff --git a/src/customdhcpcd/interface.c b/src/customdhcpcd/interface.c
index d2ff8d6..818a2f0 100644
--- a/src/customdhcpcd/interface.c
+++ b/src/customdhcpcd/interface.c
@@ -1,4 +1,4 @@
-/*
+/*
* dhcpcd - DHCP client daemon
* Copyright 2006-2008 Roy Marples <roy@marples.name>
* All rights reserved
@@ -63,438 +63,478 @@
void free_address (struct address_head *addresses)
{
- address_t *p;
- address_t *n;
-
- if (! addresses)
- return;
-
- p = STAILQ_FIRST (addresses);
- while (p) {
- n = STAILQ_NEXT (p, entries);
- free (p);
- p = n;
- }
- free (addresses);
+ address_t *p;
+ address_t *n;
+
+ if (! addresses)
+ return;
+
+ p = STAILQ_FIRST (addresses);
+ while (p)
+ {
+ n = STAILQ_NEXT (p, entries);
+ free (p);
+ p = n;
+ }
+ free (addresses);
}
void free_route (struct route_head *routes)
{
- route_t *p;
- route_t *n;
-
- if (! routes)
- return;
-
- p = STAILQ_FIRST (routes);
- while (p) {
- n = STAILQ_NEXT (p, entries);
- free (p);
- p = n;
- }
- free (routes);
+ route_t *p;
+ route_t *n;
+
+ if (! routes)
+ return;
+
+ p = STAILQ_FIRST (routes);
+ while (p)
+ {
+ n = STAILQ_NEXT (p, entries);
+ free (p);
+ p = n;
+ }
+ free (routes);
}
int inet_ntocidr (struct in_addr address)
{
- int cidr = 0;
- uint32_t mask = htonl (address.s_addr);
+ int cidr = 0;
+ uint32_t mask = htonl (address.s_addr);
- while (mask) {
- cidr++;
- mask <<= 1;
- }
+ while (mask)
+ {
+ cidr++;
+ mask <<= 1;
+ }
- return (cidr);
+ return (cidr);
}
-int inet_cidrtoaddr (int cidr, struct in_addr *addr) {
- int ocets;
-
- if (cidr < 0 || cidr > 32) {
- errno = EINVAL;
- return (-1);
- }
- ocets = (cidr + 7) / 8;
-
- memset (addr, 0, sizeof (*addr));
- if (ocets > 0) {
- memset (&addr->s_addr, 255, (size_t) ocets - 1);
- memset ((unsigned char *) &addr->s_addr + (ocets - 1),
- (256 - (1 << (32 - cidr) % 8)), 1);
- }
-
- return (0);
+int inet_cidrtoaddr (int cidr, struct in_addr *addr)
+{
+ int ocets;
+
+ if (cidr < 0 || cidr > 32)
+ {
+ errno = EINVAL;
+ return (-1);
+ }
+ ocets = (cidr + 7) / 8;
+
+ memset (addr, 0, sizeof (*addr));
+ if (ocets > 0)
+ {
+ memset (&addr->s_addr, 255, (size_t) ocets - 1);
+ memset ((unsigned char *) &addr->s_addr + (ocets - 1),
+ (256 - (1 << (32 - cidr) % 8)), 1);
+ }
+
+ return (0);
}
uint32_t get_netmask (uint32_t addr)
{
- uint32_t dst;
+ uint32_t dst;
- if (addr == 0)
- return (0);
+ if (addr == 0)
+ return (0);
- dst = htonl (addr);
- if (IN_CLASSA (dst))
- return (ntohl (IN_CLASSA_NET));
- if (IN_CLASSB (dst))
- return (ntohl (IN_CLASSB_NET));
- if (IN_CLASSC (dst))
- return (ntohl (IN_CLASSC_NET));
+ dst = htonl (addr);
+ if (IN_CLASSA (dst))
+ return (ntohl (IN_CLASSA_NET));
+ if (IN_CLASSB (dst))
+ return (ntohl (IN_CLASSB_NET));
+ if (IN_CLASSC (dst))
+ return (ntohl (IN_CLASSC_NET));
- return (0);
+ return (0);
}
char *hwaddr_ntoa (const unsigned char *hwaddr, size_t hwlen)
{
- static char buffer[(HWADDR_LEN * 3) + 1];
- char *p = buffer;
- size_t i;
+ static char buffer[(HWADDR_LEN * 3) + 1];
+ char *p = buffer;
+ size_t i;
- for (i = 0; i < hwlen && i < HWADDR_LEN; i++) {
- if (i > 0)
- *p ++= ':';
- p += snprintf (p, 3, "%.2x", hwaddr[i]);
- }
+ for (i = 0; i < hwlen && i < HWADDR_LEN; i++)
+ {
+ if (i > 0)
+ *p ++ = ':';
+ p += snprintf (p, 3, "%.2x", hwaddr[i]);
+ }
- *p ++= '\0';
+ *p ++ = '\0';
- return (buffer);
+ return (buffer);
}
size_t hwaddr_aton (unsigned char *buffer, const char *addr)
{
- char c[3];
- const char *p = addr;
- unsigned char *bp = buffer;
- size_t len = 0;
-
- c[2] = '\0';
- while (*p) {
- c[0] = *p++;
- c[1] = *p++;
- /* Ensure that next data is EOL or a seperator with data */
- if (! (*p == '\0' || (*p == ':' && *(p + 1) != '\0'))) {
- errno = EINVAL;
- return (0);
- }
- /* Ensure that digits are hex */
- if (isxdigit ((int) c[0]) == 0 || isxdigit ((int) c[1]) == 0) {
- errno = EINVAL;
- return (0);
- }
- p++;
- if (bp)
- *bp++ = (unsigned char) strtol (c, NULL, 16);
- else
- len++;
- }
-
- if (bp)
- return (bp - buffer);
- return (len);
+ char c[3];
+ const char *p = addr;
+ unsigned char *bp = buffer;
+ size_t len = 0;
+
+ c[2] = '\0';
+ while (*p)
+ {
+ c[0] = *p++;
+ c[1] = *p++;
+ /* Ensure that next data is EOL or a seperator with data */
+ if (! (*p == '\0' || (*p == ':' && *(p + 1) != '\0')))
+ {
+ errno = EINVAL;
+ return (0);
+ }
+ /* Ensure that digits are hex */
+ if (isxdigit ((int) c[0]) == 0 || isxdigit ((int) c[1]) == 0)
+ {
+ errno = EINVAL;
+ return (0);
+ }
+ p++;
+ if (bp)
+ *bp++ = (unsigned char) strtol (c, NULL, 16);
+ else
+ len++;
+ }
+
+ if (bp)
+ return (bp - buffer);
+ return (len);
}
static int _do_interface (const char *ifname,
- _unused unsigned char *hwaddr, _unused size_t *hwlen,
- struct in_addr *addr,
- bool flush, bool get)
+ _unused unsigned char *hwaddr, _unused size_t *hwlen,
+ struct in_addr *addr,
+ bool flush, bool get)
{
- int s;
- struct ifconf ifc;
- int retval = 0;
- int len = 10 * sizeof (struct ifreq);
- int lastlen = 0;
- char *p;
-
- if ((s = socket (AF_INET, SOCK_DGRAM, 0)) == -1) {
- logger (LOG_ERR, "socket: %s", strerror (errno));
- return -1;
- }
-
- /* Not all implementations return the needed buffer size for
- * SIOGIFCONF so we loop like so for all until it works */
- memset (&ifc, 0, sizeof (ifc));
- for (;;) {
- ifc.ifc_len = len;
- ifc.ifc_buf = xmalloc ((size_t) len);
- if (ioctl (s, SIOCGIFCONF, &ifc) == -1) {
- if (errno != EINVAL || lastlen != 0) {
- logger (LOG_ERR, "ioctl SIOCGIFCONF: %s",
- strerror (errno));
- close (s);
- free (ifc.ifc_buf);
- return -1;
- }
- } else {
- if (ifc.ifc_len == lastlen)
- break;
- lastlen = ifc.ifc_len;
- }
-
- free (ifc.ifc_buf);
- ifc.ifc_buf = NULL;
- len *= 2;
- }
-
- for (p = ifc.ifc_buf; p < ifc.ifc_buf + ifc.ifc_len;) {
- union {
- char *buffer;
- struct ifreq *ifr;
- } ifreqs;
- struct sockaddr_in address;
- struct ifreq *ifr;
-
- /* Cast the ifc buffer to an ifreq cleanly */
- ifreqs.buffer = p;
- ifr = ifreqs.ifr;
+ int s;
+ struct ifconf ifc;
+ int retval = 0;
+ int len = 10 * sizeof (struct ifreq);
+ int lastlen = 0;
+ char *p;
+
+ if ((s = socket (AF_INET, SOCK_DGRAM, 0)) == -1)
+ {
+ logger (LOG_ERR, "socket: %s", strerror (errno));
+ return -1;
+ }
+
+ /* Not all implementations return the needed buffer size for
+ * SIOGIFCONF so we loop like so for all until it works */
+ memset (&ifc, 0, sizeof (ifc));
+ for (;;)
+ {
+ ifc.ifc_len = len;
+ ifc.ifc_buf = xmalloc ((size_t) len);
+ if (ioctl (s, SIOCGIFCONF, &ifc) == -1)
+ {
+ if (errno != EINVAL || lastlen != 0)
+ {
+ logger (LOG_ERR, "ioctl SIOCGIFCONF: %s",
+ strerror (errno));
+ close (s);
+ free (ifc.ifc_buf);
+ return -1;
+ }
+ }
+ else
+ {
+ if (ifc.ifc_len == lastlen)
+ break;
+ lastlen = ifc.ifc_len;
+ }
+
+ free (ifc.ifc_buf);
+ ifc.ifc_buf = NULL;
+ len *= 2;
+ }
+
+ for (p = ifc.ifc_buf; p < ifc.ifc_buf + ifc.ifc_len;)
+ {
+ union
+ {
+ char *buffer;
+ struct ifreq *ifr;
+ } ifreqs;
+ struct sockaddr_in address;
+ struct ifreq *ifr;
+
+ /* Cast the ifc buffer to an ifreq cleanly */
+ ifreqs.buffer = p;
+ ifr = ifreqs.ifr;
#ifdef __linux__
- p += sizeof (*ifr);
+ p += sizeof (*ifr);
#else
- p += offsetof (struct ifreq, ifr_ifru) + ifr->ifr_addr.sa_len;
+ p += offsetof (struct ifreq, ifr_ifru) + ifr->ifr_addr.sa_len;
#endif
- if (strcmp (ifname, ifr->ifr_name) != 0)
- continue;
+ if (strcmp (ifname, ifr->ifr_name) != 0)
+ continue;
#ifdef AF_LINK
- if (hwaddr && hwlen && ifr->ifr_addr.sa_family == AF_LINK) {
- struct sockaddr_dl sdl;
-
- memcpy (&sdl, &ifr->ifr_addr, sizeof (sdl));
- *hwlen = sdl.sdl_alen;
- memcpy (hwaddr, sdl.sdl_data + sdl.sdl_nlen,
- (size_t) sdl.sdl_alen);
- retval = 1;
- break;
- }
+ if (hwaddr && hwlen && ifr->ifr_addr.sa_family == AF_LINK)
+ {
+ struct sockaddr_dl sdl;
+
+ memcpy (&sdl, &ifr->ifr_addr, sizeof (sdl));
+ *hwlen = sdl.sdl_alen;
+ memcpy (hwaddr, sdl.sdl_data + sdl.sdl_nlen,
+ (size_t) sdl.sdl_alen);
+ retval = 1;
+ break;
+ }
#endif
- if (ifr->ifr_addr.sa_family == AF_INET) {
- memcpy (&address, &ifr->ifr_addr, sizeof (address));
- if (flush) {
- struct sockaddr_in netmask;
-
- if (ioctl (s, SIOCGIFNETMASK, ifr) == -1) {
- logger (LOG_ERR,
- "ioctl SIOCGIFNETMASK: %s",
- strerror (errno));
- continue;
- }
- memcpy (&netmask, &ifr->ifr_addr,
- sizeof (netmask));
-
- if (del_address (ifname,
- address.sin_addr,
- netmask.sin_addr) == -1)
- retval = -1;
- } else if (get) {
- addr->s_addr = address.sin_addr.s_addr;
- retval = 1;
- break;
- } else if (address.sin_addr.s_addr == addr->s_addr) {
- retval = 1;
- break;
- }
- }
-
- }
-
- close (s);
- free (ifc.ifc_buf);
- return retval;
+ if (ifr->ifr_addr.sa_family == AF_INET)
+ {
+ memcpy (&address, &ifr->ifr_addr, sizeof (address));
+ if (flush)
+ {
+ struct sockaddr_in netmask;
+
+ if (ioctl (s, SIOCGIFNETMASK, ifr) == -1)
+ {
+ logger (LOG_ERR,
+ "ioctl SIOCGIFNETMASK: %s",
+ strerror (errno));
+ continue;
+ }
+ memcpy (&netmask, &ifr->ifr_addr,
+ sizeof (netmask));
+
+ if (del_address (ifname,
+ address.sin_addr,
+ netmask.sin_addr) == -1)
+ retval = -1;
+ }
+ else if (get)
+ {
+ addr->s_addr = address.sin_addr.s_addr;
+ retval = 1;
+ break;
+ }
+ else if (address.sin_addr.s_addr == addr->s_addr)
+ {
+ retval = 1;
+ break;
+ }
+ }
+
+ }
+
+ close (s);
+ free (ifc.ifc_buf);
+ return retval;
}
interface_t *read_interface (const char *ifname, _unused int metric)
{
- int s;
- struct ifreq ifr;
- interface_t *iface = NULL;
- unsigned char *hwaddr = NULL;
- size_t hwlen = 0;
- sa_family_t family = 0;
- unsigned short mtu;
+ int s;
+ struct ifreq ifr;
+ interface_t *iface = NULL;
+ unsigned char *hwaddr = NULL;
+ size_t hwlen = 0;
+ sa_family_t family = 0;
+ unsigned short mtu;
#ifdef __linux__
- char *p;
+ char *p;
#endif
- if (! ifname)
- return NULL;
+ if (! ifname)
+ return NULL;
- memset (&ifr, 0, sizeof (ifr));
- strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
+ memset (&ifr, 0, sizeof (ifr));
+ strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
- if ((s = socket (AF_INET, SOCK_DGRAM, 0)) == -1) {
- logger (LOG_ERR, "socket: %s", strerror (errno));
- return NULL;
- }
+ if ((s = socket (AF_INET, SOCK_DGRAM, 0)) == -1)
+ {
+ logger (LOG_ERR, "socket: %s", strerror (errno));
+ return NULL;
+ }
#ifdef __linux__
- strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
- if (ioctl (s, SIOCGIFHWADDR, &ifr) == -1) {
- logger (LOG_ERR, "ioctl SIOCGIFHWADDR: %s", strerror (errno));
- goto exit;
- }
-
- switch (ifr.ifr_hwaddr.sa_family) {
- case ARPHRD_ETHER:
- case ARPHRD_IEEE802:
- hwlen = ETHER_ADDR_LEN;
- break;
- case ARPHRD_IEEE1394:
- hwlen = EUI64_ADDR_LEN;
- case ARPHRD_INFINIBAND:
- hwlen = INFINIBAND_ADDR_LEN;
- break;
- default:
- logger (LOG_ERR,
- "interface is not Ethernet, FireWire, " \
- "InfiniBand or Token Ring");
- goto exit;
- }
-
- hwaddr = xmalloc (sizeof (unsigned char) * HWADDR_LEN);
- memcpy (hwaddr, ifr.ifr_hwaddr.sa_data, hwlen);
- family = ifr.ifr_hwaddr.sa_family;
+ strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
+ if (ioctl (s, SIOCGIFHWADDR, &ifr) == -1)
+ {
+ logger (LOG_ERR, "ioctl SIOCGIFHWADDR: %s", strerror (errno));
+ goto exit;
+ }
+
+ switch (ifr.ifr_hwaddr.sa_family)
+ {
+ case ARPHRD_ETHER:
+ case ARPHRD_IEEE802:
+ hwlen = ETHER_ADDR_LEN;
+ break;
+ case ARPHRD_IEEE1394:
+ hwlen = EUI64_ADDR_LEN;
+ case ARPHRD_INFINIBAND:
+ hwlen = INFINIBAND_ADDR_LEN;
+ break;
+ default:
+ logger (LOG_ERR,
+ "interface is not Ethernet, FireWire, " \
+ "InfiniBand or Token Ring");
+ goto exit;
+ }
+
+ hwaddr = xmalloc (sizeof (unsigned char) * HWADDR_LEN);
+ memcpy (hwaddr, ifr.ifr_hwaddr.sa_data, hwlen);
+ family = ifr.ifr_hwaddr.sa_family;
#else
- ifr.ifr_metric = metric;
- strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
- if (ioctl (s, SIOCSIFMETRIC, &ifr) == -1) {
- logger (LOG_ERR, "ioctl SIOCSIFMETRIC: %s", strerror (errno));
- goto exit;
- }
-
- hwaddr = xmalloc (sizeof (unsigned char) * HWADDR_LEN);
- if (_do_interface (ifname, hwaddr, &hwlen, NULL, false, false) != 1) {
- logger (LOG_ERR, "could not find interface %s", ifname);
- goto exit;
- }
-
- family = ARPHRD_ETHER;
+ ifr.ifr_metric = metric;
+ strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
+ if (ioctl (s, SIOCSIFMETRIC, &ifr) == -1)
+ {
+ logger (LOG_ERR, "ioctl SIOCSIFMETRIC: %s", strerror (errno));
+ goto exit;
+ }
+
+ hwaddr = xmalloc (sizeof (unsigned char) * HWADDR_LEN);
+ if (_do_interface (ifname, hwaddr, &hwlen, NULL, false, false) != 1)
+ {
+ logger (LOG_ERR, "could not find interface %s", ifname);
+ goto exit;
+ }
+
+ family = ARPHRD_ETHER;
#endif
- strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
- if (ioctl (s, SIOCGIFMTU, &ifr) == -1) {
- logger (LOG_ERR, "ioctl SIOCGIFMTU: %s", strerror (errno));
- goto exit;
- }
-
- if (ifr.ifr_mtu < MTU_MIN) {
- logger (LOG_DEBUG, "MTU of %d is too low, setting to %d",
- ifr.ifr_mtu, MTU_MIN);
- ifr.ifr_mtu = MTU_MIN;
- strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
- if (ioctl (s, SIOCSIFMTU, &ifr) == -1) {
- logger (LOG_ERR, "ioctl SIOCSIFMTU,: %s",
- strerror (errno));
- goto exit;
- }
- }
- mtu = ifr.ifr_mtu;
-
- strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
+ strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
+ if (ioctl (s, SIOCGIFMTU, &ifr) == -1)
+ {
+ logger (LOG_ERR, "ioctl SIOCGIFMTU: %s", strerror (errno));
+ goto exit;
+ }
+
+ if (ifr.ifr_mtu < MTU_MIN)
+ {
+ logger (LOG_DEBUG, "MTU of %d is too low, setting to %d",
+ ifr.ifr_mtu, MTU_MIN);
+ ifr.ifr_mtu = MTU_MIN;
+ strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
+ if (ioctl (s, SIOCSIFMTU, &ifr) == -1)
+ {
+ logger (LOG_ERR, "ioctl SIOCSIFMTU,: %s",
+ strerror (errno));
+ goto exit;
+ }
+ }
+ mtu = ifr.ifr_mtu;
+
+ strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
#ifdef __linux__
- /* We can only bring the real interface up */
- if ((p = strchr (ifr.ifr_name, ':')))
- *p = '\0';
+ /* We can only bring the real interface up */
+ if ((p = strchr (ifr.ifr_name, ':')))
+ * p = '\0';
#endif
- if (ioctl (s, SIOCGIFFLAGS, &ifr) == -1) {
- logger (LOG_ERR, "ioctl SIOCGIFFLAGS: %s", strerror (errno));
- goto exit;
- }
-
- if (! (ifr.ifr_flags & IFF_UP) || ! (ifr.ifr_flags & IFF_RUNNING)) {
- ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
- if (ioctl (s, SIOCSIFFLAGS, &ifr) != 0) {
- logger (LOG_ERR, "ioctl SIOCSIFFLAGS: %s",
- strerror (errno));
- goto exit;
- }
- }
-
- iface = xzalloc (sizeof (*iface));
- strlcpy (iface->name, ifname, IF_NAMESIZE);
+ if (ioctl (s, SIOCGIFFLAGS, &ifr) == -1)
+ {
+ logger (LOG_ERR, "ioctl SIOCGIFFLAGS: %s", strerror (errno));
+ goto exit;
+ }
+
+ if (! (ifr.ifr_flags & IFF_UP) || ! (ifr.ifr_flags & IFF_RUNNING))
+ {
+ ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
+ if (ioctl (s, SIOCSIFFLAGS, &ifr) != 0)
+ {
+ logger (LOG_ERR, "ioctl SIOCSIFFLAGS: %s",
+ strerror (errno));
+ goto exit;
+ }
+ }
+
+ iface = xzalloc (sizeof (*iface));
+ strlcpy (iface->name, ifname, IF_NAMESIZE);
#ifdef ENABLE_INFO
- snprintf (iface->infofile, PATH_MAX, INFOFILE, ifname);
+ snprintf (iface->infofile, PATH_MAX, INFOFILE, ifname);
#endif
- memcpy (&iface->hwaddr, hwaddr, hwlen);
- iface->hwlen = hwlen;
+ memcpy (&iface->hwaddr, hwaddr, hwlen);
+ iface->hwlen = hwlen;
- iface->family = family;
- iface->arpable = ! (ifr.ifr_flags & (IFF_NOARP | IFF_LOOPBACK));
- iface->mtu = iface->previous_mtu = mtu;
+ iface->family = family;
+ iface->arpable = ! (ifr.ifr_flags & (IFF_NOARP | IFF_LOOPBACK));
+ iface->mtu = iface->previous_mtu = mtu;
- logger (LOG_INFO, "hardware address = %s",
- hwaddr_ntoa (iface->hwaddr, iface->hwlen));
+ logger (LOG_INFO, "hardware address = %s",
+ hwaddr_ntoa (iface->hwaddr, iface->hwlen));
- /* 0 is a valid fd, so init to -1 */
- iface->fd = -1;
+ /* 0 is a valid fd, so init to -1 */
+ iface->fd = -1;
#ifdef __linux__
- iface->listen_fd = -1;
+ iface->listen_fd = -1;
#endif
exit:
- close (s);
- free (hwaddr);
- return iface;
+ close (s);
+ free (hwaddr);
+ return iface;
}
int get_mtu (const char *ifname)
{
- struct ifreq ifr;
- int r;
- int s;
-
- if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
- logger (LOG_ERR, "socket: %s", strerror (errno));
- return (-1);
- }
-
- memset (&ifr, 0, sizeof (ifr));
- strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
- r = ioctl (s, SIOCGIFMTU, &ifr);
- close (s);
-
- if (r == -1) {
- logger (LOG_ERR, "ioctl SIOCGIFMTU: %s", strerror (errno));
- return (-1);
- }
-
- return (ifr.ifr_mtu);
+ struct ifreq ifr;
+ int r;
+ int s;
+
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+ {
+ logger (LOG_ERR, "socket: %s", strerror (errno));
+ return (-1);
+ }
+
+ memset (&ifr, 0, sizeof (ifr));
+ strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
+ r = ioctl (s, SIOCGIFMTU, &ifr);
+ close (s);
+
+ if (r == -1)
+ {
+ logger (LOG_ERR, "ioctl SIOCGIFMTU: %s", strerror (errno));
+ return (-1);
+ }
+
+ return (ifr.ifr_mtu);
}
int set_mtu (const char *ifname, short int mtu)
{
- struct ifreq ifr;
- int r;
- int s;
-
- if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
- logger (LOG_ERR, "socket: %s", strerror (errno));
- return (-1);
- }
-
- memset (&ifr, 0, sizeof (ifr));
- logger (LOG_DEBUG, "setting MTU to %d", mtu);
- strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
- ifr.ifr_mtu = mtu;
- r = ioctl (s, SIOCSIFMTU, &ifr);
- close (s);
-
- if (r == -1)
- logger (LOG_ERR, "ioctl SIOCSIFMTU: %s", strerror (errno));
-
- return (r == 0 ? 0 : -1);
+ struct ifreq ifr;
+ int r;
+ int s;
+
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+ {
+ logger (LOG_ERR, "socket: %s", strerror (errno));
+ return (-1);
+ }
+
+ memset (&ifr, 0, sizeof (ifr));
+ logger (LOG_DEBUG, "setting MTU to %d", mtu);
+ strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
+ ifr.ifr_mtu = mtu;
+ r = ioctl (s, SIOCSIFMTU, &ifr);
+ close (s);
+
+ if (r == -1)
+ logger (LOG_ERR, "ioctl SIOCSIFMTU: %s", strerror (errno));
+
+ return (r == 0 ? 0 : -1);
}
static void log_route (struct in_addr destination,
- struct in_addr netmask,
- struct in_addr gateway,
- _unused int metric,
- int change, int del)
+ struct in_addr netmask,
+ struct in_addr gateway,
+ _unused int metric,
+ int change, int del)
{
- char *dstd = xstrdup (inet_ntoa (destination));
+ char *dstd = xstrdup (inet_ntoa (destination));
#ifdef __linux__
#define METRIC " metric %d"
@@ -502,34 +542,34 @@ static void log_route (struct in_addr destination,
#define METRIC ""
#endif
- if (gateway.s_addr == destination.s_addr ||
- gateway.s_addr == INADDR_ANY)
- logger (LOG_INFO, "%s route to %s/%d" METRIC,
- change ? "changing" : del ? "removing" : "adding",
- dstd, inet_ntocidr (netmask)
+ if (gateway.s_addr == destination.s_addr ||
+ gateway.s_addr == INADDR_ANY)
+ logger (LOG_INFO, "%s route to %s/%d" METRIC,
+ change ? "changing" : del ? "removing" : "adding",
+ dstd, inet_ntocidr (netmask)
#ifdef __linux__
- , metric
+ , metric
#endif
- );
- else if (destination.s_addr == INADDR_ANY)
- logger (LOG_INFO, "%s default route via %s" METRIC,
- change ? "changing" : del ? "removing" : "adding",
- inet_ntoa (gateway)
+ );
+ else if (destination.s_addr == INADDR_ANY)
+ logger (LOG_INFO, "%s default route via %s" METRIC,
+ change ? "changing" : del ? "removing" : "adding",
+ inet_ntoa (gateway)
#ifdef __linux__
- , metric
+ , metric
#endif
- );
- else
- logger (LOG_INFO, "%s route to %s/%d via %s" METRIC,
- change ? "changing" : del ? "removing" : "adding",
- dstd, inet_ntocidr (netmask), inet_ntoa (gateway)
+ );
+ else
+ logger (LOG_INFO, "%s route to %s/%d via %s" METRIC,
+ change ? "changing" : del ? "removing" : "adding",
+ dstd, inet_ntocidr (netmask), inet_ntoa (gateway)
#ifdef __linux__
- , metric
+ , metric
#endif
- );
+ );
- free (dstd);
+ free (dstd);
}
#if defined(BSD) || defined(__FreeBSD_kernel__)
@@ -543,22 +583,23 @@ static void log_route (struct in_addr destination,
#endif
static int do_address (const char *ifname, struct in_addr address,
- struct in_addr netmask, struct in_addr broadcast,
- int del)
+ struct in_addr netmask, struct in_addr broadcast,
+ int del)
{
- int s;
- struct ifaliasreq ifa;
+ int s;
+ struct ifaliasreq ifa;
- if (! ifname)
- return -1;
+ if (! ifname)
+ return -1;
- if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
- logger (LOG_ERR, "socket: %s", strerror (errno));
- return -1;
- }
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+ {
+ logger (LOG_ERR, "socket: %s", strerror (errno));
+ return -1;
+ }
- memset (&ifa, 0, sizeof (ifa));
- strlcpy (ifa.ifra_name, ifname, sizeof (ifa.ifra_name));
+ memset (&ifa, 0, sizeof (ifa));
+ strlcpy (ifa.ifra_name, ifname, sizeof (ifa.ifra_name));
#define ADDADDR(_var, _addr) { \
union { struct sockaddr *sa; struct sockaddr_in *sin; } _s; \
@@ -568,70 +609,73 @@ static int do_address (const char *ifname, struct in_addr address,
memcpy (&_s.sin->sin_addr, &_addr, sizeof (_s.sin->sin_addr)); \
}
- ADDADDR (ifa.ifra_addr, address);
- ADDADDR (ifa.ifra_mask, netmask);
-if (! del)
- ADDADDR (ifa.ifra_broadaddr, broadcast);
+ ADDADDR (ifa.ifra_addr, address);
+ ADDADDR (ifa.ifra_mask, netmask);
+ if (! del)
+ ADDADDR (ifa.ifra_broadaddr, broadcast);
#undef ADDADDR
- if (ioctl (s, del ? SIOCDIFADDR : SIOCAIFADDR, &ifa) == -1) {
- logger (LOG_ERR, "ioctl %s: %s",
- del ? "SIOCDIFADDR" : "SIOCAIFADDR",
- strerror (errno));
- close (s);
- return -1;
- }
-
-close (s);
-return 0;
+ if (ioctl (s, del ? SIOCDIFADDR : SIOCAIFADDR, &ifa) == -1)
+ {
+ logger (LOG_ERR, "ioctl %s: %s",
+ del ? "SIOCDIFADDR" : "SIOCAIFADDR",
+ strerror (errno));
+ close (s);
+ return -1;
+ }
+
+ close (s);
+ return 0;
}
static int do_route (const char *ifname,
- struct in_addr destination,
- struct in_addr netmask,
- struct in_addr gateway,
- int metric,
- int change, int del)
+ struct in_addr destination,
+ struct in_addr netmask,
+ struct in_addr gateway,
+ int metric,
+ int change, int del)
{
- int s;
- static int seq;
- union sockunion {
- struct sockaddr sa;
- struct sockaddr_in sin;
+ int s;
+ static int seq;
+ union sockunion
+ {
+ struct sockaddr sa;
+ struct sockaddr_in sin;
#ifdef INET6
- struct sockaddr_in6 sin6;
+ struct sockaddr_in6 sin6;
#endif
- struct sockaddr_dl sdl;
- struct sockaddr_storage ss;
- } su;
- struct rtm
- {
- struct rt_msghdr hdr;
- char buffer[sizeof (su) * 3];
- } rtm;
- char *bp = rtm.buffer;
- size_t l;
-
- if (! ifname)
- return -1;
-
- log_route (destination, netmask, gateway, metric, change, del);
-
- if ((s = socket (PF_ROUTE, SOCK_RAW, 0)) == -1) {
- logger (LOG_ERR, "socket: %s", strerror (errno));
- return -1;
- }
-
- memset (&rtm, 0, sizeof (rtm));
-
- rtm.hdr.rtm_version = RTM_VERSION;
- rtm.hdr.rtm_seq = ++seq;
- rtm.hdr.rtm_type = change ? RTM_CHANGE : del ? RTM_DELETE : RTM_ADD;
- rtm.hdr.rtm_flags = RTF_UP | RTF_STATIC;
-
- /* This order is important */
- rtm.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
+ struct sockaddr_dl sdl;
+ struct sockaddr_storage ss;
+ } su;
+ struct rtm
+ {
+ struct rt_msghdr hdr;
+ char buffer[sizeof (su) * 3];
+ } rtm;
+ char *bp = rtm.buffer;
+ size_t l;
+
+ if (! ifname)
+ return -1;
+
+ log_route (destination, netmask, gateway, metric, change, del);
+
+ if ((s = socket (PF_ROUTE, SOCK_RAW, 0)) == -1)
+ {
+ logger (LOG_ERR, "socket: %s", strerror (errno));
+ return -1;
+ }
+
+ memset (&rtm, 0, sizeof (rtm));
+
+ rtm.hdr.rtm_version = RTM_VERSION;
+ rtm.hdr.rtm_seq = ++seq;
+ rtm.hdr.rtm_type = change ? RTM_CHANGE : del ? RTM_DELETE : RTM_ADD;
+ rtm.hdr.rtm_flags = RTF_UP | RTF_STATIC;
+
+ /* This order is important */
+ rtm.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
#define ADDADDR(_addr) \
memset (&su, 0, sizeof (su)); \
@@ -642,52 +686,55 @@ static int do_route (const char *ifname,
memcpy (bp, &(su), l); \
bp += l;
- ADDADDR (destination);
-
- if (netmask.s_addr == INADDR_BROADCAST ||
- gateway.s_addr == INADDR_ANY)
- {
- /* Make us a link layer socket */
- unsigned char *hwaddr;
- size_t hwlen = 0;
-
- if (netmask.s_addr == INADDR_BROADCAST)
- rtm.hdr.rtm_flags |= RTF_HOST;
-
- hwaddr = xmalloc (sizeof (unsigned char) * HWADDR_LEN);
- _do_interface (ifname, hwaddr, &hwlen, NULL, false, false);
- memset (&su, 0, sizeof (su));
- su.sdl.sdl_len = sizeof (su.sdl);
- su.sdl.sdl_family = AF_LINK;
- su.sdl.sdl_nlen = strlen (ifname);
- memcpy (&su.sdl.sdl_data, ifname, (size_t) su.sdl.sdl_nlen);
- su.sdl.sdl_alen = hwlen;
- memcpy (((unsigned char *) &su.sdl.sdl_data) + su.sdl.sdl_nlen,
- hwaddr, (size_t) su.sdl.sdl_alen);
-
- l = SA_SIZE (&(su.sa));
- memcpy (bp, &su, l);
- bp += l;
- free (hwaddr);
- } else {
- rtm.hdr.rtm_flags |= RTF_GATEWAY;
- ADDADDR (gateway);
- }
-
- ADDADDR (netmask);
+ ADDADDR (destination);
+
+ if (netmask.s_addr == INADDR_BROADCAST ||
+ gateway.s_addr == INADDR_ANY)
+ {
+ /* Make us a link layer socket */
+ unsigned char *hwaddr;
+ size_t hwlen = 0;
+
+ if (netmask.s_addr == INADDR_BROADCAST)
+ rtm.hdr.rtm_flags |= RTF_HOST;
+
+ hwaddr = xmalloc (sizeof (unsigned char) * HWADDR_LEN);
+ _do_interface (ifname, hwaddr, &hwlen, NULL, false, false);
+ memset (&su, 0, sizeof (su));
+ su.sdl.sdl_len = sizeof (su.sdl);
+ su.sdl.sdl_family = AF_LINK;
+ su.sdl.sdl_nlen = strlen (ifname);
+ memcpy (&su.sdl.sdl_data, ifname, (size_t) su.sdl.sdl_nlen);
+ su.sdl.sdl_alen = hwlen;
+ memcpy (((unsigned char *) &su.sdl.sdl_data) + su.sdl.sdl_nlen,
+ hwaddr, (size_t) su.sdl.sdl_alen);
+
+ l = SA_SIZE (&(su.sa));
+ memcpy (bp, &su, l);
+ bp += l;
+ free (hwaddr);
+ }
+ else
+ {
+ rtm.hdr.rtm_flags |= RTF_GATEWAY;
+ ADDADDR (gateway);
+ }
+
+ ADDADDR (netmask);
#undef ADDADDR
- rtm.hdr.rtm_msglen = l = bp - (char *)&rtm;
- if (write (s, &rtm, l) == -1) {
- /* Don't report error about routes already existing */
- if (errno != EEXIST)
- logger (LOG_ERR, "write: %s", strerror (errno));
- close (s);
- return -1;
- }
-
- close (s);
- return 0;
+ rtm.hdr.rtm_msglen = l = bp - (char *)&rtm;
+ if (write (s, &rtm, l) == -1)
+ {
+ /* Don't report error about routes already existing */
+ if (errno != EEXIST)
+ logger (LOG_ERR, "write: %s", strerror (errno));
+ close (s);
+ return -1;
+ }
+
+ close (s);
+ return 0;
}
#elif __linux__
@@ -698,363 +745,381 @@ static int do_route (const char *ifname,
#define BUFFERLEN 256
int send_netlink (struct nlmsghdr *hdr, netlink_callback callback, void *arg)
{
- int s;
- pid_t mypid = getpid ();
- struct sockaddr_nl nl;
- struct iovec iov;
- struct msghdr msg;
- static unsigned int seq;
- char *buffer;
- ssize_t bytes;
- union
- {
- char *buffer;
- struct nlmsghdr *nlm;
- } h;
-
- if ((s = socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1) {
- logger (LOG_ERR, "socket: %s", strerror (errno));
- return -1;
- }
-
- memset (&nl, 0, sizeof (nl));
- nl.nl_family = AF_NETLINK;
- if (bind (s, (struct sockaddr *) &nl, sizeof (nl)) == -1) {
- logger (LOG_ERR, "bind: %s", strerror (errno));
- close (s);
- return -1;
- }
-
- memset (&iov, 0, sizeof (iov));
- iov.iov_base = hdr;
- iov.iov_len = hdr->nlmsg_len;
-
- memset (&msg, 0, sizeof (msg));
- msg.msg_name = &nl;
- msg.msg_namelen = sizeof (nl);
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
-
- /* Request a reply */
- hdr->nlmsg_flags |= NLM_F_ACK;
- hdr->nlmsg_seq = ++seq;
-
- if (sendmsg (s, &msg, 0) == -1) {
- logger (LOG_ERR, "write: %s", strerror (errno));
- close (s);
- return -1;
- }
-
- buffer = xzalloc (sizeof (char) * BUFFERLEN);
- iov.iov_base = buffer;
-
- for (;;) {
- iov.iov_len = BUFFERLEN;
- bytes = recvmsg (s, &msg, 0);
-
- if (bytes == -1) {
- if (errno != EINTR)
- logger (LOG_ERR, "recvmsg: %s",
- strerror (errno));
- continue;
- }
-
- if (bytes == 0) {
- logger (LOG_ERR, "netlink: EOF");
- goto eexit;
- }
-
- if (msg.msg_namelen != sizeof (nl)) {
- logger (LOG_ERR,
- "netlink: sender address length mismatch");
- goto eexit;
- }
-
- for (h.buffer = buffer; bytes >= (signed) sizeof (*h.nlm); ) {
- int len = h.nlm->nlmsg_len;
- int l = len - sizeof (*h.nlm);
- struct nlmsgerr *err = (struct nlmsgerr *) NLMSG_DATA (h.nlm);
-
- if (l < 0 || len > bytes) {
- if (msg.msg_flags & MSG_TRUNC)
- logger (LOG_ERR, "netlink: truncated message");
- else
- logger (LOG_ERR, "netlink: malformed message");
- goto eexit;
- }
-
- /* Ensure it's our message */
- if (nl.nl_pid != 0 ||
- (pid_t) h.nlm->nlmsg_pid != mypid ||
- h.nlm->nlmsg_seq != seq)
- {
- /* Next Message */
- bytes -= NLMSG_ALIGN (len);
- h.buffer += NLMSG_ALIGN (len);
- continue;
- }
-
- /* We get an NLMSG_ERROR back with a code of zero for success */
- if (h.nlm->nlmsg_type != NLMSG_ERROR) {
- logger (LOG_ERR, "netlink: unexpected reply %d",
- h.nlm->nlmsg_type);
- goto eexit;
- }
-
- if ((unsigned) l < sizeof (*err)) {
- logger (LOG_ERR, "netlink: error truncated");
- goto eexit;
- }
-
- if (err->error == 0) {
- int retval = 0;
-
- close (s);
- if (callback) {
- if ((retval = callback (hdr, arg)) == -1)
- logger (LOG_ERR, "netlink: callback failed");
- }
- free (buffer);
- return (retval);
- }
-
- errno = -err->error;
- /* Don't report on something already existing */
- if (errno != EEXIST)
- logger (LOG_ERR, "netlink: %s",
- strerror (errno));
- goto eexit;
- }
- }
+ int s;
+ pid_t mypid = getpid ();
+ struct sockaddr_nl nl;
+ struct iovec iov;
+ struct msghdr msg;
+ static unsigned int seq;
+ char *buffer;
+ ssize_t bytes;
+ union
+ {
+ char *buffer;
+ struct nlmsghdr *nlm;
+ } h;
+
+ if ((s = socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1)
+ {
+ logger (LOG_ERR, "socket: %s", strerror (errno));
+ return -1;
+ }
+
+ memset (&nl, 0, sizeof (nl));
+ nl.nl_family = AF_NETLINK;
+ if (bind (s, (struct sockaddr *) &nl, sizeof (nl)) == -1)
+ {
+ logger (LOG_ERR, "bind: %s", strerror (errno));
+ close (s);
+ return -1;
+ }
+
+ memset (&iov, 0, sizeof (iov));
+ iov.iov_base = hdr;
+ iov.iov_len = hdr->nlmsg_len;
+
+ memset (&msg, 0, sizeof (msg));
+ msg.msg_name = &nl;
+ msg.msg_namelen = sizeof (nl);
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+
+ /* Request a reply */
+ hdr->nlmsg_flags |= NLM_F_ACK;
+ hdr->nlmsg_seq = ++seq;
+
+ if (sendmsg (s, &msg, 0) == -1)
+ {
+ logger (LOG_ERR, "write: %s", strerror (errno));
+ close (s);
+ return -1;
+ }
+
+ buffer = xzalloc (sizeof (char) * BUFFERLEN);
+ iov.iov_base = buffer;
+
+ for (;;)
+ {
+ iov.iov_len = BUFFERLEN;
+ bytes = recvmsg (s, &msg, 0);
+
+ if (bytes == -1)
+ {
+ if (errno != EINTR)
+ logger (LOG_ERR, "recvmsg: %s",
+ strerror (errno));
+ continue;
+ }
+
+ if (bytes == 0)
+ {
+ logger (LOG_ERR, "netlink: EOF");
+ goto eexit;
+ }
+
+ if (msg.msg_namelen != sizeof (nl))
+ {
+ logger (LOG_ERR,
+ "netlink: sender address length mismatch");
+ goto eexit;
+ }
+
+ for (h.buffer = buffer; bytes >= (signed) sizeof (*h.nlm); )
+ {
+ int len = h.nlm->nlmsg_len;
+ int l = len - sizeof (*h.nlm);
+ struct nlmsgerr *err = (struct nlmsgerr *) NLMSG_DATA (h.nlm);
+
+ if (l < 0 || len > bytes)
+ {
+ if (msg.msg_flags & MSG_TRUNC)
+ logger (LOG_ERR, "netlink: truncated message");
+ else
+ logger (LOG_ERR, "netlink: malformed message");
+ goto eexit;
+ }
+
+ /* Ensure it's our message */
+ if (nl.nl_pid != 0 ||
+ (pid_t) h.nlm->nlmsg_pid != mypid ||
+ h.nlm->nlmsg_seq != seq)
+ {
+ /* Next Message */
+ bytes -= NLMSG_ALIGN (len);
+ h.buffer += NLMSG_ALIGN (len);
+ continue;
+ }
+
+ /* We get an NLMSG_ERROR back with a code of zero for success */
+ if (h.nlm->nlmsg_type != NLMSG_ERROR)
+ {
+ logger (LOG_ERR, "netlink: unexpected reply %d",
+ h.nlm->nlmsg_type);
+ goto eexit;
+ }
+
+ if ((unsigned) l < sizeof (*err))
+ {
+ logger (LOG_ERR, "netlink: error truncated");
+ goto eexit;
+ }
+
+ if (err->error == 0)
+ {
+ int retval = 0;
+
+ close (s);
+ if (callback)
+ {
+ if ((retval = callback (hdr, arg)) == -1)
+ logger (LOG_ERR, "netlink: callback failed");
+ }
+ free (buffer);
+ return (retval);
+ }
+
+ errno = -err->error;
+ /* Don't report on something already existing */
+ if (errno != EEXIST)
+ logger (LOG_ERR, "netlink: %s",
+ strerror (errno));
+ goto eexit;
+ }
+ }
eexit:
- close (s);
- free (buffer);
- return -1;
+ close (s);
+ free (buffer);
+ return -1;
}
#define NLMSG_TAIL(nmsg) \
((struct rtattr *) (((ptrdiff_t) (nmsg)) + NLMSG_ALIGN ((nmsg)->nlmsg_len)))
static int add_attr_l(struct nlmsghdr *n, unsigned int maxlen, int type,
- const void *data, int alen)
+ const void *data, int alen)
{
- int len = RTA_LENGTH(alen);
- struct rtattr *rta;
-
- if (NLMSG_ALIGN (n->nlmsg_len) + RTA_ALIGN (len) > maxlen) {
- logger (LOG_ERR, "add_attr_l: message exceeded bound of %d\n",
- maxlen);
- return -1;
- }
-
- rta = NLMSG_TAIL (n);
- rta->rta_type = type;
- rta->rta_len = len;
- memcpy (RTA_DATA (rta), data, alen);
- n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + RTA_ALIGN (len);
-
- return 0;
+ int len = RTA_LENGTH(alen);
+ struct rtattr *rta;
+
+ if (NLMSG_ALIGN (n->nlmsg_len) + RTA_ALIGN (len) > maxlen)
+ {
+ logger (LOG_ERR, "add_attr_l: message exceeded bound of %d\n",
+ maxlen);
+ return -1;
+ }
+
+ rta = NLMSG_TAIL (n);
+ rta->rta_type = type;
+ rta->rta_len = len;
+ memcpy (RTA_DATA (rta), data, alen);
+ n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + RTA_ALIGN (len);
+
+ return 0;
}
static int add_attr_32(struct nlmsghdr *n, unsigned int maxlen, int type,
- uint32_t data)
+ uint32_t data)
{
- int len = RTA_LENGTH (sizeof (data));
- struct rtattr *rta;
-
- if (NLMSG_ALIGN (n->nlmsg_len) + len > maxlen) {
- logger (LOG_ERR, "add_attr32: message exceeded bound of %d\n",
- maxlen);
- return -1;
- }
-
- rta = NLMSG_TAIL (n);
- rta->rta_type = type;
- rta->rta_len = len;
- memcpy (RTA_DATA (rta), &data, sizeof (data));
- n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + len;
-
- return 0;
+ int len = RTA_LENGTH (sizeof (data));
+ struct rtattr *rta;
+
+ if (NLMSG_ALIGN (n->nlmsg_len) + len > maxlen)
+ {
+ logger (LOG_ERR, "add_attr32: message exceeded bound of %d\n",
+ maxlen);
+ return -1;
+ }
+
+ rta = NLMSG_TAIL (n);
+ rta->rta_type = type;
+ rta->rta_len = len;
+ memcpy (RTA_DATA (rta), &data, sizeof (data));
+ n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + len;
+
+ return 0;
}
struct nlma
{
- struct nlmsghdr hdr;
- struct ifaddrmsg ifa;
- char buffer[64];
+ struct nlmsghdr hdr;
+ struct ifaddrmsg ifa;
+ char buffer[64];
};
struct nlmr
{
- struct nlmsghdr hdr;
- struct rtmsg rt;
- char buffer[256];
+ struct nlmsghdr hdr;
+ struct rtmsg rt;
+ char buffer[256];
};
static int do_address(const char *ifname,
- struct in_addr address, struct in_addr netmask,
- struct in_addr broadcast, int del)
+ struct in_addr address, struct in_addr netmask,
+ struct in_addr broadcast, int del)
{
- struct nlma *nlm;
- int retval;
-
- if (!ifname)
- return -1;
-
- nlm = xzalloc (sizeof (*nlm));
- nlm->hdr.nlmsg_len = NLMSG_LENGTH (sizeof (struct ifaddrmsg));
- nlm->hdr.nlmsg_flags = NLM_F_REQUEST;
- if (! del)
- nlm->hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE;
- nlm->hdr.nlmsg_type = del ? RTM_DELADDR : RTM_NEWADDR;
- if (! (nlm->ifa.ifa_index = if_nametoindex (ifname))) {
- logger (LOG_ERR, "if_nametoindex: no index for interface `%s'",
- ifname);
- free (nlm);
- return -1;
- }
- nlm->ifa.ifa_family = AF_INET;
-
- nlm->ifa.ifa_prefixlen = inet_ntocidr (netmask);
-
- /* This creates the aliased interface */
- add_attr_l (&nlm->hdr, sizeof (*nlm), IFA_LABEL,
- ifname, strlen (ifname) + 1);
-
- add_attr_l (&nlm->hdr, sizeof (*nlm), IFA_LOCAL,
- &address.s_addr, sizeof (address.s_addr));
- if (! del)
- add_attr_l (&nlm->hdr, sizeof (*nlm), IFA_BROADCAST,
- &broadcast.s_addr, sizeof (broadcast.s_addr));
-
- retval = send_netlink (&nlm->hdr, NULL, NULL);
- free (nlm);
- return retval;
+ struct nlma *nlm;
+ int retval;
+
+ if (!ifname)
+ return -1;
+
+ nlm = xzalloc (sizeof (*nlm));
+ nlm->hdr.nlmsg_len = NLMSG_LENGTH (sizeof (struct ifaddrmsg));
+ nlm->hdr.nlmsg_flags = NLM_F_REQUEST;
+ if (! del)
+ nlm->hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE;
+ nlm->hdr.nlmsg_type = del ? RTM_DELADDR : RTM_NEWADDR;
+ if (! (nlm->ifa.ifa_index = if_nametoindex (ifname)))
+ {
+ logger (LOG_ERR, "if_nametoindex: no index for interface `%s'",
+ ifname);
+ free (nlm);
+ return -1;
+ }
+ nlm->ifa.ifa_family = AF_INET;
+
+ nlm->ifa.ifa_prefixlen = inet_ntocidr (netmask);
+
+ /* This creates the aliased interface */
+ add_attr_l (&nlm->hdr, sizeof (*nlm), IFA_LABEL,
+ ifname, strlen (ifname) + 1);
+
+ add_attr_l (&nlm->hdr, sizeof (*nlm), IFA_LOCAL,
+ &address.s_addr, sizeof (address.s_addr));
+ if (! del)
+ add_attr_l (&nlm->hdr, sizeof (*nlm), IFA_BROADCAST,
+ &broadcast.s_addr, sizeof (broadcast.s_addr));
+
+ retval = send_netlink (&nlm->hdr, NULL, NULL);
+ free (nlm);
+ return retval;
}
static int do_route (const char *ifname,
- struct in_addr destination,
- struct in_addr netmask,
- struct in_addr gateway,
- int metric, int change, int del)
+ struct in_addr destination,
+ struct in_addr netmask,
+ struct in_addr gateway,
+ int metric, int change, int del)
{
- struct nlmr *nlm;
- unsigned int ifindex;
- int retval;
-
- if (! ifname)
- return -1;
-
- log_route (destination, netmask, gateway, metric, change, del);
-
- if (! (ifindex = if_nametoindex (ifname))) {
- logger (LOG_ERR, "if_nametoindex: no index for interface `%s'",
- ifname);
- return -1;
- }
-
- nlm = xzalloc (sizeof (*nlm));
- nlm->hdr.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg));
- if (change)
- nlm->hdr.nlmsg_flags = NLM_F_REPLACE;
- else if (! del)
- nlm->hdr.nlmsg_flags = NLM_F_CREATE | NLM_F_EXCL;
- nlm->hdr.nlmsg_flags |= NLM_F_REQUEST;
- nlm->hdr.nlmsg_type = del ? RTM_DELROUTE : RTM_NEWROUTE;
- nlm->rt.rtm_family = AF_INET;
- nlm->rt.rtm_table = RT_TABLE_MAIN;
-
- if (del)
- nlm->rt.rtm_scope = RT_SCOPE_NOWHERE;
- else {
- nlm->hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
- nlm->rt.rtm_protocol = RTPROT_BOOT;
- if (netmask.s_addr == INADDR_BROADCAST ||
- gateway.s_addr == INADDR_ANY)
- nlm->rt.rtm_scope = RT_SCOPE_LINK;
- else
- nlm->rt.rtm_scope = RT_SCOPE_UNIVERSE;
- nlm->rt.rtm_type = RTN_UNICAST;
- }
-
- nlm->rt.rtm_dst_len = inet_ntocidr (netmask);
- add_attr_l (&nlm->hdr, sizeof (*nlm), RTA_DST,
- &destination.s_addr, sizeof (destination.s_addr));
- if (netmask.s_addr != INADDR_BROADCAST &&
- destination.s_addr != gateway.s_addr)
- add_attr_l (&nlm->hdr, sizeof (*nlm), RTA_GATEWAY,
- &gateway.s_addr, sizeof (gateway.s_addr));
-
- add_attr_32 (&nlm->hdr, sizeof (*nlm), RTA_OIF, ifindex);
- add_attr_32 (&nlm->hdr, sizeof (*nlm), RTA_PRIORITY, metric);
-
- retval = send_netlink (&nlm->hdr, NULL, NULL);
- free (nlm);
- return retval;
+ struct nlmr *nlm;
+ unsigned int ifindex;
+ int retval;
+
+ if (! ifname)
+ return -1;
+
+ log_route (destination, netmask, gateway, metric, change, del);
+
+ if (! (ifindex = if_nametoindex (ifname)))
+ {
+ logger (LOG_ERR, "if_nametoindex: no index for interface `%s'",
+ ifname);
+ return -1;
+ }
+
+ nlm = xzalloc (sizeof (*nlm));
+ nlm->hdr.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg));
+ if (change)
+ nlm->hdr.nlmsg_flags = NLM_F_REPLACE;
+ else if (! del)
+ nlm->hdr.nlmsg_flags = NLM_F_CREATE | NLM_F_EXCL;
+ nlm->hdr.nlmsg_flags |= NLM_F_REQUEST;
+ nlm->hdr.nlmsg_type = del ? RTM_DELROUTE : RTM_NEWROUTE;
+ nlm->rt.rtm_family = AF_INET;
+ nlm->rt.rtm_table = RT_TABLE_MAIN;
+
+ if (del)
+ nlm->rt.rtm_scope = RT_SCOPE_NOWHERE;
+ else
+ {
+ nlm->hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
+ nlm->rt.rtm_protocol = RTPROT_BOOT;
+ if (netmask.s_addr == INADDR_BROADCAST ||
+ gateway.s_addr == INADDR_ANY)
+ nlm->rt.rtm_scope = RT_SCOPE_LINK;
+ else
+ nlm->rt.rtm_scope = RT_SCOPE_UNIVERSE;
+ nlm->rt.rtm_type = RTN_UNICAST;
+ }
+
+ nlm->rt.rtm_dst_len = inet_ntocidr (netmask);
+ add_attr_l (&nlm->hdr, sizeof (*nlm), RTA_DST,
+ &destination.s_addr, sizeof (destination.s_addr));
+ if (netmask.s_addr != INADDR_BROADCAST &&
+ destination.s_addr != gateway.s_addr)
+ add_attr_l (&nlm->hdr, sizeof (*nlm), RTA_GATEWAY,
+ &gateway.s_addr, sizeof (gateway.s_addr));
+
+ add_attr_32 (&nlm->hdr, sizeof (*nlm), RTA_OIF, ifindex);
+ add_attr_32 (&nlm->hdr, sizeof (*nlm), RTA_PRIORITY, metric);
+
+ retval = send_netlink (&nlm->hdr, NULL, NULL);
+ free (nlm);
+ return retval;
}
#else
- #error "Platform not supported!"
- #error "We currently support BPF and Linux sockets."
- #error "Other platforms may work using BPF. If yours does, please let me know"
- #error "so I can add it to our list."
+#error "Platform not supported!"
+#error "We currently support BPF and Linux sockets."
+#error "Other platforms may work using BPF. If yours does, please let me know"
+#error "so I can add it to our list."
#endif
int add_address (const char *ifname, struct in_addr address,
- struct in_addr netmask, struct in_addr broadcast)
+ struct in_addr netmask, struct in_addr broadcast)
{
- logger (LOG_INFO, "adding IP address %s/%d",
- inet_ntoa (address), inet_ntocidr (netmask));
+ logger (LOG_INFO, "adding IP address %s/%d",
+ inet_ntoa (address), inet_ntocidr (netmask));
- return (do_address (ifname, address, netmask, broadcast, 0));
+ return (do_address (ifname, address, netmask, broadcast, 0));
}
int del_address (const char *ifname,
- struct in_addr address, struct in_addr netmask)
+ struct in_addr address, struct in_addr netmask)
{
- struct in_addr t;
+ struct in_addr t;
- logger (LOG_INFO, "removing IP address %s/%d",
- inet_ntoa (address), inet_ntocidr (netmask));
+ logger (LOG_INFO, "removing IP address %s/%d",
+ inet_ntoa (address), inet_ntocidr (netmask));
- memset (&t, 0, sizeof (t));
- return (do_address (ifname, address, netmask, t, 1));
+ memset (&t, 0, sizeof (t));
+ return (do_address (ifname, address, netmask, t, 1));
}
int add_route (const char *ifname, struct in_addr destination,
- struct in_addr netmask, struct in_addr gateway, int metric)
+ struct in_addr netmask, struct in_addr gateway, int metric)
{
- return (do_route (ifname, destination, netmask, gateway, metric, 0, 0));
+ return (do_route (ifname, destination, netmask, gateway, metric, 0, 0));
}
int change_route (const char *ifname, struct in_addr destination,
- struct in_addr netmask, struct in_addr gateway, int metric)
+ struct in_addr netmask, struct in_addr gateway, int metric)
{
- return (do_route (ifname, destination, netmask, gateway, metric, 1, 0));
+ return (do_route (ifname, destination, netmask, gateway, metric, 1, 0));
}
int del_route (const char *ifname, struct in_addr destination,
- struct in_addr netmask, struct in_addr gateway, int metric)
+ struct in_addr netmask, struct in_addr gateway, int metric)
{
- return (do_route (ifname, destination, netmask, gateway, metric, 0, 1));
+ return (do_route (ifname, destination, netmask, gateway, metric, 0, 1));
}
int flush_addresses (const char *ifname)
{
- return (_do_interface (ifname, NULL, NULL, NULL, true, false));
+ return (_do_interface (ifname, NULL, NULL, NULL, true, false));
}
in_addr_t get_address (const char *ifname)
{
- struct in_addr address;
- if (_do_interface (ifname, NULL, NULL, &address, false, true) > 0)
- return (address.s_addr);
- return (0);
+ struct in_addr address;
+ if (_do_interface (ifname, NULL, NULL, &address, false, true) > 0)
+ return (address.s_addr);
+ return (0);
}
int has_address (const char *ifname, struct in_addr address)
{
- return (_do_interface (ifname, NULL, NULL, &address, false, false));
+ return (_do_interface (ifname, NULL, NULL, &address, false, false));
}
diff --git a/src/customdhcpcd/interface.h b/src/customdhcpcd/interface.h
index 8215d48..8431080 100644
--- a/src/customdhcpcd/interface.h
+++ b/src/customdhcpcd/interface.h
@@ -1,4 +1,4 @@
-/*
+/*
* dhcpcd - DHCP client daemon
* Copyright 2006-2008 Roy Marples <roy@marples.name>
* All rights reserved
@@ -93,48 +93,48 @@
typedef struct route_t
{
- struct in_addr destination;
- struct in_addr netmask;
- struct in_addr gateway;
- STAILQ_ENTRY (route_t) entries;
+ struct in_addr destination;
+ struct in_addr netmask;
+ struct in_addr gateway;
+ STAILQ_ENTRY (route_t) entries;
} route_t;
STAILQ_HEAD (route_head, route_t);
typedef struct address_t
{
- struct in_addr address;
- STAILQ_ENTRY (address_t) entries;
+ struct in_addr address;
+ STAILQ_ENTRY (address_t) entries;
} address_t;
STAILQ_HEAD (address_head, address_t);
typedef struct interface_t
{
- char name[IF_NAMESIZE];
- sa_family_t family;
- unsigned char hwaddr[HWADDR_LEN];
- size_t hwlen;
- bool arpable;
- unsigned short mtu;
+ char name[IF_NAMESIZE];
+ sa_family_t family;
+ unsigned char hwaddr[HWADDR_LEN];
+ size_t hwlen;
+ bool arpable;
+ unsigned short mtu;
- int fd;
- size_t buffer_length;
+ int fd;
+ size_t buffer_length;
#ifdef __linux__
- int listen_fd;
- int socket_protocol;
+ int listen_fd;
+ int socket_protocol;
#endif
- char infofile[PATH_MAX];
+ char infofile[PATH_MAX];
- unsigned short previous_mtu;
- struct in_addr previous_address;
- struct in_addr previous_netmask;
- struct route_head *previous_routes;
+ unsigned short previous_mtu;
+ struct in_addr previous_address;
+ struct in_addr previous_netmask;
+ struct route_head *previous_routes;
- time_t start_uptime;
+ time_t start_uptime;
- unsigned char *clientid;
- size_t clientid_len;
+ unsigned char *clientid;
+ size_t clientid_len;
} interface_t;
void free_address (struct address_head *addresses);
@@ -148,20 +148,20 @@ int get_mtu (const char *ifname);
int set_mtu (const char *ifname, short int mtu);
int add_address (const char *ifname, struct in_addr address,
- struct in_addr netmask, struct in_addr broadcast);
+ struct in_addr netmask, struct in_addr broadcast);
int del_address (const char *ifname, struct in_addr address,
- struct in_addr netmask);
+ struct in_addr netmask);
int flush_addresses (const char *ifname);
in_addr_t get_address (const char *ifname);
int has_address (const char *ifname, struct in_addr address);
int add_route (const char *ifname, struct in_addr destination,
- struct in_addr netmask, struct in_addr gateway, int metric);
+ struct in_addr netmask, struct in_addr gateway, int metric);
int change_route (const char *ifname, struct in_addr destination,
- struct in_addr netmask, struct in_addr gateway, int metric);
+ struct in_addr netmask, struct in_addr gateway, int metric);
int del_route (const char *ifname, struct in_addr destination,
- struct in_addr netmask, struct in_addr gateway, int metric);
+ struct in_addr netmask, struct in_addr gateway, int metric);
int inet_ntocidr (struct in_addr address);
int inet_cidrtoaddr (int cidr, struct in_addr *addr);
diff --git a/src/customdhcpcd/ipv4ll.c b/src/customdhcpcd/ipv4ll.c
index 9742b9a..c8ce8b8 100644
--- a/src/customdhcpcd/ipv4ll.c
+++ b/src/customdhcpcd/ipv4ll.c
@@ -1,4 +1,4 @@
-/*
+/*
* dhcpcd - DHCP client daemon
* Copyright 2006-2008 Roy Marples <roy@marples.name>
* All rights reserved
@@ -35,36 +35,38 @@
#ifdef ENABLE_IPV4LL
#ifndef ENABLE_ARP
- # error IPV4LL requires ARP
+# error IPV4LL requires ARP
#endif
-#define IPV4LL_LEASETIME 20
+#define IPV4LL_LEASETIME 20
-int ipv4ll_get_address (interface_t *iface, dhcp_t *dhcp) {
- struct in_addr addr;
+int ipv4ll_get_address (interface_t *iface, dhcp_t *dhcp)
+{
+ struct in_addr addr;
- for (;;) {
- addr.s_addr = htonl (LINKLOCAL_ADDR |
- (((uint32_t) abs ((int) random ())
- % 0xFD00) + 0x0100));
- errno = 0;
- if (! arp_claim (iface, addr))
- break;
- /* Our ARP may have been interrupted */
- if (errno)
- return (-1);
- }
+ for (;;)
+ {
+ addr.s_addr = htonl (LINKLOCAL_ADDR |
+ (((uint32_t) abs ((int) random ())
+ % 0xFD00) + 0x0100));
+ errno = 0;
+ if (! arp_claim (iface, addr))
+ break;
+ /* Our ARP may have been interrupted */
+ if (errno)
+ return (-1);
+ }
- dhcp->address.s_addr = addr.s_addr;
- dhcp->netmask.s_addr = htonl (LINKLOCAL_MASK);
- dhcp->broadcast.s_addr = htonl (LINKLOCAL_BRDC);
+ dhcp->address.s_addr = addr.s_addr;
+ dhcp->netmask.s_addr = htonl (LINKLOCAL_MASK);
+ dhcp->broadcast.s_addr = htonl (LINKLOCAL_BRDC);
- /* Finally configure some DHCP like lease times */
- dhcp->leasetime = IPV4LL_LEASETIME;
- dhcp->renewaltime = (dhcp->leasetime * 0.5);
- dhcp->rebindtime = (dhcp->leasetime * 0.875);
+ /* Finally configure some DHCP like lease times */
+ dhcp->leasetime = IPV4LL_LEASETIME;
+ dhcp->renewaltime = (dhcp->leasetime * 0.5);
+ dhcp->rebindtime = (dhcp->leasetime * 0.875);
- return (0);
+ return (0);
}
#endif
diff --git a/src/customdhcpcd/ipv4ll.h b/src/customdhcpcd/ipv4ll.h
index 4fa8943..2dfc266 100644
--- a/src/customdhcpcd/ipv4ll.h
+++ b/src/customdhcpcd/ipv4ll.h
@@ -1,4 +1,4 @@
-/*
+/*
* dhcpcd - DHCP client daemon
* Copyright 2006-2008 Roy Marples <roy@marples.name>
* All rights reserved
diff --git a/src/customdhcpcd/logger.c b/src/customdhcpcd/logger.c
index 2c8431d..48e6fa6 100644
--- a/src/customdhcpcd/logger.c
+++ b/src/customdhcpcd/logger.c
@@ -1,4 +1,4 @@
-/*
+/*
* dhcpcd - DHCP client daemon
* Copyright 2006-2008 Roy Marples <roy@marples.name>
* All rights reserved
@@ -46,109 +46,114 @@
static int loglevel = LOG_WARNING;
static char logprefix[12] = { 0 };
-int logtolevel(const char *priority) {
- CODE *c;
+int logtolevel(const char *priority)
+{
+ CODE *c;
- if (isdigit ((int) *priority))
- return (atoi(priority));
+ if (isdigit ((int) *priority))
+ return (atoi(priority));
- for (c = prioritynames; c->c_name; c++)
- if (!strcasecmp(priority, c->c_name))
- return (c->c_val);
+ for (c = prioritynames; c->c_name; c++)
+ if (!strcasecmp(priority, c->c_name))
+ return (c->c_val);
- return (-1);
+ return (-1);
}
-static const char *leveltolog(int level) {
- CODE *c;
+static const char *leveltolog(int level)
+{
+ CODE *c;
- for (c = prioritynames; c->c_name; c++)
- if (c->c_val == level)
- return (c->c_name);
+ for (c = prioritynames; c->c_name; c++)
+ if (c->c_val == level)
+ return (c->c_name);
- return (NULL);
+ return (NULL);
}
-void setloglevel(int level) {
- loglevel = level;
+void setloglevel(int level)
+{
+ loglevel = level;
}
-void setlogprefix(const char *prefix) {
- snprintf(logprefix, sizeof(logprefix), "%s", prefix);
+void setlogprefix(const char *prefix)
+{
+ snprintf(logprefix, sizeof(logprefix), "%s", prefix);
}
-void logger(int level, const char *fmt, ...) {
- va_list p;
- //va_list p2;
-// FILE *f = stderr;
- FILE *f;
- FILE *f2;
- char* path = "/tmp/cdhcpcd.log";
- char* msgpath = "/tmp/cdhcpcd-msg.log";
- int size = 512;
- char *msg = (char *) malloc (size);
-
-
- f = fopen(path,"a");
- f2 = fopen(msgpath,"a");
- va_start (p, fmt);
- //va_copy (p2, p);
-
-
- vsnprintf (msg, size, fmt, p);
- strcat(msg,"\n");
- logToQt(level, DHCPCD_LOG, msg);
-
- fprintf(f2, "%s, %s", leveltolog(level), logprefix);
- fprintf(f2, "%s", msg);
- fputc('\n', f2);
-
- fprintf(f, "%s, %s", leveltolog(level), logprefix);
- vfprintf(f, fmt, p);
- fputc('\n', f);
-
- /* stdout, stderr may be re-directed to some kind of buffer.
- * So we always flush to ensure it's written. */
- fflush(f);
-
-// //logLoggerToQt(level, fmt, p);
-// if (level <= LOG_ERR || level <= loglevel) {
-//
-// /* new function by Niklas Goby
-// * send the log message also to our Qt programm.
-// * implemented in logwriter.c
-// * */
-// //logLoggerToQt(level, fmt, p);
-//
-// if (level == LOG_DEBUG || level == LOG_INFO)
-// f = stdout;
-// fprintf(f, "%s, %s", leveltolog(level), logprefix);
-// vfprintf(f, fmt, p);
-// fputc('\n', f);
-//
-// /* stdout, stderr may be re-directed to some kind of buffer.
-// * So we always flush to ensure it's written. */
-// fflush(f);
-// }
-// if (level < LOG_DEBUG || level <= loglevel) {
-// size_t len = strlen(logprefix);
-// size_t fmt2len = strlen(fmt) + len + 1;
-// char *fmt2 = malloc(sizeof(char) * fmt2len);
-// char *pf = fmt2;
-// if (fmt2) {
-// memcpy(pf, logprefix, len);
-// pf += len;
-// strlcpy(pf, fmt, fmt2len - len);
-// vsyslog(level, fmt2, p2);
-// free(fmt2);
-// } else {
-// vsyslog(level, fmt, p2);
-// syslog(LOG_ERR, "logger: memory exhausted");
-// exit(EXIT_FAILURE);
-// }
-// }
-
- //va_end (p2);
- va_end (p);
+void logger(int level, const char *fmt, ...)
+{
+ va_list p;
+ //va_list p2;
+ // FILE *f = stderr;
+ FILE *f;
+ FILE *f2;
+ char* path = "/tmp/cdhcpcd.log";
+ char* msgpath = "/tmp/cdhcpcd-msg.log";
+ int size = 512;
+ char *msg = (char *) malloc (size);
+
+
+ f = fopen(path, "a");
+ f2 = fopen(msgpath, "a");
+ va_start (p, fmt);
+ //va_copy (p2, p);
+
+
+ vsnprintf (msg, size, fmt, p);
+ strcat(msg, "\n");
+ logToQt(level, DHCPCD_LOG, msg);
+
+ fprintf(f2, "%s, %s", leveltolog(level), logprefix);
+ fprintf(f2, "%s", msg);
+ fputc('\n', f2);
+
+ fprintf(f, "%s, %s", leveltolog(level), logprefix);
+ vfprintf(f, fmt, p);
+ fputc('\n', f);
+
+ /* stdout, stderr may be re-directed to some kind of buffer.
+ * So we always flush to ensure it's written. */
+ fflush(f);
+
+ // //logLoggerToQt(level, fmt, p);
+ // if (level <= LOG_ERR || level <= loglevel) {
+ //
+ // /* new function by Niklas Goby
+ // * send the log message also to our Qt programm.
+ // * implemented in logwriter.c
+ // * */
+ // //logLoggerToQt(level, fmt, p);
+ //
+ // if (level == LOG_DEBUG || level == LOG_INFO)
+ // f = stdout;
+ // fprintf(f, "%s, %s", leveltolog(level), logprefix);
+ // vfprintf(f, fmt, p);
+ // fputc('\n', f);
+ //
+ // /* stdout, stderr may be re-directed to some kind of buffer.
+ // * So we always flush to ensure it's written. */
+ // fflush(f);
+ // }
+ // if (level < LOG_DEBUG || level <= loglevel) {
+ // size_t len = strlen(logprefix);
+ // size_t fmt2len = strlen(fmt) + len + 1;
+ // char *fmt2 = malloc(sizeof(char) * fmt2len);
+ // char *pf = fmt2;
+ // if (fmt2) {
+ // memcpy(pf, logprefix, len);
+ // pf += len;
+ // strlcpy(pf, fmt, fmt2len - len);
+ // vsyslog(level, fmt2, p2);
+ // free(fmt2);
+ // } else {
+ // vsyslog(level, fmt, p2);
+ // syslog(LOG_ERR, "logger: memory exhausted");
+ // exit(EXIT_FAILURE);
+ // }
+ // }
+
+ //va_end (p2);
+ va_end (p);
}
diff --git a/src/customdhcpcd/logger.h b/src/customdhcpcd/logger.h
index 70e2ed5..52552f6 100644
--- a/src/customdhcpcd/logger.h
+++ b/src/customdhcpcd/logger.h
@@ -1,4 +1,4 @@
-/*
+/*
* dhcpcd - DHCP client daemon
* Copyright 2006-2008 Roy Marples <roy@marples.name>
* All rights reserved
diff --git a/src/customdhcpcd/logwriter.c b/src/customdhcpcd/logwriter.c
index ee8bb1d..e3316cb 100644
--- a/src/customdhcpcd/logwriter.c
+++ b/src/customdhcpcd/logwriter.c
@@ -25,236 +25,260 @@ int retval = -1;
char socketName[QTSOCKETADDRESSLENGTH];
char interfaceName[IF_NAMESIZE];
-void setSocketName(const char * sn) {
- snprintf(socketName, sizeof(socketName), "%s", sn);
+void setSocketName(const char * sn)
+{
+ snprintf(socketName, sizeof(socketName), "%s", sn);
}
-void setInterfaceName(const char * in) {
- snprintf(interfaceName, sizeof(interfaceName), "%s", in);
+void setInterfaceName(const char * in)
+{
+ snprintf(interfaceName, sizeof(interfaceName), "%s", in);
}
-int initQtLoggerSocket() {
- /**
- * new code. seems to be right.
- */
-
- struct sockaddr_un serv_addr;
- fprintf(stdout, "start init \n");
- sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (sockfd < 0) {
- fprintf(stdout, "ERROR opening socket \n");
- retval = sockfd;
- return sockfd;
- }
- serv_addr.sun_family = AF_UNIX;
- strcpy(serv_addr.sun_path, socketName);
-
- retval = connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
- if (retval < 0)
- fprintf(stdout, "ERROR connecting \n");
- fprintf(stdout, "init Qt Logger Socket done \n");
- return retval;
+int initQtLoggerSocket()
+{
+ /**
+ * new code. seems to be right.
+ */
+
+ struct sockaddr_un serv_addr;
+ fprintf(stdout, "start init \n");
+ sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (sockfd < 0)
+ {
+ fprintf(stdout, "ERROR opening socket \n");
+ retval = sockfd;
+ return sockfd;
+ }
+ serv_addr.sun_family = AF_UNIX;
+ strcpy(serv_addr.sun_path, socketName);
+
+ retval = connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
+ if (retval < 0)
+ fprintf(stdout, "ERROR connecting \n");
+ fprintf(stdout, "init Qt Logger Socket done \n");
+ return retval;
}
-void closeQtLoggerSocket() {
- close(sockfd);
+void closeQtLoggerSocket()
+{
+ close(sockfd);
}
-void sendToQt(log_msg * msg) {
- int n = -1;
- int t;
- int ret;
- const char *tpl = "%s;%d;%d;%s\n";
- char outbuf[DHCP_MESSAGE_SIZE];
- char ack[ACK_SIZE];
- /*
- size_t outbuf_size = sizeof(char) * 4 + // ";" *3 + newline
- sizeof(int) * 2 + // status, substatus
- sizeof(msg->device) + // devicename
- sizeof(msg->msg); // msg
- outbuf = malloc(outbuf_size);
- memset(outbuf, 0, outbuf_size);
- snprintf(outbuf, sizeof(char) * 3 + sizeof(int) * 2 + sizeof(msg->device)
- + sizeof(msg->msg), tpl, msg->device, msg->status, msg->substatus,
- msg->msg);
- */
- memset(outbuf, '\0', DHCP_MESSAGE_SIZE);
- ret = snprintf(outbuf, DHCP_MESSAGE_SIZE, tpl, msg->device, msg->status,
- msg->substatus, msg->msg);
- if (ret < 1) {
- log ger(LOG_INFO, "[fbgui] ERROR filling message buffer");
- //syslog(LOG_INFO, "[fbgui] ERROR filling message buffer");
- return;
- }
- if (outbuf != NULL) {
- n = send(sockfd, outbuf, DHCP_MESSAGE_SIZE, 0);
- }
- syslog(LOG_INFO, "[fbgui] INFO writing to socket: [%d:%d] %s (%s)",
- msg->status, msg->substatus, msg->msg, msg->device);
-
- if (n <= 0) {
- logger(LOG_ERR, "[fbgui] ERROR writing to socket: [%d:%d] %s (%s)",
- msg->status, msg->substatus, msg->msg, msg->device);
- //syslog(LOG_ERR, "[fbgui] ERROR writing to socket: [%d:%d] %s (%s)",
- // msg->status, msg->substatus, msg->msg, msg->device);
- }
- /*
- memset(ack, 0, ACK_SIZE);
- if ((t = recv(sockfd, ack, ACK_SIZE, 0)) > 0) {
- syslog(LOG_ERR, "[fbgui] recv ack echo> %s", ack);
- printf("received: %s\n", ack);
- } else {
- if (t < 0)
- syslog(LOG_ERR, "[fbgui] ERROR receiving from socket");
- else
- syslog(LOG_ERR, "[fbgui] ERROR Server closed");
- }
- */
+void sendToQt(log_msg * msg)
+{
+ int n = -1;
+ int t;
+ int ret;
+ const char *tpl = "%s;%d;%d;%s\n";
+ char outbuf[DHCP_MESSAGE_SIZE];
+ char ack[ACK_SIZE];
+ /*
+ size_t outbuf_size = sizeof(char) * 4 + // ";" *3 + newline
+ sizeof(int) * 2 + // status, substatus
+ sizeof(msg->device) + // devicename
+ sizeof(msg->msg); // msg
+ outbuf = malloc(outbuf_size);
+ memset(outbuf, 0, outbuf_size);
+ snprintf(outbuf, sizeof(char) * 3 + sizeof(int) * 2 + sizeof(msg->device)
+ + sizeof(msg->msg), tpl, msg->device, msg->status, msg->substatus,
+ msg->msg);
+ */
+ memset(outbuf, '\0', DHCP_MESSAGE_SIZE);
+ ret = snprintf(outbuf, DHCP_MESSAGE_SIZE, tpl, msg->device, msg->status,
+ msg->substatus, msg->msg);
+ if (ret < 1)
+ {
+ log ger(LOG_INFO, "[fbgui] ERROR filling message buffer");
+ //syslog(LOG_INFO, "[fbgui] ERROR filling message buffer");
+ return;
+ }
+ if (outbuf != NULL)
+ {
+ n = send(sockfd, outbuf, DHCP_MESSAGE_SIZE, 0);
+ }
+ syslog(LOG_INFO, "[fbgui] INFO writing to socket: [%d:%d] %s (%s)",
+ msg->status, msg->substatus, msg->msg, msg->device);
+
+ if (n <= 0)
+ {
+ logger(LOG_ERR, "[fbgui] ERROR writing to socket: [%d:%d] %s (%s)",
+ msg->status, msg->substatus, msg->msg, msg->device);
+ //syslog(LOG_ERR, "[fbgui] ERROR writing to socket: [%d:%d] %s (%s)",
+ // msg->status, msg->substatus, msg->msg, msg->device);
+ }
+ /*
+ memset(ack, 0, ACK_SIZE);
+ if ((t = recv(sockfd, ack, ACK_SIZE, 0)) > 0) {
+ syslog(LOG_ERR, "[fbgui] recv ack echo> %s", ack);
+ printf("received: %s\n", ack);
+ } else {
+ if (t < 0)
+ syslog(LOG_ERR, "[fbgui] ERROR receiving from socket");
+ else
+ syslog(LOG_ERR, "[fbgui] ERROR Server closed");
+ }
+ */
}
-void logToQt(int status, int substatus, const char * msg) {
- if (retval >= 0) {
- log_msg lm;
- lm.status = status;
- lm.substatus = substatus;
- snprintf(lm.msg, sizeof(lm.msg), "%s", msg);
- snprintf(lm.device, sizeof(lm.device), "%s", interfaceName);
- sendToQt(&lm);
- }
+void logToQt(int status, int substatus, const char * msg)
+{
+ if (retval >= 0)
+ {
+ log_msg lm;
+ lm.status = status;
+ lm.substatus = substatus;
+ snprintf(lm.msg, sizeof(lm.msg), "%s", msg);
+ snprintf(lm.device, sizeof(lm.device), "%s", interfaceName);
+ sendToQt(&lm);
+ }
}
-void logSendToQt(int type) {
- switch (type) {
- case DHCP_DISCOVER:
- logToQt(LOG_INFO, DHCP_DISCOVER, "send discover");
- break;
- case DHCP_OFFER:
- logToQt(LOG_INFO, DHCP_OFFER, "send offer");
- break;
- case DHCP_REQUEST:
- logToQt(LOG_INFO, DHCP_REQUEST, "send request");
- break;
- case DHCP_DECLINE:
- logToQt(LOG_INFO, DHCP_DECLINE, "send decline");
- break;
- case DHCP_ACK:
- logToQt(LOG_INFO, DHCP_ACK, "send ack");
- break;
- case DHCP_NAK:
- logToQt(LOG_INFO, DHCP_NAK, "send nak");
- break;
- case DHCP_RELEASE:
- logToQt(LOG_INFO, DHCP_RELEASE, "send release");
- break;
- case DHCP_INFORM:
- logToQt(LOG_INFO, DHCP_INFORM, "send inform");
- break;
- default:
- break;
- }
+void logSendToQt(int type)
+{
+ switch (type)
+ {
+ case DHCP_DISCOVER:
+ logToQt(LOG_INFO, DHCP_DISCOVER, "send discover");
+ break;
+ case DHCP_OFFER:
+ logToQt(LOG_INFO, DHCP_OFFER, "send offer");
+ break;
+ case DHCP_REQUEST:
+ logToQt(LOG_INFO, DHCP_REQUEST, "send request");
+ break;
+ case DHCP_DECLINE:
+ logToQt(LOG_INFO, DHCP_DECLINE, "send decline");
+ break;
+ case DHCP_ACK:
+ logToQt(LOG_INFO, DHCP_ACK, "send ack");
+ break;
+ case DHCP_NAK:
+ logToQt(LOG_INFO, DHCP_NAK, "send nak");
+ break;
+ case DHCP_RELEASE:
+ logToQt(LOG_INFO, DHCP_RELEASE, "send release");
+ break;
+ case DHCP_INFORM:
+ logToQt(LOG_INFO, DHCP_INFORM, "send inform");
+ break;
+ default:
+ break;
+ }
}
static void print_addresses (FILE *f, const struct address_head *addresses)
{
- const address_t *addr;
-
- STAILQ_FOREACH (addr, addresses, entries) {
- fprintf (f, "%s", inet_ntoa (addr->address));
- if (STAILQ_NEXT (addr, entries))
- fprintf (f, " ");
- }
+ const address_t *addr;
+
+ STAILQ_FOREACH (addr, addresses, entries)
+ {
+ fprintf (f, "%s", inet_ntoa (addr->address));
+ if (STAILQ_NEXT (addr, entries))
+ fprintf (f, " ");
+ }
}
-void logGatewayToFile(const interface_t *iface, const dhcp_t *dhcp) {
- /*void logGatewayToFile(const interface_t iface, const dhcp_t *dhcp,
- const options_t options)*/
- //char path[QTSOCKETADDRESSLENGTH];
-
- /*
- strcpy(path, DEFAULT_GATEWAY_INFO_LOCATION);
- strcat(path, iface.name);
- strcpy(iface.infofile, path);
- options.test = false;
- syslog(LOG_INFO, "[fbgui] try to open file: %s", iface.infofile);
- write_info(&iface, dhcp, &options, true);
- */
- FILE *f;
- route_t *route;
- char path[QTSOCKETADDRESSLENGTH];
-
- strcpy(path, DEFAULT_INTERFACE_CONF_LOCATION);
- strcat(path, iface->name);
-
- syslog(LOG_INFO, "[fbgui] try to open file: %s", path);
-
- logger(LOG_DEBUG, "writing %s", iface->infofile);
- if ((f = fopen(path, "w")) == NULL) {
- logger(LOG_ERR, "fopen `%s': %s", path, strerror(errno));
- //TODO: exit/return ..
- return;
- }
-
- if (dhcp->address.s_addr) {
- struct in_addr n;
- n.s_addr = dhcp->address.s_addr & dhcp->netmask.s_addr;
- fprintf(f, "IPADDR='%s'\n", inet_ntoa(dhcp->address));
- fprintf(f, "NETMASK='%s'\n", inet_ntoa(dhcp->netmask));
- fprintf(f, "NETWORK='%s'\n", inet_ntoa(n));
- fprintf(f, "BROADCAST='%s'\n", inet_ntoa(dhcp->broadcast));
- }
-
- if (dhcp->routes) {
- bool doneone = false;
- fprintf(f, "ROUTES='");
- STAILQ_FOREACH (route, dhcp->routes, entries) {
- if (route->destination.s_addr != 0) {
- if (doneone)
- fprintf(f, " ");
- fprintf(f, "%s", inet_ntoa(route->destination));
- fprintf(f, ",%s", inet_ntoa(route->netmask));
- fprintf(f, ",%s", inet_ntoa(route->gateway));
- doneone = true;
- }
- }
- fprintf(f, "'\n");
-
- doneone = false;
- fprintf(f, "GATEWAYS='");
- STAILQ_FOREACH (route, dhcp->routes, entries) {
- if (route->destination.s_addr == 0) {
- if (doneone)
- fprintf(f, " ");
- fprintf(f, "%s", inet_ntoa(route->gateway));
- doneone = true;
- }
- }
- fprintf(f, "'\n");
- }
-
- fprintf(f, "HOSTNAME='%s", dhcp->hostname);
- fprintf(f, "'\n");
- fprintf(f, "DNSSEARCH='%s", dhcp->dnssearch);
- fprintf(f, "'\n");
-
- if (dhcp->dnsservers) {
- fprintf(f, "DNSSERVERS='");
- print_addresses(f, dhcp->dnsservers);
- fprintf(f, "'\n");
- }
- fprintf(f, "INTERFACE='%s", iface->name);
- fprintf(f, "'\n");
- if (iface->clientid_len > 0) {
- fprintf(f, "CLIENTID='%s'\n", hwaddr_ntoa(iface->clientid,
- iface->clientid_len));
- }
- fprintf(f, "DHCPCHADDR='%s'\n", hwaddr_ntoa(iface->hwaddr, iface->hwlen));
- fclose(f);
+void logGatewayToFile(const interface_t *iface, const dhcp_t *dhcp)
+{
+ /*void logGatewayToFile(const interface_t iface, const dhcp_t *dhcp,
+ const options_t options)*/
+ //char path[QTSOCKETADDRESSLENGTH];
+
+ /*
+ strcpy(path, DEFAULT_GATEWAY_INFO_LOCATION);
+ strcat(path, iface.name);
+ strcpy(iface.infofile, path);
+ options.test = false;
+ syslog(LOG_INFO, "[fbgui] try to open file: %s", iface.infofile);
+ write_info(&iface, dhcp, &options, true);
+ */
+ FILE *f;
+ route_t *route;
+ char path[QTSOCKETADDRESSLENGTH];
+
+ strcpy(path, DEFAULT_INTERFACE_CONF_LOCATION);
+ strcat(path, iface->name);
+
+ syslog(LOG_INFO, "[fbgui] try to open file: %s", path);
+
+ logger(LOG_DEBUG, "writing %s", iface->infofile);
+ if ((f = fopen(path, "w")) == NULL)
+ {
+ logger(LOG_ERR, "fopen `%s': %s", path, strerror(errno));
+ //TODO: exit/return ..
+ return;
+ }
+
+ if (dhcp->address.s_addr)
+ {
+ struct in_addr n;
+ n.s_addr = dhcp->address.s_addr & dhcp->netmask.s_addr;
+ fprintf(f, "IPADDR='%s'\n", inet_ntoa(dhcp->address));
+ fprintf(f, "NETMASK='%s'\n", inet_ntoa(dhcp->netmask));
+ fprintf(f, "NETWORK='%s'\n", inet_ntoa(n));
+ fprintf(f, "BROADCAST='%s'\n", inet_ntoa(dhcp->broadcast));
+ }
+
+ if (dhcp->routes)
+ {
+ bool doneone = false;
+ fprintf(f, "ROUTES='");
+ STAILQ_FOREACH (route, dhcp->routes, entries)
+ {
+ if (route->destination.s_addr != 0)
+ {
+ if (doneone)
+ fprintf(f, " ");
+ fprintf(f, "%s", inet_ntoa(route->destination));
+ fprintf(f, ",%s", inet_ntoa(route->netmask));
+ fprintf(f, ",%s", inet_ntoa(route->gateway));
+ doneone = true;
+ }
+ }
+ fprintf(f, "'\n");
+
+ doneone = false;
+ fprintf(f, "GATEWAYS='");
+ STAILQ_FOREACH (route, dhcp->routes, entries)
+ {
+ if (route->destination.s_addr == 0)
+ {
+ if (doneone)
+ fprintf(f, " ");
+ fprintf(f, "%s", inet_ntoa(route->gateway));
+ doneone = true;
+ }
+ }
+ fprintf(f, "'\n");
+ }
+
+ fprintf(f, "HOSTNAME='%s", dhcp->hostname);
+ fprintf(f, "'\n");
+ fprintf(f, "DNSSEARCH='%s", dhcp->dnssearch);
+ fprintf(f, "'\n");
+
+ if (dhcp->dnsservers)
+ {
+ fprintf(f, "DNSSERVERS='");
+ print_addresses(f, dhcp->dnsservers);
+ fprintf(f, "'\n");
+ }
+ fprintf(f, "INTERFACE='%s", iface->name);
+ fprintf(f, "'\n");
+ if (iface->clientid_len > 0)
+ {
+ fprintf(f, "CLIENTID='%s'\n", hwaddr_ntoa(iface->clientid,
+ iface->clientid_len));
+ }
+ fprintf(f, "DHCPCHADDR='%s'\n", hwaddr_ntoa(iface->hwaddr, iface->hwlen));
+ fclose(f);
}
diff --git a/src/customdhcpcd/logwriter.h b/src/customdhcpcd/logwriter.h
index 43f35fa..9d7af47 100644
--- a/src/customdhcpcd/logwriter.h
+++ b/src/customdhcpcd/logwriter.h
@@ -16,11 +16,12 @@
#define LOG_MSG_SIZE 1024
typedef struct _log_msg log_msg;
-struct _log_msg {
- int status;
- int substatus;
- char device[IF_NAMESIZE];
- char msg[LOG_MSG_SIZE];
+struct _log_msg
+{
+ int status;
+ int substatus;
+ char device[IF_NAMESIZE];
+ char msg[LOG_MSG_SIZE];
};
/**
diff --git a/src/customdhcpcd/signal.c b/src/customdhcpcd/signal.c
index 9055c9f..297d8b2 100644
--- a/src/customdhcpcd/signal.c
+++ b/src/customdhcpcd/signal.c
@@ -1,4 +1,4 @@
-/*
+/*
* dhcpcd - DHCP client daemon
* Copyright 2006-2008 Roy Marples <roy@marples.name>
* All rights reserved
@@ -40,44 +40,45 @@
static int signal_pipe[2];
static int signals[5];
-static const int handle_sigs[] = {
- SIGHUP,
- SIGALRM,
- SIGTERM,
- SIGINT
+static const int handle_sigs[] =
+{
+ SIGHUP,
+ SIGALRM,
+ SIGTERM,
+ SIGINT
};
static void signal_handler (int sig)
{
- unsigned int i = 0;
- int serrno = errno;
-
- /* Add a signal to our stack */
- while (signals[i])
- i++;
- if (i > sizeof (signals) / sizeof (signals[0]))
- logger (LOG_ERR, "signal buffer overrun");
- else
- signals[i] = sig;
-
- if (write (signal_pipe[1], &sig, sizeof (sig)) == -1)
- logger (LOG_ERR, "Could not send signal: %s", strerror (errno));
-
- /* Restore errno */
- errno = serrno;
+ unsigned int i = 0;
+ int serrno = errno;
+
+ /* Add a signal to our stack */
+ while (signals[i])
+ i++;
+ if (i > sizeof (signals) / sizeof (signals[0]))
+ logger (LOG_ERR, "signal buffer overrun");
+ else
+ signals[i] = sig;
+
+ if (write (signal_pipe[1], &sig, sizeof (sig)) == -1)
+ logger (LOG_ERR, "Could not send signal: %s", strerror (errno));
+
+ /* Restore errno */
+ errno = serrno;
}
int signal_fd (void)
{
- return (signal_pipe[0]);
+ return (signal_pipe[0]);
}
/* Check if we have a signal or not */
int signal_exists (const struct pollfd *fd)
{
- if (signals[0] || (fd && fd->revents & POLLIN))
- return (0);
- return (-1);
+ if (signals[0] || (fd && fd->revents & POLLIN))
+ return (0);
+ return (-1);
}
/* Read a signal from the signal pipe. Returns 0 if there is
@@ -85,99 +86,106 @@ int signal_exists (const struct pollfd *fd)
* your signal on success */
int signal_read (struct pollfd *fd)
{
- int sig = -1;
-
- /* Pop a signal off the our stack */
- if (signals[0]) {
- unsigned int i = 0;
- sig = signals[0];
- while (i < (sizeof (signals) / sizeof (signals[0])) - 1) {
- signals[i] = signals[i + 1];
- if (! signals[++i])
- break;
- }
- }
-
- if (fd && fd->revents & POLLIN) {
- char buf[16];
- size_t bytes;
-
- memset (buf, 0, sizeof (buf));
- bytes = read (signal_pipe[0], buf, sizeof (buf));
-
- if (bytes >= sizeof (sig))
- memcpy (&sig, buf, sizeof (sig));
-
- /* We need to clear us from rset if nothing left in the buffer
- * in case we are called many times */
- if (bytes == sizeof (sig))
- fd->revents = 0;
- }
-
- return (sig);
+ int sig = -1;
+
+ /* Pop a signal off the our stack */
+ if (signals[0])
+ {
+ unsigned int i = 0;
+ sig = signals[0];
+ while (i < (sizeof (signals) / sizeof (signals[0])) - 1)
+ {
+ signals[i] = signals[i + 1];
+ if (! signals[++i])
+ break;
+ }
+ }
+
+ if (fd && fd->revents & POLLIN)
+ {
+ char buf[16];
+ size_t bytes;
+
+ memset (buf, 0, sizeof (buf));
+ bytes = read (signal_pipe[0], buf, sizeof (buf));
+
+ if (bytes >= sizeof (sig))
+ memcpy (&sig, buf, sizeof (sig));
+
+ /* We need to clear us from rset if nothing left in the buffer
+ * in case we are called many times */
+ if (bytes == sizeof (sig))
+ fd->revents = 0;
+ }
+
+ return (sig);
}
/* Call this before doing anything else. Sets up the socket pair
* and installs the signal handler */
int signal_init (void)
{
- struct sigaction sa;
-
- if (pipe (signal_pipe) == -1) {
- logger (LOG_ERR, "pipe: %s", strerror (errno));
- return (-1);
- }
-
- /* Stop any scripts from inheriting us */
- 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) {
- logger (LOG_ERR, "sigaction: %s", strerror (errno));
- return (-1);
- }
-
- memset (signals, 0, sizeof (signals));
- return (0);
+ struct sigaction sa;
+
+ if (pipe (signal_pipe) == -1)
+ {
+ logger (LOG_ERR, "pipe: %s", strerror (errno));
+ return (-1);
+ }
+
+ /* Stop any scripts from inheriting us */
+ 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)
+ {
+ logger (LOG_ERR, "sigaction: %s", strerror (errno));
+ return (-1);
+ }
+
+ memset (signals, 0, sizeof (signals));
+ return (0);
}
int signal_setup (void)
{
- unsigned int i;
- struct sigaction sa;
-
- memset (&sa, 0, sizeof (sa));
- sa.sa_handler = signal_handler;
- sigemptyset (&sa.sa_mask);
-
- for (i = 0; i < sizeof (handle_sigs) / sizeof (handle_sigs[0]); i++)
- if (sigaction (handle_sigs[i], &sa, NULL) == -1) {
- logger (LOG_ERR, "sigaction: %s", strerror (errno));
- return (-1);
- }
-
- return (0);
+ unsigned int i;
+ struct sigaction sa;
+
+ memset (&sa, 0, sizeof (sa));
+ sa.sa_handler = signal_handler;
+ sigemptyset (&sa.sa_mask);
+
+ for (i = 0; i < sizeof (handle_sigs) / sizeof (handle_sigs[0]); i++)
+ if (sigaction (handle_sigs[i], &sa, NULL) == -1)
+ {
+ logger (LOG_ERR, "sigaction: %s", strerror (errno));
+ return (-1);
+ }
+
+ return (0);
}
int signal_reset (void)
{
- struct sigaction sa;
- unsigned int i;
+ struct sigaction sa;
+ unsigned int i;
- memset (&sa, 0, sizeof (sa));
- sa.sa_handler = SIG_DFL;
- sigemptyset (&sa.sa_mask);
+ memset (&sa, 0, sizeof (sa));
+ sa.sa_handler = SIG_DFL;
+ sigemptyset (&sa.sa_mask);
- for (i = 0; i < sizeof (handle_sigs) / sizeof (handle_sigs[0]); i++)
- if (sigaction (handle_sigs[i], &sa, NULL) == -1) {
- logger (LOG_ERR, "sigaction: %s", strerror (errno));
- return (-1);
- }
+ for (i = 0; i < sizeof (handle_sigs) / sizeof (handle_sigs[0]); i++)
+ if (sigaction (handle_sigs[i], &sa, NULL) == -1)
+ {
+ logger (LOG_ERR, "sigaction: %s", strerror (errno));
+ return (-1);
+ }
- return (0);
+ return (0);
}
diff --git a/src/customdhcpcd/signal.h b/src/customdhcpcd/signal.h
index 63a5906..1c29f80 100644
--- a/src/customdhcpcd/signal.h
+++ b/src/customdhcpcd/signal.h
@@ -1,4 +1,4 @@
-/*
+/*
* dhcpcd - DHCP client daemon
* Copyright 2006-2008 Roy Marples <roy@marples.name>
* All rights reserved
diff --git a/src/customdhcpcd/socket.c b/src/customdhcpcd/socket.c
index 58ad6c5..9cb1227 100644
--- a/src/customdhcpcd/socket.c
+++ b/src/customdhcpcd/socket.c
@@ -65,583 +65,629 @@
#endif
/* Broadcast address for IPoIB */
-static const uint8_t ipv4_bcast_addr[] = {
- 0x00, 0xff, 0xff, 0xff,
- 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff
+static const uint8_t ipv4_bcast_addr[] =
+{
+ 0x00, 0xff, 0xff, 0xff,
+ 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff
};
/* Credit where credit is due :)
* The below BPF filter is taken from ISC DHCP */
-static struct bpf_insn dhcp_bpf_filter [] = {
- /* Make sure this is an IP packet... */
- BPF_STMT (BPF_LD + BPF_H + BPF_ABS, 12),
- BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 8),
+static struct bpf_insn dhcp_bpf_filter [] =
+{
+ /* Make sure this is an IP packet... */
+ BPF_STMT (BPF_LD + BPF_H + BPF_ABS, 12),
+ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 8),
- /* Make sure it's a UDP packet... */
- BPF_STMT (BPF_LD + BPF_B + BPF_ABS, 23),
- BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6),
+ /* Make sure it's a UDP packet... */
+ BPF_STMT (BPF_LD + BPF_B + BPF_ABS, 23),
+ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6),
- /* Make sure this isn't a fragment... */
- BPF_STMT (BPF_LD + BPF_H + BPF_ABS, 20),
- BPF_JUMP (BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),
+ /* Make sure this isn't a fragment... */
+ BPF_STMT (BPF_LD + BPF_H + BPF_ABS, 20),
+ BPF_JUMP (BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),
- /* Get the IP header length... */
- BPF_STMT (BPF_LDX + BPF_B + BPF_MSH, 14),
+ /* Get the IP header length... */
+ BPF_STMT (BPF_LDX + BPF_B + BPF_MSH, 14),
- /* Make sure it's to the right port... */
- BPF_STMT (BPF_LD + BPF_H + BPF_IND, 16),
- BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, DHCP_CLIENT_PORT, 0, 1),
+ /* Make sure it's to the right port... */
+ BPF_STMT (BPF_LD + BPF_H + BPF_IND, 16),
+ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, DHCP_CLIENT_PORT, 0, 1),
- /* If we passed all the tests, ask for the whole packet. */
- BPF_STMT (BPF_RET + BPF_K, ~0U),
+ /* If we passed all the tests, ask for the whole packet. */
+ BPF_STMT (BPF_RET + BPF_K, ~0U),
- /* Otherwise, drop it. */
- BPF_STMT (BPF_RET + BPF_K, 0),
+ /* Otherwise, drop it. */
+ BPF_STMT (BPF_RET + BPF_K, 0),
};
-static struct bpf_insn arp_bpf_filter [] = {
- /* Make sure this is an ARP packet... */
- BPF_STMT (BPF_LD + BPF_H + BPF_ABS, 12),
- BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_ARP, 0, 3),
+static struct bpf_insn arp_bpf_filter [] =
+{
+ /* Make sure this is an ARP packet... */
+ BPF_STMT (BPF_LD + BPF_H + BPF_ABS, 12),
+ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_ARP, 0, 3),
- /* Make sure this is an ARP REPLY... */
- BPF_STMT (BPF_LD + BPF_H + BPF_ABS, 20),
- BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ARPOP_REPLY, 0, 1),
+ /* Make sure this is an ARP REPLY... */
+ BPF_STMT (BPF_LD + BPF_H + BPF_ABS, 20),
+ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ARPOP_REPLY, 0, 1),
- /* If we passed all the tests, ask for the whole packet. */
- BPF_STMT (BPF_RET + BPF_K, ~0U),
+ /* If we passed all the tests, ask for the whole packet. */
+ BPF_STMT (BPF_RET + BPF_K, ~0U),
- /* Otherwise, drop it. */
- BPF_STMT (BPF_RET + BPF_K, 0),
+ /* Otherwise, drop it. */
+ BPF_STMT (BPF_RET + BPF_K, 0),
};
void setup_packet_filters (void)
{
#ifdef __linux__
- /* We need to massage the filters for Linux cooked packets */
- dhcp_bpf_filter[1].jf = 0; /* skip the IP packet type check */
- dhcp_bpf_filter[2].k -= ETH_HLEN;
- dhcp_bpf_filter[4].k -= ETH_HLEN;
- dhcp_bpf_filter[6].k -= ETH_HLEN;
- dhcp_bpf_filter[7].k -= ETH_HLEN;
-
- arp_bpf_filter[1].jf = 0; /* skip the IP packet type check */
- arp_bpf_filter[2].k -= ETH_HLEN;
+ /* We need to massage the filters for Linux cooked packets */
+ dhcp_bpf_filter[1].jf = 0; /* skip the IP packet type check */
+ dhcp_bpf_filter[2].k -= ETH_HLEN;
+ dhcp_bpf_filter[4].k -= ETH_HLEN;
+ dhcp_bpf_filter[6].k -= ETH_HLEN;
+ dhcp_bpf_filter[7].k -= ETH_HLEN;
+
+ arp_bpf_filter[1].jf = 0; /* skip the IP packet type check */
+ arp_bpf_filter[2].k -= ETH_HLEN;
#endif
}
static uint16_t checksum (unsigned char *addr, uint16_t len)
{
- uint32_t sum = 0;
- union
- {
- unsigned char *addr;
- uint16_t *i;
- } p;
- uint16_t nleft = len;
-
- p.addr = addr;
- while (nleft > 1) {
- sum += *p.i++;
- nleft -= 2;
- }
-
- if (nleft == 1) {
- uint8_t a = 0;
- memcpy (&a, p.i, 1);
- sum += ntohs (a) << 8;
- }
-
- sum = (sum >> 16) + (sum & 0xffff);
- sum += (sum >> 16);
-
- return ~sum;
+ uint32_t sum = 0;
+ union
+ {
+ unsigned char *addr;
+ uint16_t *i;
+ } p;
+ uint16_t nleft = len;
+
+ p.addr = addr;
+ while (nleft > 1)
+ {
+ sum += *p.i++;
+ nleft -= 2;
+ }
+
+ if (nleft == 1)
+ {
+ uint8_t a = 0;
+ memcpy (&a, p.i, 1);
+ sum += ntohs (a) << 8;
+ }
+
+ sum = (sum >> 16) + (sum & 0xffff);
+ sum += (sum >> 16);
+
+ return ~sum;
}
void make_dhcp_packet(struct udp_dhcp_packet *packet,
- const unsigned char *data, size_t length,
- struct in_addr source, struct in_addr dest)
+ const unsigned char *data, size_t length,
+ struct in_addr source, struct in_addr dest)
{
- struct ip *ip = &packet->ip;
- struct udphdr *udp = &packet->udp;
-
- /* OK, this is important :)
- * We copy the data to our packet and then create a small part of the
- * ip structure and an invalid ip_len (basically udp length).
- * We then fill the udp structure and put the checksum
- * of the whole packet into the udp checksum.
- * Finally we complete the ip structure and ip checksum.
- * If we don't do the ordering like so then the udp checksum will be
- * broken, so find another way of doing it! */
-
- memcpy (&packet->dhcp, data, length);
-
- ip->ip_p = IPPROTO_UDP;
- ip->ip_src.s_addr = source.s_addr;
- if (dest.s_addr == 0)
- ip->ip_dst.s_addr = INADDR_BROADCAST;
- else
- ip->ip_dst.s_addr = dest.s_addr;
-
- udp->uh_sport = htons (DHCP_CLIENT_PORT);
- udp->uh_dport = htons (DHCP_SERVER_PORT);
- udp->uh_ulen = htons (sizeof (*udp) + length);
- ip->ip_len = udp->uh_ulen;
- udp->uh_sum = checksum ((unsigned char *) packet, sizeof (*packet));
-
- ip->ip_v = IPVERSION;
- ip->ip_hl = 5;
- ip->ip_id = 0;
- ip->ip_tos = IPTOS_LOWDELAY;
- ip->ip_len = htons (sizeof (*ip) + sizeof (*udp) + length);
- ip->ip_id = 0;
- ip->ip_off = htons (IP_DF); /* Don't fragment */
- ip->ip_ttl = IPDEFTTL;
-
- ip->ip_sum = checksum ((unsigned char *) ip, sizeof (*ip));
+ struct ip *ip = &packet->ip;
+ struct udphdr *udp = &packet->udp;
+
+ /* OK, this is important :)
+ * We copy the data to our packet and then create a small part of the
+ * ip structure and an invalid ip_len (basically udp length).
+ * We then fill the udp structure and put the checksum
+ * of the whole packet into the udp checksum.
+ * Finally we complete the ip structure and ip checksum.
+ * If we don't do the ordering like so then the udp checksum will be
+ * broken, so find another way of doing it! */
+
+ memcpy (&packet->dhcp, data, length);
+
+ ip->ip_p = IPPROTO_UDP;
+ ip->ip_src.s_addr = source.s_addr;
+ if (dest.s_addr == 0)
+ ip->ip_dst.s_addr = INADDR_BROADCAST;
+ else
+ ip->ip_dst.s_addr = dest.s_addr;
+
+ udp->uh_sport = htons (DHCP_CLIENT_PORT);
+ udp->uh_dport = htons (DHCP_SERVER_PORT);
+ udp->uh_ulen = htons (sizeof (*udp) + length);
+ ip->ip_len = udp->uh_ulen;
+ udp->uh_sum = checksum ((unsigned char *) packet, sizeof (*packet));
+
+ ip->ip_v = IPVERSION;
+ ip->ip_hl = 5;
+ ip->ip_id = 0;
+ ip->ip_tos = IPTOS_LOWDELAY;
+ ip->ip_len = htons (sizeof (*ip) + sizeof (*udp) + length);
+ ip->ip_id = 0;
+ ip->ip_off = htons (IP_DF); /* Don't fragment */
+ ip->ip_ttl = IPDEFTTL;
+
+ ip->ip_sum = checksum ((unsigned char *) ip, sizeof (*ip));
}
static int valid_dhcp_packet (unsigned char *data)
{
- union
- {
- unsigned char *data;
- struct udp_dhcp_packet *packet;
- } d;
- uint16_t bytes;
- uint16_t ipsum;
- uint16_t iplen;
- uint16_t udpsum;
- struct in_addr source;
- struct in_addr dest;
- int retval = 0;
-
- d.data = data;
- bytes = ntohs (d.packet->ip.ip_len);
- ipsum = d.packet->ip.ip_sum;
- iplen = d.packet->ip.ip_len;
- udpsum = d.packet->udp.uh_sum;
-
- d.data = data;
- d.packet->ip.ip_sum = 0;
- if (ipsum != checksum ((unsigned char *) &d.packet->ip,
- sizeof (d.packet->ip)))
- {
- logger (LOG_DEBUG, "bad IP header checksum, ignoring");
- retval = -1;
- goto eexit;
- }
-
- memcpy (&source, &d.packet->ip.ip_src, sizeof (d.packet->ip.ip_src));
- memcpy (&dest, &d.packet->ip.ip_dst, sizeof (d.packet->ip.ip_dst));
- memset (&d.packet->ip, 0, sizeof (d.packet->ip));
- d.packet->udp.uh_sum = 0;
-
- d.packet->ip.ip_p = IPPROTO_UDP;
- memcpy (&d.packet->ip.ip_src, &source, sizeof (d.packet->ip.ip_src));
- memcpy (&d.packet->ip.ip_dst, &dest, sizeof (d.packet->ip.ip_dst));
- d.packet->ip.ip_len = d.packet->udp.uh_ulen;
- if (udpsum && udpsum != checksum (d.data, bytes)) {
- logger (LOG_ERR, "bad UDP checksum, ignoring");
- retval = -1;
- }
+ union
+ {
+ unsigned char *data;
+ struct udp_dhcp_packet *packet;
+ } d;
+ uint16_t bytes;
+ uint16_t ipsum;
+ uint16_t iplen;
+ uint16_t udpsum;
+ struct in_addr source;
+ struct in_addr dest;
+ int retval = 0;
+
+ d.data = data;
+ bytes = ntohs (d.packet->ip.ip_len);
+ ipsum = d.packet->ip.ip_sum;
+ iplen = d.packet->ip.ip_len;
+ udpsum = d.packet->udp.uh_sum;
+
+ d.data = data;
+ d.packet->ip.ip_sum = 0;
+ if (ipsum != checksum ((unsigned char *) &d.packet->ip,
+ sizeof (d.packet->ip)))
+ {
+ logger (LOG_DEBUG, "bad IP header checksum, ignoring");
+ retval = -1;
+ goto eexit;
+ }
+
+ memcpy (&source, &d.packet->ip.ip_src, sizeof (d.packet->ip.ip_src));
+ memcpy (&dest, &d.packet->ip.ip_dst, sizeof (d.packet->ip.ip_dst));
+ memset (&d.packet->ip, 0, sizeof (d.packet->ip));
+ d.packet->udp.uh_sum = 0;
+
+ d.packet->ip.ip_p = IPPROTO_UDP;
+ memcpy (&d.packet->ip.ip_src, &source, sizeof (d.packet->ip.ip_src));
+ memcpy (&d.packet->ip.ip_dst, &dest, sizeof (d.packet->ip.ip_dst));
+ d.packet->ip.ip_len = d.packet->udp.uh_ulen;
+ if (udpsum && udpsum != checksum (d.data, bytes))
+ {
+ logger (LOG_ERR, "bad UDP checksum, ignoring");
+ retval = -1;
+ }
eexit:
- d.packet->ip.ip_sum = ipsum;
- d.packet->ip.ip_len = iplen;
- d.packet->udp.uh_sum = udpsum;
+ d.packet->ip.ip_sum = ipsum;
+ d.packet->ip.ip_len = iplen;
+ d.packet->udp.uh_sum = udpsum;
- return retval;
+ return retval;
}
#if defined(BSD) || defined(__FreeBSD_kernel__)
int open_socket (interface_t *iface, int protocol)
{
- int n = 0;
- int fd = -1;
- char *device;
- int flags;
- struct ifreq ifr;
- int buf = 0;
- struct bpf_program pf;
-
- device = xmalloc (sizeof (char) * PATH_MAX);
- do {
- snprintf (device, PATH_MAX, "/dev/bpf%d", n++);
- fd = open (device, O_RDWR);
- } while (fd == -1 && errno == EBUSY);
- free (device);
-
- if (fd == -1) {
- logger (LOG_ERR, "unable to open a BPF device");
- return -1;
- }
-
- close_on_exec (fd);
-
- memset (&ifr, 0, sizeof (ifr));
- strlcpy (ifr.ifr_name, iface->name, sizeof (ifr.ifr_name));
- if (ioctl (fd, BIOCSETIF, &ifr) == -1) {
- logger (LOG_ERR,
- "cannot attach interface `%s' to bpf device `%s': %s",
- iface->name, device, strerror (errno));
- close (fd);
- return -1;
- }
-
- /* Get the required BPF buffer length from the kernel. */
- if (ioctl (fd, BIOCGBLEN, &buf) == -1) {
- logger (LOG_ERR, "ioctl BIOCGBLEN: %s", strerror (errno));
- close (fd);
- return -1;
- }
- iface->buffer_length = buf;
-
- flags = 1;
- if (ioctl (fd, BIOCIMMEDIATE, &flags) == -1) {
- logger (LOG_ERR, "ioctl BIOCIMMEDIATE: %s", strerror (errno));
- close (fd);
- return -1;
- }
-
- /* Install the DHCP filter */
- if (protocol == ETHERTYPE_ARP) {
- pf.bf_insns = arp_bpf_filter;
- pf.bf_len = sizeof (arp_bpf_filter)
- / sizeof (arp_bpf_filter[0]);
- } else {
- pf.bf_insns = dhcp_bpf_filter;
- pf.bf_len = sizeof (dhcp_bpf_filter)
- / sizeof (dhcp_bpf_filter[0]);
- }
- if (ioctl (fd, BIOCSETF, &pf) == -1) {
- logger (LOG_ERR, "ioctl BIOCSETF: %s", strerror (errno));
- close (fd);
- return -1;
- }
-
- if (iface->fd > -1)
- close (iface->fd);
- iface->fd = fd;
-
- return fd;
+ int n = 0;
+ int fd = -1;
+ char *device;
+ int flags;
+ struct ifreq ifr;
+ int buf = 0;
+ struct bpf_program pf;
+
+ device = xmalloc (sizeof (char) * PATH_MAX);
+ do
+ {
+ snprintf (device, PATH_MAX, "/dev/bpf%d", n++);
+ fd = open (device, O_RDWR);
+ }
+ while (fd == -1 && errno == EBUSY);
+ free (device);
+
+ if (fd == -1)
+ {
+ logger (LOG_ERR, "unable to open a BPF device");
+ return -1;
+ }
+
+ close_on_exec (fd);
+
+ memset (&ifr, 0, sizeof (ifr));
+ strlcpy (ifr.ifr_name, iface->name, sizeof (ifr.ifr_name));
+ if (ioctl (fd, BIOCSETIF, &ifr) == -1)
+ {
+ logger (LOG_ERR,
+ "cannot attach interface `%s' to bpf device `%s': %s",
+ iface->name, device, strerror (errno));
+ close (fd);
+ return -1;
+ }
+
+ /* Get the required BPF buffer length from the kernel. */
+ if (ioctl (fd, BIOCGBLEN, &buf) == -1)
+ {
+ logger (LOG_ERR, "ioctl BIOCGBLEN: %s", strerror (errno));
+ close (fd);
+ return -1;
+ }
+ iface->buffer_length = buf;
+
+ flags = 1;
+ if (ioctl (fd, BIOCIMMEDIATE, &flags) == -1)
+ {
+ logger (LOG_ERR, "ioctl BIOCIMMEDIATE: %s", strerror (errno));
+ close (fd);
+ return -1;
+ }
+
+ /* Install the DHCP filter */
+ if (protocol == ETHERTYPE_ARP)
+ {
+ pf.bf_insns = arp_bpf_filter;
+ pf.bf_len = sizeof (arp_bpf_filter)
+ / sizeof (arp_bpf_filter[0]);
+ }
+ else
+ {
+ pf.bf_insns = dhcp_bpf_filter;
+ pf.bf_len = sizeof (dhcp_bpf_filter)
+ / sizeof (dhcp_bpf_filter[0]);
+ }
+ if (ioctl (fd, BIOCSETF, &pf) == -1)
+ {
+ logger (LOG_ERR, "ioctl BIOCSETF: %s", strerror (errno));
+ close (fd);
+ return -1;
+ }
+
+ if (iface->fd > -1)
+ close (iface->fd);
+ iface->fd = fd;
+
+ return fd;
}
ssize_t send_packet (const interface_t *iface, int type,
- const unsigned char *data, size_t len)
+ const unsigned char *data, size_t len)
{
- ssize_t retval = -1;
- struct iovec iov[2];
-
- if (iface->family == ARPHRD_ETHER) {
- struct ether_header hw;
- memset (&hw, 0, sizeof (hw));
- memset (&hw.ether_dhost, 0xff, ETHER_ADDR_LEN);
- hw.ether_type = htons (type);
-
- iov[0].iov_base = &hw;
- iov[0].iov_len = sizeof (hw);
- } else {
- logger (LOG_ERR, "unsupported interace type %d", iface->family);
- return -1;
- }
- iov[1].iov_base = (unsigned char *) data;
- iov[1].iov_len = len;
-
- if ((retval = writev(iface->fd, iov, 2)) == -1)
- logger (LOG_ERR, "writev: %s", strerror (errno));
-
- return retval;
+ ssize_t retval = -1;
+ struct iovec iov[2];
+
+ if (iface->family == ARPHRD_ETHER)
+ {
+ struct ether_header hw;
+ memset (&hw, 0, sizeof (hw));
+ memset (&hw.ether_dhost, 0xff, ETHER_ADDR_LEN);
+ hw.ether_type = htons (type);
+
+ iov[0].iov_base = &hw;
+ iov[0].iov_len = sizeof (hw);
+ }
+ else
+ {
+ logger (LOG_ERR, "unsupported interace type %d", iface->family);
+ return -1;
+ }
+ iov[1].iov_base = (unsigned char *) data;
+ iov[1].iov_len = len;
+
+ if ((retval = writev(iface->fd, iov, 2)) == -1)
+ logger (LOG_ERR, "writev: %s", strerror (errno));
+
+ return retval;
}
/* BPF requires that we read the entire buffer.
* So we pass the buffer in the API so we can loop on >1 dhcp packet. */
ssize_t get_packet (const interface_t *iface, unsigned char *data,
- unsigned char *buffer,
- size_t *buffer_len, size_t *buffer_pos)
+ unsigned char *buffer,
+ size_t *buffer_len, size_t *buffer_pos)
{
- union
- {
- unsigned char *buffer;
- struct bpf_hdr *packet;
- } bpf;
-
- bpf.buffer = buffer;
-
- if (*buffer_pos < 1) {
- memset (bpf.buffer, 0, iface->buffer_length);
- *buffer_len = read (iface->fd, bpf.buffer, iface->buffer_length);
- *buffer_pos = 0;
- if (*buffer_len < 1) {
- struct timespec ts;
- logger (LOG_ERR, "read: %s", strerror (errno));
- ts.tv_sec = 3;
- ts.tv_nsec = 0;
- nanosleep (&ts, NULL);
- return (-1);
- }
- } else
- bpf.buffer += *buffer_pos;
-
- while (bpf.packet) {
- size_t len = 0;
- union
- {
- unsigned char *buffer;
- struct ether_header *hw;
- } hdr;
- unsigned char *payload;
- bool have_data = false;
-
- /* Ensure that the entire packet is in our buffer */
- if (*buffer_pos + bpf.packet->bh_hdrlen + bpf.packet->bh_caplen
- > (unsigned) *buffer_len)
- break;
-
- hdr.buffer = bpf.buffer + bpf.packet->bh_hdrlen;
- payload = hdr.buffer + sizeof (*hdr.hw);
-
- /* If it's an ARP reply, then just send it back */
- if (hdr.hw->ether_type == htons (ETHERTYPE_ARP)) {
- len = bpf.packet->bh_caplen -
- sizeof (*hdr.hw);
- memcpy (data, payload, len);
- have_data = true;
- } else {
- if (valid_dhcp_packet (payload) >= 0) {
- union
- {
- unsigned char *buffer;
- struct udp_dhcp_packet *packet;
- } pay;
- pay.buffer = payload;
- len = ntohs (pay.packet->ip.ip_len) -
- sizeof (pay.packet->ip) -
- sizeof (pay.packet->udp);
- memcpy (data, &pay.packet->dhcp, len);
- have_data = true;
- }
- }
-
- /* Update the buffer_pos pointer */
- bpf.buffer += BPF_WORDALIGN (bpf.packet->bh_hdrlen +
- bpf.packet->bh_caplen);
- if ((unsigned) (bpf.buffer - buffer) < *buffer_len)
- *buffer_pos = bpf.buffer - buffer;
- else
- *buffer_pos = 0;
-
- if (have_data)
- return len;
-
- if (*buffer_pos == 0)
- break;
- }
-
- /* No valid packets left, so return */
- *buffer_pos = 0;
- return -1;
+ union
+ {
+ unsigned char *buffer;
+ struct bpf_hdr *packet;
+ } bpf;
+
+ bpf.buffer = buffer;
+
+ if (*buffer_pos < 1)
+ {
+ memset (bpf.buffer, 0, iface->buffer_length);
+ *buffer_len = read (iface->fd, bpf.buffer, iface->buffer_length);
+ *buffer_pos = 0;
+ if (*buffer_len < 1)
+ {
+ struct timespec ts;
+ logger (LOG_ERR, "read: %s", strerror (errno));
+ ts.tv_sec = 3;
+ ts.tv_nsec = 0;
+ nanosleep (&ts, NULL);
+ return (-1);
+ }
+ }
+ else
+ bpf.buffer += *buffer_pos;
+
+ while (bpf.packet)
+ {
+ size_t len = 0;
+ union
+ {
+ unsigned char *buffer;
+ struct ether_header *hw;
+ } hdr;
+ unsigned char *payload;
+ bool have_data = false;
+
+ /* Ensure that the entire packet is in our buffer */
+ if (*buffer_pos + bpf.packet->bh_hdrlen + bpf.packet->bh_caplen
+ > (unsigned) *buffer_len)
+ break;
+
+ hdr.buffer = bpf.buffer + bpf.packet->bh_hdrlen;
+ payload = hdr.buffer + sizeof (*hdr.hw);
+
+ /* If it's an ARP reply, then just send it back */
+ if (hdr.hw->ether_type == htons (ETHERTYPE_ARP))
+ {
+ len = bpf.packet->bh_caplen -
+ sizeof (*hdr.hw);
+ memcpy (data, payload, len);
+ have_data = true;
+ }
+ else
+ {
+ if (valid_dhcp_packet (payload) >= 0)
+ {
+ union
+ {
+ unsigned char *buffer;
+ struct udp_dhcp_packet *packet;
+ } pay;
+ pay.buffer = payload;
+ len = ntohs (pay.packet->ip.ip_len) -
+ sizeof (pay.packet->ip) -
+ sizeof (pay.packet->udp);
+ memcpy (data, &pay.packet->dhcp, len);
+ have_data = true;
+ }
+ }
+
+ /* Update the buffer_pos pointer */
+ bpf.buffer += BPF_WORDALIGN (bpf.packet->bh_hdrlen +
+ bpf.packet->bh_caplen);
+ if ((unsigned) (bpf.buffer - buffer) < *buffer_len)
+ *buffer_pos = bpf.buffer - buffer;
+ else
+ *buffer_pos = 0;
+
+ if (have_data)
+ return len;
+
+ if (*buffer_pos == 0)
+ break;
+ }
+
+ /* No valid packets left, so return */
+ *buffer_pos = 0;
+ return -1;
}
#elif __linux__
int open_socket (interface_t *iface, int protocol)
{
- int fd;
- union sockunion {
- struct sockaddr sa;
- struct sockaddr_in sin;
- struct sockaddr_ll sll;
- struct sockaddr_storage ss;
- } su;
- struct sock_fprog pf;
- struct ifreq ifr;
- int n = 1;
-
- /* We need to bind to a port, otherwise Linux generate ICMP messages
- * that cannot contect the port when we have an address.
- * We don't actually use this fd at all, instead using our packet
- * filter socket. */
- if (iface->listen_fd == -1 && protocol == ETHERTYPE_IP) {
- if ((fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
- logger (LOG_ERR, "socket: %s", strerror (errno));
- } else {
- memset (&su, 0, sizeof (su));
- su.sin.sin_family = AF_INET;
- su.sin.sin_port = htons (DHCP_CLIENT_PORT);
- if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR,
- &n, sizeof (n)) == -1)
- logger (LOG_ERR, "SO_REUSEADDR: %s",
- strerror (errno));
- if (setsockopt (fd, SOL_SOCKET, SO_RCVBUF,
- &n, sizeof (n)) == -1)
- logger (LOG_ERR, "SO_RCVBUF: %s",
- strerror (errno));
- memset (&ifr, 0, sizeof (ifr));
- strncpy (ifr.ifr_name, iface->name,
- sizeof (ifr.ifr_name));
- if (setsockopt (fd, SOL_SOCKET, SO_BINDTODEVICE,
- &ifr, sizeof (ifr)) == -1)
- logger (LOG_ERR, "SO_SOBINDTODEVICE: %s",
- strerror (errno));
- if (bind (fd, &su.sa, sizeof (su)) == -1) {
- logger (LOG_ERR, "bind: %s", strerror (errno));
- close (fd);
- } else {
- iface->listen_fd = fd;
- close_on_exec (fd);
- }
- }
- }
-
- if ((fd = socket (PF_PACKET, SOCK_DGRAM, htons (protocol))) == -1) {
- logger (LOG_ERR, "socket: %s", strerror (errno));
- return (-1);
- }
- close_on_exec (fd);
-
- memset (&su, 0, sizeof (su));
- su.sll.sll_family = PF_PACKET;
- su.sll.sll_protocol = htons (protocol);
- if (! (su.sll.sll_ifindex = if_nametoindex (iface->name))) {
- logger (LOG_ERR,
- "if_nametoindex: no index for interface `%s'",
- iface->name);
- close (fd);
- return (-1);
- }
-
- /* Install the DHCP filter */
- memset (&pf, 0, sizeof (pf));
- if (protocol == ETHERTYPE_ARP) {
- pf.filter = arp_bpf_filter;
- pf.len = sizeof (arp_bpf_filter) / sizeof (arp_bpf_filter[0]);
- } else {
- pf.filter = dhcp_bpf_filter;
- pf.len = sizeof (dhcp_bpf_filter) / sizeof (dhcp_bpf_filter[0]);
- }
- if (setsockopt (fd, SOL_SOCKET, SO_ATTACH_FILTER,
- &pf, sizeof (pf)) != 0)
- {
- logger (LOG_ERR, "SO_ATTACH_FILTER: %s", strerror (errno));
- close (fd);
- return (-1);
- }
-
- if (bind (fd, &su.sa, sizeof (su)) == -1) {
- logger (LOG_ERR, "bind: %s", strerror (errno));
- close (fd);
- return (-1);
- }
-
- if (iface->fd > -1)
- close (iface->fd);
- iface->fd = fd;
- iface->socket_protocol = protocol;
- iface->buffer_length = BUFFER_LENGTH;
-
- return (fd);
+ int fd;
+ union sockunion
+ {
+ struct sockaddr sa;
+ struct sockaddr_in sin;
+ struct sockaddr_ll sll;
+ struct sockaddr_storage ss;
+ } su;
+ struct sock_fprog pf;
+ struct ifreq ifr;
+ int n = 1;
+
+ /* We need to bind to a port, otherwise Linux generate ICMP messages
+ * that cannot contect the port when we have an address.
+ * We don't actually use this fd at all, instead using our packet
+ * filter socket. */
+ if (iface->listen_fd == -1 && protocol == ETHERTYPE_IP)
+ {
+ if ((fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
+ {
+ logger (LOG_ERR, "socket: %s", strerror (errno));
+ }
+ else
+ {
+ memset (&su, 0, sizeof (su));
+ su.sin.sin_family = AF_INET;
+ su.sin.sin_port = htons (DHCP_CLIENT_PORT);
+ if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR,
+ &n, sizeof (n)) == -1)
+ logger (LOG_ERR, "SO_REUSEADDR: %s",
+ strerror (errno));
+ if (setsockopt (fd, SOL_SOCKET, SO_RCVBUF,
+ &n, sizeof (n)) == -1)
+ logger (LOG_ERR, "SO_RCVBUF: %s",
+ strerror (errno));
+ memset (&ifr, 0, sizeof (ifr));
+ strncpy (ifr.ifr_name, iface->name,
+ sizeof (ifr.ifr_name));
+ if (setsockopt (fd, SOL_SOCKET, SO_BINDTODEVICE,
+ &ifr, sizeof (ifr)) == -1)
+ logger (LOG_ERR, "SO_SOBINDTODEVICE: %s",
+ strerror (errno));
+ if (bind (fd, &su.sa, sizeof (su)) == -1)
+ {
+ logger (LOG_ERR, "bind: %s", strerror (errno));
+ close (fd);
+ }
+ else
+ {
+ iface->listen_fd = fd;
+ close_on_exec (fd);
+ }
+ }
+ }
+
+ if ((fd = socket (PF_PACKET, SOCK_DGRAM, htons (protocol))) == -1)
+ {
+ logger (LOG_ERR, "socket: %s", strerror (errno));
+ return (-1);
+ }
+ close_on_exec (fd);
+
+ memset (&su, 0, sizeof (su));
+ su.sll.sll_family = PF_PACKET;
+ su.sll.sll_protocol = htons (protocol);
+ if (! (su.sll.sll_ifindex = if_nametoindex (iface->name)))
+ {
+ logger (LOG_ERR,
+ "if_nametoindex: no index for interface `%s'",
+ iface->name);
+ close (fd);
+ return (-1);
+ }
+
+ /* Install the DHCP filter */
+ memset (&pf, 0, sizeof (pf));
+ if (protocol == ETHERTYPE_ARP)
+ {
+ pf.filter = arp_bpf_filter;
+ pf.len = sizeof (arp_bpf_filter) / sizeof (arp_bpf_filter[0]);
+ }
+ else
+ {
+ pf.filter = dhcp_bpf_filter;
+ pf.len = sizeof (dhcp_bpf_filter) / sizeof (dhcp_bpf_filter[0]);
+ }
+ if (setsockopt (fd, SOL_SOCKET, SO_ATTACH_FILTER,
+ &pf, sizeof (pf)) != 0)
+ {
+ logger (LOG_ERR, "SO_ATTACH_FILTER: %s", strerror (errno));
+ close (fd);
+ return (-1);
+ }
+
+ if (bind (fd, &su.sa, sizeof (su)) == -1)
+ {
+ logger (LOG_ERR, "bind: %s", strerror (errno));
+ close (fd);
+ return (-1);
+ }
+
+ if (iface->fd > -1)
+ close (iface->fd);
+ iface->fd = fd;
+ iface->socket_protocol = protocol;
+ iface->buffer_length = BUFFER_LENGTH;
+
+ return (fd);
}
ssize_t send_packet (const interface_t *iface, int type,
- const unsigned char *data, size_t len)
+ const unsigned char *data, size_t len)
{
- union sockunion {
- struct sockaddr sa;
- struct sockaddr_ll sll;
- struct sockaddr_storage ss;
- } su;
- ssize_t retval;
-
- if (! iface)
- return (-1);
-
- memset (&su, 0, sizeof (su));
- su.sll.sll_family = AF_PACKET;
- su.sll.sll_protocol = htons (type);
-
- if (! (su.sll.sll_ifindex = if_nametoindex (iface->name))) {
- logger (LOG_ERR, "if_nametoindex: no index for interface `%s'",
- iface->name);
- return (-1);
- }
-
- su.sll.sll_hatype = htons (iface->family);
- su.sll.sll_halen = iface->hwlen;
- if (iface->family == ARPHRD_INFINIBAND)
- memcpy (&su.sll.sll_addr,
- &ipv4_bcast_addr, sizeof (ipv4_bcast_addr));
- else
- memset (&su.sll.sll_addr, 0xff, iface->hwlen);
-
- if ((retval = sendto (iface->fd, data, len, 0, &su.sa,
- sizeof (su))) == -1)
-
- logger (LOG_ERR, "sendto: %s", strerror (errno));
- return (retval);
+ union sockunion
+ {
+ struct sockaddr sa;
+ struct sockaddr_ll sll;
+ struct sockaddr_storage ss;
+ } su;
+ ssize_t retval;
+
+ if (! iface)
+ return (-1);
+
+ memset (&su, 0, sizeof (su));
+ su.sll.sll_family = AF_PACKET;
+ su.sll.sll_protocol = htons (type);
+
+ if (! (su.sll.sll_ifindex = if_nametoindex (iface->name)))
+ {
+ logger (LOG_ERR, "if_nametoindex: no index for interface `%s'",
+ iface->name);
+ return (-1);
+ }
+
+ su.sll.sll_hatype = htons (iface->family);
+ su.sll.sll_halen = iface->hwlen;
+ if (iface->family == ARPHRD_INFINIBAND)
+ memcpy (&su.sll.sll_addr,
+ &ipv4_bcast_addr, sizeof (ipv4_bcast_addr));
+ else
+ memset (&su.sll.sll_addr, 0xff, iface->hwlen);
+
+ if ((retval = sendto (iface->fd, data, len, 0, &su.sa,
+ sizeof (su))) == -1)
+
+ logger (LOG_ERR, "sendto: %s", strerror (errno));
+ return (retval);
}
/* Linux has no need for the buffer as we can read as much as we want.
* We only have the buffer listed to keep the same API. */
ssize_t get_packet (const interface_t *iface, unsigned char *data,
- unsigned char *buffer,
- size_t *buffer_len, size_t *buffer_pos)
+ unsigned char *buffer,
+ size_t *buffer_len, size_t *buffer_pos)
{
- ssize_t bytes;
- union
- {
- unsigned char *buffer;
- struct udp_dhcp_packet *packet;
- } pay;
-
- /* We don't use the given buffer, but we need to rewind the position */
- *buffer_pos = 0;
-
- memset (buffer, 0, iface->buffer_length);
- bytes = read (iface->fd, buffer, iface->buffer_length);
-
- if (bytes == -1) {
- struct timespec ts;
- logger (LOG_ERR, "read: %s", strerror (errno));
- ts.tv_sec = 3;
- ts.tv_nsec = 0;
- nanosleep (&ts, NULL);
- return (-1);
- }
-
- *buffer_len = bytes;
- /* If it's an ARP reply, then just send it back */
- if (iface->socket_protocol == ETHERTYPE_ARP) {
- memcpy (data, buffer, bytes);
- return (bytes);
- }
-
- if ((unsigned) bytes < (sizeof (pay.packet->ip) +
- sizeof (pay.packet->udp)))
- {
- logger (LOG_DEBUG, "message too short, ignoring");
- return (-1);
- }
-
- pay.buffer = buffer;
- if (bytes < ntohs (pay.packet->ip.ip_len)) {
- logger (LOG_DEBUG, "truncated packet, ignoring");
- return (-1);
- }
-
- if (valid_dhcp_packet (buffer) == -1)
- return (-1);
-
- bytes = ntohs (pay.packet->ip.ip_len) -
- (sizeof (pay.packet->ip) + sizeof (pay.packet->udp));
- memcpy (data, &pay.packet->dhcp, bytes);
- return (bytes);
+ ssize_t bytes;
+ union
+ {
+ unsigned char *buffer;
+ struct udp_dhcp_packet *packet;
+ } pay;
+
+ /* We don't use the given buffer, but we need to rewind the position */
+ *buffer_pos = 0;
+
+ memset (buffer, 0, iface->buffer_length);
+ bytes = read (iface->fd, buffer, iface->buffer_length);
+
+ if (bytes == -1)
+ {
+ struct timespec ts;
+ logger (LOG_ERR, "read: %s", strerror (errno));
+ ts.tv_sec = 3;
+ ts.tv_nsec = 0;
+ nanosleep (&ts, NULL);
+ return (-1);
+ }
+
+ *buffer_len = bytes;
+ /* If it's an ARP reply, then just send it back */
+ if (iface->socket_protocol == ETHERTYPE_ARP)
+ {
+ memcpy (data, buffer, bytes);
+ return (bytes);
+ }
+
+ if ((unsigned) bytes < (sizeof (pay.packet->ip) +
+ sizeof (pay.packet->udp)))
+ {
+ logger (LOG_DEBUG, "message too short, ignoring");
+ return (-1);
+ }
+
+ pay.buffer = buffer;
+ if (bytes < ntohs (pay.packet->ip.ip_len))
+ {
+ logger (LOG_DEBUG, "truncated packet, ignoring");
+ return (-1);
+ }
+
+ if (valid_dhcp_packet (buffer) == -1)
+ return (-1);
+
+ bytes = ntohs (pay.packet->ip.ip_len) -
+ (sizeof (pay.packet->ip) + sizeof (pay.packet->udp));
+ memcpy (data, &pay.packet->dhcp, bytes);
+ return (bytes);
}
#else
- #error "Platform not supported!"
- #error "We currently support BPF and Linux sockets."
- #error "Other platforms may work using BPF. If yours does, please let me know"
- #error "so I can add it to our list."
+#error "Platform not supported!"
+#error "We currently support BPF and Linux sockets."
+#error "Other platforms may work using BPF. If yours does, please let me know"
+#error "so I can add it to our list."
#endif
diff --git a/src/customdhcpcd/socket.h b/src/customdhcpcd/socket.h
index bdf26d0..1ab53ab 100644
--- a/src/customdhcpcd/socket.h
+++ b/src/customdhcpcd/socket.h
@@ -1,4 +1,4 @@
-/*
+/*
* dhcpcd - DHCP client daemon
* Copyright 2006-2008 Roy Marples <roy@marples.name>
* All rights reserved
@@ -35,12 +35,12 @@
void setup_packet_filters (void);
void make_dhcp_packet(struct udp_dhcp_packet *packet,
- const unsigned char *data, size_t length,
- struct in_addr source, struct in_addr dest);
+ const unsigned char *data, size_t length,
+ struct in_addr source, struct in_addr dest);
int open_socket (interface_t *iface, int protocol);
ssize_t send_packet (const interface_t *iface, int type,
- const unsigned char *data, size_t len);
+ const unsigned char *data, size_t len);
ssize_t get_packet (const interface_t *iface, unsigned char *data,
- unsigned char *buffer, size_t *buffer_len, size_t *buffer_pos);
+ unsigned char *buffer, size_t *buffer_len, size_t *buffer_pos);
#endif