fprintf (f, "search %s\n", dhcp->dnsdomain);
}
- for (address = dhcp->dnsservers; address; address = address->next)
+ STAILQ_FOREACH (address, dhcp->dnsservers, entries)
fprintf (f, "nameserver %s\n", inet_ntoa (address->address));
#ifdef ENABLE_RESOLVCONF
#endif
}
-static bool in_addresses (const address_t *addresses, struct in_addr addr)
+static bool in_addresses (const struct address_head *addresses,
+ struct in_addr address)
{
- const address_t *address;
+ const address_t *addr;
- for (address = addresses; address; address = address->next)
- if (address->address.s_addr == addr.s_addr)
+ STAILQ_FOREACH (addr, addresses, entries)
+ if (addr->address.s_addr == address.s_addr)
return (true);
return (false);
}
-static bool in_routes (const route_t *routes, route_t *route)
+static bool in_routes (const struct route_head *routes, route_t *route)
{
const route_t *r;
+
+ if (! routes)
+ return (false);
- for (r = routes; r; r=r->next)
+ 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)
char *token;
bool ntp = false;
- for (address = dhcp->ntpservers; address; address = address->next)
+ STAILQ_FOREACH (address, dhcp->ntpservers, entries)
tomatch++;
/* Check that we really need to update the servers.
}
#endif
- for (address = dhcp->ntpservers; address; address = address->next) {
+ STAILQ_FOREACH (address, dhcp->ntpservers, entries) {
a = inet_ntoa (address->address);
if (ntp)
fprintf (f, "restrict %s nomodify notrap noquery\n", a);
else
snprintf (prefix, PREFIXSIZE, "%s", "ypserver");
- for (address = dhcp->nisservers; address; address = address->next)
+ STAILQ_FOREACH (address, dhcp->nisservers, entries)
fprintf (f, "%s %s\n", prefix, inet_ntoa (address->address));
free (prefix);
const dhcp_t *dhcp, bool up)
{
route_t *route = NULL;
- route_t *new_routes = NULL;
+ struct route_head *new_routes = NULL;
route_t *new_route = NULL;
char *newhostname = NULL;
char *curhostname = NULL;
/* 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. */
- for (route = iface->previous_routes; route; route = route->next)
+ 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) {
#endif
/* Remember added routes */
- for (route = dhcp->routes; route; route = route->next) {
+ 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 (remember >= 0) {
if (! new_routes) {
new_routes = xmalloc (sizeof (*new_routes));
- new_route = new_routes;
- } else {
- new_route->next = xmalloc (sizeof (*new_route));
- new_route = new_route->next;
+ STAILQ_INIT (new_routes);
}
+ new_route = xmalloc (sizeof (route_t));
memcpy (new_route, route, sizeof (*new_route));
- new_route -> next = NULL;
+ STAILQ_INSERT_TAIL (new_routes, new_route, entries);
}
#ifdef THERE_IS_NO_FORK
/* If we have daemonised yet we need to record which routes
if (remember >= 0) {
if (! new_routes) {
new_routes = xmalloc (sizeof (*new_routes));
- new_route = new_routes;
- } else {
- new_route->next = xmalloc (sizeof (*new_route));
- new_route = new_route->next;
+ 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;
- new_route->next = NULL;
+ STAILQ_INSERT_TAIL (new_routes, new_route, entries);
}
}
#endif
#include "logger.h"
#include "socket.h"
+#ifndef STAILQ_CONCAT
+#define STAILQ_CONCAT(head1, head2) do { \
+ if (!STAILQ_EMPTY((head2))) { \
+ *(head1)->stqh_last = (head2)->stqh_first; \
+ (head1)->stqh_last = (head2)->stqh_last; \
+ STAILQ_INIT((head2)); \
+ } \
+} while (0)
+#endif
+
typedef struct message {
int value;
const char *name;
/* Add our classless static routes to the routes variable
* and return the last route set */
-static route_t *decode_CSR(const unsigned char *p, int len)
+static struct route_head *decode_CSR (const unsigned char *p, int len)
{
const unsigned char *q = p;
unsigned int cidr;
unsigned int ocets;
- route_t *first;
+ 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;
- first = xzalloc (sizeof (*first));
- route = first;
-
while (q - p < len) {
- memset (route, 0, sizeof (*route));
+ 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 (first);
+ free_route (routes);
return (NULL);
}
ocets = (cidr + 7) / 8;
memcpy (&route->gateway.s_addr, q, 4);
q += 4;
- /* We have another route */
- if (q - p < len) {
- route->next = xzalloc (sizeof (*route));
- route = route->next;
- }
+ STAILQ_INSERT_TAIL (routes, route, entries);
}
- return first;
+ return (routes);
}
void free_dhcp (dhcp_t *dhcp)
}
}
-static bool dhcp_add_address (address_t **address,
- const unsigned char *data, int length)
+static bool dhcp_add_address (struct address_head **addresses,
+ const unsigned char *data,
+ int length)
{
int i;
- address_t *p = *address;
+ address_t *address;
for (i = 0; i < length; i += 4) {
- if (*address == NULL) {
- p = *address = xzalloc (sizeof (*p));
- } else {
- p->next = xzalloc (sizeof (*p));
- p = p->next;
- }
-
/* Sanity check */
if (i + 4 > length) {
logger (LOG_ERR, "invalid address length");
return (false);
}
- memcpy (&p->address.s_addr, data + i, 4);
+ 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);
return (htonl (~t));
}
-static route_t *decode_routes (const unsigned char *data, int length)
+static struct route_head *decode_routes (const unsigned char *data, int length)
{
int i;
- route_t *head = NULL;
- route_t *routes = NULL;
+ struct route_head *head = NULL;
+ route_t *route;
for (i = 0; i < length; i += 8) {
- if (routes) {
- routes->next = xzalloc (sizeof (*routes));
- routes = routes->next;
- } else
- head = routes = xzalloc (sizeof (*head));
- memcpy (&routes->destination.s_addr, data + i, 4);
- memcpy (&routes->gateway.s_addr, data + i + 4, 4);
- routes->netmask.s_addr =
- route_netmask (routes->destination.s_addr);
+ 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 route_t *decode_routers (const unsigned char *data, int length)
+static struct route_head *decode_routers (const unsigned char *data, int length)
{
int i;
- route_t *head = NULL;
- route_t *routes = NULL;
+ struct route_head *head = NULL;
+ route_t *route = NULL;
for (i = 0; i < length; i += 4) {
- if (routes) {
- routes->next = xzalloc (sizeof (*routes));
- routes = routes->next;
- } else
- head = routes = xzalloc (sizeof (*head));
- memcpy (&routes->gateway.s_addr, data + 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);
unsigned int len = 0;
int retval = -1;
struct timeval tv;
- route_t *routers = NULL;
- route_t *routes = NULL;
- route_t *csr = NULL;
- route_t *mscsr = NULL;
+ 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;
free_route (routes);
} else {
/* Ensure that we apply static routes before routers */
- if (routes)
- {
- dhcp->routes = routes;
- while (routes->next)
- routes = routes->next;
- routes->next = routers;
- } else
- dhcp->routes = routers;
+ if (! routes)
+ routes = routers;
+ else if (routers)
+ STAILQ_CONCAT (routes, routers);
+ dhcp->routes = routes;
}
return (retval);
uint32_t renewaltime;
uint32_t rebindtime;
- route_t *routes;
+ struct route_head *routes;
char *hostname;
fqdn_t *fqdn;
- address_t *dnsservers;
+ struct address_head *dnsservers;
char *dnsdomain;
char *dnssearch;
- address_t *ntpservers;
+ struct address_head *ntpservers;
- address_t *nisservers;
+ struct address_head *nisservers;
char *nisdomain;
char *sipservers;
}
-static void print_addresses (FILE *f, const address_t *addresses)
+static void print_addresses (FILE *f, const struct address_head *addresses)
{
const address_t *addr;
- for (addr = addresses; addr; addr = addr->next) {
+ STAILQ_FOREACH (addr, addresses, entries) {
fprintf (f, "%s", inet_ntoa (addr->address));
- if (addr->next)
+ if (STAILQ_NEXT (addr, entries))
fprintf (f, " ");
}
}
if (dhcp->routes) {
bool doneone = false;
fprintf (f, "ROUTES='");
- for (route = dhcp->routes; route; route = route->next) {
+ STAILQ_FOREACH (route, dhcp->routes, entries) {
if (route->destination.s_addr != 0) {
if (doneone)
fprintf (f, " ");
doneone = false;
fprintf (f, "GATEWAYS='");
- for (route = dhcp->routes; route; route = route->next) {
+ STAILQ_FOREACH (route, dhcp->routes, entries) {
if (route->destination.s_addr == 0) {
if (doneone)
fprintf (f, " ");
address_t *addr;
fprintf (f, "DNS='");
- for (addr = dhcp->dnsservers; addr; addr = addr->next) {
+ STAILQ_FOREACH (addr, dhcp->dnsservers, entries) {
fprintf (f, "%s", inet_ntoa (addr->address));
- if (addr->next)
+ if (STAILQ_NEXT (addr, entries))
fprintf (f, ",");
}
fprintf (f, "'\n");
if (dhcp->routes) {
bool doneone = false;
fprintf (f, "GATEWAY='");
- for (route = dhcp->routes; route; route = route->next) {
+ STAILQ_FOREACH (route, dhcp->routes, entries) {
if (route->destination.s_addr == 0) {
if (doneone)
fprintf (f, ",");
return (true);
}
-static bool parse_addresses (address_t **address, char *value, const char *var)
+static struct address_head *parse_addresses (char *value, const char *var)
{
char *token;
char *p = value;
- bool retval = true;
+ 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);
- retval = false;
- } else {
- if (*address) {
- address_t *aa = *address;
- while (aa->next)
- aa = aa->next;
- aa->next = a;
- } else
- *address = a;
+ return (NULL);
}
+
+ if (! head) {
+ head = xmalloc (sizeof (*head));
+ STAILQ_INIT (head);
+ }
+ STAILQ_INSERT_TAIL (head, a, entries);
}
- return (retval);
+ return (head);
}
bool read_info (const interface_t *iface, dhcp_t *dhcp)
}
/* OK, now add our route */
- if (dhcp->routes) {
- route_t *r = dhcp->routes;
- while (r->next)
- r = r->next;
- r->next = route;
- } else
- dhcp->routes = 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) {
- route_t *r = dhcp->routes;
- while (r->next)
- r = r->next;
- r->next = route;
- } else
- dhcp->routes = route;
+ 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, "DNSSEARCH") == 0)
dhcp->dnssearch = xstrdup (value);
else if (strcmp (var, "DNSSERVERS") == 0)
- parse_addresses (&dhcp->dnsservers, value, "DNSSERVERS");
+ dhcp->dnsservers = parse_addresses (value, "DNSSERVERS");
else if (strcmp (var, "NTPSERVERS") == 0)
- parse_addresses (&dhcp->ntpservers, value, "NTPSERVERS");
+ dhcp->ntpservers = parse_addresses (value, "NTPSERVERS");
else if (strcmp (var, "NISDOMAIN") == 0)
dhcp->nisdomain = xstrdup (value);
else if (strcmp (var, "NISSERVERS") == 0)
- parse_addresses (&dhcp->nisservers, value, "NISSERVERS");
+ dhcp->nisservers = parse_addresses (value, "NISSERVERS");
else if (strcmp (var, "ROOTPATH") == 0)
dhcp->rootpath = xstrdup (value);
else if (strcmp (var, "DHCPSID") == 0)
#include "interface.h"
#include "logger.h"
-void free_address (address_t *addresses)
+void free_address (struct address_head *addresses)
{
- address_t *p = addresses;
- address_t *n = NULL;
+ address_t *p;
+ address_t *n;
+ if (! addresses)
+ return;
+
+ p = STAILQ_FIRST (addresses);
while (p) {
- n = p->next;
+ n = STAILQ_NEXT (p, entries);
free (p);
p = n;
}
}
-void free_route (route_t *routes)
+void free_route (struct route_head *routes)
{
- route_t *p = routes;
- route_t *n = NULL;
+ route_t *p;
+ route_t *n;
+
+ if (! routes)
+ return;
+ p = STAILQ_FIRST (routes);
while (p) {
- n = p->next;
+ n = STAILQ_NEXT (p, entries);
free (p);
p = n;
}
#include <sys/types.h>
#include <sys/param.h>
+#include <sys/queue.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
# define IN_LINKLOCAL(addr) ((addr & IN_CLASSB_NET) == LINKLOCAL_ADDR)
#endif
+#define NSTAILQ_FOREACH(var, head, field) \
+ if (head) STAILQ_FOREACH (var, head, field)
+
typedef struct route_t
{
struct in_addr destination;
struct in_addr netmask;
struct in_addr gateway;
- struct route_t *next;
+ STAILQ_ENTRY (route_t) entries;
} route_t;
+STAILQ_HEAD (route_head, route_t);
typedef struct address_t
{
struct in_addr address;
- struct address_t *next;
+ STAILQ_ENTRY (address_t) entries;
} address_t;
+STAILQ_HEAD (address_head, address_t);
typedef struct interface_t
{
unsigned short previous_mtu;
struct in_addr previous_address;
struct in_addr previous_netmask;
- route_t *previous_routes;
+ struct route_head *previous_routes;
time_t start_uptime;
size_t clientid_len;
} interface_t;
-void free_address (address_t *addresses);
-void free_route (route_t *routes);
+void free_address (struct address_head *addresses);
+void free_route (struct route_head *routes);
uint32_t get_netmask (uint32_t addr);
char *hwaddr_ntoa (const unsigned char *hwaddr, size_t hwlen);
size_t hwaddr_aton (unsigned char *hwaddr, const char *addr);