Mercurial > hg > dhcpcd
changeset 45:c17863fc1b2d draft
Add static routes before any default routes as a router may require a host
route in the static routes.
| author | Roy Marples <roy@marples.name> |
|---|---|
| date | Thu, 28 Dec 2006 18:44:16 +0000 |
| parents | 5e34595a9e0f |
| children | 23d8133bf061 |
| files | ChangeLog configure.c dhcp.c interface.c socket.c |
| diffstat | 5 files changed, 103 insertions(+), 40 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Thu Dec 21 21:12:28 2006 +0000 +++ b/ChangeLog Thu Dec 28 18:44:16 2006 +0000 @@ -1,3 +1,6 @@ +Add static routes before any default routes as a router may require a host +route in the static routes. + dhcpcd-3.0.8 Fix arp checking. linux header asm/types.h doesn't work with c99 which is just wrong,
--- a/configure.c Thu Dec 21 21:12:28 2006 +0000 +++ b/configure.c Thu Dec 28 18:44:16 2006 +0000 @@ -426,7 +426,7 @@ #ifdef __linux__ /* On linux, we need to change the subnet route to have our metric. */ if (iface->previous_address.s_addr != dhcp->address.s_addr - && options->metric > 0) + && options->metric > 0 && dhcp->netmask.s_addr != INADDR_BROADCAST) { struct in_addr td; struct in_addr tg;
--- a/dhcp.c Thu Dec 21 21:12:28 2006 +0000 +++ b/dhcp.c Thu Dec 28 18:44:16 2006 +0000 @@ -165,8 +165,8 @@ *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_STATICROUTE; *p++ = DHCP_HOSTNAME; *p++ = DHCP_DNSSEARCH; *p++ = DHCP_DNSDOMAIN;
--- a/interface.c Thu Dec 21 21:12:28 2006 +0000 +++ b/interface.c Thu Dec 28 18:44:16 2006 +0000 @@ -115,7 +115,7 @@ for (p = ifap; p; p = p->ifa_next) { union - { + { struct sockaddr *sa; struct sockaddr_dl *sdl; } us; @@ -130,11 +130,11 @@ /* && us.sdl->sdl_type != IFT_ISO88025)) */ - { - logger (LOG_ERR, "interface is not Ethernet"); - freeifaddrs (ifap); - return NULL; - } + { + 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 = us.sdl->sdl_type; @@ -278,13 +278,19 @@ int change, int del) { int s; - char *destd; + char *dstd; char *gend; struct rtm { struct rt_msghdr hdr; struct sockaddr_in destination; - struct sockaddr_in gateway; + union + { + 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; @@ -295,13 +301,22 @@ /* Do something with metric to satisfy compiler warnings */ metric = 0; - destd = strdup (inet_ntoa (destination)); + dstd = strdup (inet_ntoa (destination)); gend = strdup (inet_ntoa (netmask)); - logger (LOG_INFO, "%s route to %s (%s) via %s", - change ? "changing" : del ? "removing" : "adding", - destd, gend, inet_ntoa(gateway)); - if (destd) - free (destd); + if (gateway.s_addr == destination.s_addr) + logger (LOG_INFO, "%s route to %s (%s)", + change ? "changing" : del ? "removing" : "adding", + dstd, gend); + 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)); + else + logger (LOG_INFO, "%s route to %s (%s) via %s", + change ? "changing" : del ? "removing" : "adding", + dstd, gend, inet_ntoa (gateway)); + if (dstd) + free (dstd); if (gend) free (gend); @@ -317,9 +332,11 @@ rtm.hdr.rtm_seq = ++seq; rtm.hdr.rtm_type = change ? RTM_CHANGE : del ? RTM_DELETE : RTM_ADD; - rtm.hdr.rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC; - if (netmask.s_addr == 0xffffffff) + rtm.hdr.rtm_flags = RTF_UP | RTF_STATIC; + if (netmask.s_addr == INADDR_BROADCAST) rtm.hdr.rtm_flags |= RTF_HOST; + else + rtm.hdr.rtm_flags |= RTF_GATEWAY; rtm.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK; @@ -329,7 +346,40 @@ memcpy (&_var.sin_addr, &_addr, sizeof (struct in_addr)); ADDADDR (rtm.destination, destination); - ADDADDR (rtm.gateway, gateway); + if (netmask.s_addr == INADDR_BROADCAST) + { + struct ifaddrs *ifap, *ifa; + union + { + struct sockaddr *sa; + struct sockaddr_dl *sdl; + } us; + + if (getifaddrs (&ifap)) + { + 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 (strcmp (ifname, ifa->ifa_name)) + continue; + + us.sa = ifa->ifa_addr; + memcpy (&rtm.gateway.sdl, us.sdl, us.sdl->sdl_len); + break; + } + freeifaddrs (ifap); + } + else + { + ADDADDR (rtm.gateway.sin, gateway); + } + ADDADDR (rtm.netmask, netmask); #undef ADDADDR @@ -369,10 +419,10 @@ static unsigned int seq; char buffer[16384]; union - { - char *buffer; - struct nlmsghdr *nlm; - } h; + { + char *buffer; + struct nlmsghdr *nlm; + } h; if ((s = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) < 0) { @@ -504,7 +554,7 @@ } #define NLMSG_TAIL(nmsg) \ - ((struct rtattr *) (((ptrdiff_t) (nmsg)) + NLMSG_ALIGN ((nmsg)->nlmsg_len))) + ((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) @@ -532,7 +582,7 @@ { int len = RTA_LENGTH (sizeof (uint32_t)); struct rtattr *rta; - + if (NLMSG_ALIGN (n->nlmsg_len) + len > maxlen) { logger (LOG_ERR, "add_attr32: message exceeded bound of %d\n", maxlen); @@ -610,9 +660,18 @@ dstd = strdup (inet_ntoa (destination)); gend = strdup (inet_ntoa (netmask)); - logger (LOG_INFO, "%s route to %s (%s) via %s, metric %d", - change ? "changing" : del ? "removing" : "adding", - dstd, gend, inet_ntoa (gateway), metric); + 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); + 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); + else + logger (LOG_INFO, "%s route to %s (%s) via %s metric %d", + change ? "changing" : del ? "removing" : "adding", + dstd, gend, inet_ntoa (gateway), metric); if (dstd) free (dstd); if (gend) @@ -636,7 +695,8 @@ { nlm.hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL; nlm.rt.rtm_protocol = RTPROT_BOOT; - if (gateway.s_addr == 0) + if (gateway.s_addr == INADDR_ANY || + netmask.s_addr == INADDR_BROADCAST) nlm.rt.rtm_scope = RT_SCOPE_LINK; else nlm.rt.rtm_scope = RT_SCOPE_UNIVERSE; @@ -652,7 +712,7 @@ add_attr_l (&nlm.hdr, sizeof (nlm), RTA_DST, &destination.s_addr, sizeof (destination.s_addr)); - if (gateway.s_addr != 0) + 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)); @@ -684,7 +744,7 @@ int del_address (const char *ifname, struct in_addr address) { struct in_addr t; - + logger (LOG_INFO, "deleting IP address %s", inet_ntoa (address)); memset (&t, 0, sizeof (t)); @@ -724,7 +784,7 @@ for (p = ifap; p; p = p->ifa_next) { union - { + { struct sockaddr *sa; struct sockaddr_in *sin; } us;
--- a/socket.c Thu Dec 21 21:12:28 2006 +0000 +++ b/socket.c Thu Dec 28 18:44:16 2006 +0000 @@ -112,7 +112,7 @@ ip->ip_len = udp->uh_ulen; udp->uh_sum = checksum ((unsigned char *) packet, sizeof (struct udp_dhcp_packet)); - + ip->ip_v = IPVERSION; ip->ip_hl = 5; ip->ip_id = 0; @@ -180,7 +180,7 @@ } #if defined(__FreeBSD__) || defined(__NetBSD__) || defined (__OpenBSD__) \ -|| defined(__APPLE__) + || defined(__APPLE__) /* Credit where credit is due :) The below BPF filter is taken from ISC DHCP */ @@ -373,7 +373,7 @@ { int len = -1; union - { + { unsigned char *buffer; struct ether_header *hw; } hdr; @@ -398,7 +398,7 @@ if (valid_dhcp_packet (payload) >= 0) { union - { + { unsigned char *buffer; struct udp_dhcp_packet *packet; } pay; @@ -411,7 +411,7 @@ /* Update the buffer_pos pointer */ bpf.buffer += - BPF_WORDALIGN (bpf.packet->bh_hdrlen + bpf.packet->bh_caplen); + BPF_WORDALIGN (bpf.packet->bh_hdrlen + bpf.packet->bh_caplen); if (bpf.buffer - buffer < *buffer_len) *buffer_pos = bpf.buffer - buffer; else @@ -508,10 +508,10 @@ { long bytes; union - { + { unsigned char *buffer; struct udp_dhcp_packet *packet; - } pay; + } pay; /* We don't use the given buffer, but we need to rewind the position */ *buffer_pos = 0; @@ -563,7 +563,7 @@ 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)); }
