#define ar_sha(ap) (((unsigned char *) ((ap) + 1)) + 0)
#define ar_spa(ap) (((unsigned char *) ((ap) + 1)) + (ap)->ar_hln)
#define ar_tha(ap) (((unsigned char *) ((ap) + 1)) + \
- (ap)->ar_hln + (ap)->ar_pln)
+ (ap)->ar_hln + (ap)->ar_pln)
#define ar_tpa(ap) (((unsigned char *) ((ap) + 1)) + \
- 2 * (ap)->ar_hln + (ap)->ar_pln)
+ 2 * (ap)->ar_hln + (ap)->ar_pln)
#define arphdr_len2(ar_hln, ar_pln) (sizeof (struct arphdr) + \
- 2 * (ar_hln) + 2 * (ar_pln))
+ 2 * (ar_hln) + 2 * (ar_pln))
#define arphdr_len(ap) (arphdr_len2 ((ap)->ar_hln, (ap)->ar_pln))
#endif
int arp_check (interface_t *iface, struct in_addr address)
{
union
- {
- unsigned char buffer[iface->buffer_length];
- struct arphdr ah;
- } arp;
+ {
+ unsigned char buffer[iface->buffer_length];
+ struct arphdr ah;
+ } arp;
int bytes;
struct timeval tv;
if (! iface->arpable)
{
logger (LOG_DEBUG, "arp_check: interface `%s' is not ARPable",
- iface->name);
+ iface->name);
return 0;
}
memcpy (ar_tpa (&arp.ah), &address, arp.ah.ar_pln);
logger (LOG_INFO, "checking %s is available on attached networks", inet_ntoa
- (address));
+ (address));
open_socket (iface, true);
send_packet (iface, ETHERTYPE_ARP, (unsigned char *) &arp.buffer,
- arphdr_len (&arp.ah));
+ arphdr_len (&arp.ah));
timeout = uptime() + TIMEOUT;
while (1)
tv.tv_usec = 0;
if (tv.tv_sec < 1)
- break; /* Time out */
+ break; /* Time out */
FD_ZERO (&rset);
FD_SET (iface->fd, &rset);
if (select (iface->fd + 1, &rset, NULL, NULL, &tv) == 0)
- break;
+ break;
if (! FD_ISSET (iface->fd, &rset))
- continue;
+ continue;
memset (arp.buffer, 0, sizeof (arp.buffer));
while (bufpos != 0)
- {
- union
- {
- unsigned char buffer[buflen];
- struct arphdr hdr;
- } reply;
- union
- {
- unsigned char *c;
- struct in_addr *a;
- } rp;
- union
- {
- unsigned char *c;
- struct ether_addr *a;
- } rh;
- memset (reply.buffer, 0, sizeof (reply.buffer));
- if ((bytes = get_packet (iface, reply.buffer, arp.buffer,
- &buflen, &bufpos)) < 0)
- break;
-
- /* Only these types are recognised */
- if (reply.hdr.ar_op != htons(ARPOP_REPLY))
- continue;
-
- /* Protocol must be IP. */
- if (reply.hdr.ar_pro != htons (ETHERTYPE_IP))
- continue;
- if (reply.hdr.ar_pln != sizeof (struct in_addr))
- continue;
-
- if (reply.hdr.ar_hln != ETHER_ADDR_LEN)
- continue;
- if ((unsigned) bytes < sizeof (reply.hdr) +
- 2 * (4 + reply.hdr.ar_hln))
- continue;
-
- rp.c = (unsigned char *) ar_spa (&reply.hdr);
- rh.c = (unsigned char *) ar_sha (&reply.hdr);
- logger (LOG_ERR, "ARPOP_REPLY received from %s (%s)",
- inet_ntoa (*rp.a), ether_ntoa (rh.a));
- close (iface->fd);
- iface->fd = -1;
- return 1;
- }
+ {
+ union
+ {
+ unsigned char buffer[buflen];
+ struct arphdr hdr;
+ } reply;
+ union
+ {
+ unsigned char *c;
+ struct in_addr *a;
+ } rp;
+ union
+ {
+ unsigned char *c;
+ struct ether_addr *a;
+ } rh;
+ memset (reply.buffer, 0, sizeof (reply.buffer));
+ if ((bytes = get_packet (iface, reply.buffer, arp.buffer,
+ &buflen, &bufpos)) < 0)
+ break;
+
+ /* Only these types are recognised */
+ if (reply.hdr.ar_op != htons(ARPOP_REPLY))
+ continue;
+
+ /* Protocol must be IP. */
+ if (reply.hdr.ar_pro != htons (ETHERTYPE_IP))
+ continue;
+ if (reply.hdr.ar_pln != sizeof (struct in_addr))
+ continue;
+
+ if (reply.hdr.ar_hln != ETHER_ADDR_LEN)
+ continue;
+ if ((unsigned) bytes < sizeof (reply.hdr) +
+ 2 * (4 + reply.hdr.ar_hln))
+ continue;
+
+ rp.c = (unsigned char *) ar_spa (&reply.hdr);
+ rh.c = (unsigned char *) ar_sha (&reply.hdr);
+ logger (LOG_ERR, "ARPOP_REPLY received from %s (%s)",
+ inet_ntoa (*rp.a), ether_ntoa (rh.a));
+ close (iface->fd);
+ iface->fd = -1;
+ return 1;
+ }
}
close (iface->fd);
{ \
memset (&dhcp->address, 0, sizeof (struct in_addr)); \
if (iface->previous_address.s_addr != 0 && ! options->persistent) \
- configure (options, iface, dhcp); \
+ configure (options, iface, dhcp); \
free_dhcp (dhcp); \
memset (dhcp, 0, sizeof (dhcp_t)); \
}
fd = open ("/dev/urandom", 0);
if (fd < 0 || read (fd, &seed, sizeof(seed)) < 0)
- {
- logger (LOG_WARNING, "Could not load seed from /dev/urandom: %s",
- strerror (errno));
- seed = time (0);
- }
+ {
+ logger (LOG_WARNING, "Could not load seed from /dev/urandom: %s",
+ strerror (errno));
+ seed = time (0);
+ }
if (fd >= 0)
- close(fd);
+ close(fd);
srand(seed);
initialized++;
int buffer_pos = 0;
if (! options || (iface = (read_interface (options->interface,
- options->metric))) == NULL)
+ options->metric))) == NULL)
return -1;
/* Remove all existing addresses.
while (1)
{
if (timeout > 0 || (options->timeout == 0 &&
- (state != STATE_INIT || xid)))
- {
- if (options->timeout == 0 ||
- (dhcp->leasetime == (unsigned) -1 && state == STATE_BOUND))
- {
- int retry = 0;
- logger (LOG_DEBUG, "waiting on select for infinity");
- retval = 0;
- while (retval == 0)
- {
- maxfd = signal_fd_set (&rset, iface->fd);
- if (iface->fd == -1)
- retval = select (maxfd + 1, &rset, NULL, NULL, NULL);
- else
- {
- /* Slow down our requests */
- if (retry < TIMEOUT_MINI_INF)
- retry += TIMEOUT_MINI;
- else if (retry > TIMEOUT_MINI_INF)
- retry = TIMEOUT_MINI_INF;
-
- tv.tv_sec = retry;
- tv.tv_usec = 0;
- retval = select (maxfd + 1, &rset, NULL, NULL, &tv);
- if (retval == 0)
- SEND_MESSAGE (last_type);
- }
- }
- }
- else
- {
- /* Resend our message if we're getting loads of packets
- that aren't for us. This mainly happens on Linux as it
- doesn't have a nice BPF filter. */
- if (iface->fd > -1 && uptime () - last_send >= TIMEOUT_MINI)
- SEND_MESSAGE (last_type);
-
- logger (LOG_DEBUG, "waiting on select for %ld seconds",
- 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 (timeout > 0 && retval == 0)
- {
- if (iface->fd == -1)
- tv.tv_sec = SELECT_MAX;
- else
- tv.tv_sec = TIMEOUT_MINI;
- if (timeout < tv.tv_sec)
- tv.tv_sec = timeout;
- tv.tv_usec = 0;
- start = uptime ();
- maxfd = signal_fd_set (&rset, iface->fd);
- retval = select (maxfd + 1, &rset, NULL, NULL, &tv);
- timeout -= uptime () - start;
- if (retval == 0 && iface->fd != -1 && timeout > 0)
- SEND_MESSAGE (last_type);
- }
- }
- }
+ (state != STATE_INIT || xid)))
+ {
+ if (options->timeout == 0 ||
+ (dhcp->leasetime == (unsigned) -1 && state == STATE_BOUND))
+ {
+ int retry = 0;
+ logger (LOG_DEBUG, "waiting on select for infinity");
+ retval = 0;
+ while (retval == 0)
+ {
+ maxfd = signal_fd_set (&rset, iface->fd);
+ if (iface->fd == -1)
+ retval = select (maxfd + 1, &rset, NULL, NULL, NULL);
+ else
+ {
+ /* Slow down our requests */
+ if (retry < TIMEOUT_MINI_INF)
+ retry += TIMEOUT_MINI;
+ else if (retry > TIMEOUT_MINI_INF)
+ retry = TIMEOUT_MINI_INF;
+
+ tv.tv_sec = retry;
+ tv.tv_usec = 0;
+ retval = select (maxfd + 1, &rset, NULL, NULL, &tv);
+ if (retval == 0)
+ SEND_MESSAGE (last_type);
+ }
+ }
+ }
+ else
+ {
+ /* Resend our message if we're getting loads of packets
+ that aren't for us. This mainly happens on Linux as it
+ doesn't have a nice BPF filter. */
+ if (iface->fd > -1 && uptime () - last_send >= TIMEOUT_MINI)
+ SEND_MESSAGE (last_type);
+
+ logger (LOG_DEBUG, "waiting on select for %ld seconds",
+ 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 (timeout > 0 && retval == 0)
+ {
+ if (iface->fd == -1)
+ tv.tv_sec = SELECT_MAX;
+ else
+ tv.tv_sec = TIMEOUT_MINI;
+ if (timeout < tv.tv_sec)
+ tv.tv_sec = timeout;
+ tv.tv_usec = 0;
+ start = uptime ();
+ maxfd = signal_fd_set (&rset, iface->fd);
+ retval = select (maxfd + 1, &rset, NULL, NULL, &tv);
+ timeout -= uptime () - start;
+ if (retval == 0 && iface->fd != -1 && timeout > 0)
+ SEND_MESSAGE (last_type);
+ }
+ }
+ }
else
- retval = 0;
+ retval = 0;
/* We should always handle our signals first */
if (retval > 0 && (sig = signal_read (&rset)))
- {
- switch (sig)
- {
- case SIGINT:
- logger (LOG_INFO, "received SIGINT, stopping");
- retval = (! daemonised);
- goto eexit;
-
- case SIGTERM:
- logger (LOG_INFO, "received SIGTERM, stopping");
- retval = (! daemonised);
- goto eexit;
-
- case SIGALRM:
-
- logger (LOG_INFO, "received SIGALRM, renewing lease");
- switch (state)
- {
- case STATE_BOUND:
- case STATE_RENEWING:
- case STATE_REBINDING:
- state = STATE_RENEW_REQUESTED;
- break;
- case STATE_RENEW_REQUESTED:
- case STATE_REQUESTING:
- case STATE_RELEASED:
- state = STATE_INIT;
- break;
- }
-
- timeout = 0;
- xid = 0;
- break;
-
- case SIGHUP:
- if (state == STATE_BOUND || state == STATE_RENEWING
- || state == STATE_REBINDING)
- {
- logger (LOG_INFO, "received SIGHUP, releasing lease");
- SOCKET_MODE (SOCKET_OPEN);
- xid = random_xid ();
- if ((open_socket (iface, false)) >= 0)
- SEND_MESSAGE (DHCP_RELEASE);
- SOCKET_MODE (SOCKET_CLOSED);
- unlink (iface->infofile);
- }
- else
- logger (LOG_ERR,
- "received SIGHUP, but no we have lease to release");
- retval = 0;
- goto eexit;
-
- default:
- logger (LOG_ERR,
- "received signal %d, but don't know what to do with it",
- sig);
- }
- }
+ {
+ switch (sig)
+ {
+ case SIGINT:
+ logger (LOG_INFO, "received SIGINT, stopping");
+ retval = (! daemonised);
+ goto eexit;
+
+ case SIGTERM:
+ logger (LOG_INFO, "received SIGTERM, stopping");
+ retval = (! daemonised);
+ goto eexit;
+
+ case SIGALRM:
+
+ logger (LOG_INFO, "received SIGALRM, renewing lease");
+ switch (state)
+ {
+ case STATE_BOUND:
+ case STATE_RENEWING:
+ case STATE_REBINDING:
+ state = STATE_RENEW_REQUESTED;
+ break;
+ case STATE_RENEW_REQUESTED:
+ case STATE_REQUESTING:
+ case STATE_RELEASED:
+ state = STATE_INIT;
+ break;
+ }
+
+ timeout = 0;
+ xid = 0;
+ break;
+
+ case SIGHUP:
+ if (state == STATE_BOUND || state == STATE_RENEWING
+ || state == STATE_REBINDING)
+ {
+ logger (LOG_INFO, "received SIGHUP, releasing lease");
+ SOCKET_MODE (SOCKET_OPEN);
+ xid = random_xid ();
+ if ((open_socket (iface, false)) >= 0)
+ SEND_MESSAGE (DHCP_RELEASE);
+ SOCKET_MODE (SOCKET_CLOSED);
+ unlink (iface->infofile);
+ }
+ else
+ logger (LOG_ERR,
+ "received SIGHUP, but no we have lease to release");
+ retval = 0;
+ goto eexit;
+
+ default:
+ logger (LOG_ERR,
+ "received signal %d, but don't know what to do with it",
+ sig);
+ }
+ }
else if (retval == 0) /* timed out */
- {
- switch (state)
- {
- case STATE_INIT:
- if (iface->previous_address.s_addr != 0)
- {
- logger (LOG_ERR, "lost lease");
- xid = 0;
- SOCKET_MODE (SOCKET_CLOSED);
- if (! options->persistent)
- DROP_CONFIG;
- }
-
- if (xid == 0)
- xid = random_xid ();
- else
- {
- logger (LOG_ERR, "timed out");
- if (! daemonised)
- {
- retval = -1;
- goto eexit;
- }
- }
-
- SOCKET_MODE (SOCKET_OPEN);
- timeout = options->timeout;
- iface->start_uptime = uptime ();
- if (dhcp->address.s_addr == 0)
- {
- logger (LOG_INFO, "broadcasting for a lease");
- SEND_MESSAGE (DHCP_DISCOVER);
- }
- else
- {
- logger (LOG_INFO, "broadcasting for a lease of %s",
- inet_ntoa (dhcp->address));
- SEND_MESSAGE (DHCP_REQUEST);
- state = STATE_REQUESTING;
- }
-
- break;
- case STATE_BOUND:
- case STATE_RENEW_REQUESTED:
- state = STATE_RENEWING;
- xid = random_xid ();
- case STATE_RENEWING:
- iface->start_uptime = uptime ();
- logger (LOG_INFO, "renewing lease of %s", inet_ntoa
- (dhcp->address));
- SOCKET_MODE (SOCKET_OPEN);
- SEND_MESSAGE (DHCP_REQUEST);
- timeout = dhcp->rebindtime - dhcp->renewaltime;
- state = STATE_REBINDING;
- break;
- case STATE_REBINDING:
- logger (LOG_ERR, "lost lease, attemping to rebind");
- memset (&dhcp->address, 0, sizeof (struct in_addr));
- SOCKET_MODE (SOCKET_OPEN);
- SEND_MESSAGE (DHCP_REQUEST);
- timeout = dhcp->leasetime - dhcp->rebindtime;
- state = STATE_REQUESTING;
- break;
- case STATE_REQUESTING:
- if (iface->previous_address.s_addr != 0)
- logger (LOG_ERR, "lost lease");
- else
- logger (LOG_ERR, "timed out");
- if (! daemonised && options->daemonise)
- goto eexit;
-
- state = STATE_INIT;
- SOCKET_MODE (SOCKET_CLOSED);
- timeout = 0;
- xid = 0;
- DROP_CONFIG;
- break;
-
- case STATE_RELEASED:
- dhcp->leasetime = -1;
- break;
- }
- }
+ {
+ switch (state)
+ {
+ case STATE_INIT:
+ if (iface->previous_address.s_addr != 0)
+ {
+ logger (LOG_ERR, "lost lease");
+ xid = 0;
+ SOCKET_MODE (SOCKET_CLOSED);
+ if (! options->persistent)
+ DROP_CONFIG;
+ }
+
+ if (xid == 0)
+ xid = random_xid ();
+ else
+ {
+ logger (LOG_ERR, "timed out");
+ if (! daemonised)
+ {
+ retval = -1;
+ goto eexit;
+ }
+ }
+
+ SOCKET_MODE (SOCKET_OPEN);
+ timeout = options->timeout;
+ iface->start_uptime = uptime ();
+ if (dhcp->address.s_addr == 0)
+ {
+ logger (LOG_INFO, "broadcasting for a lease");
+ SEND_MESSAGE (DHCP_DISCOVER);
+ }
+ else
+ {
+ logger (LOG_INFO, "broadcasting for a lease of %s",
+ inet_ntoa (dhcp->address));
+ SEND_MESSAGE (DHCP_REQUEST);
+ state = STATE_REQUESTING;
+ }
+
+ break;
+ case STATE_BOUND:
+ case STATE_RENEW_REQUESTED:
+ state = STATE_RENEWING;
+ xid = random_xid ();
+ case STATE_RENEWING:
+ iface->start_uptime = uptime ();
+ logger (LOG_INFO, "renewing lease of %s", inet_ntoa
+ (dhcp->address));
+ SOCKET_MODE (SOCKET_OPEN);
+ SEND_MESSAGE (DHCP_REQUEST);
+ timeout = dhcp->rebindtime - dhcp->renewaltime;
+ state = STATE_REBINDING;
+ break;
+ case STATE_REBINDING:
+ logger (LOG_ERR, "lost lease, attemping to rebind");
+ memset (&dhcp->address, 0, sizeof (struct in_addr));
+ SOCKET_MODE (SOCKET_OPEN);
+ SEND_MESSAGE (DHCP_REQUEST);
+ timeout = dhcp->leasetime - dhcp->rebindtime;
+ state = STATE_REQUESTING;
+ break;
+ case STATE_REQUESTING:
+ if (iface->previous_address.s_addr != 0)
+ logger (LOG_ERR, "lost lease");
+ else
+ logger (LOG_ERR, "timed out");
+ if (! daemonised && options->daemonise)
+ goto eexit;
+
+ state = STATE_INIT;
+ SOCKET_MODE (SOCKET_CLOSED);
+ timeout = 0;
+ xid = 0;
+ DROP_CONFIG;
+ break;
+
+ case STATE_RELEASED:
+ dhcp->leasetime = -1;
+ break;
+ }
+ }
else if (retval > 0 && mode != SOCKET_CLOSED && FD_ISSET(iface->fd, &rset))
- {
- int valid = 0;
- struct dhcp_t *new_dhcp;
-
- /* 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 (! buffer)
- buffer = xmalloc (iface->buffer_length);
- buffer_len = iface->buffer_length;
- buffer_pos = -1;
-
- /* 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 (struct dhcpmessage_t));
- new_dhcp = xmalloc (sizeof (dhcp_t));
-
- while (buffer_pos != 0)
- {
- if (get_packet (iface, (unsigned char *) &message, buffer,
- &buffer_len, &buffer_pos) < 0)
- break;
-
- if (xid != message.xid)
- {
- logger (LOG_ERR,
- "ignoring packet with xid 0x%x as it's not ours (0x%x)",
- message.xid, xid);
- continue;
- }
-
- logger (LOG_DEBUG, "got a packet with xid 0x%x", message.xid);
- memset (new_dhcp, 0, sizeof (dhcp_t));
- if ((type = parse_dhcpmessage (new_dhcp, &message)) < 0)
- {
- logger (LOG_ERR, "failed to parse packet");
- free_dhcp (new_dhcp);
- continue;
- }
-
- /* 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 = 1;
- break;
- }
-
- /* No packets for us, so wait until we get one */
- if (! valid)
- {
- free (new_dhcp);
- continue;
- }
-
- /* new_dhcp is now our master DHCP message */
- free_dhcp (dhcp);
- free (dhcp);
- dhcp = new_dhcp;
- new_dhcp = NULL;
-
- /* We should restart on a NAK */
- if (type == DHCP_NAK)
- {
- logger (LOG_INFO, "received NAK: %s", dhcp->message);
- state = STATE_INIT;
- timeout = 0;
- xid = 0;
- DROP_CONFIG;
- continue;
- }
-
- switch (state)
- {
- case STATE_INIT:
- if (type == DHCP_OFFER)
- {
- 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);
-
- SEND_MESSAGE (DHCP_REQUEST);
- state = STATE_REQUESTING;
- }
- break;
-
- case STATE_RENEW_REQUESTED:
- case STATE_REQUESTING:
- case STATE_RENEWING:
- case STATE_REBINDING:
- if (type == DHCP_ACK)
- {
- SOCKET_MODE (SOCKET_CLOSED);
- if (options->doarp && iface->previous_address.s_addr !=
- dhcp->address.s_addr)
- {
- if (arp_check (iface, dhcp->address))
- {
- SOCKET_MODE (SOCKET_OPEN);
- SEND_MESSAGE (DHCP_DECLINE);
- SOCKET_MODE (SOCKET_CLOSED);
- DROP_CONFIG;
-
- xid = 0;
- timeout = 0;
- state = STATE_INIT;
- /* RFC 2131 says that we should wait for 10 seconds
- before doing anything else */
- logger (LOG_INFO, "sleeping for 10 seconds");
- tv.tv_sec = 10;
- tv.tv_usec = 0;
- select (0, NULL, NULL, NULL, &tv);
- continue;
- }
- }
-
- if (dhcp->leasetime == (unsigned) -1)
- {
- dhcp->renewaltime = dhcp->rebindtime = dhcp->leasetime;
- timeout = 1; /* So we select on infinity */
- logger (LOG_INFO, "leased %s for infinity",
- inet_ntoa (dhcp->address));
- }
- 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);
-
- timeout = dhcp->renewaltime;
- }
-
- state = STATE_BOUND;
- xid = 0;
-
- if (configure (options, iface, dhcp) < 0 && ! daemonised)
- {
- retval = -1;
- goto eexit;
- }
-
- if (! daemonised && options->daemonise)
- {
- if ((daemonise (options->pidfile)) < 0 )
- {
- retval = -1;
- goto eexit;
- }
- daemonised = true;
- }
- }
- else if (type == DHCP_OFFER)
- logger (LOG_INFO, "got subsequent offer of %s, ignoring ",
- inet_ntoa (dhcp->address));
- else
- logger (LOG_ERR,
- "no idea what to do with DHCP type %d at this point",
- type);
- break;
- }
- }
+ {
+ int valid = 0;
+ struct dhcp_t *new_dhcp;
+
+ /* 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 (! buffer)
+ buffer = xmalloc (iface->buffer_length);
+ buffer_len = iface->buffer_length;
+ buffer_pos = -1;
+
+ /* 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 (struct dhcpmessage_t));
+ new_dhcp = xmalloc (sizeof (dhcp_t));
+
+ while (buffer_pos != 0)
+ {
+ if (get_packet (iface, (unsigned char *) &message, buffer,
+ &buffer_len, &buffer_pos) < 0)
+ break;
+
+ if (xid != message.xid)
+ {
+ logger (LOG_ERR,
+ "ignoring packet with xid 0x%x as it's not ours (0x%x)",
+ message.xid, xid);
+ continue;
+ }
+
+ logger (LOG_DEBUG, "got a packet with xid 0x%x", message.xid);
+ memset (new_dhcp, 0, sizeof (dhcp_t));
+ if ((type = parse_dhcpmessage (new_dhcp, &message)) < 0)
+ {
+ logger (LOG_ERR, "failed to parse packet");
+ free_dhcp (new_dhcp);
+ continue;
+ }
+
+ /* 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 = 1;
+ break;
+ }
+
+ /* No packets for us, so wait until we get one */
+ if (! valid)
+ {
+ free (new_dhcp);
+ continue;
+ }
+
+ /* new_dhcp is now our master DHCP message */
+ free_dhcp (dhcp);
+ free (dhcp);
+ dhcp = new_dhcp;
+ new_dhcp = NULL;
+
+ /* We should restart on a NAK */
+ if (type == DHCP_NAK)
+ {
+ logger (LOG_INFO, "received NAK: %s", dhcp->message);
+ state = STATE_INIT;
+ timeout = 0;
+ xid = 0;
+ DROP_CONFIG;
+ continue;
+ }
+
+ switch (state)
+ {
+ case STATE_INIT:
+ if (type == DHCP_OFFER)
+ {
+ 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);
+
+ SEND_MESSAGE (DHCP_REQUEST);
+ state = STATE_REQUESTING;
+ }
+ break;
+
+ case STATE_RENEW_REQUESTED:
+ case STATE_REQUESTING:
+ case STATE_RENEWING:
+ case STATE_REBINDING:
+ if (type == DHCP_ACK)
+ {
+ SOCKET_MODE (SOCKET_CLOSED);
+ if (options->doarp && iface->previous_address.s_addr !=
+ dhcp->address.s_addr)
+ {
+ if (arp_check (iface, dhcp->address))
+ {
+ SOCKET_MODE (SOCKET_OPEN);
+ SEND_MESSAGE (DHCP_DECLINE);
+ SOCKET_MODE (SOCKET_CLOSED);
+ DROP_CONFIG;
+
+ xid = 0;
+ timeout = 0;
+ state = STATE_INIT;
+ /* RFC 2131 says that we should wait for 10 seconds
+ before doing anything else */
+ logger (LOG_INFO, "sleeping for 10 seconds");
+ tv.tv_sec = 10;
+ tv.tv_usec = 0;
+ select (0, NULL, NULL, NULL, &tv);
+ continue;
+ }
+ }
+
+ if (dhcp->leasetime == (unsigned) -1)
+ {
+ dhcp->renewaltime = dhcp->rebindtime = dhcp->leasetime;
+ timeout = 1; /* So we select on infinity */
+ logger (LOG_INFO, "leased %s for infinity",
+ inet_ntoa (dhcp->address));
+ }
+ 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);
+
+ timeout = dhcp->renewaltime;
+ }
+
+ state = STATE_BOUND;
+ xid = 0;
+
+ if (configure (options, iface, dhcp) < 0 && ! daemonised)
+ {
+ retval = -1;
+ goto eexit;
+ }
+
+ if (! daemonised && options->daemonise)
+ {
+ if ((daemonise (options->pidfile)) < 0 )
+ {
+ retval = -1;
+ goto eexit;
+ }
+ daemonised = true;
+ }
+ }
+ else if (type == DHCP_OFFER)
+ logger (LOG_INFO, "got subsequent offer of %s, ignoring ",
+ inet_ntoa (dhcp->address));
+ else
+ logger (LOG_ERR,
+ "no idea what to do with DHCP type %d at this point",
+ type);
+ break;
+ }
+ }
else if (retval == -1 && errno == EINTR)
- {
- /* The interupt will be handled above */
- }
+ {
+ /* The interupt will be handled above */
+ }
else
- {
- /* An error occured. As we heavily depend on select, we abort. */
- logger (LOG_ERR, "error on select: %s", strerror (errno));
- retval = -1;
- goto eexit;
- }
+ {
+ /* An error occured. As we heavily depend on select, we abort. */
+ logger (LOG_ERR, "error on select: %s", strerror (errno));
+ retval = -1;
+ goto eexit;
+ }
}
eexit:
if (iface)
{
if (iface->previous_routes)
- free_route (iface->previous_routes);
+ free_route (iface->previous_routes);
free (iface);
}
if (n && --n)
do
{
- if (! (*dst++ = *src++))
- break;
+ if (! (*dst++ = *src++))
+ break;
}
while (--n);
if (! n)
{
if (size)
- *dst = '\0';
+ *dst = '\0';
while (*src++)
- ;
+ ;
}
return (src - s - 1);
}
- #endif
+#endif
#endif
/* This requires us to link to rt on glibc, so we use sysinfo instead */
if ((pid = fork ()) == 0)
{
if (execv (cmd, argv) && errno != ENOENT)
- logger (LOG_ERR, "error executing \"%s\": %s",
- cmd, strerror (errno));
+ logger (LOG_ERR, "error executing \"%s\": %s",
+ cmd, strerror (errno));
exit (0);
}
else if (pid == -1)
}
static void exec_script (const char *script, const char *infofile,
- const char *arg)
+ const char *arg)
{
struct stat buf;
if (stat (script, &buf) < 0)
{
if (strcmp (script, DEFAULT_SCRIPT) != 0)
- logger (LOG_ERR, "`%s': %s", script, strerror (ENOENT));
+ logger (LOG_ERR, "`%s': %s", script, strerror (ENOENT));
return;
}
f = popen (resolvconf, "w");
if (! f)
- logger (LOG_ERR, "popen: %s", strerror (errno));
+ logger (LOG_ERR, "popen: %s", strerror (errno));
}
else
#endif
{
logger (LOG_DEBUG, "writing "RESOLVFILE);
if (! (f = fopen(RESOLVFILE, "w")))
- logger (LOG_ERR, "fopen `%s': %s", RESOLVFILE, strerror (errno));
+ logger (LOG_ERR, "fopen `%s': %s", RESOLVFILE, strerror (errno));
}
if (f)
{
fprintf (f, "# Generated by dhcpcd for interface %s\n", ifname);
if (dhcp->dnssearch)
- fprintf (f, "search %s\n", dhcp->dnssearch);
+ fprintf (f, "search %s\n", dhcp->dnssearch);
else if (dhcp->dnsdomain) {
- fprintf (f, "search %s\n", dhcp->dnsdomain);
+ fprintf (f, "search %s\n", dhcp->dnsdomain);
}
for (address = dhcp->dnsservers; address; address = address->next)
- fprintf (f, "nameserver %s\n", inet_ntoa (address->address));
+ fprintf (f, "nameserver %s\n", inet_ntoa (address->address));
if (*resolvconf)
- pclose (f);
+ pclose (f);
else
- fclose (f);
+ fclose (f);
}
else
return -1;
if (! (f = fopen (file, "r")))
{
if (errno != ENOENT)
- {
- logger (LOG_ERR, "fopen `%s': %s", file, strerror (errno));
- return -1;
- }
+ {
+ logger (LOG_ERR, "fopen `%s': %s", file, strerror (errno));
+ return -1;
+ }
}
else
{
memset (buffer, 0, sizeof (buffer));
while (fgets (buffer, sizeof (buffer), f))
- {
- a = buffer;
- token = strsep (&a, " ");
- if (! token || strcmp (token, "server") != 0)
- continue;
-
- if ((token = strsep (&a, " \n")) == NULL)
- continue;
-
- for (address = dhcp->ntpservers; address; address = address->next)
- if (strcmp (token, inet_ntoa (address->address)) == 0)
- {
- tomatch--;
- break;
- }
-
- if (tomatch == 0)
- break;
- }
+ {
+ a = buffer;
+ token = strsep (&a, " ");
+ if (! token || strcmp (token, "server") != 0)
+ continue;
+
+ if ((token = strsep (&a, " \n")) == NULL)
+ continue;
+
+ for (address = dhcp->ntpservers; address; address = address->next)
+ if (strcmp (token, inet_ntoa (address->address)) == 0)
+ {
+ tomatch--;
+ break;
+ }
+
+ if (tomatch == 0)
+ break;
+ }
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, "%s already configured, skipping", file);
+ return 0;
+ }
}
logger (LOG_DEBUG, "writing %s", file);
{
a = inet_ntoa (address->address);
if (ntp)
- fprintf (f, "restrict %s nomodify notrap noquery\n", a);
+ fprintf (f, "restrict %s nomodify notrap noquery\n", a);
fprintf (f, "server %s\n", a);
}
setdomainname (dhcp->nisdomain, strlen (dhcp->nisdomain));
if (dhcp->nisservers)
- snprintf (prefix, sizeof (prefix), "domain %s server", dhcp->nisdomain);
+ snprintf (prefix, sizeof (prefix), "domain %s server", dhcp->nisdomain);
else
- fprintf (f, "domain %s broadcast\n", dhcp->nisdomain);
+ fprintf (f, "domain %s broadcast\n", dhcp->nisdomain);
}
else
snprintf (prefix, sizeof (prefix), "%s", "ypserver");
memset (buffer, 0, sizeof (buffer));
if (cstr == NULL || strlen (cstr) == 0)
- return b;
+ return b;
do
if (*cstr == 39)
{
- *b++ = '\'';
- *b++ = '\\';
- *b++ = '\'';
- *b++ = '\'';
+ *b++ = '\'';
+ *b++ = '\\';
+ *b++ = '\'';
+ *b++ = '\'';
}
else
*b++ = *cstr;
}
static int write_info(const interface_t *iface, const dhcp_t *dhcp,
- const options_t *options)
+ const options_t *options)
{
FILE *f;
route_t *route;
{
fprintf (f, "ROUTES='");
for (route = dhcp->routes; route; route = route->next)
- {
- fprintf (f, "%s", inet_ntoa (route->destination));
- fprintf (f, ",%s", inet_ntoa (route->netmask));
- fprintf (f, ",%s", inet_ntoa (route->gateway));
- if (route->next)
- fprintf (f, " ");
- }
+ {
+ fprintf (f, "%s", inet_ntoa (route->destination));
+ fprintf (f, ",%s", inet_ntoa (route->netmask));
+ fprintf (f, ",%s", inet_ntoa (route->gateway));
+ if (route->next)
+ fprintf (f, " ");
+ }
fprintf (f, "'\n");
}
{
fprintf (f, "DNSSERVERS='");
for (address = dhcp->dnsservers; address; address = address->next)
- {
- fprintf (f, "%s", inet_ntoa (address->address));
- if (address->next)
- fprintf (f, " ");
- }
+ {
+ fprintf (f, "%s", inet_ntoa (address->address));
+ if (address->next)
+ fprintf (f, " ");
+ }
fprintf (f, "'\n");
}
{
fprintf (f, "NTPSERVERS='");
for (address = dhcp->ntpservers; address; address = address->next)
- {
- fprintf (f, "%s", inet_ntoa (address->address));
- if (address->next)
- fprintf (f, " ");
- }
+ {
+ fprintf (f, "%s", inet_ntoa (address->address));
+ if (address->next)
+ fprintf (f, " ");
+ }
fprintf (f, "'\n");
}
{
fprintf (f, "NISSERVERS='");
for (address = dhcp->nisservers; address; address = address->next)
- {
- fprintf (f, "%s", inet_ntoa (address->address));
- if (address->next)
- fprintf (f, " ");
- }
+ {
+ fprintf (f, "%s", inet_ntoa (address->address));
+ if (address->next)
+ fprintf (f, " ");
+ }
fprintf (f, "'\n");
}
#endif
int configure (const options_t *options, interface_t *iface,
- const dhcp_t *dhcp)
+ const dhcp_t *dhcp)
{
route_t *route = NULL;
route_t *new_route = NULL;
if (iface->previous_routes)
{
for (route = iface->previous_routes; route; route = route->next)
- if (route->destination.s_addr || options->dogateway)
- {
- int have = 0;
- if (dhcp->address.s_addr != 0)
- for (new_route = dhcp->routes; new_route; new_route = new_route->next)
- if (new_route->destination.s_addr == route->destination.s_addr
- && new_route->netmask.s_addr == route->netmask.s_addr
- && new_route->gateway.s_addr == route->gateway.s_addr)
- {
- have = 1;
- break;
- }
- if (! have)
- del_route (iface->name, route->destination, route->netmask,
- route->gateway, options->metric);
- }
+ if (route->destination.s_addr || options->dogateway)
+ {
+ int have = 0;
+ if (dhcp->address.s_addr != 0)
+ for (new_route = dhcp->routes; new_route; new_route = new_route->next)
+ if (new_route->destination.s_addr == route->destination.s_addr
+ && new_route->netmask.s_addr == route->netmask.s_addr
+ && new_route->gateway.s_addr == route->gateway.s_addr)
+ {
+ have = 1;
+ break;
+ }
+ if (! have)
+ del_route (iface->name, route->destination, route->netmask,
+ route->gateway, options->metric);
+ }
}
/* If we don't have an address, then return */
if (dhcp->address.s_addr == 0)
{
if (iface->previous_routes)
- {
- free_route (iface->previous_routes);
- iface->previous_routes = NULL;
- }
+ {
+ 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;
- }
+ {
+ set_mtu (iface->name, iface->mtu);
+ iface->previous_mtu = iface->mtu;
+ }
/* Only reset things if we had set them before */
if (iface->previous_address.s_addr != 0)
- {
- del_address (iface->name, iface->previous_address,
- iface->previous_netmask);
- memset (&iface->previous_address, 0, sizeof (struct in_addr));
- memset (&iface->previous_netmask, 0, sizeof (struct in_addr));
+ {
+ del_address (iface->name, iface->previous_address,
+ iface->previous_netmask);
+ memset (&iface->previous_address, 0, sizeof (struct in_addr));
+ memset (&iface->previous_netmask, 0, sizeof (struct in_addr));
- restore_resolv (iface->name);
+ restore_resolv (iface->name);
- /* we currently don't have a resolvconf style programs for ntp/nis */
- exec_script (options->script, iface->infofile, "down");
- }
+ /* we currently don't have a resolvconf style programs for ntp/nis */
+ exec_script (options->script, iface->infofile, "down");
+ }
return 0;
}
{
unsigned short mtu = iface->mtu;
if (dhcp->mtu)
- mtu = dhcp->mtu;
+ mtu = dhcp->mtu;
if (mtu != iface->previous_mtu)
- {
- if (set_mtu (iface->name, mtu) == 0)
- iface->previous_mtu = mtu;
- }
+ {
+ if (set_mtu (iface->name, mtu) == 0)
+ iface->previous_mtu = mtu;
+ }
}
if (add_address (iface->name, dhcp->address, dhcp->netmask,
- dhcp->broadcast) < 0 && errno != EEXIST)
+ dhcp->broadcast) < 0 && errno != EEXIST)
return -1;
/* Now delete the old address if different */
int remember;
for (route = dhcp->routes; route; route = route->next)
- {
- /* 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)
- for (old_route = iface->previous_routes; old_route;
- old_route = old_route->next)
- if (old_route->destination.s_addr == route->destination.s_addr
- && old_route->netmask.s_addr == route->netmask.s_addr
- && old_route->gateway.s_addr == route->gateway.s_addr)
- {
- remember = 1;
- break;
- }
-
- if (remember >= 0)
- {
- if (! new_routes)
- {
- new_routes = xmalloc (sizeof (route_t));
- memset (new_routes, 0, sizeof (route_t));
- new_route = new_routes;
- }
- else
- {
- new_route->next = xmalloc (sizeof (route_t));
- new_route = new_route->next;
- }
- memcpy (new_route, route, sizeof (route_t));
- new_route -> next = NULL;
- }
- }
+ {
+ /* 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)
+ for (old_route = iface->previous_routes; old_route;
+ old_route = old_route->next)
+ if (old_route->destination.s_addr == route->destination.s_addr
+ && old_route->netmask.s_addr == route->netmask.s_addr
+ && old_route->gateway.s_addr == route->gateway.s_addr)
+ {
+ remember = 1;
+ break;
+ }
+
+ if (remember >= 0)
+ {
+ if (! new_routes)
+ {
+ new_routes = xmalloc (sizeof (route_t));
+ memset (new_routes, 0, sizeof (route_t));
+ new_route = new_routes;
+ }
+ else
+ {
+ new_route->next = xmalloc (sizeof (route_t));
+ new_route = new_route->next;
+ }
+ memcpy (new_route, route, sizeof (route_t));
+ new_route -> next = NULL;
+ }
+ }
if (iface->previous_routes)
- free_route (iface->previous_routes);
+ free_route (iface->previous_routes);
iface->previous_routes = new_routes;
}
if (options->dohostname && ! dhcp->hostname)
{
he = gethostbyaddr (inet_ntoa (dhcp->address),
- sizeof (struct in_addr), AF_INET);
+ sizeof (struct in_addr), AF_INET);
if (he)
- {
- dname = he->h_name;
- while (*dname > 32)
- dname++;
- dnamel = dname - he->h_name;
- memcpy (newhostname, he->h_name, dnamel);
- newhostname[dnamel] = 0;
- }
+ {
+ dname = he->h_name;
+ while (*dname > 32)
+ dname++;
+ dnamel = dname - he->h_name;
+ memcpy (newhostname, he->h_name, dnamel);
+ newhostname[dnamel] = 0;
+ }
}
gethostname (curhostname, sizeof (curhostname));
|| strcmp (curhostname, "localhost") == 0)
{
if (dhcp->hostname)
- strlcpy (newhostname, dhcp->hostname, sizeof (newhostname));
+ strlcpy (newhostname, dhcp->hostname, sizeof (newhostname));
if (*newhostname)
- {
- logger (LOG_INFO, "setting hostname to `%s'", newhostname);
- sethostname (newhostname, strlen (newhostname));
- }
+ {
+ logger (LOG_INFO, "setting hostname to `%s'", newhostname);
+ sethostname (newhostname, strlen (newhostname));
+ }
}
#ifdef ENABLE_INFO
iface->previous_netmask.s_addr != dhcp->netmask.s_addr)
{
memcpy (&iface->previous_address,
- &dhcp->address, sizeof (struct in_addr));
+ &dhcp->address, sizeof (struct in_addr));
memcpy (&iface->previous_netmask,
- &dhcp->netmask, sizeof (struct in_addr));
+ &dhcp->netmask, sizeof (struct in_addr));
exec_script (options->script, iface->infofile, "new");
}
else
};
size_t send_message (const interface_t *iface, const dhcp_t *dhcp,
- unsigned long xid, char type,
- const options_t *options)
+ unsigned long xid, char type,
+ const options_t *options)
{
dhcpmessage_t message;
struct udp_dhcp_packet packet;
case ARPHRD_IEEE1394:
case ARPHRD_INFINIBAND:
if (message.ciaddr == 0)
- message.flags = htons (BROADCAST_FLAG);
+ message.flags = htons (BROADCAST_FLAG);
message.hwlen = 0;
break;
default:
*p++ = 2;
sz = get_mtu (iface->name);
if (sz < MTU_MIN)
- {
- if (set_mtu (iface->name, MTU_MIN) == 0)
- sz = MTU_MIN;
- }
+ {
+ if (set_mtu (iface->name, MTU_MIN) == 0)
+ sz = MTU_MIN;
+ }
sz = htons (sz);
memcpy (p, &sz, 2);
p += 2;
if (type == DHCP_REQUEST || type == DHCP_DISCOVER)
{
if (options->leasetime != 0)
- {
- *p++ = DHCP_LEASETIME;
- *p++ = 4;
- ul = htonl (options->leasetime);
- memcpy (p, &ul, 4);
- p += 4;
- }
+ {
+ *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)
*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 we can safely do this. */
+ RFC2131 Section 3.5 states that the REQUEST must include the list
+ from the DISCOVER message, so I think we can safely do this. */
if (type == DHCP_DISCOVER)
- *p++ = DHCP_DNSSERVER;
+ *p++ = DHCP_DNSSERVER;
else
- {
- *p++ = DHCP_RENEWALTIME;
- *p++ = DHCP_REBINDTIME;
- *p++ = DHCP_NETMASK;
- *p++ = DHCP_BROADCAST;
- *p++ = DHCP_CSR;
- /* 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;
- *p++ = DHCP_NISDOMAIN;
- *p++ = DHCP_NISSERVER;
- *p++ = DHCP_NTPSERVER;
- *p++ = DHCP_MTU;
- /* These parameters were requested by dhcpcd-2.0 and earlier
- but we never did anything with them */
- /* *p++ = DHCP_DEFAULTIPTTL;
- *p++ = DHCP_MASKDISCOVERY;
- *p++ = DHCP_ROUTERDISCOVERY; */
- }
+ {
+ *p++ = DHCP_RENEWALTIME;
+ *p++ = DHCP_REBINDTIME;
+ *p++ = DHCP_NETMASK;
+ *p++ = DHCP_BROADCAST;
+ *p++ = DHCP_CSR;
+ /* 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;
+ *p++ = DHCP_NISDOMAIN;
+ *p++ = DHCP_NISSERVER;
+ *p++ = DHCP_NTPSERVER;
+ *p++ = DHCP_MTU;
+ /* These parameters were requested by dhcpcd-2.0 and earlier
+ but we never did anything with them */
+ /* *p++ = DHCP_DEFAULTIPTTL;
+ *p++ = DHCP_MASKDISCOVERY;
+ *p++ = DHCP_ROUTERDISCOVERY; */
+ }
*n_params = p - n_params - 1;
if (*options->hostname)
- {
- 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; /* rcode1, response from DNS server for PTR RR */
- *p++ = 0; /* rcode2, response from DNS server for A RR if S=1 */
- memcpy (p, options->hostname, l);
- p += l;
- }
- }
+ {
+ 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; /* rcode1, response from DNS server for PTR RR */
+ *p++ = 0; /* rcode2, response from DNS server for A RR if S=1 */
+ memcpy (p, options->hostname, l);
+ p += l;
+ }
+ }
}
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;
- }
-
+ {
+ *p++ = DHCP_USERCLASS;
+ *p++ = options->userclass_len;
+ memcpy (p, &options->userclass, options->userclass_len);
+ p += options->userclass_len;
+ }
+
*p++ = DHCP_CLASSID;
*p++ = l = strlen (options->classid);
memcpy (p, options->classid, l);
memset (&packet, 0, sizeof (struct udp_dhcp_packet));
make_dhcp_packet (&packet, (unsigned char *) &message, message_length,
- from, to);
+ from, to);
logger (LOG_DEBUG, "sending %s with xid 0x%lx", dhcp_message[(int) type], xid);
return send_packet (iface, ETHERTYPE_IP, (unsigned char *) &packet,
- message_length + sizeof (struct ip) +
- sizeof (struct udphdr));
+ message_length + sizeof (struct ip) +
+ sizeof (struct udphdr));
}
static unsigned long getnetmask (unsigned long ip_in)
else
{
if (IN_CLASSB (p))
- t = ~IN_CLASSB_NET;
+ t = ~IN_CLASSB_NET;
else
- {
- if (IN_CLASSC (p))
- t = ~IN_CLASSC_NET;
- else
- t = 0;
- }
+ {
+ if (IN_CLASSC (p))
+ t = ~IN_CLASSC_NET;
+ else
+ t = 0;
+ }
}
while (t & p) t >>= 1;
return htonl (~t);
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;
- }
- }
+ {
+ 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) = ' ';
+ *(out - 1) = ' ';
if (r)
- q = r;
+ q = r;
}
/* change last space to zero terminator */
cidr = *q++;
if (cidr == 0)
- ocets = 0;
+ ocets = 0;
else if (cidr < 9)
- ocets = 1;
+ ocets = 1;
else if (cidr < 17)
- ocets = 2;
+ ocets = 2;
else if (cidr < 25)
- ocets = 3;
+ ocets = 3;
else
- ocets = 4;
+ ocets = 4;
if (ocets > 0)
- {
- memcpy (&route->destination.s_addr, q, ocets);
- q += ocets;
- }
+ {
+ memcpy (&route->destination.s_addr, q, ocets);
+ q += ocets;
+ }
/* Now enter the netmask */
if (ocets > 0)
- {
- memset (&route->netmask.s_addr, 255, ocets - 1);
- memset ((unsigned char *) &route->netmask.s_addr + (ocets - 1),
- (256 - (1 << (32 - cidr) % 8)), 1);
- }
+ {
+ memset (&route->netmask.s_addr, 255, 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);
/* We have another route */
if (q - p < len)
- {
- route->next = xmalloc (sizeof (route_t));
- route = route->next;
- }
+ {
+ route->next = xmalloc (sizeof (route_t));
+ route = route->next;
+ }
}
return first;
if (dhcp->fqdn)
{
if (dhcp->fqdn->name)
- free (dhcp->fqdn->name);
+ free (dhcp->fqdn->name);
free (dhcp->fqdn);
}
}
for (i = 0; i < length; i += 4)
{
if (*address == NULL)
- {
- *address = xmalloc (sizeof (address_t));
- p = *address;
- }
+ {
+ *address = xmalloc (sizeof (address_t));
+ p = *address;
+ }
else
- {
- p->next = xmalloc (sizeof (address_t));
- p = p->next;
- }
+ {
+ p->next = xmalloc (sizeof (address_t));
+ p = p->next;
+ }
memset (p, 0, sizeof (address_t));
-
+
/* Sanity check */
if (i + 4 > length)
- {
- logger (LOG_ERR, "invalid address length");
- return (false);
- }
+ {
+ logger (LOG_ERR, "invalid address length");
+ return (false);
+ }
memcpy (&p->address.s_addr, data + i, 4);
}
dhcp->address.s_addr = message->yiaddr;
strlcpy (dhcp->servername, message->servername,
- sizeof (dhcp->servername));
+ sizeof (dhcp->servername));
#define LEN_ERR \
{ \
{
option = *p++;
if (!option)
- continue;
+ continue;
length = *p++;
if (p + length >= end)
- {
- logger (LOG_ERR, "dhcp option exceeds message length");
- retval = -1;
- goto eexit;
- }
+ {
+ logger (LOG_ERR, "dhcp option exceeds message length");
+ retval = -1;
+ goto eexit;
+ }
switch (option)
- {
- case DHCP_END:
- goto eexit;
-
- case DHCP_MESSAGETYPE:
- retval = (int) *p;
- p += length;
- continue;
-
- default:
- if (length == 0)
- {
- logger (LOG_DEBUG, "option %d has zero length, skipping",
- option);
- continue;
- }
- }
+ {
+ case DHCP_END:
+ goto eexit;
+
+ 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) \
_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 (minimum maximum message size) */
- if (dhcp->mtu < MTU_MIN)
- {
- logger (LOG_DEBUG, "MTU %d is too low, minium is %d; ignoring", dhcp->mtu, MTU_MIN);
- dhcp->mtu = 0;
- }
- break;
+ {
+ 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 (minimum maximum message size) */
+ if (dhcp->mtu < MTU_MIN)
+ {
+ logger (LOG_DEBUG, "MTU %d is too low, minium is %d; ignoring", dhcp->mtu, MTU_MIN);
+ dhcp->mtu = 0;
+ }
+ break;
#undef GET_UINT32_H
#undef GET_UINT32
#undef GET_UINT8
#define GETSTR(_var) \
- MIN_LENGTH (sizeof (char)); \
- if (_var) free (_var); \
- _var = xmalloc (length + 1); \
- memcpy (_var, p, 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_ROOTPATH:
- GETSTR (dhcp->rootpath);
- break;
- case DHCP_NISDOMAIN:
- GETSTR (dhcp->nisdomain);
- break;
+ MIN_LENGTH (sizeof (char)); \
+ if (_var) free (_var); \
+ _var = xmalloc (length + 1); \
+ memcpy (_var, p, 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_ROOTPATH:
+ GETSTR (dhcp->rootpath);
+ break;
+ case DHCP_NISDOMAIN:
+ GETSTR (dhcp->nisdomain);
+ break;
#undef GETSTR
#define GETADDR(_var) \
- MULT_LENGTH (4); \
- if (! dhcp_add_address (&_var, p, length)) \
- { \
- retval = -1; \
- goto eexit; \
- }
- case DHCP_DNSSERVER:
- GETADDR (dhcp->dnsservers);
- break;
- case DHCP_NTPSERVER:
- GETADDR (dhcp->ntpservers);
- break;
- case DHCP_NISSERVER:
- GETADDR (dhcp->nisservers);
- break;
+ MULT_LENGTH (4); \
+ if (! dhcp_add_address (&_var, p, length)) \
+ { \
+ retval = -1; \
+ goto eexit; \
+ }
+ case DHCP_DNSSERVER:
+ GETADDR (dhcp->dnsservers);
+ break;
+ case DHCP_NTPSERVER:
+ GETADDR (dhcp->ntpservers);
+ break;
+ case DHCP_NISSERVER:
+ GETADDR (dhcp->nisservers);
+ break;
#undef GETADDR
- case DHCP_DNSSEARCH:
- MIN_LENGTH (1);
- if (dhcp->dnssearch)
- free (dhcp->dnssearch);
- if ((len = decode_search (p, length, NULL)) > 0)
- {
- dhcp->dnssearch = xmalloc (len);
- decode_search (p, length, dhcp->dnssearch);
- }
- break;
-
- case DHCP_CSR:
- MIN_LENGTH (5);
- if (csr)
- free_route (csr);
- csr = decodeCSR (p, length);
- break;
-
- case DHCP_STATICROUTE:
- MULT_LENGTH (8);
- for (i = 0; i < length; i += 8)
- {
- memcpy (&route->destination.s_addr, p + i, 4);
- memcpy (&route->gateway.s_addr, p + i + 4, 4);
- route->netmask.s_addr = getnetmask (route->destination.s_addr);
- last_route = route;
- route->next = xmalloc (sizeof (route_t));
- route = route->next;
- memset (route, 0, sizeof (route_t));
- }
- break;
-
- case DHCP_ROUTERS:
- MULT_LENGTH (4);
- for (i = 0; i < length; i += 4)
- {
- memcpy (&route->gateway.s_addr, p + i, 4);
- last_route = route;
- route->next = xmalloc (sizeof (route_t));
- route = route->next;
- memset (route, 0, sizeof (route_t));
- }
- break;
+ case DHCP_DNSSEARCH:
+ MIN_LENGTH (1);
+ if (dhcp->dnssearch)
+ free (dhcp->dnssearch);
+ if ((len = decode_search (p, length, NULL)) > 0)
+ {
+ dhcp->dnssearch = xmalloc (len);
+ decode_search (p, length, dhcp->dnssearch);
+ }
+ break;
+
+ case DHCP_CSR:
+ MIN_LENGTH (5);
+ if (csr)
+ free_route (csr);
+ csr = decodeCSR (p, length);
+ break;
+
+ case DHCP_STATICROUTE:
+ MULT_LENGTH (8);
+ for (i = 0; i < length; i += 8)
+ {
+ memcpy (&route->destination.s_addr, p + i, 4);
+ memcpy (&route->gateway.s_addr, p + i + 4, 4);
+ route->netmask.s_addr = getnetmask (route->destination.s_addr);
+ last_route = route;
+ route->next = xmalloc (sizeof (route_t));
+ route = route->next;
+ memset (route, 0, sizeof (route_t));
+ }
+ break;
+
+ case DHCP_ROUTERS:
+ MULT_LENGTH (4);
+ for (i = 0; i < length; i += 4)
+ {
+ memcpy (&route->gateway.s_addr, p + i, 4);
+ last_route = route;
+ route->next = xmalloc (sizeof (route_t));
+ route = route->next;
+ memset (route, 0, sizeof (route_t));
+ }
+ 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;
}
{
dhcp->routes = first_route;
if (last_route)
- {
- free (last_route->next);
- last_route->next = NULL;
- }
+ {
+ free (last_route->next);
+ last_route->next = NULL;
+ }
else
- {
- free_route (dhcp->routes);
- dhcp->routes = NULL;
- }
+ {
+ free_route (dhcp->routes);
+ dhcp->routes = NULL;
+ }
}
return retval;
static void usage ()
{
printf ("usage: "PACKAGE" [-adknpGHMNRY] [-c script] [-h hostame] [-i classID]\n"
- " [-l leasetime] [-m metric] [-s ipaddress] [-t timeout]\n"
- " [-u userclass] [-F [none | ptr | both]] [-I clientID]\n");
+ " [-l leasetime] [-m metric] [-s ipaddress] [-t timeout]\n"
+ " [-u userclass] [-F [none | ptr | both]] [-I clientID]\n");
}
int main(int argc, char **argv)
const struct option longopts[] =
{
- {"arp", no_argument, NULL, 'a'},
- {"script",required_argument, NULL, 'c'},
- {"debug", no_argument, NULL, 'd'},
- {"hostname", required_argument, NULL, 'h'},
- {"classid", required_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'},
- {"request", required_argument, NULL, 's'},
- {"timeout", required_argument, NULL, 't'},
- {"userclass", required_argument, NULL, 'u'},
- {"fqdn", optional_argument, NULL, 'F'},
- {"nogateway", no_argument, NULL, 'G'},
- {"sethostname", no_argument, NULL, 'H'},
- {"clientid", required_argument, NULL, 'I'},
- {"nomtu", no_argument, NULL, 'M'},
- {"nontp", no_argument, NULL, 'N'},
- {"nodns", no_argument, NULL, 'R'},
- {"nonis", no_argument, NULL, 'Y'},
- {"help", no_argument, &dohelp, 1},
- {"version", no_argument, &doversion, 1},
- {NULL, 0, NULL, 0}
+ {"arp", no_argument, NULL, 'a'},
+ {"script",required_argument, NULL, 'c'},
+ {"debug", no_argument, NULL, 'd'},
+ {"hostname", required_argument, NULL, 'h'},
+ {"classid", required_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'},
+ {"request", required_argument, NULL, 's'},
+ {"timeout", required_argument, NULL, 't'},
+ {"userclass", required_argument, NULL, 'u'},
+ {"fqdn", optional_argument, NULL, 'F'},
+ {"nogateway", no_argument, NULL, 'G'},
+ {"sethostname", no_argument, NULL, 'H'},
+ {"clientid", required_argument, NULL, 'I'},
+ {"nomtu", no_argument, NULL, 'M'},
+ {"nontp", no_argument, NULL, 'N'},
+ {"nodns", no_argument, NULL, 'R'},
+ {"nonis", no_argument, NULL, 'Y'},
+ {"help", no_argument, &dohelp, 1},
+ {"version", no_argument, &doversion, 1},
+ {NULL, 0, NULL, 0}
};
/* Sanitize our fd's */
if ((zero = open (_PATH_DEVNULL, O_RDWR, 0)) >= 0)
{
while (zero < 3)
- zero = dup (zero);
+ zero = dup (zero);
close(zero);
}
options.timeout = DEFAULT_TIMEOUT;
while ((ch = getopt_long(argc, argv, "ac:dh:i:kl:m:nps:t:u:F:GHI:MNRY", longopts,
- &option_index)) != -1)
+ &option_index)) != -1)
switch (ch)
{
case 0:
- if (longopts[option_index].flag)
- break;
- logger (LOG_ERR, "option `%s' should set a flag",
- longopts[option_index].name);
- exit (EXIT_FAILURE);
- break;
+ if (longopts[option_index].flag)
+ break;
+ logger (LOG_ERR, "option `%s' should set a flag",
+ longopts[option_index].name);
+ exit (EXIT_FAILURE);
+ break;
case 'a':
- options.doarp = true;
- break;
+ options.doarp = true;
+ break;
case 'c':
- options.script = optarg;
- break;
+ options.script = optarg;
+ break;
case 'd':
- debug++;
- switch (debug)
- {
- case 1:
- setloglevel(LOG_DEBUG);
- break;
- case 2:
- options.daemonise = false;
- break;
- }
- break;
+ debug++;
+ switch (debug)
+ {
+ case 1:
+ setloglevel(LOG_DEBUG);
+ break;
+ case 2:
+ options.daemonise = false;
+ break;
+ }
+ break;
case 'h':
- if (strlen (optarg) > HOSTNAME_MAX_LEN)
- {
- logger (LOG_ERR, "`%s' too long for HostName string, max is %d",
- optarg, HOSTNAME_MAX_LEN);
- exit (EXIT_FAILURE);
- }
- else
- strlcpy (options.hostname, optarg, sizeof (options.hostname));
- break;
+ if (strlen (optarg) > HOSTNAME_MAX_LEN)
+ {
+ logger (LOG_ERR, "`%s' too long for HostName string, max is %d",
+ optarg, HOSTNAME_MAX_LEN);
+ exit (EXIT_FAILURE);
+ }
+ else
+ strlcpy (options.hostname, optarg, sizeof (options.hostname));
+ break;
case 'i':
- if (strlen (optarg) > CLASS_ID_MAX_LEN)
- {
- logger (LOG_ERR, "`%s' too long for ClassID string, max is %d",
- optarg, CLASS_ID_MAX_LEN);
- exit (EXIT_FAILURE);
- }
- else
- strlcpy (options.classid, optarg, sizeof (options.classid));
- break;
+ if (strlen (optarg) > CLASS_ID_MAX_LEN)
+ {
+ logger (LOG_ERR, "`%s' too long for ClassID string, max is %d",
+ optarg, CLASS_ID_MAX_LEN);
+ exit (EXIT_FAILURE);
+ }
+ else
+ strlcpy (options.classid, optarg, sizeof (options.classid));
+ break;
case 'k':
- options.signal = SIGHUP;
- break;
+ options.signal = SIGHUP;
+ break;
case 'l':
- STRINGINT (optarg, options.leasetime);
- if (options.leasetime <= 0)
- {
- logger (LOG_ERR, "leasetime must be a positive value");
- exit (EXIT_FAILURE);
- }
- break;
+ STRINGINT (optarg, options.leasetime);
+ if (options.leasetime <= 0)
+ {
+ logger (LOG_ERR, "leasetime must be a positive value");
+ exit (EXIT_FAILURE);
+ }
+ break;
case 'm':
- STRINGINT (optarg, options.metric);
- break;
+ STRINGINT (optarg, options.metric);
+ break;
case 'n':
- options.signal = SIGALRM;
- break;
+ options.signal = SIGALRM;
+ break;
case 'p':
- options.persistent = true;
- break;
+ options.persistent = true;
+ break;
case 's':
- if (! inet_aton (optarg, &options.requestaddress))
- {
- logger (LOG_ERR, "`%s' is not a valid IP address", optarg);
- exit (EXIT_FAILURE);
- }
- break;
+ if (! inet_aton (optarg, &options.requestaddress))
+ {
+ logger (LOG_ERR, "`%s' is not a valid IP address", optarg);
+ exit (EXIT_FAILURE);
+ }
+ break;
case 't':
- STRINGINT (optarg, options.timeout);
- if (options.timeout < 0)
- {
- logger (LOG_ERR, "timeout must be a positive value");
- exit (EXIT_FAILURE);
- }
- break;
+ STRINGINT (optarg, options.timeout);
+ if (options.timeout < 0)
+ {
+ logger (LOG_ERR, "timeout must be a positive value");
+ exit (EXIT_FAILURE);
+ }
+ break;
case 'u':
- {
- int i;
- 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);
- exit (EXIT_FAILURE);
- }
- userclasses++;
- memcpy (options.userclass + offset + 1 , optarg, strlen (optarg));
- options.userclass[offset] = strlen (optarg);
- options.userclass_len += (strlen (optarg)) + 1;
- }
- break;
+ {
+ int i;
+ 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);
+ exit (EXIT_FAILURE);
+ }
+ userclasses++;
+ memcpy (options.userclass + offset + 1 , optarg, strlen (optarg));
+ options.userclass[offset] = strlen (optarg);
+ options.userclass_len += (strlen (optarg)) + 1;
+ }
+ break;
case 'F':
- if (strcmp (optarg, "none") == 0)
- options.fqdn = FQDN_NONE;
- else if (strcmp (optarg, "ptr") == 0)
- options.fqdn = FQDN_PTR;
- else if (strcmp (optarg, "both") == 0)
- options.fqdn = FQDN_BOTH;
- else
- {
- logger (LOG_ERR, "invalid value `%s' for FQDN", optarg);
- exit (EXIT_FAILURE);
- }
- break;
+ if (strcmp (optarg, "none") == 0)
+ options.fqdn = FQDN_NONE;
+ else if (strcmp (optarg, "ptr") == 0)
+ options.fqdn = FQDN_PTR;
+ else if (strcmp (optarg, "both") == 0)
+ options.fqdn = FQDN_BOTH;
+ else
+ {
+ logger (LOG_ERR, "invalid value `%s' for FQDN", optarg);
+ exit (EXIT_FAILURE);
+ }
+ break;
case 'G':
- options.dogateway = false;
- break;
+ options.dogateway = false;
+ break;
case 'H':
- options.dohostname = true;
- break;
+ options.dohostname = true;
+ break;
case 'I':
- if (strlen (optarg) > CLIENT_ID_MAX_LEN)
- {
- logger (LOG_ERR, "`%s' is too long for ClientID, max is %d",
- optarg, CLIENT_ID_MAX_LEN);
- exit (EXIT_FAILURE);
- }
- else
- strlcpy (options.clientid, optarg, sizeof (options.clientid));
- break;
+ if (strlen (optarg) > CLIENT_ID_MAX_LEN)
+ {
+ logger (LOG_ERR, "`%s' is too long for ClientID, max is %d",
+ optarg, CLIENT_ID_MAX_LEN);
+ exit (EXIT_FAILURE);
+ }
+ else
+ strlcpy (options.clientid, optarg, sizeof (options.clientid));
+ break;
case 'M':
- options.domtu = false;
- break;
+ options.domtu = false;
+ break;
case 'N':
- options.dontp = false;
- break;
+ options.dontp = false;
+ break;
case 'R':
- options.dodns = false;
- break;
+ options.dodns = false;
+ break;
case 'Y':
- options.donis = false;
- break;
+ options.donis = false;
+ break;
case '?':
- usage ();
- exit (EXIT_FAILURE);
+ usage ();
+ exit (EXIT_FAILURE);
default:
- usage ();
- exit (EXIT_FAILURE);
+ usage ();
+ exit (EXIT_FAILURE);
}
if (doversion)
if (optind < argc)
{
if (strlen (argv[optind]) > IF_NAMESIZE)
- {
- logger (LOG_ERR, "`%s' is too long for an interface name (max=%d)",
- argv[optind], IF_NAMESIZE);
- exit (EXIT_FAILURE);
- }
+ {
+ logger (LOG_ERR, "`%s' is too long for an interface name (max=%d)",
+ argv[optind], IF_NAMESIZE);
+ exit (EXIT_FAILURE);
+ }
strlcpy (options.interface, argv[optind],
- sizeof (options.interface));
+ sizeof (options.interface));
}
else
{
/* If only version was requested then exit now */
if (doversion || dohelp)
- exit (EXIT_SUCCESS);
+ exit (EXIT_SUCCESS);
logger (LOG_ERR, "no interface specified");
exit (EXIT_FAILURE);
snprintf (prefix, IF_NAMESIZE, "%s: ", options.interface);
setlogprefix (prefix);
snprintf (options.pidfile, sizeof (options.pidfile), PIDFILE,
- options.interface);
+ options.interface);
if (options.signal != 0)
{
logger (LOG_INFO, "sending signal %d to pid %d", options.signal, pid);
if (! pid || (killed = kill (pid, options.signal)))
- logger (options.signal == SIGALRM ? LOG_INFO : LOG_ERR, ""PACKAGE" not running");
+ logger (options.signal == SIGALRM ? LOG_INFO : LOG_ERR, ""PACKAGE" not running");
if (pid != 0 && (options.signal != SIGALRM || killed != 0))
- unlink (options.pidfile);
+ unlink (options.pidfile);
if (killed == 0)
- exit (EXIT_SUCCESS);
+ exit (EXIT_SUCCESS);
if (options.signal != SIGALRM)
- exit (EXIT_FAILURE);
+ exit (EXIT_FAILURE);
}
umask (022);
if (mkdir (CONFIGDIR, S_IRUSR |S_IWUSR |S_IXUSR | S_IRGRP | S_IXGRP
- | S_IROTH | S_IXOTH) && errno != EEXIST )
+ | S_IROTH | S_IXOTH) && errno != EEXIST )
{
logger (LOG_ERR, "mkdir(\"%s\",0): %s\n", CONFIGDIR, strerror (errno));
exit (EXIT_FAILURE);
}
if (mkdir (ETCDIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP
- | S_IROTH | S_IXOTH) && errno != EEXIST )
+ | S_IROTH | S_IXOTH) && errno != EEXIST )
{
logger (LOG_ERR, "mkdir(\"%s\",0): %s\n", ETCDIR, strerror (errno));
exit (EXIT_FAILURE);
#endif
#else
#include <net/if_arp.h> /*dietlibc requires this - normally from
- netinet/ether.h */
+ netinet/ether.h */
#include <net/if_dl.h>
#include <net/if_types.h>
#include <net/route.h>
{
int cidr = 0;
uint32_t mask = htonl (address.s_addr);
-
+
while (mask)
{
cidr++;
for (i = 0; i < hwlen && i < 125; i++)
{
if (i > 0)
- *p ++= ':';
+ *p ++= ':';
p += snprintf (p, 3, "%.2x", hwaddr[i]);
}
*p ++= '\0';
for (p = ifap; p; p = p->ifa_next)
{
union
- {
- struct sockaddr *sa;
- struct sockaddr_dl *sdl;
- } us;
+ {
+ struct sockaddr *sa;
+ struct sockaddr_dl *sdl;
+ } us;
if (strcmp (p->ifa_name, ifname) != 0)
- continue;
+ continue;
us.sa = p->ifa_addr;
if (p->ifa_addr->sa_family != AF_LINK
- || (us.sdl->sdl_type != IFT_ETHER))
- /*
- && us.sdl->sdl_type != IFT_ISO88025))
- */
- {
- logger (LOG_ERR, "interface is not Ethernet");
- freeifaddrs (ifap);
- return NULL;
- }
+ || (us.sdl->sdl_type != IFT_ETHER))
+ /*
+ && us.sdl->sdl_type != IFT_ISO88025))
+ */
+ {
+ logger (LOG_ERR, "interface is not Ethernet");
+ freeifaddrs (ifap);
+ return NULL;
+ }
memcpy (hwaddr, us.sdl->sdl_data + us.sdl->sdl_nlen, ETHER_ADDR_LEN);
family = ARPHRD_ETHER;
ifr.ifr_mtu = MTU_MIN;
strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
if (ioctl(s, SIOCSIFMTU, &ifr) < 0)
- {
- logger (LOG_ERR, "ioctl SIOCSIFMTU,: %s", strerror (errno));
- close (s);
- return NULL;
- }
+ {
+ logger (LOG_ERR, "ioctl SIOCSIFMTU,: %s", strerror (errno));
+ close (s);
+ return NULL;
+ }
}
mtu = ifr.ifr_mtu;
iface->mtu = iface->previous_mtu = mtu;
logger (LOG_INFO, "hardware address = %s",
- hwaddr_ntoa (iface->hwaddr, iface->hwlen));
+ hwaddr_ntoa (iface->hwaddr, iface->hwlen));
/* 0 is a valid fd, so init to -1 */
iface->fd = -1;
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined (__OpenBSD__) \
|| defined(__APPLE__)
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;
if (ioctl (s, del ? SIOCDIFADDR : SIOCAIFADDR, &ifa) == -1)
{
logger (LOG_ERR, "ioctl %s: %s", del ? "SIOCDIFADDR" : "SIOCAIFADDR",
- strerror (errno));
+ strerror (errno));
close (s);
return -1;
}
}
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;
char *dstd;
struct rt_msghdr hdr;
struct sockaddr_in destination;
union
- {
- struct sockaddr sa;
- struct sockaddr_in sin;
- struct sockaddr_dl sdl;
- struct sockaddr_storage sss; /* added to avoid memory overrun */
- } gateway;
+ {
+ struct sockaddr sa;
+ struct sockaddr_in sin;
+ struct sockaddr_dl sdl;
+ struct sockaddr_storage sss; /* added to avoid memory overrun */
+ } gateway;
struct sockaddr_in netmask;
} rtm;
static int seq;
dstd = strdup (inet_ntoa (destination));
if (gateway.s_addr == destination.s_addr)
logger (LOG_INFO, "%s route to %s/%d",
- change ? "changing" : del ? "removing" : "adding",
- dstd, inet_ntocidr (netmask));
+ change ? "changing" : del ? "removing" : "adding",
+ dstd, inet_ntocidr (netmask));
else if (destination.s_addr == INADDR_ANY && netmask.s_addr == INADDR_ANY)
logger (LOG_INFO, "%s default route via %s",
- change ? "changing" : del ? "removing" : "adding",
- inet_ntoa (gateway));
+ change ? "changing" : del ? "removing" : "adding",
+ inet_ntoa (gateway));
else
logger (LOG_INFO, "%s route to %s/%d via %s",
- change ? "changing" : del ? "removing" : "adding",
- dstd, inet_ntocidr (netmask), inet_ntoa (gateway));
+ change ? "changing" : del ? "removing" : "adding",
+ dstd, inet_ntocidr (netmask), inet_ntoa (gateway));
if (dstd)
free (dstd);
{
struct ifaddrs *ifap, *ifa;
union
- {
- struct sockaddr *sa;
- struct sockaddr_dl *sdl;
- } us;
+ {
+ struct sockaddr *sa;
+ struct sockaddr_dl *sdl;
+ } us;
if (getifaddrs (&ifap))
- {
- logger (LOG_ERR, "getifaddrs: %s", strerror (errno));
- return -1;
- }
+ {
+ logger (LOG_ERR, "getifaddrs: %s", strerror (errno));
+ return -1;
+ }
for (ifa = ifap; ifa; ifa = ifa->ifa_next)
- {
- if (ifa->ifa_addr->sa_family != AF_LINK)
- continue;
+ {
+ if (ifa->ifa_addr->sa_family != AF_LINK)
+ continue;
- if (strcmp (ifname, ifa->ifa_name))
- continue;
+ if (strcmp (ifname, ifa->ifa_name))
+ continue;
- us.sa = ifa->ifa_addr;
- memcpy (&rtm.gateway.sdl, us.sdl, us.sdl->sdl_len);
- break;
- }
+ us.sa = ifa->ifa_addr;
+ memcpy (&rtm.gateway.sdl, us.sdl, us.sdl->sdl_len);
+ break;
+ }
freeifaddrs (ifap);
}
else
{
/* Don't report error about routes already existing */
if (errno != EEXIST)
- logger (LOG_ERR, "write: %s", strerror (errno));
+ logger (LOG_ERR, "write: %s", strerror (errno));
close (s);
return -1;
}
bytes = recvmsg(s, &msg, 0);
if (bytes < 0)
- {
- if (errno != EINTR)
- logger (LOG_ERR, "netlink: overrun");
- continue;
- }
+ {
+ if (errno != EINTR)
+ logger (LOG_ERR, "netlink: overrun");
+ continue;
+ }
if (bytes == 0)
- {
- logger (LOG_ERR, "netlink: EOF");
- goto eexit;
- }
+ {
+ logger (LOG_ERR, "netlink: EOF");
+ goto eexit;
+ }
if (msg.msg_namelen != sizeof (nl))
- {
- logger (LOG_ERR, "netlink: sender address length mismatch");
- goto eexit;
- }
+ {
+ 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);
-
- 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;
- }
-
- if (nl.nl_pid != 0 ||
- (pid_t) h.nlm->nlmsg_pid != mypid ||
- h.nlm->nlmsg_seq != seq)
- /* Message isn't for us, so skip it */
- goto next;
-
- /* We get an NLMSG_ERROR back with a code of zero for success */
- if (h.nlm->nlmsg_type == NLMSG_ERROR)
- {
- struct nlmsgerr *err = (struct nlmsgerr *) NLMSG_DATA (h.nlm);
- if ((unsigned) l < sizeof (struct nlmsgerr))
- logger (LOG_ERR, "netlink: truncated error message");
- else
- {
- errno = -err->error;
- if (errno == 0)
- {
- close (s);
- return 0;
- }
-
- /* Don't report on something already existing */
- if (errno != EEXIST)
- logger (LOG_ERR, "netlink: %s", strerror (errno));
- }
- goto eexit;
- }
-
- logger (LOG_ERR, "netlink: unexpected reply");
+ {
+ int len = h.nlm->nlmsg_len;
+ int l = len - sizeof (*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;
+ }
+
+ if (nl.nl_pid != 0 ||
+ (pid_t) h.nlm->nlmsg_pid != mypid ||
+ h.nlm->nlmsg_seq != seq)
+ /* Message isn't for us, so skip it */
+ goto next;
+
+ /* We get an NLMSG_ERROR back with a code of zero for success */
+ if (h.nlm->nlmsg_type == NLMSG_ERROR)
+ {
+ struct nlmsgerr *err = (struct nlmsgerr *) NLMSG_DATA (h.nlm);
+ if ((unsigned) l < sizeof (struct nlmsgerr))
+ logger (LOG_ERR, "netlink: truncated error message");
+ else
+ {
+ errno = -err->error;
+ if (errno == 0)
+ {
+ close (s);
+ return 0;
+ }
+
+ /* Don't report on something already existing */
+ if (errno != EEXIST)
+ logger (LOG_ERR, "netlink: %s", strerror (errno));
+ }
+ goto eexit;
+ }
+
+ logger (LOG_ERR, "netlink: unexpected reply");
next:
- bytes -= NLMSG_ALIGN (len);
- h.buffer += NLMSG_ALIGN (len);
- }
+ bytes -= NLMSG_ALIGN (len);
+ h.buffer += NLMSG_ALIGN (len);
+ }
if (msg.msg_flags & MSG_TRUNC)
- {
- logger (LOG_ERR, "netlink: truncated message");
- continue;
- }
+ {
+ logger (LOG_ERR, "netlink: truncated message");
+ continue;
+ }
if (bytes)
- {
- logger (LOG_ERR, "netlink: remnant of size %d", bytes);
- goto eexit;
- }
+ {
+ logger (LOG_ERR, "netlink: remnant of size %d", bytes);
+ goto eexit;
+ }
}
eexit:
((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;
}
static int add_attr_32(struct nlmsghdr *n, unsigned int maxlen, int type,
- uint32_t data)
+ uint32_t data)
{
int len = RTA_LENGTH (sizeof (uint32_t));
struct rtattr *rta;
}
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
{
if (! (nlm.ifa.ifa_index = if_nametoindex (ifname)))
{
logger (LOG_ERR, "if_nametoindex: Couldn't find index for interface `%s'",
- ifname);
+ ifname);
return -1;
}
nlm.ifa.ifa_family = AF_INET;
nlm.ifa.ifa_prefixlen = inet_ntocidr (netmask);
add_attr_l (&nlm.hdr, sizeof (nlm), IFA_LOCAL, &address.s_addr,
- sizeof (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));
+ sizeof (broadcast.s_addr));
return send_netlink (&nlm.hdr);
}
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)
{
char *dstd;
char *gend;
gend = strdup (inet_ntoa (netmask));
if (gateway.s_addr == destination.s_addr)
logger (LOG_INFO, "%s route to %s (%s) metric %d",
- change ? "changing" : del ? "removing" : "adding",
- dstd, gend, metric);
+ change ? "changing" : del ? "removing" : "adding",
+ dstd, gend, metric);
else if (destination.s_addr == INADDR_ANY && netmask.s_addr == INADDR_ANY)
logger (LOG_INFO, "%s default route via %s metric %d",
- change ? "changing" : del ? "removing" : "adding",
- inet_ntoa (gateway), metric);
+ change ? "changing" : del ? "removing" : "adding",
+ inet_ntoa (gateway), metric);
else
logger (LOG_INFO, "%s route to %s (%s) via %s metric %d",
- change ? "changing" : del ? "removing" : "adding",
- dstd, gend, inet_ntoa (gateway), metric);
+ change ? "changing" : del ? "removing" : "adding",
+ dstd, gend, inet_ntoa (gateway), metric);
if (dstd)
free (dstd);
if (gend)
nlm.hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
nlm.rt.rtm_protocol = RTPROT_BOOT;
if (gateway.s_addr == INADDR_ANY ||
- netmask.s_addr == INADDR_BROADCAST)
- nlm.rt.rtm_scope = RT_SCOPE_LINK;
+ netmask.s_addr == INADDR_BROADCAST)
+ nlm.rt.rtm_scope = RT_SCOPE_LINK;
else
- nlm.rt.rtm_scope = RT_SCOPE_UNIVERSE;
+ 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));
+ sizeof (destination.s_addr));
if (gateway.s_addr != INADDR_ANY && gateway.s_addr != destination.s_addr)
add_attr_l (&nlm.hdr, sizeof (nlm), RTA_GATEWAY, &gateway.s_addr,
- sizeof (gateway.s_addr));
+ sizeof (gateway.s_addr));
if (! (ifindex = if_nametoindex (ifname)))
{
logger (LOG_ERR, "if_nametoindex: Couldn't find index for interface `%s'",
- ifname);
+ ifname);
return -1;
}
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));
+ inet_ntoa (address), inet_ntocidr (netmask));
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;
logger (LOG_INFO, "deleting IP address %s/%d",
- inet_ntoa (address), inet_ntocidr (netmask));
+ inet_ntoa (address), inet_ntocidr (netmask));
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));
}
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));
}
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));
}
for (p = ifap; p; p = p->ifa_next)
{
union
- {
- struct sockaddr *sa;
- struct sockaddr_in *sin;
- } us_a, us_m;
+ {
+ struct sockaddr *sa;
+ struct sockaddr_in *sin;
+ } us_a, us_m;
if (strcmp (p->ifa_name, ifname) != 0)
- continue;
+ continue;
us_a.sa = p->ifa_addr;
us_m.sa = p->ifa_netmask;
if (us_a.sin->sin_family == AF_INET)
- if (del_address (ifname, us_a.sin->sin_addr, us_m.sin->sin_addr) < 0)
- retval = -1;
+ if (del_address (ifname, us_a.sin->sin_addr, us_m.sin->sin_addr) < 0)
+ retval = -1;
}
freeifaddrs (ifap);
struct sockaddr_in *netm = (struct sockaddr_in *) &ifr->ifr_netmask;
if (ifr->ifr_addr.sa_family == AF_INET
- && strcmp (ifname, ifr->ifr_name) == 0)
- if (del_address (ifname, addr->sin_addr, netm->sin_addr) < 0)
- retval = -1;
+ && strcmp (ifname, ifr->ifr_name) == 0)
+ if (del_address (ifname, addr->sin_addr, netm->sin_addr) < 0)
+ retval = -1;
ifr++;
}
while (syslog_level[i])
{
if (!strcmp (priority, syslog_level[i]))
- return i;
+ return i;
i++;
}
return -1;
if (level <= LOG_ERR || level <= loglevel)
{
if (level == LOG_DEBUG || level == LOG_INFO)
- f = stdout;
+ f = stdout;
fprintf (f, "%s, %s", syslog_level_msg[level], logprefix);
vfprintf (f, fmt, p);
fputc ('\n', f);
wait (0);
return;
}
-
+
if (send (signal_pipe[1], &sig, sizeof (sig), MSG_DONTWAIT) < 0)
logger (LOG_ERR, "Could not send signal: %s", strerror (errno));
}
/* Stop any scripts from inheriting us */
for (i = 0; i < 2; i++)
if ((flags = fcntl (signal_pipe[i], F_GETFD, 0)) < 0 ||
- fcntl (signal_pipe[i], F_SETFD, flags | FD_CLOEXEC) < 0)
+ fcntl (signal_pipe[i], F_SETFD, flags | FD_CLOEXEC) < 0)
logger (LOG_ERR ,"fcntl: %s", strerror (errno));
-
+
signal (SIGHUP, signal_handler);
signal (SIGALRM, signal_handler);
signal (SIGTERM, signal_handler);
}
void make_dhcp_packet(struct udp_dhcp_packet *packet,
- const unsigned char *data, int length,
- struct in_addr source, struct in_addr dest)
+ const unsigned char *data, int length,
+ struct in_addr source, struct in_addr dest)
{
struct ip *ip = &packet->ip;
struct udphdr *udp = &packet->udp;
udp->uh_ulen = htons (sizeof (struct udphdr) + length);
ip->ip_len = udp->uh_ulen;
udp->uh_sum = checksum ((unsigned char *) packet,
- sizeof (struct udp_dhcp_packet));
+ sizeof (struct udp_dhcp_packet));
ip->ip_v = IPVERSION;
ip->ip_hl = 5;
ip->ip_id = 0;
ip->ip_tos = IPTOS_LOWDELAY;
ip->ip_len = htons (sizeof (struct ip) + sizeof (struct udphdr) +
- length);
+ length);
ip->ip_id = 0;
ip->ip_off = 0;
ip->ip_ttl = IPDEFTTL;
if (ioctl (fd, BIOCSETIF, &ifr) < 0)
{
logger (LOG_ERR, "cannot attach interface `%s' to bpf device `%s': %s",
- iface->name, device, strerror (errno));
+ iface->name, device, strerror (errno));
close (fd);
return -1;
}
}
int send_packet (const interface_t *iface, int type,
- const unsigned char *data, int len)
+ const unsigned char *data, int len)
{
int retval = -1;
struct iovec iov[2];
/* BPF requires that we read the entire buffer.
So we pass the buffer in the API so we can loop on >1 dhcp packet. */
int get_packet (const interface_t *iface, unsigned char *data,
- unsigned char *buffer, int *buffer_len, int *buffer_pos)
+ unsigned char *buffer, int *buffer_len, int *buffer_pos)
{
union
{
*buffer_len = read (iface->fd, bpf.buffer, iface->buffer_length);
*buffer_pos = 0;
if (*buffer_len < 1)
- {
- struct timeval tv;
- logger (LOG_ERR, "read: %s", strerror (errno));
- tv.tv_sec = 3;
- tv.tv_usec = 0;
- select (0, NULL, NULL, NULL, &tv);
- return -1;
- }
+ {
+ struct timeval tv;
+ logger (LOG_ERR, "read: %s", strerror (errno));
+ tv.tv_sec = 3;
+ tv.tv_usec = 0;
+ select (0, NULL, NULL, NULL, &tv);
+ return -1;
+ }
}
else
bpf.buffer += *buffer_pos;
{
int len = -1;
union
- {
- unsigned char *buffer;
- struct ether_header *hw;
- } hdr;
+ {
+ unsigned char *buffer;
+ struct ether_header *hw;
+ } hdr;
unsigned char *payload;
/* Ensure that the entire packet is in our buffer */
if (*buffer_pos + bpf.packet->bh_hdrlen + bpf.packet->bh_caplen
- > (unsigned) *buffer_len)
- break;
+ > (unsigned) *buffer_len)
+ break;
hdr.buffer = bpf.buffer + bpf.packet->bh_hdrlen;
payload = hdr.buffer + sizeof (struct ether_header);
/* 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 (struct ether_header);
- memcpy (data, payload, len);
- }
+ {
+ len = bpf.packet->bh_caplen - sizeof (struct ether_header);
+ memcpy (data, payload, len);
+ }
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 (struct ip) -
- sizeof (struct udphdr);
- memcpy (data, &pay.packet->dhcp, len);
- }
- }
+ {
+ 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 (struct ip) -
+ sizeof (struct udphdr);
+ memcpy (data, &pay.packet->dhcp, len);
+ }
+ }
/* Update the buffer_pos pointer */
bpf.buffer +=
BPF_WORDALIGN (bpf.packet->bh_hdrlen + bpf.packet->bh_caplen);
if (bpf.buffer - buffer < *buffer_len)
- *buffer_pos = bpf.buffer - buffer;
+ *buffer_pos = bpf.buffer - buffer;
else
- *buffer_pos = 0;
+ *buffer_pos = 0;
if (len != -1)
- return len;
+ return len;
if (*buffer_pos == 0)
- break;
+ break;
}
/* No valid packets left, so return */
if (! (sll.sll_ifindex = if_nametoindex (iface->name)))
{
logger (LOG_ERR, "if_nametoindex: Couldn't find index for interface `%s'",
- iface->name);
+ iface->name);
close (fd);
return -1;
}
}
int send_packet (const interface_t *iface, const int type,
- const unsigned char *data, const int len)
+ const unsigned char *data, const int len)
{
struct sockaddr_ll sll;
int retval;
if (! (sll.sll_ifindex = if_nametoindex (iface->name)))
{
logger (LOG_ERR, "if_nametoindex: Couldn't find index for interface `%s'",
- iface->name);
+ iface->name);
return -1;
}
sll.sll_halen = ETHER_ADDR_LEN;
memset(sll.sll_addr, 0xff, sizeof (sll.sll_addr));
if ((retval = sendto (iface->fd, data, len, 0, (struct sockaddr *) &sll,
- sizeof (struct sockaddr_ll))) < 0)
+ sizeof (struct sockaddr_ll))) < 0)
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. */
int get_packet (const interface_t *iface, unsigned char *data,
- unsigned char *buffer, int *buffer_len, int *buffer_pos)
+ unsigned char *buffer, int *buffer_len, int *buffer_pos)
{
long bytes;
union
return -1;
memcpy(data, &pay.packet->dhcp,
- bytes - (sizeof (pay.packet->ip) + sizeof (pay.packet->udp)));
+ bytes - (sizeof (pay.packet->ip) + sizeof (pay.packet->udp)));
return bytes - (sizeof (pay.packet->ip) + sizeof (pay.packet->udp));
}