From: brian Date: Sun, 19 Mar 2000 10:33:32 +0000 (+0000) Subject: Allow environment variables on command/config lines; markk@knigma.org X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=7a0c5b4c48c94589865e04ed0995251bbfd6f2ca;p=openbsd Allow environment variables on command/config lines; markk@knigma.org Add the ``resolv'' command so that when ``enable dns'' is used, it's possible to restore the file. --- diff --git a/usr.sbin/ppp/ppp/README.changes b/usr.sbin/ppp/ppp/README.changes index 931de39ee6b..b8df2019beb 100644 --- a/usr.sbin/ppp/ppp/README.changes +++ b/usr.sbin/ppp/ppp/README.changes @@ -98,3 +98,4 @@ o Unbalanced quotes in commands are now warned about and the entire command is ignored. o It is now only necessary to escape the `-' character in chat scripts twice. See the example files for details. +o Environment variables and ~ are expanded on in commands diff --git a/usr.sbin/ppp/ppp/alias_db.c b/usr.sbin/ppp/ppp/alias_db.c index 837b4eec1e5..d299b0ec1e0 100644 --- a/usr.sbin/ppp/ppp/alias_db.c +++ b/usr.sbin/ppp/ppp/alias_db.c @@ -105,7 +105,7 @@ See HISTORY file for additional revisions. - $OpenBSD: alias_db.c,v 1.6 2000/02/27 01:38:24 brian Exp $ + $OpenBSD: alias_db.c,v 1.7 2000/03/19 10:33:32 brian Exp $ */ @@ -1101,7 +1101,7 @@ FindLinkOut(struct in_addr src_addr, } -struct alias_link * +static struct alias_link * _FindLinkIn(struct in_addr dst_addr, struct in_addr alias_addr, u_short dst_port, @@ -1652,11 +1652,13 @@ GetAliasPort(struct alias_link *link) return(link->alias_port); } -u_short +#ifndef NO_FW_PUNCH +static u_short GetDestPort(struct alias_link *link) { return(link->dst_port); } +#endif void SetAckModified(struct alias_link *link) diff --git a/usr.sbin/ppp/ppp/bundle.c b/usr.sbin/ppp/ppp/bundle.c index 9506055509c..8f645409628 100644 --- a/usr.sbin/ppp/ppp/bundle.c +++ b/usr.sbin/ppp/ppp/bundle.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: bundle.c,v 1.31 2000/03/03 21:52:56 brian Exp $ + * $OpenBSD: bundle.c,v 1.32 2000/03/19 10:33:32 brian Exp $ */ #include @@ -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 diff --git a/usr.sbin/ppp/ppp/bundle.h b/usr.sbin/ppp/ppp/bundle.h index c94932b1c46..c96d2cadb6c 100644 --- a/usr.sbin/ppp/ppp/bundle.h +++ b/usr.sbin/ppp/ppp/bundle.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: bundle.h,v 1.12 2000/02/27 01:38:24 brian Exp $ + * $OpenBSD: bundle.h,v 1.13 2000/03/19 10:33:32 brian Exp $ */ #define PHASE_DEAD 0 /* Link is dead */ @@ -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 *); diff --git a/usr.sbin/ppp/ppp/command.c b/usr.sbin/ppp/ppp/command.c index 8e042af350d..7a4dc049cc2 100644 --- a/usr.sbin/ppp/ppp/command.c +++ b/usr.sbin/ppp/ppp/command.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $OpenBSD: command.c,v 1.38 2000/02/27 01:38:25 brian Exp $ + * $OpenBSD: command.c,v 1.39 2000/03/19 10:33:32 brian Exp $ * */ #include @@ -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, @@ -905,6 +934,18 @@ FindExec(struct bundle *bundle, struct cmdtab const *cmds, int argc, int argn, return val; } +int +command_Expand_Interpret(char *buff, int nb, char *argv[MAXARGS], int offset) +{ + char buff2[LINE_LEN-offset]; + + InterpretArg(buff, buff2); + strncpy(buff, buff2, LINE_LEN - offset - 1); + buff[LINE_LEN - offset - 1] = '\0'; + + return command_Interpret(buff, nb, argv); +} + int command_Interpret(char *buff, int nb, char *argv[MAXARGS]) { @@ -984,7 +1025,7 @@ command_Decode(struct bundle *bundle, char *buff, int nb, struct prompt *prompt, int argc; char *argv[MAXARGS]; - if ((argc = command_Interpret(buff, nb, argv)) < 0) + if ((argc = command_Expand_Interpret(buff, nb, argv, 0)) < 0) return 0; command_Run(bundle, argc, (char const *const *)argv, prompt, label, NULL); @@ -1669,12 +1710,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 +1725,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 +2015,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 ? ' for" - " syntax help.\n"); + " syntax help.\n"); else log_Printf(LogWARN, "set command must have arguments\n"); @@ -1999,6 +2045,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 +2058,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 +2102,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) { diff --git a/usr.sbin/ppp/ppp/command.h b/usr.sbin/ppp/ppp/command.h index 58a58b2770e..3a5892e3da8 100644 --- a/usr.sbin/ppp/ppp/command.h +++ b/usr.sbin/ppp/ppp/command.h @@ -15,7 +15,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $OpenBSD: command.h,v 1.6 2000/02/27 01:38:25 brian Exp $ + * $OpenBSD: command.h,v 1.7 2000/03/19 10:33:32 brian Exp $ * * TODO: */ @@ -55,6 +55,7 @@ extern const char Version[]; extern void command_Expand(char **, int, char const *const *, struct bundle *, int, pid_t); +extern int command_Expand_Interpret(char *, int, char *vector[MAXARGS], int); extern int command_Interpret(char *, int, char *vector[MAXARGS]); extern void command_Run(struct bundle *, int, char const *const *, struct prompt *, const char *, struct datalink *); @@ -62,3 +63,4 @@ extern int command_Decode(struct bundle *, char *, int, struct prompt *, const char *); extern struct link *command_ChooseLink(struct cmdargs const *); extern const char *command_ShowNegval(unsigned); + diff --git a/usr.sbin/ppp/ppp/filter.c b/usr.sbin/ppp/ppp/filter.c index 78287d3305d..b37ca51c074 100644 --- a/usr.sbin/ppp/ppp/filter.c +++ b/usr.sbin/ppp/ppp/filter.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $OpenBSD: filter.c,v 1.12 2000/02/27 01:38:26 brian Exp $ + * $OpenBSD: filter.c,v 1.13 2000/03/19 10:33:33 brian Exp $ * * TODO: Should send ICMP error message when we discard packets. */ @@ -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]; + } } } diff --git a/usr.sbin/ppp/ppp/filter.h b/usr.sbin/ppp/ppp/filter.h index 06a7fee826a..88c6c638af3 100644 --- a/usr.sbin/ppp/ppp/filter.h +++ b/usr.sbin/ppp/ppp/filter.h @@ -15,7 +15,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $OpenBSD: filter.h,v 1.9 2000/02/27 01:38:26 brian Exp $ + * $OpenBSD: filter.h,v 1.10 2000/03/19 10:33:33 brian Exp $ * * TODO: */ @@ -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 @@ -63,8 +65,8 @@ struct filterent { unsigned f_proto : 8; /* Protocol: P_... */ unsigned f_srcop : 2; /* Source port operation: OP_... */ unsigned f_dstop : 2; /* Destination port operation: OP_... */ - unsigned f_srctype : 2; /* T_ value of src */ - unsigned f_dsttype : 2; /* T_ value of dst */ + unsigned f_srctype : 3; /* T_ value of src */ + unsigned f_dsttype : 3; /* T_ value of dst */ unsigned f_estab : 1; /* Check TCP ACK bit */ unsigned f_syn : 1; /* Check TCP SYN bit */ unsigned f_finrst : 1; /* Check TCP FIN/RST bits */ @@ -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]); diff --git a/usr.sbin/ppp/ppp/ipcp.c b/usr.sbin/ppp/ppp/ipcp.c index 78c86c42b8b..a25717230d9 100644 --- a/usr.sbin/ppp/ppp/ipcp.c +++ b/usr.sbin/ppp/ppp/ipcp.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $OpenBSD: ipcp.c,v 1.22 2000/03/03 21:52:57 brian Exp $ + * $OpenBSD: ipcp.c,v 1.23 2000/03/19 10:33:33 brian Exp $ * * TODO: * o Support IPADDRS properly @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -246,116 +247,177 @@ 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; + + ipcp->ns.dns[0].s_addr = ipcp->ns.dns[1].s_addr = INADDR_NONE; - 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; - - 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; - - 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; - } - } - fclose(fp); + 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; } - 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); - } + 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); + } + if (fclose(fp) == EOF) { + log_Printf(LogERROR, "write(): Failed updating %s: %s\n", _PATH_RESCONF, + strerror(errno)); + return 0; + } + } else + umask(mask); - 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); - } + return 1; +} - if (wlen) { +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_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; + 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, "setdns: open(): %s\n", strerror(errno)); - return 0; - } - } - - return 1; + } 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 @@ -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) { diff --git a/usr.sbin/ppp/ppp/ipcp.h b/usr.sbin/ppp/ppp/ipcp.h index af827ee6d12..17a3f04ab04 100644 --- a/usr.sbin/ppp/ppp/ipcp.h +++ b/usr.sbin/ppp/ppp/ipcp.h @@ -15,7 +15,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $OpenBSD: ipcp.h,v 1.8 2000/02/27 01:38:26 brian Exp $ + * $OpenBSD: ipcp.h,v 1.9 2000/03/19 10:33:33 brian Exp $ * * TODO: */ @@ -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) diff --git a/usr.sbin/ppp/ppp/ppp.8 b/usr.sbin/ppp/ppp/ppp.8 index 83cedd5e839..3e3f58d52fa 100644 --- a/usr.sbin/ppp/ppp/ppp.8 +++ b/usr.sbin/ppp/ppp/ppp.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ppp.8,v 1.79 2000/03/14 21:31:44 aaron Exp $ +.\" $OpenBSD: ppp.8,v 1.80 2000/03/19 10:33:33 brian Exp $ .Dd 20 September 1995 .nr XX \w'\fC00' .Dt PPP 8 @@ -34,9 +34,9 @@ flag (or flag for backwards compatability) does the equivalent of a .Dq nat enable yes , enabling -.Nm ppp Ns No s +.Nm Ns No 's network address translation features. This allows -.Nm ppp +.Nm to act as a NAT or masquerading engine for all machines on an internal LAN. Refer to .Xr libalias 3 @@ -113,7 +113,7 @@ In foreground mode, attempts to establish a connection with the peer immediately, but never becomes a daemon. The link is created in background mode. This is useful if you wish to control -.Nm ppp Ns No s +.Nm Ns No 's invocation from another process. .It Fl direct This is used for receiving incoming connections. @@ -443,7 +443,7 @@ after altering .Pa /etc/syslog.conf . .It Although not strictly relevant to -.Nm ppp Ns No s +.Nm Ns No 's operation, you should configure your resolver so that it works correctly. This can be done by configuring a local DNS .Pq using Xr named 8 @@ -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 @@ -508,7 +510,7 @@ description below too - you'll probably need to Usually, parity is set to .Dq none , and this is -.Nm ppp Ns No s +.Nm Ns No 's default. Parity is a rather archaic error checking mechanism that is no longer used because modern modems do their own error checking, and most link-layer protocols (that's what @@ -853,8 +855,9 @@ options. You must also specify the destination label in .Pa /etc/ppp/ppp.conf to use. It must contain the .Dq set ifaddr -command to define the remote peers IP address. (refer to -.Pa /etc/ppp/ppp.conf.sample ) +command to define the remote peers IP address. +(refer to +.Pa /usr/share/examples/ppp/ppp.conf.sample ) .Bd -literal -offset indent # ppp -auto pmdemand .Ed @@ -911,7 +914,8 @@ command: .Bl -tag -width attempts -compact .It Ar secs is the number of seconds to wait before attempting -to connect again. If the argument is the literal string +to connect again. +If the argument is the literal string .Sq Li random , the delay period is a random value between 1 and 30 seconds inclusive. .It Ar inc @@ -980,7 +984,8 @@ Modifying the dial delay is very useful when running .Nm in .Fl auto -mode on both ends of the link. If each end has the same timeout, +mode on both ends of the link. +If each end has the same timeout, both ends wind up calling each other at the same time if the link drops and both ends have packets queued. At some locations, the serial link may not be reliable, and carrier @@ -1131,7 +1136,7 @@ commands. Refer to their descriptions below. .Pp .Sh RECEIVING INCOMING PPP CONNECTIONS (Method 2) This method differs in that we use -.Nm ppp +.Nm to authenticate the connection rather than .Xr login 1 : .Bl -enum @@ -1257,7 +1262,7 @@ may also contain a list of numbers or a as if passed to the .Dq set cbcp command. The value will be used in -.Nm ppp Ns No s +.Nm Ns No 's subsequent CBCP phase. .Sh PPP OVER TCP and UDP (a.k.a Tunnelling) Instead of running @@ -1421,7 +1426,8 @@ and that other machines have designated the .Nm host as the gateway for the LAN. .Sh PACKET FILTERING -This implementation supports packet filtering. There are four kinds of +This implementation supports packet filtering. +There are four kinds of filters; the .Em in filter, the @@ -1635,13 +1641,15 @@ to successfully negotiate DEFLATE with version 2.3.*. .Sh CONTROLLING IP ADDRESS .Nm -uses IPCP to negotiate IP addresses. Each side of the connection +uses IPCP to negotiate IP addresses. +Each side of the connection specifies the IP address that it's willing to use, and if the requested IP address is acceptable then .Nm returns ACK to the requester. Otherwise, .Nm -returns NAK to suggest that the peer use a different IP address. When +returns NAK to suggest that the peer use a different IP address. +When both sides of the connection agree to accept the received request (and send ACK), IPCP is set to the open state and a network level connection is established. @@ -1972,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 . @@ -2263,7 +2278,7 @@ directory. This socket is used to pass link information (including the actual link file descriptor) between different .Nm invocations. This facilitates -.Nm ppp Ns No s +.Nm Ns No 's ability to be run from a .Xr getty 8 or directly from @@ -2580,7 +2595,7 @@ and wait for the controlling .Nm to finish with the link and deliver a signal back to the idle process. This prevents the confusion that results from -.Nm ppp Ns No 's +.Nm Ns No 's parent considering the link resource available again. .Pp For tty devices that have entries in @@ -2706,7 +2721,7 @@ The option can only be enabled if network address translation is enabled With this option enabled, .Nm will pass traffic for old interface addresses through the NAT engine -.Pq see Xr libalias 5 , +.Pq see Xr libalias 3 , resulting in the ability (in .Fl auto mode) to properly connect the process that caused the PPP link to @@ -2769,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 . @@ -3029,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 @@ -3350,6 +3372,69 @@ Renaming it to or .Sq USR may make the log file more readable. +.It resolv Ar command +This command controls +.Nm 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 @@ -3575,7 +3660,7 @@ options) if you wish callback to be optional. .Oc .Xc If no arguments are given, CBCP (Microsoft's CallBack Control Protocol) -is disabled - i.e., configuring CBCP in the +is disabled - ie, configuring CBCP in the .Dq set callback command will result in .Nm @@ -3635,7 +3720,7 @@ result in a warning when the device is opened. .Pp Some modems take more than one second after connecting to assert the carrier signal. If this delay isn't increased, this will result in -.Nm ppp Ns No s +.Nm Ns No 's inability to detect when the link is dropped, as .Nm assumes that the device isn't asserting carrier. diff --git a/usr.sbin/ppp/ppp/route.c b/usr.sbin/ppp/ppp/route.c index 4240402eaa0..7b7243cf11c 100644 --- a/usr.sbin/ppp/ppp/route.c +++ b/usr.sbin/ppp/ppp/route.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $OpenBSD: route.c,v 1.7 2000/02/27 01:38:28 brian Exp $ + * $OpenBSD: route.c,v 1.8 2000/03/19 10:33:34 brian Exp $ * */ @@ -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)); diff --git a/usr.sbin/ppp/ppp/route.h b/usr.sbin/ppp/ppp/route.h index fc5b20c75b2..b10bd995dd5 100644 --- a/usr.sbin/ppp/ppp/route.h +++ b/usr.sbin/ppp/ppp/route.h @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $OpenBSD: route.h,v 1.4 2000/02/27 01:38:28 brian Exp $ + * $OpenBSD: route.h,v 1.5 2000/03/19 10:33:34 brian Exp $ * */ @@ -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); diff --git a/usr.sbin/ppp/ppp/systems.c b/usr.sbin/ppp/ppp/systems.c index 9c5359b36af..99bd9986843 100644 --- a/usr.sbin/ppp/ppp/systems.c +++ b/usr.sbin/ppp/ppp/systems.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $OpenBSD: systems.c,v 1.11 2000/02/27 01:38:29 brian Exp $ + * $OpenBSD: systems.c,v 1.12 2000/03/19 10:33:34 brian Exp $ * * TODO: */ @@ -59,79 +59,106 @@ CloseSecret(FILE *fp) } /* Move string from ``from'' to ``to'', interpreting ``~'' and $.... */ -static const char * +const char * InterpretArg(const char *from, char *to) { - const char *env; char *ptr, *startto, *endto; - int len; + struct passwd *pwd; + int len, instring; + const char *env; + instring = 0; startto = to; endto = to + LINE_LEN - 1; while(issep(*from)) from++; - if (*from == '~') { - struct passwd *pwd; - - ptr = strchr(++from, '/'); - len = ptr ? ptr - from : strlen(from); - if (len == 0) { - pwd = getpwuid(ID0realuid()); - } else { - strncpy(to, from, len); - to[len] = '\0'; - pwd = getpwnam(to); - } - strncpy(to, pwd ? pwd->pw_dir : _PATH_PPP, endto - to); - endpwent(); - - *endto = '\0'; - to += strlen(to); - from += len; - } - - while (to < endto && !issep(*from) && *from != '#' && *from != '\0') { - if (*from == '$') { - if (from[1] == '$') { - *to = '\0'; /* For an empty var name below */ - from += 2; - } else if (from[1] == '{') { - ptr = strchr(from+2, '}'); - if (ptr) { - len = ptr - from - 2; - if (endto - to < len ) - len = endto - to; - if (len) { - strncpy(to, from+2, len); - to[len] = '\0'; - from = ptr+1; + while (*from != '\0') { + switch (*from) { + case '"': + instring = !instring; + *to++ = *from++; + break; + case '\\': + switch (*++from) { + case '$': + case '~': + break; /* Swallow the escapes */ + + default: + *to++ = '\\'; /* Pass the escapes on, maybe skipping \# */ + break; + } + *to++ = *from++; + break; + case '$': + if (from[1] == '$') { + *to = '\0'; /* For an empty var name below */ + from += 2; + } else if (from[1] == '{') { + ptr = strchr(from+2, '}'); + if (ptr) { + len = ptr - from - 2; + if (endto - to < len ) + len = endto - to; + if (len) { + strncpy(to, from+2, len); + to[len] = '\0'; + from = ptr+1; + } else { + *to++ = *from++; + continue; + } } else { *to++ = *from++; continue; } } else { - *to++ = *from++; - continue; + ptr = to; + for (from++; (isalnum(*from) || *from == '_') && ptr < endto; from++) + *ptr++ = *from; + *ptr = '\0'; } - } else { - ptr = to; - for (from++; (isalnum(*from) || *from == '_') && ptr < endto; from++) - *ptr++ = *from; - *ptr = '\0'; - } - if (*to == '\0') - *to++ = '$'; - else if ((env = getenv(to)) != NULL) { - strncpy(to, env, endto - to); - *endto = '\0'; - to += strlen(to); - } - } else { - if (*from == '\\') - from++; - *to++ = *from++; + if (*to == '\0') + *to++ = '$'; + else if ((env = getenv(to)) != NULL) { + strncpy(to, env, endto - to); + *endto = '\0'; + to += strlen(to); + } + break; + + case '~': + ptr = strchr(++from, '/'); + len = ptr ? ptr - from : strlen(from); + if (len == 0) + pwd = getpwuid(ID0realuid()); + else { + strncpy(to, from, len); + to[len] = '\0'; + pwd = getpwnam(to); + } + if (pwd == NULL) + *to++ = '~'; + else { + strncpy(to, pwd->pw_dir, endto - to); + *endto = '\0'; + to += strlen(to); + from += len; + } + endpwent(); + break; + + case '#': + if (!instring) + while (*from != '\0') + *to++ = *from++; + break; + + default: + *to++ = *from++; + break; } } @@ -144,9 +171,6 @@ InterpretArg(const char *from, char *to) } *to = '\0'; - while (issep(*from)) - from++; - return from; } @@ -363,7 +387,7 @@ ReadSystem(struct bundle *bundle, const char *name, const char *file, } len = strlen(cp); - if ((argc = command_Interpret(cp, len, argv)) < 0) + if ((argc = command_Expand_Interpret(cp, len, argv, cp - line)) < 0) log_Printf(LogWARN, "%s: %d: Syntax error\n", filename, linenum); else { allowcmd = argc > 0 && !strcasecmp(argv[0], "allow"); diff --git a/usr.sbin/ppp/ppp/systems.h b/usr.sbin/ppp/ppp/systems.h index 8f6925dcda2..c20db641cd5 100644 --- a/usr.sbin/ppp/ppp/systems.h +++ b/usr.sbin/ppp/ppp/systems.h @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $OpenBSD: systems.h,v 1.4 2000/02/27 01:38:29 brian Exp $ + * $OpenBSD: systems.h,v 1.5 2000/03/19 10:33:34 brian Exp $ * */ @@ -35,3 +35,4 @@ extern int AllowUsers(struct cmdargs const *); extern int AllowModes(struct cmdargs const *); extern int LoadCommand(struct cmdargs const *); extern int SaveCommand(struct cmdargs const *); +extern const char *InterpretArg(const char *, char *);