if (options->doinform &&
has_address(iface->name, dhcp->address) < 1)
{
- add_address(iface->name, dhcp->address,
- dhcp->netmask, dhcp->broadcast);
+ /* add_address */
iface->previous_address = dhcp->address;
iface->previous_netmask = dhcp->netmask;
}
logger(LOG_INFO, "received approval for %s",
inet_ntoa(dhcp->address));
if (iface->previous_netmask.s_addr != dhcp->netmask.s_addr) {
- add_address(iface->name, dhcp->address,
- dhcp->netmask, dhcp->broadcast);
+ /* add_address */
iface->previous_netmask.s_addr = dhcp->netmask.s_addr;
}
state->timeout = options->leasetime;
#include "signal.h"
#include "socket.h"
+static void
+log_route(const struct in_addr *destination,
+ const struct in_addr *netmask,
+ const struct in_addr *gateway, _unused int metric, int del)
+{
+ char *dstd = xstrdup(inet_ntoa(*destination));
+
+#ifdef __linux__
+#define METRIC " metric %d"
+#else
+#define METRIC ""
+#endif
+
+ if (gateway->s_addr == destination->s_addr ||
+ gateway->s_addr == INADDR_ANY)
+ logger(LOG_INFO, "%s route to %s/%d" METRIC,
+ del ? "removing" : "adding",
+ dstd, inet_ntocidr(*netmask)
+#ifdef __linux__
+ , metric
+#endif
+ );
+ else if (destination->s_addr == INADDR_ANY)
+ logger(LOG_INFO, "%s default route via %s" METRIC,
+ del ? "removing" : "adding",
+ inet_ntoa(*gateway)
+
+#ifdef __linux__
+ , metric
+#endif
+ );
+ else
+ logger(LOG_INFO, "%s route to %s/%d via %s" METRIC,
+ del ? "removing" : "adding",
+ dstd, inet_ntocidr(*netmask), inet_ntoa(*gateway)
+#ifdef __linux__
+ , metric
+#endif
+ );
+
+ free(dstd);
+}
+
+static int
+a_address(const char *ifname, const struct in_addr *address,
+ const struct in_addr *netmask, const struct in_addr *broadcast)
+{
+ int retval;
+
+ logger(LOG_INFO, "adding IP address %s/%d",
+ inet_ntoa(*address), inet_ntocidr(*netmask));
+ retval = add_address(ifname, address, netmask, broadcast);
+ if (retval == -1)
+ logger(LOG_ERR, "if_address: %s", strerror(errno));
+ return retval;
+}
+
+static int
+d_address(const char *ifname,
+ const struct in_addr *address, const struct in_addr *netmask)
+{
+ int retval;
+
+ logger(LOG_INFO, "removing IP address %s/%d",
+ inet_ntoa(*address), inet_ntocidr(*netmask));
+ retval = del_address(ifname, address, netmask);
+ if (retval == -1)
+ logger(LOG_ERR, "del_address: %s", strerror(errno));
+ return retval;
+}
+
+
+static int
+a_route(const char *ifname, const struct in_addr *destination,
+ const struct in_addr *netmask, const struct in_addr *gateway,
+ int metric)
+{
+ int retval;
+
+ log_route(destination, netmask, gateway, metric, 0);
+ retval = add_route(ifname, destination, netmask, gateway, metric);
+ if (retval == -1)
+ logger(LOG_ERR, "add_route: %s", strerror(errno));
+ return retval;
+}
+
+static int
+d_route(const char *ifname, const struct in_addr *destination,
+ const struct in_addr *netmask, const struct in_addr *gateway,
+ int metric)
+{
+ int retval;
+
+ log_route(destination, netmask, gateway, metric, 1);
+ retval = del_route(ifname, destination, netmask, gateway, metric);
+ if (retval == -1)
+ logger(LOG_ERR, "del_route: %s", strerror(errno));
+ return retval;
+}
+
#ifdef ENABLE_RESOLVCONF
static int
file_in_path(const char *file)
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,
+ 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) {
/* This also changes netmask */
if (!options->doinform || !has_address (iface->name, dhcp->address))
- if (add_address(iface->name, dhcp->address, dhcp->netmask,
- dhcp->broadcast) == -1 &&
+ if (a_address(iface->name, &dhcp->address, &dhcp->netmask,
+ &dhcp->broadcast) == -1 &&
errno != EEXIST)
return false;
if (iface->previous_address.s_addr != dhcp->address.s_addr &&
iface->previous_address.s_addr != 0 &&
! options->keep_address)
- del_address(iface->name,
- iface->previous_address, iface->previous_netmask);
+ d_address(iface->name,
+ &iface->previous_address, &iface->previous_netmask);
#ifdef __linux__
/* On linux, we need to change the subnet route to have our metric. */
{
dest.s_addr = dhcp->address.s_addr & dhcp->netmask.s_addr;
gate.s_addr = 0;
- add_route(iface->name, dest, dhcp->netmask, gate, options->metric);
- del_route(iface->name, dest, dhcp->netmask, gate, 0);
+ a_route(iface->name, &dest, &dhcp->netmask, &gate, options->metric);
+ d_route(iface->name, &dest, &dhcp->netmask, &gate, 0);
}
#endif
! options->dogateway)
continue;
- remember = add_route(iface->name, route->destination,
- route->netmask, route->gateway,
- options->metric);
+ remember = a_route(iface->name, &route->destination,
+ &route->netmask, &route->gateway,
+ options->metric);
/* If we failed to add the route, we may have already added it
ourselves. If so, remember it again. */
if (remember < 0 && in_routes(iface->previous_routes, route))
dest.s_addr = htonl(LINKLOCAL_ADDR);
mask.s_addr = htonl(LINKLOCAL_MASK);
gate.s_addr = 0;
- remember = add_route(iface->name, dest, mask, gate,
- options->metric);
+ remember = d_route(iface->name, &dest, &mask, &gate,
+ options->metric);
if (remember >= 0) {
if (! new_routes) {
int
if_route(const char *ifname, struct in_addr destination,
struct in_addr netmask, struct in_addr gateway,
- int metric, int change, int del)
+ int metric, int action)
{
int s;
static int seq;
memset(&rtm, 0, sizeof(rtm));
rtm.hdr.rtm_version = RTM_VERSION;
rtm.hdr.rtm_seq = ++seq;
- rtm.hdr.rtm_type = change ? RTM_CHANGE : del ? RTM_DELETE : RTM_ADD;
+ if (action == 0)
+ rtm.hdr.rtm_type = RTM_CHANGE;
+ else if (action > 0)
+ rtm.hdr.rtm_type = RTM_ADD;
+ else
+ rtm.hdr.rtm_type = RTM_DELETE;
rtm.hdr.rtm_flags = RTF_UP | RTF_STATIC;
/* This order is important */
int
if_address(const char *ifname,
- struct in_addr address, struct in_addr netmask,
- struct in_addr broadcast, int del)
+ const struct in_addr *address, const struct in_addr *netmask,
+ const struct in_addr *broadcast, int action)
{
struct nlma *nlm;
int retval = 0;
nlm = xzalloc(sizeof(*nlm));
nlm->hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
nlm->hdr.nlmsg_flags = NLM_F_REQUEST;
- if (!del)
+ if (action >= 0) {
nlm->hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE;
- nlm->hdr.nlmsg_type = del ? RTM_DELADDR : RTM_NEWADDR;
+ nlm->hdr.nlmsg_type = RTM_NEWADDR;
+ } else
+ nlm->hdr.nlmsg_type = RTM_DELADDR;
if (!(nlm->ifa.ifa_index = if_nametoindex(ifname))) {
free(nlm);
errno = ENODEV;
return -1;
}
nlm->ifa.ifa_family = AF_INET;
- nlm->ifa.ifa_prefixlen = inet_ntocidr(netmask);
+ nlm->ifa.ifa_prefixlen = inet_ntocidr(*netmask);
/* This creates the aliased interface */
add_attr_l(&nlm->hdr, sizeof(*nlm), IFA_LABEL,
ifname, strlen(ifname) + 1);
add_attr_l(&nlm->hdr, sizeof(*nlm), IFA_LOCAL,
- &address.s_addr, sizeof(address.s_addr));
- if (!del)
+ &address->s_addr, sizeof(address->s_addr));
+ if (action >= 0)
add_attr_l(&nlm->hdr, sizeof(*nlm), IFA_BROADCAST,
- &broadcast.s_addr, sizeof(broadcast.s_addr));
+ &broadcast->s_addr, sizeof(broadcast->s_addr));
if (send_netlink(&nlm->hdr) == -1)
retval = -1;
int
if_route(const char *ifname,
- struct in_addr destination, struct in_addr netmask,
- struct in_addr gateway, int metric, int change, int del)
+ const struct in_addr *destination, const struct in_addr *netmask,
+ const struct in_addr *gateway, int metric, int action)
{
struct nlmr *nlm;
unsigned int ifindex;
nlm = xzalloc(sizeof(*nlm));
nlm->hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
- if (change)
+ nlm->hdr.nlmsg_type = RTM_NEWROUTE;
+ if (action == 0)
nlm->hdr.nlmsg_flags = NLM_F_REPLACE;
- else if (!del)
+ else if (action > 0)
nlm->hdr.nlmsg_flags = NLM_F_CREATE | NLM_F_EXCL;
+ else
+ nlm->hdr.nlmsg_type = RTM_DELROUTE;
nlm->hdr.nlmsg_flags |= NLM_F_REQUEST;
- nlm->hdr.nlmsg_type = del ? RTM_DELROUTE : RTM_NEWROUTE;
nlm->rt.rtm_family = AF_INET;
nlm->rt.rtm_table = RT_TABLE_MAIN;
- if (del)
+ if (action < 0)
nlm->rt.rtm_scope = RT_SCOPE_NOWHERE;
else {
nlm->hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
nlm->rt.rtm_protocol = RTPROT_BOOT;
- if (netmask.s_addr == INADDR_BROADCAST ||
- gateway.s_addr == INADDR_ANY)
+ if (netmask->s_addr == INADDR_BROADCAST ||
+ gateway->s_addr == INADDR_ANY)
nlm->rt.rtm_scope = RT_SCOPE_LINK;
else
nlm->rt.rtm_scope = RT_SCOPE_UNIVERSE;
nlm->rt.rtm_type = RTN_UNICAST;
}
- nlm->rt.rtm_dst_len = inet_ntocidr(netmask);
+ nlm->rt.rtm_dst_len = inet_ntocidr(*netmask);
add_attr_l(&nlm->hdr, sizeof(*nlm), RTA_DST,
- &destination.s_addr, sizeof(destination.s_addr));
- if (netmask.s_addr != INADDR_BROADCAST &&
- destination.s_addr != gateway.s_addr)
+ &destination->s_addr, sizeof(destination->s_addr));
+ if (netmask->s_addr != INADDR_BROADCAST &&
+ destination->s_addr != gateway->s_addr)
add_attr_l(&nlm->hdr, sizeof(*nlm), RTA_GATEWAY,
- &gateway.s_addr, sizeof(gateway.s_addr));
+ &gateway->s_addr, sizeof(gateway->s_addr));
add_attr_32(&nlm->hdr, sizeof(*nlm), RTA_OIF, ifindex);
add_attr_32(&nlm->hdr, sizeof(*nlm), RTA_PRIORITY, metric);
#include "common.h"
#include "dhcp.h"
#include "if.h"
-#include "logger.h"
int
inet_ntocidr(struct in_addr address)
return ifr.ifr_mtu;
}
-static void
-log_route(struct in_addr destination, struct in_addr netmask,
- struct in_addr gateway, _unused int metric, int del)
-{
- char *dstd = xstrdup(inet_ntoa(destination));
-
-#ifdef __linux__
-#define METRIC " metric %d"
-#else
-#define METRIC ""
-#endif
-
- if (gateway.s_addr == destination.s_addr ||
- gateway.s_addr == INADDR_ANY)
- logger(LOG_INFO, "%s route to %s/%d" METRIC,
- del ? "removing" : "adding",
- dstd, inet_ntocidr(netmask)
-#ifdef __linux__
- , metric
-#endif
- );
- else if (destination.s_addr == INADDR_ANY)
- logger(LOG_INFO, "%s default route via %s" METRIC,
- del ? "removing" : "adding",
- inet_ntoa(gateway)
-
-#ifdef __linux__
- , metric
-#endif
- );
- else
- logger(LOG_INFO, "%s route to %s/%d via %s" METRIC,
- del ? "removing" : "adding",
- dstd, inet_ntocidr(netmask), inet_ntoa(gateway)
-#ifdef __linux__
- , metric
-#endif
- );
-
- free(dstd);
-}
-
-
-int
-add_address(const char *ifname, struct in_addr address,
- struct in_addr netmask, struct in_addr broadcast)
-{
- int retval;
-
- logger(LOG_INFO, "adding IP address %s/%d",
- inet_ntoa(address), inet_ntocidr(netmask));
- retval = if_address(ifname, address, netmask, broadcast, 0);
- if (retval == -1)
- logger(LOG_ERR, "if_address: %s", strerror(errno));
- return retval;
-}
-
-int
-del_address(const char *ifname, struct in_addr address, struct in_addr netmask)
-{
- struct in_addr t;
- int retval;
-
- logger(LOG_INFO, "removing IP address %s/%d",
- inet_ntoa(address), inet_ntocidr(netmask));
- t.s_addr = 0;
- retval = if_address(ifname, address, netmask, t, 1);
- if (retval == -1)
- logger(LOG_ERR, "if_address: %s", strerror(errno));
- return retval;
-}
-
-int
-add_route(const char *ifname, struct in_addr destination,
- struct in_addr netmask, struct in_addr gateway, int metric)
-{
- int retval;
-
- log_route(destination, netmask, gateway, metric, 0);
- retval = if_route(ifname, destination, netmask, gateway, metric, 0, 0);
- if (retval == -1)
- logger(LOG_ERR, "if_route: %s", strerror(errno));
- return retval;
-}
-
-int
-del_route(const char *ifname, struct in_addr destination,
- struct in_addr netmask, struct in_addr gateway, int metric)
-{
- int retval;
-
- log_route(destination, netmask, gateway, metric, 1);
- retval = if_route(ifname, destination, netmask, gateway, metric, 0, 1);
- if (retval == -1)
- logger(LOG_ERR, "if_route: %s", strerror(errno));
- return retval;
-}
in_addr_t
get_address(const char *ifname)
retval = do_interface(ifname, NULL, NULL, &address, false, true);
if (retval > 0)
return address.s_addr;
- if (retval == -1)
- logger(LOG_ERR, "do_interface: %s", strerror(errno));
return retval;
}
#ifdef ENABLE_DUID
#ifndef DUID_LEN
-# define DUID_LEN 128 + 2
+# define DUID_LEN 128 + 2
#endif
#endif
#define get_mtu(iface) do_mtu(iface, 0)
#define set_mtu(iface, mtu) do_mtu(iface, mtu)
-int add_address(const char *, struct in_addr, struct in_addr, struct in_addr);
-int del_address(const char *, struct in_addr, struct in_addr);
-int flush_addresses(const char *);
+#define add_address(ifname, addr, mask, brd) \
+ if_address(ifname, &(addr), &(mask), brd, 1)
+#define del_address(ifname, addr, mask) \
+ if_address(ifname, &(addr), &(mask), NULL, -1)
#define flush_addresses(ifname) \
do_interface(ifname, NULL, NULL, NULL, true, false)
in_addr_t get_address(const char *);
#define has_address(ifname, addr) \
do_interface(ifname, NULL, NULL, (struct in_addr *)&(addr), false, false)
-int add_route(const char *, struct in_addr, struct in_addr, struct in_addr,
- int);
-int del_route(const char *, struct in_addr, struct in_addr, struct in_addr,
- int);
+#define add_route(ifname, dest, mask, gate, metric) \
+ if_route(ifname, dest, mask, gate, metric, 1)
+#define del_route(ifname, dest, mask, gate, metric) \
+ if_route(ifname, dest, mask, gate, metric, -1)
int inet_ntocidr(struct in_addr);
int inet_cidrtoaddr(int, struct in_addr *);
int do_interface(const char *, unsigned char *, size_t *, struct in_addr *,
bool, bool);
-int if_address(const char *, struct in_addr, struct in_addr, struct in_addr,
- int del);
-int if_route(const char *, struct in_addr, struct in_addr, struct in_addr,
- int metric, int change, int del);
+int if_address(const char *, const struct in_addr *, const struct in_addr *,
+ const struct in_addr *, int);
+int if_route(const char *, const struct in_addr *, const struct in_addr *,
+ const struct in_addr *, int, int);
#endif