diff options
| author | Roy Marples <roy@marples.name> | 2008-01-16 16:38:47 +0000 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2008-01-16 16:38:47 +0000 |
| commit | 2f736fb7ce0e5e8a21387ac78819bebf673eca79 (patch) | |
| tree | f75bd0812c3aa915b95af242d7ee89a670b4fed7 /configure.c | |
| parent | fc367a018f017e43544224bea067d6957efb4eca (diff) | |
| download | dhcpcd-2f736fb7ce0e5e8a21387ac78819bebf673eca79.tar.xz | |
Re format for standard tabs.
Diffstat (limited to 'configure.c')
| -rw-r--r-- | configure.c | 460 |
1 files changed, 243 insertions, 217 deletions
diff --git a/configure.c b/configure.c index f67a5b41..b0944182 100644 --- a/configure.c +++ b/configure.c @@ -67,7 +67,7 @@ static int file_in_path (const char *file) if (! p) { errno = ENOENT; - return -1; + return (-1); } path = strdup (p); @@ -80,7 +80,7 @@ static int file_in_path (const char *file) } } free (path); - return retval; + return (retval); } /* IMPORTANT: Ensure that the last parameter is NULL when calling */ @@ -108,7 +108,7 @@ static int exec_cmd (const char *cmd, const char *args, ...) if ((pid = vfork ()) == 0) { if (execvp (cmd, argv) && errno != ENOENT) logger (LOG_ERR, "error executing \"%s\": %s", - cmd, strerror (errno)); + cmd, strerror (errno)); _exit (0); } else if (pid == -1) { logger (LOG_ERR, "vfork: %s", strerror (errno)); @@ -121,7 +121,7 @@ static int exec_cmd (const char *cmd, const char *args, ...) } static void exec_script (const char *script, const char *infofile, - const char *arg) + const char *arg) { struct stat buf; @@ -156,7 +156,8 @@ static int make_resolv (const char *ifname, const dhcp_t *dhcp) resolvconf = xmalloc (sizeof (char) * len); snprintf (resolvconf, len, "resolvconf -a %s", ifname); if ((f = popen (resolvconf , "w"))) - logger (LOG_DEBUG, "sending DNS information to resolvconf"); + logger (LOG_DEBUG, + "sending DNS information to resolvconf"); else if (errno == EEXIST) logger (LOG_ERR, "popen: %s", strerror (errno)); @@ -206,6 +207,30 @@ static void restore_resolv (const char *ifname) #endif } +static bool in_addresses (const address_t *addresses, struct in_addr addr) +{ + const address_t *address; + + for (address = addresses; address; address = address->next) + if (address->address.s_addr == addr.s_addr) + return (true); + + return (false); +} + +static bool in_routes (const route_t *routes, route_t *route) +{ + const route_t *r; + + for (r = routes; r; r=r->next) + 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) + return (true); + + return (false); +} + #ifdef ENABLE_NTP static int _make_ntp (const char *file, const char *ifname, const dhcp_t *dhcp) { @@ -224,47 +249,44 @@ static int _make_ntp (const char *file, const char *ifname, const dhcp_t *dhcp) We do this because ntp has to be restarted to work with a changed config */ 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 { - while ((line = getline (f))) { + while (tomatch != 0 && (line = getline (f))) { + struct in_addr addr; + a = line; token = strsep (&a, " "); - if (! token || strcmp (token, "server") != 0) { - free (line); - continue; - } + if (! token || strcmp (token, "server") != 0) + goto next; - if ((token = strsep (&a, " \n")) == NULL) { - free (line); - continue; - } + if ((token = strsep (&a, " \n")) == NULL) + goto next; - for (address = dhcp->ntpservers; address; address = address->next) - if (strcmp (token, inet_ntoa (address->address)) == 0) { - tomatch--; - break; - } + if (inet_aton (token, &addr) == 0 && + in_addresses (dhcp->ntpservers, addr)) + tomatch--; - if (tomatch == 0) { - free (line); - break; - } +next: + free (line); } fclose (f); - /* File has the same name servers that we do, so no need to restart ntp */ + /* 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); if (! (f = fopen (file, "w"))) { logger (LOG_ERR, "fopen `%s': %s", file, strerror (errno)); - return -1; + return (-1); } fprintf (f, "# Generated by dhcpcd for interface %s\n", ifname); @@ -284,7 +306,7 @@ static int _make_ntp (const char *file, const char *ifname, const dhcp_t *dhcp) } fclose (f); - return 1; + return (1); } static int make_ntp (const char *ifname, const dhcp_t *dhcp) @@ -312,28 +334,32 @@ static int make_ntp (const char *ifname, const dhcp_t *dhcp) #ifdef NTPCHECK if (system (NTPCHECK) == 0) #endif - retval += exec_cmd (NTPSERVICE, NTPRESTARTARGS, (char *) NULL); + retval += exec_cmd (NTPSERVICE, NTPRESTARTARGS, + (char *) NULL); } #endif #if defined (NTPSERVICE) && defined (OPENNTPSERVICE) if (restart_openntp && - (strcmp (NTPSERVICE, OPENNTPSERVICE) != 0 || ! restart_ntp)) + (strcmp (NTPSERVICE, OPENNTPSERVICE) != 0 || ! restart_ntp)) { #ifdef OPENNTPCHECK if (system (OPENNTPCHECK) == 0) #endif - retval += exec_cmd (OPENNTPSERVICE, OPENNTPRESTARTARGS, (char *) NULL); + retval += exec_cmd (OPENNTPSERVICE, + OPENNTPRESTARTARGS, (char *) NULL); } #elif defined (OPENNTPSERVICE) && ! defined (NTPSERVICE) if (restart_openntp) { #ifdef OPENNTPCHECK if (system (OPENNTPCHECK) == 0) #endif - retval += exec_cmd (OPENNTPSERVICE, OPENNTPRESTARTARGS, (char *) NULL); + retval += exec_cmd (OPENNTPSERVICE, + OPENNTPRESTARTARGS, (char *) NULL); + } #endif - return retval; + return (retval); } #endif @@ -348,7 +374,7 @@ static int make_nis (const char *ifname, const dhcp_t *dhcp) logger (LOG_DEBUG, "writing "NISFILE); if (! (f = fopen(NISFILE, "w"))) { logger (LOG_ERR, "fopen `%s': %s", NISFILE, strerror (errno)); - return -1; + return (-1); } prefix = xmalloc (sizeof (char) * PREFIXSIZE); @@ -359,7 +385,8 @@ static int make_nis (const char *ifname, const dhcp_t *dhcp) setdomainname (dhcp->nisdomain, strlen (dhcp->nisdomain)); if (dhcp->nisservers) - snprintf (prefix, PREFIXSIZE, "domain %s server", dhcp->nisdomain); + snprintf (prefix, PREFIXSIZE, "domain %s server", + dhcp->nisdomain); else fprintf (f, "domain %s broadcast\n", dhcp->nisdomain); } @@ -376,17 +403,100 @@ static int make_nis (const char *ifname, const dhcp_t *dhcp) if (system (NISCHECK) == 0) #endif exec_cmd (NISSERVICE, NISRESTARTARGS, (char *) NULL); - return 0; + return (0); } #endif +static char *lookuphostname (char *hostname, const dhcp_t *dhcp, + const options_t *options) +{ + union { + struct sockaddr sa; + struct sockaddr_in sin; + } su; + socklen_t salen; + char *addr; + struct addrinfo hints; + struct addrinfo *res; + int result; + char *p; + + logger (LOG_DEBUG, "Looking up hostname via DNS"); + addr = xmalloc (sizeof (char) * NI_MAXHOST); + salen = sizeof (struct sockaddr); + memset (&su.sa, 0, salen); + su.sin.sin_family = AF_INET; + memcpy (&su.sin.sin_addr, &dhcp->address, sizeof (struct in_addr)); + + if ((result = getnameinfo (&su.sa, salen, addr, NI_MAXHOST, + NULL, 0, NI_NAMEREQD)) != 0) { + logger (LOG_ERR, + "Failed to lookup hostname via DNS: %s", + gai_strerror (result)); + free (addr); + return (NULL); + } + + /* Check for a malicious PTR record */ + memset (&hints, 0, sizeof (hints)); + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_NUMERICHOST; + result = getaddrinfo (addr, "0", &hints, &res); + freeaddrinfo (res); + if (result == 0) + logger (LOG_ERR, "malicious PTR record detected"); + if (result == 0 || ! *addr) { + free (addr); + return (NULL); + } + + p = strchr (addr, '.'); + if (p) { + switch (options->dohostname) { + case 1: /* -H */ + case 4: /* -HHHH */ + break; + case 2: /* -HH */ + case 5: /* -HHHHH */ + /* Strip out the domain if it matches */ + p++; + if (*p && dhcp->dnssearch) { + char *s = xstrdup (dhcp->dnssearch); + char *sp = s; + char *t; + + while ((t = strsep (&sp, " "))) + if (strcmp (t, p) == 0) { + *--p = '\0'; + break; + } + free (s); + } else if (dhcp->dnsdomain) { + if (strcmp (dhcp->dnsdomain, p) == 0) + *--p = '\0'; + } + break; + case 3: /* -HHH */ + case 6: /* -HHHHHH */ + /* Just strip the domain */ + *p = '\0'; + break; + default: /* Too many H! */ + break; + } + } + + strlcpy (hostname, addr, MAXHOSTNAMELEN); + free (addr); + return (hostname); +} + int configure (const options_t *options, interface_t *iface, - const dhcp_t *dhcp, bool up) + const dhcp_t *dhcp, bool up) { route_t *route = NULL; route_t *new_routes = NULL; route_t *new_route = NULL; - route_t *old_route = NULL; char *newhostname = NULL; char *curhostname = NULL; int remember; @@ -394,6 +504,7 @@ int configure (const options_t *options, interface_t *iface, bool haslinklocal = false; #endif #ifdef THERE_IS_NO_FORK + int skip = 0; size_t skiplen; char *skipp; #endif @@ -407,24 +518,12 @@ int configure (const options_t *options, interface_t *iface, /* 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 */ - if (iface->previous_routes) { - for (route = iface->previous_routes; route; route = route->next) - if (route->destination.s_addr || options->dogateway) { - int have = 0; - if (up) - 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); - } - } + for (route = iface->previous_routes; route; route = route->next) + 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) { @@ -448,24 +547,25 @@ int configure (const options_t *options, interface_t *iface, /* Only reset things if we had set them before */ if (iface->previous_address.s_addr != 0) { if (! options->keep_address) { - 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); - /* we currently don't have a resolvconf style programs for ntp/nis */ - exec_script (options->script, iface->infofile, "down"); return (0); } /* Set the MTU requested. - If the DHCP server no longer sends one OR it's invalid then we restore - the original MTU */ + If the DHCP server no longer sends one OR it's invalid then + we restore the original MTU */ if (options->domtu) { unsigned short mtu = iface->mtu; if (dhcp->mtu) @@ -480,19 +580,21 @@ int configure (const options_t *options, interface_t *iface, /* 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 && errno != EEXIST) + dhcp->broadcast) == -1 && errno != EEXIST) return (false); - + /* Now delete the old address if different */ - if (iface->previous_address.s_addr != dhcp->address.s_addr) { - if (iface->previous_address.s_addr != 0 && ! options->keep_address) - del_address (iface->name, iface->previous_address, iface->previous_netmask); - } + 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); #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 && dhcp->netmask.s_addr != INADDR_BROADCAST) + if (iface->previous_address.s_addr != dhcp->address.s_addr && + options->metric > 0 && + dhcp->netmask.s_addr != INADDR_BROADCAST) { struct in_addr td; struct in_addr tg; @@ -514,66 +616,54 @@ int configure (const options_t *options, interface_t *iface, #endif /* Remember added routes */ - if (dhcp->routes) { -#ifdef THERE_IS_NO_FORK - int skip = 0; -#endif - - for (route = dhcp->routes; route; route = route->next) { + for (route = dhcp->routes; route; route = route->next) { #ifdef ENABLE_IPV4LL - /* Check if we have already got a link locale route dished - * out by the DHCP server */ - if (route->destination.s_addr == htonl (LINKLOCAL_ADDR) && - route->netmask.s_addr == htonl (LINKLOCAL_MASK)) - haslinklocal = true; + /* Check if we have already got a link locale route dished + * out by the DHCP server */ + if (route->destination.s_addr == htonl (LINKLOCAL_ADDR) && + route->netmask.s_addr == htonl (LINKLOCAL_MASK)) + haslinklocal = true; #endif - /* 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 && in_routes (iface->previous_routes, route)) + remember = 1; + + 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; + } #ifdef THERE_IS_NO_FORK - /* If we have daemonised yet we need to record which routes - * we failed to add so we can skip them */ - else if (! options->daemonised) { - /* We can never have more than 255 / 4 routes, so 3 chars is - * plently */ - if (*skipp) - *skipp++ = ','; - skipp += snprintf (skipp, dhcpcd_skiproutes + skiplen - skipp, - "%d", skip); - } - skip++; -#endif + /* If we have daemonised yet we need to record which routes + * we failed to add so we can skip them */ + else if (! options->daemonised) { + /* We can never have more than 255 / 4 routes, + * so 3 chars is plently */ + if (*skipp) + *skipp++ = ','; + skipp += snprintf (skipp, + dhcpcd_skiproutes + skiplen - skipp, + "%d", skip); } + skip++; +#endif } #ifdef THERE_IS_NO_FORK @@ -589,8 +679,8 @@ int configure (const options_t *options, interface_t *iface, /* Ensure we always add the link local route if we got a private * address and isn't link local itself */ if (options->doipv4ll && - ! haslinklocal && - IN_PRIVATE (ntohl (dhcp->address.s_addr))) + ! haslinklocal && + IN_PRIVATE (ntohl (dhcp->address.s_addr))) { struct in_addr dest; struct in_addr mask; @@ -600,7 +690,7 @@ int configure (const options_t *options, interface_t *iface, mask.s_addr = htonl (LINKLOCAL_MASK); gate.s_addr = 0; remember = add_route (iface->name, dest, mask, gate, - options->metric); + options->metric); if (remember >= 0) { if (! new_routes) { @@ -640,99 +730,35 @@ int configure (const options_t *options, interface_t *iface, curhostname = xmalloc (sizeof (char) * MAXHOSTNAMELEN); *curhostname = '\0'; - newhostname = xmalloc (sizeof (char) * MAXHOSTNAMELEN); - *newhostname = '\0'; - - /* Now we have made a resolv.conf we can obtain a hostname if we need it */ - if (options->dohostname && (! dhcp->hostname || options->dohostname > 3)) { - union { - struct sockaddr sa; - struct sockaddr_in sin; - } su; - socklen_t salen; - char *addr; - struct addrinfo hints, *res; - int result; - - addr = xmalloc (sizeof (char) * NI_MAXHOST); - salen = sizeof (struct sockaddr); - memset (&su.sa, 0, salen); - su.sin.sin_family = AF_INET; - memcpy (&su.sin.sin_addr, &dhcp->address, sizeof (struct in_addr)); - - logger (LOG_DEBUG, "Looking up hostname via DNS"); - if ((result = getnameinfo (&su.sa, salen, addr, NI_MAXHOST, - NULL, 0, NI_NAMEREQD)) != 0) - logger (LOG_ERR, "Failed to lookup hostname via DNS: %s", gai_strerror (result)); - else { - /* Check for a malicious PTR record */ - memset (&hints, 0, sizeof (hints)); - hints.ai_socktype = SOCK_DGRAM; - hints.ai_flags = AI_NUMERICHOST; - if (getaddrinfo (addr, "0", &hints, &res) == 0) { - freeaddrinfo (res); - addr[0] = '\0'; - logger (LOG_ERR, "malicious PTR record detected"); - } else if (*addr) { - char *p = strchr (addr, '.'); - if (p) { - switch (options->dohostname) { - case 1: /* -H */ - case 4: /* -HHHH */ - break; - case 2: /* -HH */ - case 5: /* -HHHHH */ - /* Strip out the domain if it matches */ - p++; - if (*p && dhcp->dnssearch) { - char *s = xstrdup (dhcp->dnssearch); - char *sp = s; - char *t; - - while ((t = strsep (&sp, " "))) - if (strcmp (t, p) == 0) { - *--p = '\0'; - break; - } - free (s); - } else if (dhcp->dnsdomain) { - if (strcmp (dhcp->dnsdomain, p) == 0) - *--p = '\0'; - } - break; - case 3: /* -HHH */ - case 6: /* -HHHHHH */ - /* Just strip the domain */ - *p = '\0'; - break; - default: /* Too many H! */ - break; - } - } - strlcpy (newhostname, addr, MAXHOSTNAMELEN); - } - } - free (addr); - } gethostname (curhostname, MAXHOSTNAMELEN); - - if (options->dohostname - || strlen (curhostname) == 0 - || strcmp (curhostname, "(none)") == 0 - || strcmp (curhostname, "localhost") == 0) + if (options->dohostname || + strlen (curhostname) == 0 || + strcmp (curhostname, "(none)") == 0 || + strcmp (curhostname, "localhost") == 0) { + newhostname = xmalloc (sizeof (char) * MAXHOSTNAMELEN); + if (dhcp->hostname) strlcpy (newhostname, dhcp->hostname, MAXHOSTNAMELEN); + else + *newhostname = '\0'; + + /* Now we have made a resolv.conf we can obtain a hostname + * if we need it */ + if (! *newhostname && options->dohostname > 3) + lookuphostname (newhostname, dhcp, options); if (*newhostname) { - logger (LOG_INFO, "setting hostname to `%s'", newhostname); + logger (LOG_INFO, "setting hostname to `%s'", + newhostname); sethostname (newhostname, strlen (newhostname)); } + + free (newhostname); } - + free (curhostname); - free (newhostname); #ifdef ENABLE_INFO if (! dhcp->frominfo) @@ -740,12 +766,12 @@ int configure (const options_t *options, interface_t *iface, #endif if (iface->previous_address.s_addr != dhcp->address.s_addr || - iface->previous_netmask.s_addr != dhcp->netmask.s_addr) + 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 exec_script (options->script, iface->infofile, "up"); |
