Add the ``resolv'' command for telling ppp how to deal with resolv.conf.
You can now ``resolv restore'' in ppp.linkdown ! Add DNS0 and DNS1 macros.
This commit is contained in:
parent
574a3ffd78
commit
d568d6c405
@ -1871,10 +1871,19 @@ void
|
||||
bundle_AdjustFilters(struct bundle *bundle, struct in_addr *my_ip,
|
||||
struct in_addr *peer_ip)
|
||||
{
|
||||
filter_AdjustAddr(&bundle->filter.in, my_ip, peer_ip);
|
||||
filter_AdjustAddr(&bundle->filter.out, my_ip, peer_ip);
|
||||
filter_AdjustAddr(&bundle->filter.dial, my_ip, peer_ip);
|
||||
filter_AdjustAddr(&bundle->filter.alive, my_ip, peer_ip);
|
||||
filter_AdjustAddr(&bundle->filter.in, my_ip, peer_ip, NULL);
|
||||
filter_AdjustAddr(&bundle->filter.out, my_ip, peer_ip, NULL);
|
||||
filter_AdjustAddr(&bundle->filter.dial, my_ip, peer_ip, NULL);
|
||||
filter_AdjustAddr(&bundle->filter.alive, my_ip, peer_ip, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
bundle_AdjustDNS(struct bundle *bundle, struct in_addr dns[2])
|
||||
{
|
||||
filter_AdjustAddr(&bundle->filter.in, NULL, NULL, dns);
|
||||
filter_AdjustAddr(&bundle->filter.out, NULL, NULL, dns);
|
||||
filter_AdjustAddr(&bundle->filter.dial, NULL, NULL, dns);
|
||||
filter_AdjustAddr(&bundle->filter.alive, NULL, NULL, dns);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -185,6 +185,7 @@ extern int bundle_HighestState(struct bundle *);
|
||||
extern int bundle_Exception(struct bundle *, int);
|
||||
extern void bundle_AdjustFilters(struct bundle *, struct in_addr *,
|
||||
struct in_addr *);
|
||||
extern void bundle_AdjustDNS(struct bundle *, struct in_addr [2]);
|
||||
extern void bundle_CalculateBandwidth(struct bundle *);
|
||||
extern void bundle_AutoAdjust(struct bundle *, int, int);
|
||||
extern int bundle_WantAutoloadTimer(struct bundle *);
|
||||
|
@ -436,6 +436,10 @@ command_Expand(char **nargv, int argc, char const *const *oargv,
|
||||
bundle->ncp.mp.cfg.enddisc.len));
|
||||
nargv[arg] = subst(nargv[arg], "PROCESSID", pidstr);
|
||||
nargv[arg] = subst(nargv[arg], "LABEL", bundle_GetLabel(bundle));
|
||||
nargv[arg] = subst(nargv[arg], "DNS0",
|
||||
inet_ntoa(bundle->ncp.ipcp.ns.dns[0]));
|
||||
nargv[arg] = subst(nargv[arg], "DNS1",
|
||||
inet_ntoa(bundle->ncp.ipcp.ns.dns[1]));
|
||||
}
|
||||
nargv[arg] = NULL;
|
||||
}
|
||||
@ -554,6 +558,29 @@ FgShellCommand(struct cmdargs const *arg)
|
||||
return ShellCommand(arg, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
ResolvCommand(struct cmdargs const *arg)
|
||||
{
|
||||
if (arg->argc == arg->argn + 1) {
|
||||
if (!strcasecmp(arg->argv[arg->argn], "reload"))
|
||||
ipcp_LoadDNS(&arg->bundle->ncp.ipcp);
|
||||
else if (!strcasecmp(arg->argv[arg->argn], "restore"))
|
||||
ipcp_RestoreDNS(&arg->bundle->ncp.ipcp);
|
||||
else if (!strcasecmp(arg->argv[arg->argn], "rewrite"))
|
||||
ipcp_WriteDNS(&arg->bundle->ncp.ipcp);
|
||||
else if (!strcasecmp(arg->argv[arg->argn], "readonly"))
|
||||
arg->bundle->ncp.ipcp.ns.writable = 0;
|
||||
else if (!strcasecmp(arg->argv[arg->argn], "writable"))
|
||||
arg->bundle->ncp.ipcp.ns.writable = 1;
|
||||
else
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifndef NONAT
|
||||
static struct cmdtab const AliasCommands[] =
|
||||
{
|
||||
@ -673,6 +700,8 @@ static struct cmdtab const Commands[] = {
|
||||
"Remove a link", "remove"},
|
||||
{"rename", "mv", RenameCommand, LOCAL_AUTH | LOCAL_CX,
|
||||
"Rename a link", "rename name"},
|
||||
{"resolv", NULL, ResolvCommand, LOCAL_AUTH,
|
||||
"Manipulate resolv.conf", "resolv readonly|reload|restore|rewrite|writable"},
|
||||
{"save", NULL, SaveCommand, LOCAL_AUTH,
|
||||
"Save settings", "save"},
|
||||
{"set", "setup", SetCommand, LOCAL_AUTH | LOCAL_CX_OPT,
|
||||
@ -1669,12 +1698,13 @@ SetVariable(struct cmdargs const *arg)
|
||||
|
||||
case VAR_NBNS:
|
||||
case VAR_DNS:
|
||||
if (param == VAR_DNS)
|
||||
if (param == VAR_DNS) {
|
||||
addr = arg->bundle->ncp.ipcp.cfg.ns.dns;
|
||||
else
|
||||
addr[0].s_addr = addr[1].s_addr = INADDR_NONE;
|
||||
} else {
|
||||
addr = arg->bundle->ncp.ipcp.cfg.ns.nbns;
|
||||
|
||||
addr[0].s_addr = addr[1].s_addr = INADDR_ANY;
|
||||
addr[0].s_addr = addr[1].s_addr = INADDR_ANY;
|
||||
}
|
||||
|
||||
if (arg->argc > arg->argn) {
|
||||
ParseAddr(&arg->bundle->ncp.ipcp, arg->argv[arg->argn],
|
||||
@ -1683,10 +1713,14 @@ SetVariable(struct cmdargs const *arg)
|
||||
ParseAddr(&arg->bundle->ncp.ipcp, arg->argv[arg->argn + 1],
|
||||
addr + 1, &dummyaddr, &dummyint);
|
||||
|
||||
if (addr[1].s_addr == INADDR_ANY)
|
||||
addr[1].s_addr = addr[0].s_addr;
|
||||
if (addr[0].s_addr == INADDR_ANY)
|
||||
if (addr[0].s_addr == INADDR_ANY) {
|
||||
addr[0].s_addr = addr[1].s_addr;
|
||||
addr[1].s_addr = INADDR_ANY;
|
||||
}
|
||||
if (addr[0].s_addr == INADDR_NONE) {
|
||||
addr[0].s_addr = addr[1].s_addr;
|
||||
addr[1].s_addr = INADDR_NONE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1969,7 +2003,7 @@ SetCommand(struct cmdargs const *arg)
|
||||
arg->prompt, arg->cx);
|
||||
else if (arg->prompt)
|
||||
prompt_Printf(arg->prompt, "Use `set ?' to get a list or `set ? <var>' for"
|
||||
" syntax help.\n");
|
||||
" syntax help.\n");
|
||||
else
|
||||
log_Printf(LogWARN, "set command must have arguments\n");
|
||||
|
||||
@ -1999,6 +2033,10 @@ AddCommand(struct cmdargs const *arg)
|
||||
addrs = ROUTE_DSTMYADDR;
|
||||
else if (!strncasecmp(arg->argv[arg->argn], "HISADDR", 7))
|
||||
addrs = ROUTE_DSTHISADDR;
|
||||
else if (!strncasecmp(arg->argv[arg->argn], "DNS0", 4))
|
||||
addrs = ROUTE_DSTDNS0;
|
||||
else if (!strncasecmp(arg->argv[arg->argn], "DNS1", 4))
|
||||
addrs = ROUTE_DSTDNS1;
|
||||
}
|
||||
gw = 1;
|
||||
} else {
|
||||
@ -2008,6 +2046,12 @@ AddCommand(struct cmdargs const *arg)
|
||||
} else if (strcasecmp(arg->argv[arg->argn], "HISADDR") == 0) {
|
||||
addrs = ROUTE_DSTHISADDR;
|
||||
dest = arg->bundle->ncp.ipcp.peer_ip;
|
||||
} else if (strcasecmp(arg->argv[arg->argn], "DNS0") == 0) {
|
||||
addrs = ROUTE_DSTDNS0;
|
||||
dest = arg->bundle->ncp.ipcp.ns.dns[0];
|
||||
} else if (strcasecmp(arg->argv[arg->argn], "DNS1") == 0) {
|
||||
addrs = ROUTE_DSTDNS1;
|
||||
dest = arg->bundle->ncp.ipcp.ns.dns[1];
|
||||
} else
|
||||
dest = GetIpAddr(arg->argv[arg->argn]);
|
||||
netmask = GetIpAddr(arg->argv[arg->argn+1]);
|
||||
@ -2046,6 +2090,12 @@ DeleteCommand(struct cmdargs const *arg)
|
||||
} else if (strcasecmp(arg->argv[arg->argn], "HISADDR") == 0) {
|
||||
dest = arg->bundle->ncp.ipcp.peer_ip;
|
||||
addrs = ROUTE_DSTHISADDR;
|
||||
} else if (strcasecmp(arg->argv[arg->argn], "DNS0") == 0) {
|
||||
dest = arg->bundle->ncp.ipcp.ns.dns[0];
|
||||
addrs = ROUTE_DSTDNS0;
|
||||
} else if (strcasecmp(arg->argv[arg->argn], "DNS1") == 0) {
|
||||
dest = arg->bundle->ncp.ipcp.ns.dns[1];
|
||||
addrs = ROUTE_DSTDNS1;
|
||||
} else {
|
||||
dest = GetIpAddr(arg->argv[arg->argn]);
|
||||
if (dest.s_addr == INADDR_NONE) {
|
||||
|
@ -102,6 +102,10 @@ ParseAddr(struct ipcp *ipcp, const char *data,
|
||||
*paddr = ipcp->peer_ip;
|
||||
else if (ipcp && strncasecmp(data, "MYADDR", len) == 0)
|
||||
*paddr = ipcp->my_ip;
|
||||
else if (ipcp && strncasecmp(data, "DNS0", len) == 0)
|
||||
*paddr = ipcp->ns.dns[0];
|
||||
else if (ipcp && strncasecmp(data, "DNS1", len) == 0)
|
||||
*paddr = ipcp->ns.dns[1];
|
||||
else if (len > 15)
|
||||
log_Printf(LogWARN, "ParseAddr: %s: Bad address\n", data);
|
||||
else {
|
||||
@ -320,6 +324,10 @@ addrtype(const char *addr)
|
||||
return T_MYADDR;
|
||||
if (!strncasecmp(addr, "HISADDR", 7) && (addr[7] == '\0' || addr[7] == '/'))
|
||||
return T_HISADDR;
|
||||
if (!strncasecmp(addr, "DNS0", 4) && (addr[4] == '\0' || addr[4] == '/'))
|
||||
return T_DNS0;
|
||||
if (!strncasecmp(addr, "DNS1", 4) && (addr[4] == '\0' || addr[4] == '/'))
|
||||
return T_DNS1;
|
||||
|
||||
return T_ADDR;
|
||||
}
|
||||
@ -332,6 +340,10 @@ addrstr(struct in_addr addr, unsigned type)
|
||||
return "MYADDR";
|
||||
case T_HISADDR:
|
||||
return "HISADDR";
|
||||
case T_DNS0:
|
||||
return "DNS0";
|
||||
case T_DNS1:
|
||||
return "DNS1";
|
||||
}
|
||||
return inet_ntoa(addr);
|
||||
}
|
||||
@ -670,7 +682,7 @@ filter_Nam2Op(const char *cp)
|
||||
|
||||
void
|
||||
filter_AdjustAddr(struct filter *filter, struct in_addr *my_ip,
|
||||
struct in_addr *peer_ip)
|
||||
struct in_addr *peer_ip, struct in_addr dns[2])
|
||||
{
|
||||
struct filterent *fp;
|
||||
int n;
|
||||
@ -689,5 +701,15 @@ filter_AdjustAddr(struct filter *filter, struct in_addr *my_ip,
|
||||
if (fp->f_dsttype == T_HISADDR)
|
||||
fp->f_dst.ipaddr = *peer_ip;
|
||||
}
|
||||
if (dns) {
|
||||
if (fp->f_srctype == T_DNS0)
|
||||
fp->f_src.ipaddr = dns[0];
|
||||
if (fp->f_dsttype == T_DNS0)
|
||||
fp->f_dst.ipaddr = dns[0];
|
||||
if (fp->f_srctype == T_DNS1)
|
||||
fp->f_src.ipaddr = dns[1];
|
||||
if (fp->f_dsttype == T_DNS1)
|
||||
fp->f_dst.ipaddr = dns[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +43,8 @@
|
||||
#define T_ADDR 0
|
||||
#define T_MYADDR 1
|
||||
#define T_HISADDR 2
|
||||
#define T_DNS0 3
|
||||
#define T_DNS1 4
|
||||
|
||||
/*
|
||||
* There's a struct filterent for each possible filter rule. The
|
||||
@ -107,4 +109,4 @@ extern const char *filter_Proto2Nam(int);
|
||||
extern const char *filter_Op2Nam(int);
|
||||
extern struct in_addr bits2mask(int);
|
||||
extern void filter_AdjustAddr(struct filter *, struct in_addr *,
|
||||
struct in_addr *);
|
||||
struct in_addr *, struct in_addr [2]);
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include <resolv.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@ -246,118 +247,179 @@ ipcp_AddOutOctets(struct ipcp *ipcp, int n)
|
||||
throughput_addout(&ipcp->throughput, n);
|
||||
}
|
||||
|
||||
static void
|
||||
getdns(struct ipcp *ipcp, struct in_addr addr[2])
|
||||
void
|
||||
ipcp_LoadDNS(struct ipcp *ipcp)
|
||||
{
|
||||
FILE *fp;
|
||||
int fd;
|
||||
|
||||
addr[0].s_addr = addr[1].s_addr = INADDR_ANY;
|
||||
if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
|
||||
char buf[LINE_LEN], *cp, *end;
|
||||
int n;
|
||||
ipcp->ns.dns[0].s_addr = ipcp->ns.dns[1].s_addr = INADDR_NONE;
|
||||
|
||||
n = 0;
|
||||
buf[sizeof buf - 1] = '\0';
|
||||
while (fgets(buf, sizeof buf - 1, fp)) {
|
||||
if (!strncmp(buf, "nameserver", 10) && issep(buf[10])) {
|
||||
for (cp = buf + 11; issep(*cp); cp++)
|
||||
;
|
||||
for (end = cp; isip(*end); end++)
|
||||
;
|
||||
*end = '\0';
|
||||
if (inet_aton(cp, addr+n) && ++n == 2)
|
||||
break;
|
||||
if (ipcp->ns.resolv != NULL) {
|
||||
free(ipcp->ns.resolv);
|
||||
ipcp->ns.resolv = NULL;
|
||||
}
|
||||
if (ipcp->ns.resolv_nons != NULL) {
|
||||
free(ipcp->ns.resolv_nons);
|
||||
ipcp->ns.resolv_nons = NULL;
|
||||
}
|
||||
ipcp->ns.resolver = 0;
|
||||
|
||||
if ((fd = open(_PATH_RESCONF, O_RDONLY)) != -1) {
|
||||
struct stat st;
|
||||
|
||||
if (fstat(fd, &st) == 0) {
|
||||
ssize_t got;
|
||||
|
||||
if ((ipcp->ns.resolv_nons = (char *)malloc(st.st_size + 1)) == NULL)
|
||||
log_Printf(LogERROR, "Failed to malloc %lu for %s: %s\n",
|
||||
(unsigned long)st.st_size, _PATH_RESCONF, strerror(errno));
|
||||
else if ((ipcp->ns.resolv = (char *)malloc(st.st_size + 1)) == NULL) {
|
||||
log_Printf(LogERROR, "Failed(2) to malloc %lu for %s: %s\n",
|
||||
(unsigned long)st.st_size, _PATH_RESCONF, strerror(errno));
|
||||
free(ipcp->ns.resolv_nons);
|
||||
ipcp->ns.resolv_nons = NULL;
|
||||
} else if ((got = read(fd, ipcp->ns.resolv, st.st_size)) != st.st_size) {
|
||||
if (got == -1)
|
||||
log_Printf(LogERROR, "Failed to read %s: %s\n",
|
||||
_PATH_RESCONF, strerror(errno));
|
||||
else
|
||||
log_Printf(LogERROR, "Failed to read %s, got %lu not %lu\n",
|
||||
_PATH_RESCONF, (unsigned long)got,
|
||||
(unsigned long)st.st_size);
|
||||
free(ipcp->ns.resolv_nons);
|
||||
ipcp->ns.resolv_nons = NULL;
|
||||
free(ipcp->ns.resolv);
|
||||
ipcp->ns.resolv = NULL;
|
||||
} else {
|
||||
char *cp, *cp_nons, *ncp, ch;
|
||||
int n;
|
||||
|
||||
ipcp->ns.resolv[st.st_size] = '\0';
|
||||
ipcp->ns.resolver = 1;
|
||||
|
||||
cp_nons = ipcp->ns.resolv_nons;
|
||||
cp = ipcp->ns.resolv;
|
||||
n = 0;
|
||||
|
||||
while ((ncp = strstr(cp, "nameserver")) != NULL) {
|
||||
if (ncp != cp) {
|
||||
memcpy(cp_nons, cp, ncp - cp);
|
||||
cp_nons += ncp - cp;
|
||||
}
|
||||
if ((ncp != cp && ncp[-1] != '\n') || !issep(ncp[10])) {
|
||||
memcpy(cp_nons, ncp, 9);
|
||||
cp_nons += 9;
|
||||
cp = ncp + 9; /* Can't match "nameserver" at cp... */
|
||||
continue;
|
||||
}
|
||||
|
||||
for (cp = ncp + 11; issep(*cp); cp++) /* Skip whitespace */
|
||||
;
|
||||
|
||||
for (ncp = cp; isip(*ncp); ncp++) /* Jump over IP */
|
||||
;
|
||||
|
||||
ch = *ncp;
|
||||
*ncp = '\0';
|
||||
if (n < 2 && inet_aton(cp, ipcp->ns.dns + n))
|
||||
n++;
|
||||
*ncp = ch;
|
||||
|
||||
if ((cp = strchr(ncp, '\n')) == NULL) /* Point at next line */
|
||||
cp = ncp + strlen(ncp);
|
||||
else
|
||||
cp++;
|
||||
}
|
||||
strcpy(cp_nons, cp); /* Copy the end - including the NUL */
|
||||
cp_nons += strlen(cp_nons) - 1;
|
||||
while (cp_nons >= ipcp->ns.resolv_nons && *cp_nons == '\n')
|
||||
*cp_nons-- = '\0';
|
||||
if (n == 2 && ipcp->ns.dns[0].s_addr == INADDR_ANY) {
|
||||
ipcp->ns.dns[0].s_addr = ipcp->ns.dns[1].s_addr;
|
||||
ipcp->ns.dns[1].s_addr = INADDR_ANY;
|
||||
}
|
||||
bundle_AdjustDNS(ipcp->fsm.bundle, ipcp->ns.dns);
|
||||
}
|
||||
}
|
||||
if (n == 1)
|
||||
addr[1] = addr[0];
|
||||
fclose(fp);
|
||||
} else
|
||||
log_Printf(LogERROR, "Failed to stat opened %s: %s\n",
|
||||
_PATH_RESCONF, strerror(errno));
|
||||
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
setdns(struct ipcp *ipcp, struct in_addr addr[2])
|
||||
int
|
||||
ipcp_WriteDNS(struct ipcp *ipcp)
|
||||
{
|
||||
const char *paddr;
|
||||
mode_t mask;
|
||||
FILE *fp;
|
||||
char wbuf[LINE_LEN + 54];
|
||||
int wlen;
|
||||
|
||||
if (addr[0].s_addr == INADDR_ANY || addr[1].s_addr == INADDR_ANY) {
|
||||
struct in_addr old[2];
|
||||
|
||||
getdns(ipcp, old);
|
||||
if (addr[0].s_addr == INADDR_ANY)
|
||||
addr[0] = old[0];
|
||||
if (addr[1].s_addr == INADDR_ANY)
|
||||
addr[1] = old[1];
|
||||
}
|
||||
|
||||
if (addr[0].s_addr == INADDR_ANY && addr[1].s_addr == INADDR_ANY) {
|
||||
log_Printf(LogWARN, "%s not modified: All nameservers NAKd\n",
|
||||
if (ipcp->ns.dns[0].s_addr == INADDR_ANY &&
|
||||
ipcp->ns.dns[1].s_addr == INADDR_ANY) {
|
||||
log_Printf(LogIPCP, "%s not modified: All nameservers NAKd\n",
|
||||
_PATH_RESCONF);
|
||||
return 0;
|
||||
}
|
||||
|
||||
wlen = 0;
|
||||
if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
|
||||
char buf[LINE_LEN];
|
||||
int len;
|
||||
if (ipcp->ns.dns[0].s_addr == INADDR_ANY) {
|
||||
ipcp->ns.dns[0].s_addr = ipcp->ns.dns[1].s_addr;
|
||||
ipcp->ns.dns[1].s_addr = INADDR_ANY;
|
||||
}
|
||||
|
||||
buf[sizeof buf - 1] = '\0';
|
||||
while (fgets(buf, sizeof buf - 1, fp)) {
|
||||
if (strncmp(buf, "nameserver", 10) || !issep(buf[10])) {
|
||||
len = strlen(buf);
|
||||
if (len > sizeof wbuf - wlen) {
|
||||
log_Printf(LogWARN, "%s: Can only cope with max file size %d\n",
|
||||
_PATH_RESCONF, LINE_LEN);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
memcpy(wbuf + wlen, buf, len);
|
||||
wlen += len;
|
||||
}
|
||||
mask = umask(0644);
|
||||
if ((fp = ID0fopen(_PATH_RESCONF, "w")) != NULL) {
|
||||
umask(mask);
|
||||
fputs(ipcp->ns.resolv_nons, fp);
|
||||
paddr = inet_ntoa(ipcp->ns.dns[0]);
|
||||
log_Printf(LogIPCP, "Primary nameserver set to %s\n", paddr);
|
||||
fprintf(fp, "\nnameserver %s\n", paddr);
|
||||
if (ipcp->ns.dns[1].s_addr != INADDR_ANY &&
|
||||
ipcp->ns.dns[1].s_addr != INADDR_NONE &&
|
||||
ipcp->ns.dns[1].s_addr != ipcp->ns.dns[0].s_addr) {
|
||||
paddr = inet_ntoa(ipcp->ns.dns[1]);
|
||||
log_Printf(LogIPCP, "Secondary nameserver set to %s\n", paddr);
|
||||
fprintf(fp, "nameserver %s\n", paddr);
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
if (addr[0].s_addr != INADDR_ANY) {
|
||||
snprintf(wbuf + wlen, sizeof wbuf - wlen, "nameserver %s\n",
|
||||
inet_ntoa(addr[0]));
|
||||
log_Printf(LogIPCP, "Primary nameserver set to %s", wbuf + wlen + 11);
|
||||
wlen += strlen(wbuf + wlen);
|
||||
}
|
||||
|
||||
if (addr[1].s_addr != INADDR_ANY && addr[1].s_addr != addr[0].s_addr) {
|
||||
snprintf(wbuf + wlen, sizeof wbuf - wlen, "nameserver %s\n",
|
||||
inet_ntoa(addr[1]));
|
||||
log_Printf(LogIPCP, "Secondary nameserver set to %s", wbuf + wlen + 11);
|
||||
wlen += strlen(wbuf + wlen);
|
||||
}
|
||||
|
||||
if (wlen) {
|
||||
int fd;
|
||||
|
||||
if ((fd = ID0open(_PATH_RESCONF, O_WRONLY|O_CREAT, 0644)) != -1) {
|
||||
if (write(fd, wbuf, wlen) != wlen) {
|
||||
log_Printf(LogERROR, "setdns: write(): %s\n", strerror(errno));
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
if (ftruncate(fd, wlen) == -1) {
|
||||
log_Printf(LogERROR, "setdns: truncate(): %s\n", strerror(errno));
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
close(fd);
|
||||
} else {
|
||||
log_Printf(LogERROR, "setdns: open(): %s\n", strerror(errno));
|
||||
if (fclose(fp) == EOF) {
|
||||
log_Printf(LogERROR, "write(): Failed updating %s: %s\n", _PATH_RESCONF,
|
||||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else
|
||||
umask(mask);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
ipcp_RestoreDNS(struct ipcp *ipcp)
|
||||
{
|
||||
if (ipcp->ns.resolver) {
|
||||
ssize_t got;
|
||||
size_t len;
|
||||
int fd;
|
||||
|
||||
if ((fd = ID0open(_PATH_RESCONF, O_WRONLY|O_TRUNC, 0644)) != -1) {
|
||||
len = strlen(ipcp->ns.resolv);
|
||||
if ((got = write(fd, ipcp->ns.resolv, len)) != len) {
|
||||
if (got == -1)
|
||||
log_Printf(LogERROR, "Failed rewriting %s: write: %s\n",
|
||||
_PATH_RESCONF, strerror(errno));
|
||||
else
|
||||
log_Printf(LogERROR, "Failed rewriting %s: wrote %lu of %lu\n",
|
||||
_PATH_RESCONF, (unsigned long)got, (unsigned long)len);
|
||||
}
|
||||
close(fd);
|
||||
} else
|
||||
log_Printf(LogERROR, "Failed rewriting %s: open: %s\n", _PATH_RESCONF,
|
||||
strerror(errno));
|
||||
} else if (remove(_PATH_RESCONF) == -1)
|
||||
log_Printf(LogERROR, "Failed removing %s: %s\n", _PATH_RESCONF,
|
||||
strerror(errno));
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
ipcp_Show(struct cmdargs const *arg)
|
||||
{
|
||||
@ -404,11 +466,20 @@ ipcp_Show(struct cmdargs const *arg)
|
||||
inet_ntoa(ipcp->cfg.peer_range.ipaddr),
|
||||
ipcp->cfg.peer_range.width);
|
||||
|
||||
prompt_Printf(arg->prompt, " DNS: %s, ",
|
||||
inet_ntoa(ipcp->cfg.ns.dns[0]));
|
||||
prompt_Printf(arg->prompt, "%s, %s\n", inet_ntoa(ipcp->cfg.ns.dns[1]),
|
||||
prompt_Printf(arg->prompt, " DNS: %s",
|
||||
ipcp->cfg.ns.dns[0].s_addr == INADDR_NONE ?
|
||||
"none" : inet_ntoa(ipcp->cfg.ns.dns[0]));
|
||||
if (ipcp->cfg.ns.dns[1].s_addr != INADDR_NONE)
|
||||
prompt_Printf(arg->prompt, ", %s", inet_ntoa(ipcp->cfg.ns.dns[1]));
|
||||
prompt_Printf(arg->prompt, ", %s\n",
|
||||
command_ShowNegval(ipcp->cfg.ns.dns_neg));
|
||||
prompt_Printf(arg->prompt, " NetBIOS NS: %s, ",
|
||||
prompt_Printf(arg->prompt, " Resolver DNS: %s",
|
||||
ipcp->ns.dns[0].s_addr == INADDR_NONE ?
|
||||
"none" : inet_ntoa(ipcp->ns.dns[0]));
|
||||
if (ipcp->ns.dns[1].s_addr != INADDR_NONE &&
|
||||
ipcp->ns.dns[1].s_addr != ipcp->ns.dns[0].s_addr)
|
||||
prompt_Printf(arg->prompt, ", %s", inet_ntoa(ipcp->ns.dns[1]));
|
||||
prompt_Printf(arg->prompt, "\n NetBIOS NS: %s, ",
|
||||
inet_ntoa(ipcp->cfg.ns.nbns[0]));
|
||||
prompt_Printf(arg->prompt, "%s\n", inet_ntoa(ipcp->cfg.ns.nbns[1]));
|
||||
|
||||
@ -489,8 +560,8 @@ ipcp_Init(struct ipcp *ipcp, struct bundle *bundle, struct link *l,
|
||||
iplist_setsrc(&ipcp->cfg.peer_list, "");
|
||||
ipcp->cfg.HaveTriggerAddress = 0;
|
||||
|
||||
ipcp->cfg.ns.dns[0].s_addr = INADDR_ANY;
|
||||
ipcp->cfg.ns.dns[1].s_addr = INADDR_ANY;
|
||||
ipcp->cfg.ns.dns[0].s_addr = INADDR_NONE;
|
||||
ipcp->cfg.ns.dns[1].s_addr = INADDR_NONE;
|
||||
ipcp->cfg.ns.dns_neg = 0;
|
||||
ipcp->cfg.ns.nbns[0].s_addr = INADDR_ANY;
|
||||
ipcp->cfg.ns.nbns[1].s_addr = INADDR_ANY;
|
||||
@ -512,6 +583,11 @@ ipcp_Init(struct ipcp *ipcp, struct bundle *bundle, struct link *l,
|
||||
|
||||
memset(&ipcp->vj, '\0', sizeof ipcp->vj);
|
||||
|
||||
ipcp->ns.resolv = NULL;
|
||||
ipcp->ns.resolv_nons = NULL;
|
||||
ipcp->ns.writable = 1;
|
||||
ipcp_LoadDNS(ipcp);
|
||||
|
||||
throughput_init(&ipcp->throughput, SAMPLE_PERIOD);
|
||||
memset(ipcp->Queue, '\0', sizeof ipcp->Queue);
|
||||
ipcp_Setup(ipcp, INADDR_NONE);
|
||||
@ -530,6 +606,14 @@ ipcp_Destroy(struct ipcp *ipcp)
|
||||
free(ipcp->cfg.urgent.udp.port);
|
||||
ipcp->cfg.urgent.udp.port = NULL;
|
||||
}
|
||||
if (ipcp->ns.resolv != NULL) {
|
||||
free(ipcp->ns.resolv);
|
||||
ipcp->ns.resolv = NULL;
|
||||
}
|
||||
if (ipcp->ns.resolv_nons != NULL) {
|
||||
free(ipcp->ns.resolv_nons);
|
||||
ipcp->ns.resolv_nons = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -611,6 +695,17 @@ ipcp_Setup(struct ipcp *ipcp, u_int32_t mask)
|
||||
|
||||
ipcp->peer_reject = 0;
|
||||
ipcp->my_reject = 0;
|
||||
|
||||
/* Copy startup values into ipcp->dns? */
|
||||
if (ipcp->cfg.ns.dns[0].s_addr != INADDR_NONE)
|
||||
memcpy(ipcp->dns, ipcp->cfg.ns.dns, sizeof ipcp->dns);
|
||||
else if (ipcp->ns.dns[0].s_addr != INADDR_NONE)
|
||||
memcpy(ipcp->dns, ipcp->ns.dns, sizeof ipcp->dns);
|
||||
else
|
||||
ipcp->dns[0].s_addr = ipcp->dns[1].s_addr = INADDR_ANY;
|
||||
|
||||
if (ipcp->dns[1].s_addr == INADDR_NONE)
|
||||
ipcp->dns[1] = ipcp->dns[0];
|
||||
}
|
||||
|
||||
static int
|
||||
@ -669,11 +764,13 @@ ipcp_SetIPaddress(struct bundle *bundle, struct in_addr myaddr,
|
||||
bundle_SetRoute(bundle, RTM_CHANGE, hisaddr, myaddr, none, 0, 0);
|
||||
|
||||
if (Enabled(bundle, OPT_SROUTES))
|
||||
route_Change(bundle, bundle->ncp.ipcp.route, myaddr, hisaddr);
|
||||
route_Change(bundle, bundle->ncp.ipcp.route, myaddr, hisaddr,
|
||||
bundle->ncp.ipcp.ns.dns);
|
||||
|
||||
#ifndef NORADIUS
|
||||
if (bundle->radius.valid)
|
||||
route_Change(bundle, bundle->radius.routes, myaddr, hisaddr);
|
||||
route_Change(bundle, bundle->radius.routes, myaddr, hisaddr,
|
||||
bundle->ncp.ipcp.ns.dns);
|
||||
#endif
|
||||
|
||||
if (Enabled(bundle, OPT_PROXY) || Enabled(bundle, OPT_PROXYALL)) {
|
||||
@ -773,11 +870,9 @@ IpcpSendConfigReq(struct fsm *fp)
|
||||
if (IsEnabled(ipcp->cfg.ns.dns_neg) &&
|
||||
!REJECTED(ipcp, TY_PRIMARY_DNS - TY_ADJUST_NS) &&
|
||||
!REJECTED(ipcp, TY_SECONDARY_DNS - TY_ADJUST_NS)) {
|
||||
struct in_addr dns[2];
|
||||
getdns(ipcp, dns);
|
||||
memcpy(o->data, &dns[0].s_addr, 4);
|
||||
memcpy(o->data, &ipcp->dns[0].s_addr, 4);
|
||||
INC_LCP_OPT(TY_PRIMARY_DNS, 6, o);
|
||||
memcpy(o->data, &dns[1].s_addr, 4);
|
||||
memcpy(o->data, &ipcp->dns[1].s_addr, 4);
|
||||
INC_LCP_OPT(TY_SECONDARY_DNS, 6, o);
|
||||
}
|
||||
|
||||
@ -947,15 +1042,13 @@ IpcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
|
||||
/* Deal with incoming PROTO_IPCP */
|
||||
struct iface *iface = fp->bundle->iface;
|
||||
struct ipcp *ipcp = fsm2ipcp(fp);
|
||||
int type, length, gotdns, gotdnsnak, n;
|
||||
int type, length, gotdnsnak, n;
|
||||
u_int32_t compproto;
|
||||
struct compreq *pcomp;
|
||||
struct in_addr ipaddr, dstipaddr, have_ip, dns[2], dnsnak[2];
|
||||
struct in_addr ipaddr, dstipaddr, have_ip;
|
||||
char tbuff[100], tbuff2[100];
|
||||
|
||||
gotdns = 0;
|
||||
gotdnsnak = 0;
|
||||
dnsnak[0].s_addr = dnsnak[1].s_addr = INADDR_ANY;
|
||||
|
||||
while (plen >= sizeof(struct fsmconfig)) {
|
||||
type = *cp;
|
||||
@ -1174,14 +1267,15 @@ IpcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
|
||||
dec->rejend += length;
|
||||
break;
|
||||
}
|
||||
if (!gotdns) {
|
||||
dns[0] = ipcp->cfg.ns.dns[0];
|
||||
dns[1] = ipcp->cfg.ns.dns[1];
|
||||
if (dns[0].s_addr == INADDR_ANY && dns[1].s_addr == INADDR_ANY)
|
||||
getdns(ipcp, dns);
|
||||
gotdns = 1;
|
||||
have_ip = ipcp->dns[type == TY_PRIMARY_DNS ? 0 : 1];
|
||||
|
||||
if (type == TY_PRIMARY_DNS && ipaddr.s_addr != have_ip.s_addr &&
|
||||
ipaddr.s_addr == ipcp->dns[1].s_addr) {
|
||||
/* Swap 'em 'round */
|
||||
ipcp->dns[0] = ipcp->dns[1];
|
||||
ipcp->dns[1] = have_ip;
|
||||
have_ip = ipcp->dns[0];
|
||||
}
|
||||
have_ip = dns[type == TY_PRIMARY_DNS ? 0 : 1];
|
||||
|
||||
if (ipaddr.s_addr != have_ip.s_addr) {
|
||||
/*
|
||||
@ -1201,10 +1295,10 @@ IpcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
|
||||
}
|
||||
break;
|
||||
|
||||
case MODE_NAK: /* what does this mean?? */
|
||||
case MODE_NAK:
|
||||
if (IsEnabled(ipcp->cfg.ns.dns_neg)) {
|
||||
gotdnsnak = 1;
|
||||
memcpy(&dnsnak[type == TY_PRIMARY_DNS ? 0 : 1].s_addr, cp + 2, 4);
|
||||
memcpy(&ipcp->dns[type == TY_PRIMARY_DNS ? 0 : 1].s_addr, cp + 2, 4);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1264,11 +1358,20 @@ IpcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
|
||||
cp += length;
|
||||
}
|
||||
|
||||
if (gotdnsnak)
|
||||
if (!setdns(ipcp, dnsnak)) {
|
||||
ipcp->peer_reject |= (1 << (TY_PRIMARY_DNS - TY_ADJUST_NS));
|
||||
ipcp->peer_reject |= (1 << (TY_SECONDARY_DNS - TY_ADJUST_NS));
|
||||
if (gotdnsnak) {
|
||||
memcpy(ipcp->ns.dns, ipcp->dns, sizeof ipcp->ns.dns);
|
||||
if (ipcp->ns.writable) {
|
||||
log_Printf(LogDEBUG, "Updating resolver\n");
|
||||
if (!ipcp_WriteDNS(ipcp)) {
|
||||
ipcp->peer_reject |= (1 << (TY_PRIMARY_DNS - TY_ADJUST_NS));
|
||||
ipcp->peer_reject |= (1 << (TY_SECONDARY_DNS - TY_ADJUST_NS));
|
||||
} else
|
||||
bundle_AdjustDNS(fp->bundle, ipcp->dns);
|
||||
} else {
|
||||
log_Printf(LogDEBUG, "Not updating resolver (readonly)\n");
|
||||
bundle_AdjustDNS(fp->bundle, ipcp->dns);
|
||||
}
|
||||
}
|
||||
|
||||
if (mode_type != MODE_NOP) {
|
||||
if (dec->rejend != dec->rej) {
|
||||
|
@ -87,6 +87,14 @@ struct ipcp {
|
||||
struct slstat slstat; /* VJ statistics */
|
||||
} vj;
|
||||
|
||||
struct {
|
||||
unsigned resolver : 1; /* Found resolv.conf ? */
|
||||
unsigned writable : 1; /* Can write resolv.conf ? */
|
||||
struct in_addr dns[2]; /* Current DNS addresses */
|
||||
char *resolv; /* Contents of resolv.conf */
|
||||
char *resolv_nons; /* Contents of resolv.conf without ns */
|
||||
} ns;
|
||||
|
||||
struct sticky_route *route; /* List of dynamic routes */
|
||||
|
||||
unsigned heis1172 : 1; /* True if he is speaking rfc1172 */
|
||||
@ -99,6 +107,8 @@ struct ipcp {
|
||||
struct in_addr my_ip; /* IP address I'm willing to use */
|
||||
u_int32_t my_compproto; /* VJ params I'm willing to use */
|
||||
|
||||
struct in_addr dns[2]; /* DNSs to REQ/ACK */
|
||||
|
||||
u_int32_t peer_reject; /* Request codes rejected by peer */
|
||||
u_int32_t my_reject; /* Request codes I have rejected */
|
||||
|
||||
@ -133,6 +143,9 @@ extern void ipcp_AddUrgentPort(struct port_range *, u_short);
|
||||
extern void ipcp_RemoveUrgentPort(struct port_range *, u_short);
|
||||
extern void ipcp_ClearUrgentPorts(struct port_range *);
|
||||
extern struct in_addr addr2mask(struct in_addr);
|
||||
extern int ipcp_WriteDNS(struct ipcp *);
|
||||
extern void ipcp_RestoreDNS(struct ipcp *);
|
||||
extern void ipcp_LoadDNS(struct ipcp *);
|
||||
|
||||
#define ipcp_IsUrgentTcpPort(ipcp, p1, p2) \
|
||||
ipcp_IsUrgentPort(&(ipcp)->cfg.urgent.tcp, p1, p2)
|
||||
|
@ -462,7 +462,9 @@ update
|
||||
.Pa /etc/resolv.conf
|
||||
automatically. Refer to the
|
||||
.Dq enable dns
|
||||
command below for details.
|
||||
and
|
||||
.Dq resolv
|
||||
commands below for details.
|
||||
.El
|
||||
.Sh MANUAL DIALING
|
||||
In the following examples, we assume that your machine name is
|
||||
@ -1978,9 +1980,16 @@ Ask your ISP to authenticate your nameserver address(es) with the line
|
||||
.Bd -literal -offset indent
|
||||
enable dns
|
||||
.Ed
|
||||
.Pp
|
||||
Do
|
||||
.Em NOT
|
||||
do this if you are running an local DNS, as
|
||||
do this if you are running a local DNS unless you also either use
|
||||
.Dq resolv readonly ,
|
||||
or have
|
||||
.Dq resolv restore
|
||||
in
|
||||
.Pa /etc/ppp/ppp.linkdown
|
||||
as
|
||||
.Nm
|
||||
will simply circumvent its use by entering some nameserver lines in
|
||||
.Pa /etc/resolv.conf .
|
||||
@ -2775,17 +2784,21 @@ command (see
|
||||
for further details).
|
||||
.Pp
|
||||
Routes that contain the
|
||||
.Dq HISADDR
|
||||
.Dq HISADDR ,
|
||||
.Dq MYADDR ,
|
||||
.Dq DNS0 ,
|
||||
or
|
||||
.Dq MYADDR
|
||||
.Dq DNS1
|
||||
constants are considered
|
||||
.Sq sticky .
|
||||
They are stored in a list (use
|
||||
.Dq show ipcp
|
||||
to see the list), and each time the value of
|
||||
.Dv HISADDR
|
||||
.Dv HISADDR ,
|
||||
.Dv MYADDR ,
|
||||
.Dv DNS0 ,
|
||||
or
|
||||
.Dv MYADDR
|
||||
.Dv DNS1
|
||||
changes, the appropriate routing table entries are updated. This facility
|
||||
may be disabled using
|
||||
.Dq disable sroutes .
|
||||
@ -3035,6 +3048,9 @@ This is replaced with the current process id.
|
||||
This is replaced with the username that has been authenticated with PAP or
|
||||
CHAP. Normally, this variable is assigned only in -direct mode. This value
|
||||
is available irrespective of whether utmp logging is enabled.
|
||||
.It Li DNS0 No " & " Li DNS1
|
||||
These are replaced with the primary and secondary nameserver IP numbers. If
|
||||
nameservers are negotiated by IPCP, the values of these macros will change.
|
||||
.El
|
||||
.Pp
|
||||
These substitutions are also done by the
|
||||
@ -3356,6 +3372,69 @@ Renaming it to
|
||||
or
|
||||
.Sq USR
|
||||
may make the log file more readable.
|
||||
.It resolv Ar command
|
||||
This command controls
|
||||
.Nm ppp Ns No s
|
||||
manipulation of the
|
||||
.Xr resolv.conf 5
|
||||
file. When
|
||||
.Nm
|
||||
starts up, it loads the contents of this file into memory and retains this
|
||||
image for future use.
|
||||
.Ar command
|
||||
is one of the following:
|
||||
.Bl -tag -width readonly
|
||||
.It Em readonly
|
||||
Treat
|
||||
.Pa /etc/resolv.conf
|
||||
as read only. If
|
||||
.Dq dns
|
||||
is enabled,
|
||||
.Nm
|
||||
will still attempt to negotiate nameservers with the peer, making the results
|
||||
available via the
|
||||
.Dv DNS0
|
||||
and
|
||||
.Dv DNS1
|
||||
macros. This is the opposite of the
|
||||
.Dq resolv writable
|
||||
command.
|
||||
.It Em reload
|
||||
Reload
|
||||
.Pa /etc/resolv.conf
|
||||
into memory. This may be necessary if for example a DHCP client overwrote
|
||||
.Pa /etc/resolv.conf .
|
||||
.It Em restore
|
||||
Replace
|
||||
.Pa /etc/resolv.conf
|
||||
with the version originally read at startup or with the last
|
||||
.Dq resolv reload
|
||||
command. This is sometimes a useful command to put in the
|
||||
.Pa /etc/ppp/ppp.linkdown
|
||||
file.
|
||||
.It Em rewrite
|
||||
Rewrite the
|
||||
.Pa /etc/resolv.conf
|
||||
file. This command will work even if the
|
||||
.Dq resolv readonly
|
||||
command has been used. It may be useful as a command in the
|
||||
.Pa /etc/ppp/ppp.linkup
|
||||
file if you wish to defer updating
|
||||
.Pa /etc/resolv.conf
|
||||
until after other commands have finished.
|
||||
.It Em writable
|
||||
Allow
|
||||
.Nm
|
||||
to update
|
||||
.Pa /etc/resolv.conf
|
||||
if
|
||||
.Dq dns
|
||||
is enabled and
|
||||
.Nm
|
||||
successfully negotiates a DNS. This is the opposite of the
|
||||
.Dq resolv readonly
|
||||
command.
|
||||
.El
|
||||
.It save
|
||||
This option is not (yet) implemented.
|
||||
.It set Ns Xo
|
||||
|
@ -462,7 +462,9 @@ update
|
||||
.Pa /etc/resolv.conf
|
||||
automatically. Refer to the
|
||||
.Dq enable dns
|
||||
command below for details.
|
||||
and
|
||||
.Dq resolv
|
||||
commands below for details.
|
||||
.El
|
||||
.Sh MANUAL DIALING
|
||||
In the following examples, we assume that your machine name is
|
||||
@ -1978,9 +1980,16 @@ Ask your ISP to authenticate your nameserver address(es) with the line
|
||||
.Bd -literal -offset indent
|
||||
enable dns
|
||||
.Ed
|
||||
.Pp
|
||||
Do
|
||||
.Em NOT
|
||||
do this if you are running an local DNS, as
|
||||
do this if you are running a local DNS unless you also either use
|
||||
.Dq resolv readonly ,
|
||||
or have
|
||||
.Dq resolv restore
|
||||
in
|
||||
.Pa /etc/ppp/ppp.linkdown
|
||||
as
|
||||
.Nm
|
||||
will simply circumvent its use by entering some nameserver lines in
|
||||
.Pa /etc/resolv.conf .
|
||||
@ -2775,17 +2784,21 @@ command (see
|
||||
for further details).
|
||||
.Pp
|
||||
Routes that contain the
|
||||
.Dq HISADDR
|
||||
.Dq HISADDR ,
|
||||
.Dq MYADDR ,
|
||||
.Dq DNS0 ,
|
||||
or
|
||||
.Dq MYADDR
|
||||
.Dq DNS1
|
||||
constants are considered
|
||||
.Sq sticky .
|
||||
They are stored in a list (use
|
||||
.Dq show ipcp
|
||||
to see the list), and each time the value of
|
||||
.Dv HISADDR
|
||||
.Dv HISADDR ,
|
||||
.Dv MYADDR ,
|
||||
.Dv DNS0 ,
|
||||
or
|
||||
.Dv MYADDR
|
||||
.Dv DNS1
|
||||
changes, the appropriate routing table entries are updated. This facility
|
||||
may be disabled using
|
||||
.Dq disable sroutes .
|
||||
@ -3035,6 +3048,9 @@ This is replaced with the current process id.
|
||||
This is replaced with the username that has been authenticated with PAP or
|
||||
CHAP. Normally, this variable is assigned only in -direct mode. This value
|
||||
is available irrespective of whether utmp logging is enabled.
|
||||
.It Li DNS0 No " & " Li DNS1
|
||||
These are replaced with the primary and secondary nameserver IP numbers. If
|
||||
nameservers are negotiated by IPCP, the values of these macros will change.
|
||||
.El
|
||||
.Pp
|
||||
These substitutions are also done by the
|
||||
@ -3356,6 +3372,69 @@ Renaming it to
|
||||
or
|
||||
.Sq USR
|
||||
may make the log file more readable.
|
||||
.It resolv Ar command
|
||||
This command controls
|
||||
.Nm ppp Ns No s
|
||||
manipulation of the
|
||||
.Xr resolv.conf 5
|
||||
file. When
|
||||
.Nm
|
||||
starts up, it loads the contents of this file into memory and retains this
|
||||
image for future use.
|
||||
.Ar command
|
||||
is one of the following:
|
||||
.Bl -tag -width readonly
|
||||
.It Em readonly
|
||||
Treat
|
||||
.Pa /etc/resolv.conf
|
||||
as read only. If
|
||||
.Dq dns
|
||||
is enabled,
|
||||
.Nm
|
||||
will still attempt to negotiate nameservers with the peer, making the results
|
||||
available via the
|
||||
.Dv DNS0
|
||||
and
|
||||
.Dv DNS1
|
||||
macros. This is the opposite of the
|
||||
.Dq resolv writable
|
||||
command.
|
||||
.It Em reload
|
||||
Reload
|
||||
.Pa /etc/resolv.conf
|
||||
into memory. This may be necessary if for example a DHCP client overwrote
|
||||
.Pa /etc/resolv.conf .
|
||||
.It Em restore
|
||||
Replace
|
||||
.Pa /etc/resolv.conf
|
||||
with the version originally read at startup or with the last
|
||||
.Dq resolv reload
|
||||
command. This is sometimes a useful command to put in the
|
||||
.Pa /etc/ppp/ppp.linkdown
|
||||
file.
|
||||
.It Em rewrite
|
||||
Rewrite the
|
||||
.Pa /etc/resolv.conf
|
||||
file. This command will work even if the
|
||||
.Dq resolv readonly
|
||||
command has been used. It may be useful as a command in the
|
||||
.Pa /etc/ppp/ppp.linkup
|
||||
file if you wish to defer updating
|
||||
.Pa /etc/resolv.conf
|
||||
until after other commands have finished.
|
||||
.It Em writable
|
||||
Allow
|
||||
.Nm
|
||||
to update
|
||||
.Pa /etc/resolv.conf
|
||||
if
|
||||
.Dq dns
|
||||
is enabled and
|
||||
.Nm
|
||||
successfully negotiates a DNS. This is the opposite of the
|
||||
.Dq resolv readonly
|
||||
command.
|
||||
.El
|
||||
.It save
|
||||
This option is not (yet) implemented.
|
||||
.It set Ns Xo
|
||||
|
@ -533,7 +533,7 @@ GetIfIndex(char *name)
|
||||
|
||||
void
|
||||
route_Change(struct bundle *bundle, struct sticky_route *r,
|
||||
struct in_addr me, struct in_addr peer)
|
||||
struct in_addr me, struct in_addr peer, struct in_addr dns[2])
|
||||
{
|
||||
struct in_addr none, del;
|
||||
|
||||
@ -551,6 +551,18 @@ route_Change(struct bundle *bundle, struct sticky_route *r,
|
||||
r->dst = peer;
|
||||
if (r->type & ROUTE_GWHISADDR)
|
||||
r->gw = peer;
|
||||
} else if ((r->type & ROUTE_DSTDNS0) && r->dst.s_addr != peer.s_addr) {
|
||||
del.s_addr = r->dst.s_addr & r->mask.s_addr;
|
||||
bundle_SetRoute(bundle, RTM_DELETE, del, none, none, 1, 0);
|
||||
r->dst = dns[0];
|
||||
if (r->type & ROUTE_GWHISADDR)
|
||||
r->gw = peer;
|
||||
} else if ((r->type & ROUTE_DSTDNS1) && r->dst.s_addr != peer.s_addr) {
|
||||
del.s_addr = r->dst.s_addr & r->mask.s_addr;
|
||||
bundle_SetRoute(bundle, RTM_DELETE, del, none, none, 1, 0);
|
||||
r->dst = dns[1];
|
||||
if (r->type & ROUTE_GWHISADDR)
|
||||
r->gw = peer;
|
||||
} else if ((r->type & ROUTE_GWHISADDR) && r->gw.s_addr != peer.s_addr)
|
||||
r->gw = peer;
|
||||
bundle_SetRoute(bundle, RTM_ADD, r->dst, r->gw, r->mask, 1, 0);
|
||||
@ -648,6 +660,10 @@ route_ShowSticky(struct prompt *p, struct sticky_route *r, const char *tag,
|
||||
prompt_Printf(p, "MYADDR");
|
||||
else if (r->type & ROUTE_DSTHISADDR)
|
||||
prompt_Printf(p, "HISADDR");
|
||||
else if (r->type & ROUTE_DSTDNS0)
|
||||
prompt_Printf(p, "DNS0");
|
||||
else if (r->type & ROUTE_DSTDNS1)
|
||||
prompt_Printf(p, "DNS1");
|
||||
else if (!def)
|
||||
prompt_Printf(p, "%s", inet_ntoa(r->dst));
|
||||
|
||||
|
@ -26,11 +26,13 @@ struct cmdargs;
|
||||
struct rt_msghdr;
|
||||
struct sockaddr;
|
||||
|
||||
#define ROUTE_STATIC 0
|
||||
#define ROUTE_DSTMYADDR 1
|
||||
#define ROUTE_DSTHISADDR 2
|
||||
#define ROUTE_DSTANY 3
|
||||
#define ROUTE_GWHISADDR 4 /* May be ORd with DST_MYADDR */
|
||||
#define ROUTE_STATIC 0x00
|
||||
#define ROUTE_DSTMYADDR 0x01
|
||||
#define ROUTE_DSTHISADDR 0x02
|
||||
#define ROUTE_DSTDNS0 0x04
|
||||
#define ROUTE_DSTDNS1 0x08
|
||||
#define ROUTE_DSTANY 0x0f
|
||||
#define ROUTE_GWHISADDR 0x10 /* May be ORd with DST_* */
|
||||
|
||||
struct sticky_route {
|
||||
int type; /* ROUTE_* value (not _STATIC) */
|
||||
@ -46,7 +48,7 @@ extern int route_Show(struct cmdargs const *);
|
||||
extern void route_IfDelete(struct bundle *, int);
|
||||
extern const char *Index2Nam(int);
|
||||
extern void route_Change(struct bundle *, struct sticky_route *,
|
||||
struct in_addr, struct in_addr);
|
||||
struct in_addr, struct in_addr, struct in_addr[2]);
|
||||
extern void route_Add(struct sticky_route **, int, struct in_addr,
|
||||
struct in_addr, struct in_addr);
|
||||
extern void route_Delete(struct sticky_route **, int, struct in_addr);
|
||||
|
Loading…
x
Reference in New Issue
Block a user