]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Improve PTP INFORM support some more.
authorRoy Marples <roy@marples.name>
Mon, 23 Mar 2009 22:02:37 +0000 (22:02 +0000)
committerRoy Marples <roy@marples.name>
Mon, 23 Mar 2009 22:02:37 +0000 (22:02 +0000)
configure.c
dhcp.c
dhcp.h
dhcpcd.c
dhcpcd.h

index 159f1479a5b8ba7cf719586896102bc87be7c47f..dbb9118d464b35e3274042123f38b0978051a243 100644 (file)
@@ -42,6 +42,7 @@
 #include "config.h"
 #include "common.h"
 #include "configure.h"
+#include "dhcp.h"
 #include "if-options.h"
 #include "if-pref.h"
 #include "net.h"
@@ -513,7 +514,8 @@ add_subnet_route(struct rt *rt, const struct interface *iface)
 }
 
 static struct rt *
-get_routes(const struct interface *iface) {
+get_routes(const struct interface *iface)
+{
        struct rt *rt, *nrt = NULL, *r = NULL;
 
        if (iface->state->options->routes != NULL) {
@@ -538,6 +540,22 @@ get_routes(const struct interface *iface) {
        return get_option_routes(iface->state->new);
 }
 
+static struct rt *
+add_destination_route(struct rt *rt, const struct interface *iface)
+{
+       struct rt *r;
+
+       if (!(iface->flags & IFF_POINTOPOINT) ||
+           !has_option_mask(iface->state->options->dstmask, DHO_ROUTER))
+               return rt;
+       r = xmalloc(sizeof(*r));
+       r->dest.s_addr = INADDR_ANY;
+       r->net.s_addr = INADDR_ANY;
+       r->gate.s_addr = iface->dst.s_addr;
+       r->next = rt;
+       return r;
+}
+
 void
 build_routes(void)
 {
@@ -549,6 +567,7 @@ build_routes(void)
                        continue;
                dnr = get_routes(ifp);
                dnr = add_subnet_route(dnr, ifp);
+               dnr = add_destination_route(dnr, ifp);
                for (rt = dnr; rt && (rtn = rt->next, 1); lrt = rt, rt = rtn) {
                        rt->iface = ifp;
                        /* Is this route already in our table? */
@@ -618,6 +637,7 @@ configure(struct interface *iface)
 {
        struct dhcp_message *dhcp = iface->state->new;
        struct dhcp_lease *lease = &iface->state->lease;
+       struct if_options *ifo = iface->state->options;
        struct rt *rt;
 
        /* As we are now adjusting an interface, we need to ensure
@@ -633,7 +653,7 @@ configure(struct interface *iface)
        }
 
        /* This also changes netmask */
-       if (!(iface->state->options->options & DHCPCD_INFORM) ||
+       if (!(ifo->options & DHCPCD_INFORM) ||
            !has_address(iface->name, &lease->addr, &lease->net))
        {
                syslog(LOG_DEBUG, "%s: adding IP address %s/%d",
@@ -668,7 +688,7 @@ configure(struct interface *iface)
 
        build_routes();
        if (!iface->state->lease.frominfo &&
-           !(iface->state->options->options & DHCPCD_INFORM))
+           !(ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC)))
                if (write_lease(iface, dhcp) == -1)
                        syslog(LOG_ERR, "write_lease: %m");
        run_script(iface);
diff --git a/dhcp.c b/dhcp.c
index 203dc939fde6484a1d9bffd26a8ee9e116c24c95..c5feccad7df5ef958563bca64f25e945303e7cc5 100644 (file)
--- a/dhcp.c
+++ b/dhcp.c
@@ -759,6 +759,31 @@ encode_rfc1035(const char *src, uint8_t *dst)
                memcpy(p, &_val.s_addr, 4);                             \
                p += 4;                                                 \
        }
+
+int
+dhcp_message_add_addr(struct dhcp_message *dhcp,
+    uint8_t type, struct in_addr addr)
+{
+       uint8_t *p;
+       size_t len;
+
+       p = dhcp->options;
+       while (*p != DHO_END) {
+               p++;
+               p += *p + 1;
+       }
+
+       len = p - (uint8_t *)dhcp;
+       if (len + 6 > sizeof(*dhcp)) {
+               errno = ENOMEM;
+               return -1;
+       }
+
+       PUTADDR(type, addr);
+       *p = DHO_END;
+       return 0;
+}
+
 ssize_t
 make_message(struct dhcp_message **message,
     const struct interface *iface,
diff --git a/dhcp.h b/dhcp.h
index c8d8d6fe7dd96bbb5f3390a8119053048047a9ae..90e69f52be4bc05b3c3bcb4ccdf07f753da2e694 100644 (file)
--- a/dhcp.h
+++ b/dhcp.h
@@ -186,6 +186,7 @@ struct rt *get_option_routes(const struct dhcp_message *);
 ssize_t configure_env(char **, const char *, const struct dhcp_message *,
     const struct if_options *);
 
+int dhcp_message_add_addr(struct dhcp_message *, uint8_t, struct in_addr);
 ssize_t make_message(struct dhcp_message **, const struct interface *,
     uint8_t);
 int valid_dhcp_packet(unsigned char *);
index f3ab5ee987bbcd832476a7f02071a6e342161624..f3b96a9dfa3d2d803e0d177751b165f2b10a09c8 100644 (file)
--- a/dhcpcd.c
+++ b/dhcpcd.c
@@ -600,7 +600,7 @@ handle_dhcp_packet(void *arg)
                        continue;
                }
                if (iface->flags & IFF_POINTOPOINT &&
-                   iface->state->lease.server.s_addr != from.s_addr)
+                   iface->dst.s_addr != from.s_addr)
                {
                        syslog(LOG_WARNING,
                            "%s: server %s is not destination",
@@ -687,10 +687,11 @@ configure_interface(struct interface *iface, int argc, char **argv)
        free_options(ifs->options);
        ifo = ifs->options = read_config(cffile, iface->name, iface->ssid);
        add_options(ifo, argc, argv);
-       if (iface->flags & IFF_NOARP)
-               ifo->options &= ~(DHCPCD_ARP | DHCPCD_IPV4LL);
        if (iface->flags & IFF_POINTOPOINT && !(ifo->options & DHCPCD_INFORM))
                ifo->options |= DHCPCD_STATIC;
+       if (iface->flags & IFF_NOARP ||
+           ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC))
+               ifo->options &= ~(DHCPCD_ARP | DHCPCD_IPV4LL);
        if (ifo->options & DHCPCD_LINK && carrier_status(iface->name) == -1)
                ifo->options &= ~DHCPCD_LINK;
        
@@ -1132,32 +1133,6 @@ handle_interface(int action, const char *ifname)
        }
 }
 
-static int
-dhcp_message_add_addr(struct dhcp_message *dhcp, char c, struct in_addr *addr)
-{
-       uint8_t *p;
-       size_t len;
-
-       p = dhcp->options;
-       while (*p != DHO_END) {
-               p++;
-               p += *p + 1;
-       }
-
-       len = p - (uint8_t *)dhcp;
-       if (len + 6 > sizeof(*dhcp)) {
-               errno = ENOMEM;
-               return -1;
-       }
-
-       *p++ = c;
-       *p++ = sizeof(addr->s_addr);
-       memcpy(p, &addr->s_addr, sizeof(addr->s_addr));
-       p += sizeof(addr->s_addr);
-       *p = DHO_END;
-       return 0;
-}
-
 void
 handle_ifa(int type, const char *ifname,
     struct in_addr *addr, struct in_addr *net, struct in_addr *dst)
@@ -1188,12 +1163,14 @@ handle_ifa(int type, const char *ifname,
                free(ifp->state->old);
                ifp->state->old = ifp->state->new;
                ifp->state->new = dhcp_message_new(addr, net);
+               ifp->dst.s_addr = dst ? dst->s_addr : INADDR_ANY;
                if (dst) {
                        for (i = 1; i < 255; i++)
-                               if (has_option_mask(ifo->dstmask, i))
+                               if (i != DHO_ROUTER &&
+                                   has_option_mask(ifo->dstmask, i))
                                        dhcp_message_add_addr(
                                                ifp->state->new,
-                                               i, dst);
+                                               i, *dst);
                }
                ifp->state->reason = "STATIC";
                build_routes();
@@ -1201,9 +1178,10 @@ handle_ifa(int type, const char *ifname,
                if (ifo->options & DHCPCD_INFORM) {
                        ifp->state->state = DHS_INFORM;
                        ifp->state->xid = arc4random();
+                       ifp->state->lease.server.s_addr =
+                               dst ? dst->s_addr : INADDR_ANY;
                        ifp->addr = *addr;
                        ifp->net = *net;
-                       ifp->state->lease.server = *dst;
                        open_sockets(ifp);
                        send_inform(ifp);
                }
index 927f019f6e23c5f812ff3c9589b900aedbe8bb9f..a65e8633159f67ebb9039e3d033cffe28f46c149 100644 (file)
--- a/dhcpcd.h
+++ b/dhcpcd.h
@@ -100,6 +100,7 @@ struct interface {
 
        struct in_addr addr;
        struct in_addr net;
+       struct in_addr dst;
 
        char leasefile[PATH_MAX];
        time_t start_uptime;