2007-11-15 19:35:53 +08:00
|
|
|
/*
|
2007-11-08 00:26:41 +08:00
|
|
|
* dhcpcd - DHCP client daemon
|
2008-01-08 17:51:23 +08:00
|
|
|
* Copyright 2006-2008 Roy Marples <roy@marples.name>
|
2007-11-15 19:35:53 +08:00
|
|
|
* All rights reserved
|
|
|
|
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
2006-11-28 04:23:22 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/ioctl.h>
|
2008-02-03 02:08:49 +08:00
|
|
|
#include <sys/param.h>
|
2006-11-28 04:23:22 +08:00
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
|
2006-12-15 07:17:27 +08:00
|
|
|
#include <netinet/in.h>
|
2006-11-28 04:23:22 +08:00
|
|
|
#ifdef __linux__
|
2007-09-04 20:48:40 +08:00
|
|
|
# include <netinet/ether.h>
|
2006-11-28 04:23:22 +08:00
|
|
|
#endif
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <netdb.h>
|
|
|
|
#include <resolv.h>
|
2008-02-03 05:56:12 +08:00
|
|
|
#include <signal.h>
|
2007-01-17 01:54:07 +08:00
|
|
|
#include <stdarg.h>
|
2006-11-28 04:23:22 +08:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
2007-05-10 17:39:26 +08:00
|
|
|
#include "config.h"
|
2006-11-28 04:23:22 +08:00
|
|
|
#include "common.h"
|
2006-12-15 07:17:27 +08:00
|
|
|
#include "configure.h"
|
2006-11-28 04:23:22 +08:00
|
|
|
#include "dhcp.h"
|
2007-05-10 17:39:26 +08:00
|
|
|
#ifdef ENABLE_INFO
|
2007-09-04 20:48:40 +08:00
|
|
|
# include "info.h"
|
2007-05-10 17:39:26 +08:00
|
|
|
#endif
|
2006-11-28 04:23:22 +08:00
|
|
|
#include "interface.h"
|
|
|
|
#include "dhcpcd.h"
|
|
|
|
#include "logger.h"
|
2008-02-03 03:17:08 +08:00
|
|
|
#include "signal.h"
|
2008-02-03 05:56:12 +08:00
|
|
|
#include "socket.h"
|
2008-02-03 01:28:22 +08:00
|
|
|
|
2007-11-08 18:36:49 +08:00
|
|
|
static int file_in_path (const char *file)
|
|
|
|
{
|
|
|
|
char *p = getenv ("PATH");
|
|
|
|
char *path;
|
|
|
|
char *token;
|
|
|
|
struct stat s;
|
|
|
|
char mypath[PATH_MAX];
|
|
|
|
int retval = -1;
|
|
|
|
|
|
|
|
if (! p) {
|
|
|
|
errno = ENOENT;
|
2008-01-17 00:38:47 +08:00
|
|
|
return (-1);
|
2007-11-08 18:36:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
path = strdup (p);
|
|
|
|
p = path;
|
|
|
|
while ((token = strsep (&p, ":"))) {
|
|
|
|
snprintf (mypath, PATH_MAX, "%s/%s", token, file);
|
2007-11-16 21:08:00 +08:00
|
|
|
if (stat (mypath, &s) == 0) {
|
2007-11-08 18:36:49 +08:00
|
|
|
retval = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free (path);
|
2008-01-17 00:38:47 +08:00
|
|
|
return (retval);
|
2007-11-08 18:36:49 +08:00
|
|
|
}
|
|
|
|
|
2007-01-17 01:54:07 +08:00
|
|
|
/* IMPORTANT: Ensure that the last parameter is NULL when calling */
|
|
|
|
static int exec_cmd (const char *cmd, const char *args, ...)
|
|
|
|
{
|
2007-04-11 21:18:33 +08:00
|
|
|
va_list va;
|
|
|
|
char **argv;
|
|
|
|
int n = 1;
|
2008-02-03 01:28:22 +08:00
|
|
|
int ret;
|
2008-02-03 02:08:49 +08:00
|
|
|
pid_t pid;
|
2008-02-03 03:17:08 +08:00
|
|
|
sigset_t full;
|
|
|
|
sigset_t old;
|
2007-04-11 21:18:33 +08:00
|
|
|
|
|
|
|
va_start (va, args);
|
|
|
|
while (va_arg (va, char *) != NULL)
|
|
|
|
n++;
|
|
|
|
va_end (va);
|
2007-09-04 20:48:40 +08:00
|
|
|
argv = xmalloc (sizeof (char *) * (n + 2));
|
2007-04-11 21:18:33 +08:00
|
|
|
|
|
|
|
va_start (va, args);
|
|
|
|
n = 2;
|
|
|
|
argv[0] = (char *) cmd;
|
|
|
|
argv[1] = (char *) args;
|
|
|
|
while ((argv[n] = va_arg (va, char *)) != NULL)
|
|
|
|
n++;
|
|
|
|
va_end (va);
|
|
|
|
|
2008-02-03 03:17:08 +08:00
|
|
|
/* OK, we need to block signals */
|
|
|
|
sigfillset (&full);
|
|
|
|
sigprocmask (SIG_SETMASK, &full, &old);
|
|
|
|
|
2008-02-03 05:56:12 +08:00
|
|
|
#ifdef THERE_IS_NO_FORK
|
|
|
|
signal_reset ();
|
|
|
|
pid = vfork ();
|
|
|
|
#else
|
|
|
|
pid = fork();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
switch (pid) {
|
2008-02-03 03:17:08 +08:00
|
|
|
case -1:
|
|
|
|
logger (LOG_ERR, "vfork: %s", strerror (errno));
|
|
|
|
ret = -1;
|
|
|
|
break;
|
|
|
|
case 0:
|
2008-02-03 05:56:12 +08:00
|
|
|
#ifndef THERE_IS_NO_FORK
|
2008-02-03 03:17:08 +08:00
|
|
|
signal_reset ();
|
2008-02-03 05:56:12 +08:00
|
|
|
#endif
|
2008-02-03 03:17:08 +08:00
|
|
|
sigprocmask (SIG_SETMASK, &old, NULL);
|
|
|
|
if (execvp (cmd, argv) && errno != ENOENT)
|
|
|
|
logger (LOG_ERR, "error executing \"%s\": %s",
|
|
|
|
cmd, strerror (errno));
|
2008-02-03 05:56:12 +08:00
|
|
|
_exit (111);
|
2008-02-03 03:17:08 +08:00
|
|
|
/* NOTREACHED */
|
2008-02-03 02:08:49 +08:00
|
|
|
}
|
2008-02-03 03:17:08 +08:00
|
|
|
|
2008-02-03 05:56:12 +08:00
|
|
|
#ifdef THERE_IS_NO_FORK
|
|
|
|
signal_setup ();
|
|
|
|
#endif
|
|
|
|
|
2008-02-03 03:17:08 +08:00
|
|
|
/* Restore our signals */
|
|
|
|
sigprocmask (SIG_SETMASK, &old, NULL);
|
2008-02-03 02:08:49 +08:00
|
|
|
|
2007-09-04 20:48:40 +08:00
|
|
|
free (argv);
|
2008-02-03 01:28:22 +08:00
|
|
|
return (ret);
|
2007-01-17 01:54:07 +08:00
|
|
|
}
|
|
|
|
|
2006-12-15 07:17:27 +08:00
|
|
|
static void exec_script (const char *script, const char *infofile,
|
2008-01-17 00:38:47 +08:00
|
|
|
const char *arg)
|
2006-11-28 04:23:22 +08:00
|
|
|
{
|
2007-04-11 21:18:33 +08:00
|
|
|
struct stat buf;
|
2006-12-15 22:47:01 +08:00
|
|
|
|
2007-04-11 21:18:33 +08:00
|
|
|
if (! script || ! infofile || ! arg)
|
|
|
|
return;
|
2006-11-28 04:23:22 +08:00
|
|
|
|
2007-07-18 19:35:50 +08:00
|
|
|
if (stat (script, &buf) == -1) {
|
2007-04-11 21:18:33 +08:00
|
|
|
if (strcmp (script, DEFAULT_SCRIPT) != 0)
|
|
|
|
logger (LOG_ERR, "`%s': %s", script, strerror (ENOENT));
|
|
|
|
return;
|
|
|
|
}
|
2006-12-15 22:47:01 +08:00
|
|
|
|
2007-10-22 23:03:01 +08:00
|
|
|
#ifdef ENABLE_INFO
|
2007-05-14 01:43:56 +08:00
|
|
|
logger (LOG_DEBUG, "exec \"%s\" \"%s\" \"%s\"", script, infofile, arg);
|
2007-04-11 21:18:33 +08:00
|
|
|
exec_cmd (script, infofile, arg, (char *) NULL);
|
2007-10-22 23:03:01 +08:00
|
|
|
#else
|
|
|
|
logger (LOG_DEBUG, "exec \"%s\" \"\" \"%s\"", script, arg);
|
|
|
|
exec_cmd (script, "", arg, (char *) NULL);
|
|
|
|
#endif
|
2006-11-28 04:23:22 +08:00
|
|
|
}
|
|
|
|
|
2006-12-15 07:17:27 +08:00
|
|
|
static int make_resolv (const char *ifname, const dhcp_t *dhcp)
|
2006-11-28 04:23:22 +08:00
|
|
|
{
|
2007-11-08 18:36:49 +08:00
|
|
|
FILE *f = NULL;
|
2007-04-11 21:18:33 +08:00
|
|
|
address_t *address;
|
2006-11-28 04:23:22 +08:00
|
|
|
|
2007-11-08 18:36:49 +08:00
|
|
|
#ifdef ENABLE_RESOLVCONF
|
|
|
|
char *resolvconf = NULL;
|
2007-04-11 21:18:33 +08:00
|
|
|
|
2008-01-08 04:52:49 +08:00
|
|
|
if (file_in_path ("resolvconf") == 0) {
|
|
|
|
size_t len = strlen ("resolvconf -a ") + strlen (ifname) + 1;
|
|
|
|
resolvconf = xmalloc (sizeof (char) * len);
|
|
|
|
snprintf (resolvconf, len, "resolvconf -a %s", ifname);
|
2007-11-08 18:36:49 +08:00
|
|
|
if ((f = popen (resolvconf , "w")))
|
2008-01-17 00:38:47 +08:00
|
|
|
logger (LOG_DEBUG,
|
|
|
|
"sending DNS information to resolvconf");
|
2007-11-08 18:36:49 +08:00
|
|
|
else if (errno == EEXIST)
|
2007-04-11 21:18:33 +08:00
|
|
|
logger (LOG_ERR, "popen: %s", strerror (errno));
|
2007-11-08 18:36:49 +08:00
|
|
|
|
|
|
|
if (ferror (f))
|
|
|
|
logger (LOG_ERR, "ferror");
|
|
|
|
free (resolvconf);
|
|
|
|
}
|
2007-04-03 15:03:04 +08:00
|
|
|
#endif
|
2007-11-08 18:36:49 +08:00
|
|
|
if (! f) {
|
2007-04-11 21:18:33 +08:00
|
|
|
logger (LOG_DEBUG, "writing "RESOLVFILE);
|
|
|
|
if (! (f = fopen(RESOLVFILE, "w")))
|
|
|
|
logger (LOG_ERR, "fopen `%s': %s", RESOLVFILE, strerror (errno));
|
|
|
|
}
|
|
|
|
|
2007-05-14 18:01:56 +08:00
|
|
|
if (! f)
|
|
|
|
return (-1);
|
2007-04-11 21:18:33 +08:00
|
|
|
|
2007-05-14 18:01:56 +08:00
|
|
|
fprintf (f, "# Generated by dhcpcd for interface %s\n", ifname);
|
|
|
|
if (dhcp->dnssearch)
|
|
|
|
fprintf (f, "search %s\n", dhcp->dnssearch);
|
|
|
|
else if (dhcp->dnsdomain) {
|
|
|
|
fprintf (f, "search %s\n", dhcp->dnsdomain);
|
|
|
|
}
|
2007-04-11 21:18:33 +08:00
|
|
|
|
2007-05-14 18:01:56 +08:00
|
|
|
for (address = dhcp->dnsservers; address; address = address->next)
|
|
|
|
fprintf (f, "nameserver %s\n", inet_ntoa (address->address));
|
|
|
|
|
2007-11-08 18:36:49 +08:00
|
|
|
#ifdef ENABLE_RESOLVCONF
|
2007-10-11 21:26:16 +08:00
|
|
|
if (resolvconf)
|
2007-05-14 18:01:56 +08:00
|
|
|
pclose (f);
|
|
|
|
else
|
2007-11-08 18:36:49 +08:00
|
|
|
#endif
|
2007-05-14 18:01:56 +08:00
|
|
|
fclose (f);
|
2007-04-11 21:18:33 +08:00
|
|
|
|
|
|
|
/* Refresh the local resolver */
|
|
|
|
res_init ();
|
2007-05-14 18:01:56 +08:00
|
|
|
return (0);
|
2006-11-28 04:23:22 +08:00
|
|
|
}
|
|
|
|
|
2007-10-11 21:26:16 +08:00
|
|
|
static void restore_resolv (const char *ifname)
|
2006-11-28 04:23:22 +08:00
|
|
|
{
|
2007-11-08 18:36:49 +08:00
|
|
|
#ifdef ENABLE_RESOLVCONF
|
|
|
|
if (file_in_path ("resolvconf") == 0) {
|
|
|
|
logger (LOG_DEBUG, "removing information from resolvconf");
|
|
|
|
exec_cmd("resolvconf", "-d", ifname, (char *) NULL);
|
|
|
|
}
|
2007-04-03 15:03:04 +08:00
|
|
|
#endif
|
2006-11-28 04:23:22 +08:00
|
|
|
}
|
|
|
|
|
2008-01-17 00:38:47 +08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2007-04-03 15:03:04 +08:00
|
|
|
#ifdef ENABLE_NTP
|
|
|
|
static int _make_ntp (const char *file, const char *ifname, const dhcp_t *dhcp)
|
2006-11-28 04:23:22 +08:00
|
|
|
{
|
2007-04-11 21:18:33 +08:00
|
|
|
FILE *f;
|
|
|
|
address_t *address;
|
|
|
|
char *a;
|
2008-01-08 02:14:51 +08:00
|
|
|
char *line;
|
2007-04-11 21:18:33 +08:00
|
|
|
int tomatch = 0;
|
|
|
|
char *token;
|
|
|
|
bool ntp = false;
|
|
|
|
|
|
|
|
for (address = dhcp->ntpservers; address; address = address->next)
|
|
|
|
tomatch++;
|
|
|
|
|
2008-01-29 19:20:55 +08:00
|
|
|
/* Check that we really need to update the servers.
|
|
|
|
* We do this because ntp has to be restarted to
|
|
|
|
* work with a changed config. */
|
2007-04-11 21:18:33 +08:00
|
|
|
if (! (f = fopen (file, "r"))) {
|
|
|
|
if (errno != ENOENT) {
|
2008-01-17 00:38:47 +08:00
|
|
|
logger (LOG_ERR, "fopen `%s': %s",
|
|
|
|
file, strerror (errno));
|
|
|
|
return (-1);
|
2007-04-11 21:18:33 +08:00
|
|
|
}
|
|
|
|
} else {
|
2008-02-06 18:18:03 +08:00
|
|
|
while (tomatch != 0 && (line = get_line (f))) {
|
2008-01-17 00:38:47 +08:00
|
|
|
struct in_addr addr;
|
2008-01-21 23:10:46 +08:00
|
|
|
|
2008-01-08 02:14:51 +08:00
|
|
|
a = line;
|
2007-04-11 21:18:33 +08:00
|
|
|
token = strsep (&a, " ");
|
2008-01-17 00:38:47 +08:00
|
|
|
if (! token || strcmp (token, "server") != 0)
|
|
|
|
goto next;
|
2007-04-11 21:18:33 +08:00
|
|
|
|
2008-01-17 00:38:47 +08:00
|
|
|
if ((token = strsep (&a, " \n")) == NULL)
|
|
|
|
goto next;
|
2007-04-11 21:18:33 +08:00
|
|
|
|
2008-01-21 23:10:46 +08:00
|
|
|
if (inet_aton (token, &addr) == 1 &&
|
2008-01-17 00:38:47 +08:00
|
|
|
in_addresses (dhcp->ntpservers, addr))
|
|
|
|
tomatch--;
|
2007-04-11 21:18:33 +08:00
|
|
|
|
2008-01-17 00:38:47 +08:00
|
|
|
next:
|
|
|
|
free (line);
|
2007-04-11 21:18:33 +08:00
|
|
|
}
|
|
|
|
fclose (f);
|
|
|
|
|
2008-01-17 00:38:47 +08:00
|
|
|
/* File has the same name servers that we do,
|
|
|
|
* so no need to restart ntp */
|
2007-04-11 21:18:33 +08:00
|
|
|
if (tomatch == 0) {
|
2008-01-17 00:38:47 +08:00
|
|
|
logger (LOG_DEBUG, "%s already configured, skipping",
|
|
|
|
file);
|
|
|
|
return (0);
|
2007-04-11 21:18:33 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
logger (LOG_DEBUG, "writing %s", file);
|
|
|
|
if (! (f = fopen (file, "w"))) {
|
|
|
|
logger (LOG_ERR, "fopen `%s': %s", file, strerror (errno));
|
2008-01-17 00:38:47 +08:00
|
|
|
return (-1);
|
2007-04-11 21:18:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
fprintf (f, "# Generated by dhcpcd for interface %s\n", ifname);
|
2007-04-03 15:03:04 +08:00
|
|
|
#ifdef NTPFILE
|
2007-04-11 21:18:33 +08:00
|
|
|
if (strcmp (file, NTPFILE) == 0) {
|
|
|
|
ntp = true;
|
|
|
|
fprintf (f, "restrict default noquery notrust nomodify\n");
|
|
|
|
fprintf (f, "restrict 127.0.0.1\n");
|
|
|
|
}
|
2007-04-03 15:03:04 +08:00
|
|
|
#endif
|
2006-11-28 04:23:22 +08:00
|
|
|
|
2007-04-11 21:18:33 +08:00
|
|
|
for (address = dhcp->ntpservers; address; address = address->next) {
|
|
|
|
a = inet_ntoa (address->address);
|
|
|
|
if (ntp)
|
|
|
|
fprintf (f, "restrict %s nomodify notrap noquery\n", a);
|
|
|
|
fprintf (f, "server %s\n", a);
|
|
|
|
}
|
|
|
|
fclose (f);
|
|
|
|
|
2008-01-17 00:38:47 +08:00
|
|
|
return (1);
|
2007-04-03 15:03:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static int make_ntp (const char *ifname, const dhcp_t *dhcp)
|
|
|
|
{
|
2008-01-29 19:20:55 +08:00
|
|
|
/* On some systems we have only have one ntp service, but we don't
|
|
|
|
* know which configuration file we're using. So we need to write
|
|
|
|
* to both and restart accordingly. */
|
2007-04-03 15:03:04 +08:00
|
|
|
|
2007-04-11 21:18:33 +08:00
|
|
|
bool restart_ntp = false;
|
|
|
|
bool restart_openntp = false;
|
|
|
|
int retval = 0;
|
2007-04-03 15:03:04 +08:00
|
|
|
|
|
|
|
#ifdef NTPFILE
|
2007-04-11 21:18:33 +08:00
|
|
|
if (_make_ntp (NTPFILE, ifname, dhcp) > 0)
|
|
|
|
restart_ntp = true;
|
2007-04-03 15:03:04 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef OPENNTPFILE
|
2007-04-11 21:18:33 +08:00
|
|
|
if (_make_ntp (OPENNTPFILE, ifname, dhcp) > 0)
|
|
|
|
restart_openntp = true;
|
2007-04-03 15:03:04 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef NTPSERVICE
|
2007-11-10 04:48:51 +08:00
|
|
|
if (restart_ntp) {
|
|
|
|
#ifdef NTPCHECK
|
|
|
|
if (system (NTPCHECK) == 0)
|
|
|
|
#endif
|
2008-01-17 00:38:47 +08:00
|
|
|
retval += exec_cmd (NTPSERVICE, NTPRESTARTARGS,
|
|
|
|
(char *) NULL);
|
2007-11-10 04:48:51 +08:00
|
|
|
}
|
2007-04-03 15:03:04 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined (NTPSERVICE) && defined (OPENNTPSERVICE)
|
2007-04-11 21:18:33 +08:00
|
|
|
if (restart_openntp &&
|
2008-01-17 00:38:47 +08:00
|
|
|
(strcmp (NTPSERVICE, OPENNTPSERVICE) != 0 || ! restart_ntp))
|
2007-11-10 04:48:51 +08:00
|
|
|
{
|
|
|
|
#ifdef OPENNTPCHECK
|
|
|
|
if (system (OPENNTPCHECK) == 0)
|
|
|
|
#endif
|
2008-01-17 00:38:47 +08:00
|
|
|
retval += exec_cmd (OPENNTPSERVICE,
|
|
|
|
OPENNTPRESTARTARGS, (char *) NULL);
|
2007-11-10 04:48:51 +08:00
|
|
|
}
|
2007-04-03 15:03:04 +08:00
|
|
|
#elif defined (OPENNTPSERVICE) && ! defined (NTPSERVICE)
|
2007-11-10 04:48:51 +08:00
|
|
|
if (restart_openntp) {
|
|
|
|
#ifdef OPENNTPCHECK
|
|
|
|
if (system (OPENNTPCHECK) == 0)
|
|
|
|
#endif
|
2008-01-17 00:38:47 +08:00
|
|
|
retval += exec_cmd (OPENNTPSERVICE,
|
|
|
|
OPENNTPRESTARTARGS, (char *) NULL);
|
|
|
|
}
|
2007-04-03 15:03:04 +08:00
|
|
|
#endif
|
|
|
|
|
2008-01-17 00:38:47 +08:00
|
|
|
return (retval);
|
2006-11-28 04:23:22 +08:00
|
|
|
}
|
2007-04-03 15:03:04 +08:00
|
|
|
#endif
|
2006-11-28 04:23:22 +08:00
|
|
|
|
2007-04-03 15:03:04 +08:00
|
|
|
#ifdef ENABLE_NIS
|
2007-10-11 21:26:16 +08:00
|
|
|
#define PREFIXSIZE 256
|
2006-12-15 07:17:27 +08:00
|
|
|
static int make_nis (const char *ifname, const dhcp_t *dhcp)
|
2006-11-28 04:23:22 +08:00
|
|
|
{
|
2007-04-11 21:18:33 +08:00
|
|
|
FILE *f;
|
|
|
|
address_t *address;
|
2007-10-11 21:26:16 +08:00
|
|
|
char *prefix;
|
2007-04-11 21:18:33 +08:00
|
|
|
|
|
|
|
logger (LOG_DEBUG, "writing "NISFILE);
|
|
|
|
if (! (f = fopen(NISFILE, "w"))) {
|
|
|
|
logger (LOG_ERR, "fopen `%s': %s", NISFILE, strerror (errno));
|
2008-01-17 00:38:47 +08:00
|
|
|
return (-1);
|
2007-04-11 21:18:33 +08:00
|
|
|
}
|
|
|
|
|
2007-10-12 04:30:24 +08:00
|
|
|
prefix = xmalloc (sizeof (char) * PREFIXSIZE);
|
2007-10-11 21:26:16 +08:00
|
|
|
*prefix = '\0';
|
2007-04-11 21:18:33 +08:00
|
|
|
fprintf (f, "# Generated by dhcpcd for interface %s\n", ifname);
|
2007-10-11 21:26:16 +08:00
|
|
|
|
2007-04-11 21:18:33 +08:00
|
|
|
if (dhcp->nisdomain) {
|
2008-01-22 05:19:53 +08:00
|
|
|
setdomainname (dhcp->nisdomain, (int) strlen (dhcp->nisdomain));
|
2007-04-11 21:18:33 +08:00
|
|
|
|
|
|
|
if (dhcp->nisservers)
|
2008-01-17 00:38:47 +08:00
|
|
|
snprintf (prefix, PREFIXSIZE, "domain %s server",
|
|
|
|
dhcp->nisdomain);
|
2007-04-11 21:18:33 +08:00
|
|
|
else
|
|
|
|
fprintf (f, "domain %s broadcast\n", dhcp->nisdomain);
|
|
|
|
}
|
|
|
|
else
|
2007-10-11 21:26:16 +08:00
|
|
|
snprintf (prefix, PREFIXSIZE, "%s", "ypserver");
|
2007-04-11 21:18:33 +08:00
|
|
|
|
|
|
|
for (address = dhcp->nisservers; address; address = address->next)
|
|
|
|
fprintf (f, "%s %s\n", prefix, inet_ntoa (address->address));
|
|
|
|
|
2007-10-11 21:26:16 +08:00
|
|
|
free (prefix);
|
2007-04-11 21:18:33 +08:00
|
|
|
fclose (f);
|
|
|
|
|
2007-11-10 04:48:51 +08:00
|
|
|
#ifdef NISCHECK
|
|
|
|
if (system (NISCHECK) == 0)
|
|
|
|
#endif
|
|
|
|
exec_cmd (NISSERVICE, NISRESTARTARGS, (char *) NULL);
|
2008-01-17 00:38:47 +08:00
|
|
|
return (0);
|
2006-11-28 04:23:22 +08:00
|
|
|
}
|
2007-04-03 15:03:04 +08:00
|
|
|
#endif
|
|
|
|
|
2008-01-17 00:38:47 +08:00
|
|
|
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);
|
2008-01-29 01:47:54 +08:00
|
|
|
salen = sizeof (su.sa);
|
2008-01-17 00:38:47 +08:00
|
|
|
memset (&su.sa, 0, salen);
|
|
|
|
su.sin.sin_family = AF_INET;
|
2008-01-29 00:32:04 +08:00
|
|
|
memcpy (&su.sin.sin_addr, &dhcp->address, sizeof (su.sin.sin_addr));
|
2008-01-17 00:38:47 +08:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2006-12-15 07:17:27 +08:00
|
|
|
int configure (const options_t *options, interface_t *iface,
|
2008-01-17 00:38:47 +08:00
|
|
|
const dhcp_t *dhcp, bool up)
|
2006-11-28 04:23:22 +08:00
|
|
|
{
|
2007-04-11 21:18:33 +08:00
|
|
|
route_t *route = NULL;
|
2007-10-12 19:19:29 +08:00
|
|
|
route_t *new_routes = NULL;
|
2007-04-11 21:18:33 +08:00
|
|
|
route_t *new_route = NULL;
|
2007-10-11 21:26:16 +08:00
|
|
|
char *newhostname = NULL;
|
|
|
|
char *curhostname = NULL;
|
2007-10-12 19:19:29 +08:00
|
|
|
int remember;
|
|
|
|
#ifdef ENABLE_IPV4LL
|
|
|
|
bool haslinklocal = false;
|
|
|
|
#endif
|
2008-01-08 04:52:49 +08:00
|
|
|
#ifdef THERE_IS_NO_FORK
|
2008-01-17 00:38:47 +08:00
|
|
|
int skip = 0;
|
2008-01-08 04:52:49 +08:00
|
|
|
size_t skiplen;
|
|
|
|
char *skipp;
|
|
|
|
#endif
|
2007-04-11 21:18:33 +08:00
|
|
|
|
|
|
|
if (! options || ! iface || ! dhcp)
|
2007-05-14 18:01:56 +08:00
|
|
|
return (-1);
|
|
|
|
|
|
|
|
if (dhcp->address.s_addr == 0)
|
|
|
|
up = 0;
|
2007-04-11 21:18:33 +08:00
|
|
|
|
2008-01-29 19:20:55 +08:00
|
|
|
/* 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. */
|
2008-01-17 00:38:47 +08:00
|
|
|
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);
|
2007-04-11 21:18:33 +08:00
|
|
|
|
2007-05-14 18:01:56 +08:00
|
|
|
/* If we aren't up, then reset the interface as much as we can */
|
|
|
|
if (! up) {
|
2007-04-11 21:18:33 +08:00
|
|
|
if (iface->previous_routes) {
|
|
|
|
free_route (iface->previous_routes);
|
|
|
|
iface->previous_routes = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Restore the original MTU value */
|
|
|
|
if (iface->mtu && iface->previous_mtu != iface->mtu) {
|
|
|
|
set_mtu (iface->name, iface->mtu);
|
|
|
|
iface->previous_mtu = iface->mtu;
|
|
|
|
}
|
|
|
|
|
2007-05-14 01:43:56 +08:00
|
|
|
#ifdef ENABLE_INFO
|
|
|
|
/* If we haven't created an info file, do so now */
|
2007-05-14 18:01:56 +08:00
|
|
|
if (! dhcp->frominfo)
|
|
|
|
write_info (iface, dhcp, options, false);
|
2007-05-14 01:43:56 +08:00
|
|
|
#endif
|
|
|
|
|
2007-04-11 21:18:33 +08:00
|
|
|
/* Only reset things if we had set them before */
|
|
|
|
if (iface->previous_address.s_addr != 0) {
|
2007-05-12 03:55:00 +08:00
|
|
|
if (! options->keep_address) {
|
2008-01-17 00:38:47 +08:00
|
|
|
del_address (iface->name,
|
|
|
|
iface->previous_address,
|
|
|
|
iface->previous_netmask);
|
|
|
|
memset (&iface->previous_address,
|
2008-01-29 00:32:04 +08:00
|
|
|
0, sizeof (iface->previous_address));
|
2008-01-17 00:38:47 +08:00
|
|
|
memset (&iface->previous_netmask,
|
2008-01-29 00:32:04 +08:00
|
|
|
0, sizeof (iface->previous_netmask));
|
2007-05-12 03:55:00 +08:00
|
|
|
}
|
2007-05-14 01:43:56 +08:00
|
|
|
}
|
2007-04-11 21:18:33 +08:00
|
|
|
|
2007-05-14 01:43:56 +08:00
|
|
|
restore_resolv (iface->name);
|
|
|
|
exec_script (options->script, iface->infofile, "down");
|
2007-04-11 21:18:33 +08:00
|
|
|
|
2007-05-14 18:01:56 +08:00
|
|
|
return (0);
|
2007-04-11 21:18:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Set the MTU requested.
|
2008-01-29 19:20:55 +08:00
|
|
|
* If the DHCP server no longer sends one OR it's invalid then
|
|
|
|
* we restore the original MTU */
|
2007-04-11 21:18:33 +08:00
|
|
|
if (options->domtu) {
|
|
|
|
unsigned short mtu = iface->mtu;
|
|
|
|
if (dhcp->mtu)
|
|
|
|
mtu = dhcp->mtu;
|
|
|
|
|
|
|
|
if (mtu != iface->previous_mtu) {
|
|
|
|
if (set_mtu (iface->name, mtu) == 0)
|
|
|
|
iface->previous_mtu = mtu;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-05-15 21:34:17 +08:00
|
|
|
/* This also changes netmask */
|
2007-05-12 03:55:00 +08:00
|
|
|
if (! options->doinform || ! has_address (iface->name, dhcp->address))
|
|
|
|
if (add_address (iface->name, dhcp->address, dhcp->netmask,
|
2008-01-17 00:38:47 +08:00
|
|
|
dhcp->broadcast) == -1 && errno != EEXIST)
|
2007-05-14 18:01:56 +08:00
|
|
|
return (false);
|
2008-01-17 00:38:47 +08:00
|
|
|
|
2007-04-11 21:18:33 +08:00
|
|
|
/* Now delete the old address if different */
|
2008-01-17 00:38:47 +08:00
|
|
|
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);
|
2006-11-28 04:23:22 +08:00
|
|
|
|
|
|
|
#ifdef __linux__
|
2007-04-11 21:18:33 +08:00
|
|
|
/* On linux, we need to change the subnet route to have our metric. */
|
2008-01-17 00:38:47 +08:00
|
|
|
if (iface->previous_address.s_addr != dhcp->address.s_addr &&
|
|
|
|
options->metric > 0 &&
|
|
|
|
dhcp->netmask.s_addr != INADDR_BROADCAST)
|
2007-04-11 21:18:33 +08:00
|
|
|
{
|
|
|
|
struct in_addr td;
|
|
|
|
struct in_addr tg;
|
|
|
|
memset (&td, 0, sizeof (td));
|
|
|
|
memset (&tg, 0, sizeof (tg));
|
|
|
|
td.s_addr = dhcp->address.s_addr & dhcp->netmask.s_addr;
|
|
|
|
add_route (iface->name, td, dhcp->netmask, tg, options->metric);
|
|
|
|
del_route (iface->name, td, dhcp->netmask, tg, 0);
|
|
|
|
}
|
2006-11-28 04:23:22 +08:00
|
|
|
#endif
|
|
|
|
|
2007-10-04 17:57:50 +08:00
|
|
|
#ifdef THERE_IS_NO_FORK
|
|
|
|
free (dhcpcd_skiproutes);
|
2008-01-08 04:52:49 +08:00
|
|
|
/* We can never have more than 255 routes. So we need space
|
|
|
|
* for 255 3 digit numbers and commas */
|
|
|
|
skiplen = 255 * 4 + 1;
|
|
|
|
skipp = dhcpcd_skiproutes = xmalloc (sizeof (char) * skiplen);
|
|
|
|
*skipp = '\0';
|
2007-10-04 17:57:50 +08:00
|
|
|
#endif
|
|
|
|
|
2007-04-11 21:18:33 +08:00
|
|
|
/* Remember added routes */
|
2008-01-17 00:38:47 +08:00
|
|
|
for (route = dhcp->routes; route; route = route->next) {
|
2007-10-12 19:19:29 +08:00
|
|
|
#ifdef ENABLE_IPV4LL
|
2008-01-17 00:38:47 +08:00
|
|
|
/* 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;
|
2007-10-12 19:19:29 +08:00
|
|
|
#endif
|
2008-01-17 00:38:47 +08:00
|
|
|
/* 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) {
|
2008-01-29 00:32:04 +08:00
|
|
|
new_routes = xmalloc (sizeof (*new_routes));
|
2008-01-17 00:38:47 +08:00
|
|
|
new_route = new_routes;
|
|
|
|
} else {
|
2008-01-29 00:32:04 +08:00
|
|
|
new_route->next = xmalloc (sizeof (*new_route));
|
2008-01-17 00:38:47 +08:00
|
|
|
new_route = new_route->next;
|
2007-04-11 21:18:33 +08:00
|
|
|
}
|
2008-01-29 00:32:04 +08:00
|
|
|
memcpy (new_route, route, sizeof (*new_route));
|
2008-01-17 00:38:47 +08:00
|
|
|
new_route -> next = NULL;
|
|
|
|
}
|
2007-10-04 17:57:50 +08:00
|
|
|
#ifdef THERE_IS_NO_FORK
|
2008-01-17 00:38:47 +08:00
|
|
|
/* 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);
|
2007-04-11 21:18:33 +08:00
|
|
|
}
|
2008-01-17 00:38:47 +08:00
|
|
|
skip++;
|
|
|
|
#endif
|
2008-01-08 04:52:49 +08:00
|
|
|
}
|
2007-04-11 21:18:33 +08:00
|
|
|
|
2008-01-08 04:52:49 +08:00
|
|
|
#ifdef THERE_IS_NO_FORK
|
|
|
|
if (*dhcpcd_skiproutes)
|
|
|
|
*skipp = '\0';
|
|
|
|
else {
|
|
|
|
free (dhcpcd_skiproutes);
|
|
|
|
dhcpcd_skiproutes = NULL;
|
2007-10-12 19:19:29 +08:00
|
|
|
}
|
2008-01-08 04:52:49 +08:00
|
|
|
#endif
|
2007-04-11 21:18:33 +08:00
|
|
|
|
2007-10-12 19:19:29 +08:00
|
|
|
#ifdef ENABLE_IPV4LL
|
|
|
|
/* Ensure we always add the link local route if we got a private
|
|
|
|
* address and isn't link local itself */
|
2007-11-13 22:36:09 +08:00
|
|
|
if (options->doipv4ll &&
|
2008-01-17 00:38:47 +08:00
|
|
|
! haslinklocal &&
|
|
|
|
IN_PRIVATE (ntohl (dhcp->address.s_addr)))
|
2007-10-12 19:19:29 +08:00
|
|
|
{
|
|
|
|
struct in_addr dest;
|
|
|
|
struct in_addr mask;
|
|
|
|
struct in_addr gate;
|
|
|
|
|
|
|
|
dest.s_addr = htonl (LINKLOCAL_ADDR);
|
|
|
|
mask.s_addr = htonl (LINKLOCAL_MASK);
|
|
|
|
gate.s_addr = 0;
|
|
|
|
remember = add_route (iface->name, dest, mask, gate,
|
2008-01-17 00:38:47 +08:00
|
|
|
options->metric);
|
2007-10-12 19:19:29 +08:00
|
|
|
|
|
|
|
if (remember >= 0) {
|
|
|
|
if (! new_routes) {
|
2008-01-29 00:32:04 +08:00
|
|
|
new_routes = xmalloc (sizeof (*new_routes));
|
2007-10-12 19:19:29 +08:00
|
|
|
new_route = new_routes;
|
|
|
|
} else {
|
2008-01-29 00:32:04 +08:00
|
|
|
new_route->next = xmalloc (sizeof (*new_route));
|
2007-10-12 19:19:29 +08:00
|
|
|
new_route = new_route->next;
|
|
|
|
}
|
|
|
|
new_route->destination.s_addr = dest.s_addr;
|
|
|
|
new_route->netmask.s_addr = mask.s_addr;
|
|
|
|
new_route->gateway.s_addr = gate.s_addr;
|
2008-01-28 23:32:04 +08:00
|
|
|
new_route->next = NULL;
|
2007-10-12 19:19:29 +08:00
|
|
|
}
|
2007-04-11 21:18:33 +08:00
|
|
|
}
|
2007-10-12 19:19:29 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
if (iface->previous_routes)
|
|
|
|
free_route (iface->previous_routes);
|
|
|
|
iface->previous_routes = new_routes;
|
2007-04-11 21:18:33 +08:00
|
|
|
|
|
|
|
if (options->dodns && dhcp->dnsservers)
|
|
|
|
make_resolv(iface->name, dhcp);
|
|
|
|
else
|
|
|
|
logger (LOG_DEBUG, "no dns information to write");
|
2006-11-28 04:23:22 +08:00
|
|
|
|
2007-04-03 15:03:04 +08:00
|
|
|
#ifdef ENABLE_NTP
|
2007-04-11 21:18:33 +08:00
|
|
|
if (options->dontp && dhcp->ntpservers)
|
|
|
|
make_ntp(iface->name, dhcp);
|
2007-04-03 15:03:04 +08:00
|
|
|
#endif
|
2006-11-28 04:23:22 +08:00
|
|
|
|
2007-04-03 15:03:04 +08:00
|
|
|
#ifdef ENABLE_NIS
|
2007-04-11 21:18:33 +08:00
|
|
|
if (options->donis && (dhcp->nisservers || dhcp->nisdomain))
|
|
|
|
make_nis(iface->name, dhcp);
|
2007-04-03 15:03:04 +08:00
|
|
|
#endif
|
2006-11-28 04:23:22 +08:00
|
|
|
|
2007-10-12 04:30:24 +08:00
|
|
|
curhostname = xmalloc (sizeof (char) * MAXHOSTNAMELEN);
|
2007-10-11 21:26:16 +08:00
|
|
|
*curhostname = '\0';
|
2007-04-11 21:18:33 +08:00
|
|
|
|
2007-10-11 21:26:16 +08:00
|
|
|
gethostname (curhostname, MAXHOSTNAMELEN);
|
2008-01-17 00:38:47 +08:00
|
|
|
if (options->dohostname ||
|
|
|
|
strlen (curhostname) == 0 ||
|
|
|
|
strcmp (curhostname, "(none)") == 0 ||
|
|
|
|
strcmp (curhostname, "localhost") == 0)
|
2007-04-11 21:18:33 +08:00
|
|
|
{
|
2008-01-17 00:38:47 +08:00
|
|
|
newhostname = xmalloc (sizeof (char) * MAXHOSTNAMELEN);
|
|
|
|
|
2007-04-11 21:18:33 +08:00
|
|
|
if (dhcp->hostname)
|
2007-10-11 21:26:16 +08:00
|
|
|
strlcpy (newhostname, dhcp->hostname, MAXHOSTNAMELEN);
|
2008-01-17 00:38:47 +08:00
|
|
|
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);
|
2007-04-11 21:18:33 +08:00
|
|
|
|
|
|
|
if (*newhostname) {
|
2008-01-17 00:38:47 +08:00
|
|
|
logger (LOG_INFO, "setting hostname to `%s'",
|
|
|
|
newhostname);
|
2008-01-22 05:19:53 +08:00
|
|
|
sethostname (newhostname, (int) strlen (newhostname));
|
2007-04-11 21:18:33 +08:00
|
|
|
}
|
2008-01-17 00:38:47 +08:00
|
|
|
|
|
|
|
free (newhostname);
|
2007-04-11 21:18:33 +08:00
|
|
|
}
|
2008-01-17 00:38:47 +08:00
|
|
|
|
2007-10-11 21:26:16 +08:00
|
|
|
free (curhostname);
|
2006-11-28 04:23:22 +08:00
|
|
|
|
2007-04-03 15:03:04 +08:00
|
|
|
#ifdef ENABLE_INFO
|
2007-05-10 17:39:26 +08:00
|
|
|
if (! dhcp->frominfo)
|
2007-05-14 18:01:56 +08:00
|
|
|
write_info (iface, dhcp, options, true);
|
2007-04-03 15:03:04 +08:00
|
|
|
#endif
|
2006-11-28 04:23:22 +08:00
|
|
|
|
2007-04-11 21:18:33 +08:00
|
|
|
if (iface->previous_address.s_addr != dhcp->address.s_addr ||
|
2008-01-17 00:38:47 +08:00
|
|
|
iface->previous_netmask.s_addr != dhcp->netmask.s_addr)
|
2007-04-11 21:18:33 +08:00
|
|
|
{
|
|
|
|
memcpy (&iface->previous_address,
|
2008-01-29 00:32:04 +08:00
|
|
|
&dhcp->address, sizeof (iface->previous_address));
|
2007-04-11 21:18:33 +08:00
|
|
|
memcpy (&iface->previous_netmask,
|
2008-01-29 00:32:04 +08:00
|
|
|
&dhcp->netmask, sizeof (iface->previous_netmask));
|
2007-04-11 21:18:33 +08:00
|
|
|
exec_script (options->script, iface->infofile, "new");
|
|
|
|
} else
|
|
|
|
exec_script (options->script, iface->infofile, "up");
|
|
|
|
|
2007-05-14 18:01:56 +08:00
|
|
|
return (0);
|
2006-11-28 04:23:22 +08:00
|
|
|
}
|