diff options
| author | Brian Somers <brian@FreeBSD.org> | 2000-03-21 10:23:20 +0000 |
|---|---|---|
| committer | Brian Somers <brian@FreeBSD.org> | 2000-03-21 10:23:20 +0000 |
| commit | a8f574395cd8235daba4282e257d05aa7c171d80 (patch) | |
| tree | 7d21303815fed699a13209e3f532410d9834072a | |
| parent | 9fc98f33802cb0d361238409c621a6966c85c294 (diff) | |
Notes
50 files changed, 1194 insertions, 579 deletions
diff --git a/usr.sbin/ppp/Makefile b/usr.sbin/ppp/Makefile index 7aed76e1d5a9..fda3c44bf3c0 100644 --- a/usr.sbin/ppp/Makefile +++ b/usr.sbin/ppp/Makefile @@ -23,6 +23,10 @@ CFLAGS+=-DRELEASE_CRUNCH CFLAGS+=-DNOKLDLOAD .endif +.if defined(NOINET6) +CFLAGS+=-DNOINET6 +.endif + .if defined(NOALIAS) || defined(NONAT) CFLAGS+=-DNONAT .else diff --git a/usr.sbin/ppp/README.changes b/usr.sbin/ppp/README.changes index a0a0694068e2..ac4de49937f4 100644 --- a/usr.sbin/ppp/README.changes +++ b/usr.sbin/ppp/README.changes @@ -100,3 +100,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/arp.c b/usr.sbin/ppp/arp.c index 9f370273b6a9..028f523f4cdd 100644 --- a/usr.sbin/ppp/arp.c +++ b/usr.sbin/ppp/arp.c @@ -68,6 +68,7 @@ #include "radius.h" #endif #include "bundle.h" +#include "iface.h" #include "arp.h" /* @@ -225,14 +226,13 @@ arp_ClearProxy(struct bundle *bundle, struct in_addr addr, int s) int get_ether_addr(int s, struct in_addr ipaddr, struct sockaddr_dl *hwaddr) { - int mib[6], sa_len, skip, b; + int mib[6], skip; size_t needed; char *buf, *ptr, *end; struct if_msghdr *ifm; struct ifa_msghdr *ifam; - struct sockaddr *sa; struct sockaddr_dl *dl; - struct sockaddr_in *ifa, *mask; + struct sockaddr *sa[RTAX_MAX]; mib[0] = CTL_NET; mib[1] = PF_ROUTE; @@ -269,7 +269,6 @@ get_ether_addr(int s, struct in_addr ipaddr, struct sockaddr_dl *hwaddr) ifam = (struct ifa_msghdr *)ptr; /* Next ifa_msghdr (alias) */ if (ifam->ifam_type != RTM_NEWADDR) /* finished ? */ break; - sa = (struct sockaddr *)(ifam+1); /* pile of sa's at end */ ptr += ifam->ifam_msglen; if (skip || (ifam->ifam_addrs & (RTA_NETMASK|RTA_IFA)) != (RTA_NETMASK|RTA_IFA)) @@ -279,43 +278,32 @@ get_ether_addr(int s, struct in_addr ipaddr, struct sockaddr_dl *hwaddr) ptr == (char *)ifm + ifm->ifm_msglen + ifam->ifam_msglen) log_Printf(LogDEBUG, "%.*s interface is a candidate for proxy\n", dl->sdl_nlen, dl->sdl_data); - b = 1; - ifa = mask = NULL; - while (b < (RTA_NETMASK|RTA_IFA) && sa < (struct sockaddr *)ptr) { - switch (b) { - case RTA_IFA: - ifa = (struct sockaddr_in *)sa; - break; - case RTA_NETMASK: - /* - * Careful here ! this sockaddr doesn't have sa_family set to - * AF_INET, and is only 8 bytes big ! I have no idea why ! - */ - mask = (struct sockaddr_in *)sa; - break; + + iface_ParseHdr(ifam, sa); + + if (sa[RTAX_IFA]->sa_family == AF_INET) { + struct sockaddr_in *ifa, *netmask; + + ifa = (struct sockaddr_in *)sa[RTAX_IFA]; + netmask = (struct sockaddr_in *)sa[RTAX_NETMASK]; + + if (log_IsKept(LogDEBUG)) { + char a[16]; + + strncpy(a, inet_ntoa(netmask->sin_addr), sizeof a - 1); + a[sizeof a - 1] = '\0'; + log_Printf(LogDEBUG, "Check addr %s, mask %s\n", + inet_ntoa(ifa->sin_addr), a); } - if (ifam->ifam_addrs & b) { -#define ALN sizeof(ifa->sin_addr.s_addr) - sa_len = sa->sa_len > 0 ? ((sa->sa_len-1)|(ALN-1))+1 : ALN; - sa = (struct sockaddr *)((char *)sa + sa_len); + + if ((ifa->sin_addr.s_addr & netmask->sin_addr.s_addr) == + (ipaddr.s_addr & netmask->sin_addr.s_addr)) { + log_Printf(LogPHASE, "Found interface %.*s for %s\n", + dl->sdl_alen, dl->sdl_data, inet_ntoa(ipaddr)); + memcpy(hwaddr, dl, dl->sdl_len); + free(buf); + return 1; } - b <<= 1; - } - if (log_IsKept(LogDEBUG)) { - char a[16]; - strncpy(a, inet_ntoa(mask->sin_addr), sizeof a - 1); - a[sizeof a - 1] = '\0'; - log_Printf(LogDEBUG, "Check addr %s, mask %s\n", - inet_ntoa(ifa->sin_addr), a); - } - if (ifa->sin_family == AF_INET && - (ifa->sin_addr.s_addr & mask->sin_addr.s_addr) == - (ipaddr.s_addr & mask->sin_addr.s_addr)) { - log_Printf(LogPHASE, "Found interface %.*s for %s\n", - dl->sdl_alen, dl->sdl_data, inet_ntoa(ipaddr)); - memcpy(hwaddr, dl, dl->sdl_len); - free(buf); - return 1; } } } diff --git a/usr.sbin/ppp/bundle.c b/usr.sbin/ppp/bundle.c index 73582969580e..5b5504cbeb18 100644 --- a/usr.sbin/ppp/bundle.c +++ b/usr.sbin/ppp/bundle.c @@ -426,7 +426,7 @@ bundle_FillQueues(struct bundle *bundle) } static int -bundle_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) +bundle_UpdateSet(struct fdescriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) { struct bundle *bundle = descriptor2bundle(d); struct datalink *dl; @@ -483,7 +483,7 @@ bundle_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) } static int -bundle_IsSet(struct descriptor *d, const fd_set *fdset) +bundle_IsSet(struct fdescriptor *d, const fd_set *fdset) { struct bundle *bundle = descriptor2bundle(d); struct datalink *dl; @@ -504,7 +504,7 @@ bundle_IsSet(struct descriptor *d, const fd_set *fdset) } static void -bundle_DescriptorRead(struct descriptor *d, struct bundle *bundle, +bundle_DescriptorRead(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset) { struct datalink *dl; @@ -600,7 +600,7 @@ bundle_DescriptorRead(struct descriptor *d, struct bundle *bundle, } static int -bundle_DescriptorWrite(struct descriptor *d, struct bundle *bundle, +bundle_DescriptorWrite(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset) { struct datalink *dl; @@ -1439,14 +1439,15 @@ bundle_ReceiveDatalink(struct bundle *bundle, int s) msg.msg_control = cmsgbuf; msg.msg_controllen = sizeof cmsgbuf; - log_Printf(LogDEBUG, "Expecting %d scatter/gather bytes\n", iov[0].iov_len); + log_Printf(LogDEBUG, "Expecting %u scatter/gather bytes\n", + (unsigned)iov[0].iov_len); if ((got = recvmsg(s, &msg, MSG_WAITALL)) != iov[0].iov_len) { if (got == -1) log_Printf(LogERROR, "Failed recvmsg: %s\n", strerror(errno)); else - log_Printf(LogERROR, "Failed recvmsg: Got %d, not %d\n", - got, iov[0].iov_len); + log_Printf(LogERROR, "Failed recvmsg: Got %d, not %u\n", + got, (unsigned)iov[0].iov_len); while (niov--) free(iov[niov].iov_base); return; @@ -1623,15 +1624,16 @@ bundle_SendDatalink(struct datalink *dl, int s, struct sockaddr_un *sun) log_Printf(LogERROR, "setsockopt(SO_RCVBUF, %d): %s\n", expect, strerror(errno)); - log_Printf(LogDEBUG, "Sending %d descriptor%s and %d bytes in scatter" - "/gather array\n", nfd, nfd == 1 ? "" : "s", iov[0].iov_len); + log_Printf(LogDEBUG, "Sending %d descriptor%s and %u bytes in scatter" + "/gather array\n", nfd, nfd == 1 ? "" : "s", + (unsigned)iov[0].iov_len); if ((got = sendmsg(s, &msg, 0)) == -1) log_Printf(LogERROR, "Failed sendmsg: %s: %s\n", sun->sun_path, strerror(errno)); else if (got != iov[0].iov_len) - log_Printf(LogERROR, "%s: Failed initial sendmsg: Only sent %d of %d\n", - sun->sun_path, got, iov[0].iov_len); + log_Printf(LogERROR, "%s: Failed initial sendmsg: Only sent %d of %u\n", + sun->sun_path, got, (unsigned)iov[0].iov_len); else { /* We must get the ACK before closing the descriptor ! */ int res; @@ -1869,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/bundle.h b/usr.sbin/ppp/bundle.h index 46d97c3f9495..2e53ca28f105 100644 --- a/usr.sbin/ppp/bundle.h +++ b/usr.sbin/ppp/bundle.h @@ -61,7 +61,7 @@ struct prompt; struct iface; struct bundle { - struct descriptor desc; /* really all our datalinks */ + struct fdescriptor desc; /* really all our datalinks */ int unit; /* The device/interface unit number */ struct { @@ -162,8 +162,8 @@ extern void bundle_StopIdleTimer(struct bundle *); extern int bundle_IsDead(struct bundle *); extern struct datalink *bundle2datalink(struct bundle *, const char *); -extern void bundle_RegisterDescriptor(struct bundle *, struct descriptor *); -extern void bundle_UnRegisterDescriptor(struct bundle *, struct descriptor *); +extern void bundle_RegisterDescriptor(struct bundle *, struct fdescriptor *); +extern void bundle_UnRegisterDescriptor(struct bundle *, struct fdescriptor *); extern void bundle_SetTtyCommandMode(struct bundle *, struct datalink *); @@ -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/cbcp.c b/usr.sbin/ppp/cbcp.c index 1ff5fe3f43c6..02505945ad7f 100644 --- a/usr.sbin/ppp/cbcp.c +++ b/usr.sbin/ppp/cbcp.c @@ -151,7 +151,7 @@ cbcpstate(int s) { if (s < sizeof cbcpname / sizeof cbcpname[0]) return cbcpname[s]; - return "???"; + return HexStr(s, NULL, 0); } static void @@ -214,7 +214,7 @@ cbcp_data_Type(int type) }; if (type < 1 || type > sizeof types / sizeof types[0]) - return "???"; + return HexStr(type, NULL, 0); return types[type-1]; } diff --git a/usr.sbin/ppp/ccp.c b/usr.sbin/ppp/ccp.c index ce45a09ba896..8ea977521eaf 100644 --- a/usr.sbin/ppp/ccp.c +++ b/usr.sbin/ppp/ccp.c @@ -93,35 +93,35 @@ static struct fsm_callbacks ccp_Callbacks = { static const char * const ccp_TimerNames[] = {"CCP restart", "CCP openmode", "CCP stopped"}; -static char const * const cftypes[] = { - /* Check out the latest ``Compression Control Protocol'' rfc (rfc1962.txt) */ - "OUI", /* 0: OUI */ - "PRED1", /* 1: Predictor type 1 */ - "PRED2", /* 2: Predictor type 2 */ - "PUDDLE", /* 3: Puddle Jumber */ - "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", - "HWPPC", /* 16: Hewlett-Packard PPC */ - "STAC", /* 17: Stac Electronics LZS (rfc1974) */ - "MPPC", /* 18: Microsoft PPC (rfc2118) */ - "GAND", /* 19: Gandalf FZA (rfc1993) */ - "V42BIS", /* 20: ARG->DATA.42bis compression */ - "BSD", /* 21: BSD LZW Compress */ - "???", - "LZS-DCP", /* 23: LZS-DCP Compression Protocol (rfc1967) */ - "MAGNALINK/DEFLATE", /* 24: Magnalink Variable Resource (rfc1975) */ - /* 24: Deflate (according to pppd-2.3.*) */ - "DCE", /* 25: Data Circuit-Terminating Equip (rfc1976) */ - "DEFLATE", /* 26: Deflate (rfc1979) */ -}; - -#define NCFTYPES (sizeof cftypes/sizeof cftypes[0]) - static const char * protoname(int proto) { - if (proto < 0 || proto > NCFTYPES) - return "none"; + static char const * const cftypes[] = { + /* Check out the latest ``Compression Control Protocol'' rfc (1962) */ + "OUI", /* 0: OUI */ + "PRED1", /* 1: Predictor type 1 */ + "PRED2", /* 2: Predictor type 2 */ + "PUDDLE", /* 3: Puddle Jumber */ + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + "HWPPC", /* 16: Hewlett-Packard PPC */ + "STAC", /* 17: Stac Electronics LZS (rfc1974) */ + "MPPC", /* 18: Microsoft PPC (rfc2118) */ + "GAND", /* 19: Gandalf FZA (rfc1993) */ + "V42BIS", /* 20: ARG->DATA.42bis compression */ + "BSD", /* 21: BSD LZW Compress */ + NULL, + "LZS-DCP", /* 23: LZS-DCP Compression Protocol (rfc1967) */ + "MAGNALINK/DEFLATE",/* 24: Magnalink Variable Resource (rfc1975) */ + /* 24: Deflate (according to pppd-2.3.*) */ + "DCE", /* 25: Data Circuit-Terminating Equip (rfc1976) */ + "DEFLATE", /* 26: Deflate (rfc1979) */ + }; + + if (proto < 0 || proto > sizeof cftypes / sizeof *cftypes || + cftypes[proto] == NULL) + return HexStr(proto, NULL, 0); + return cftypes[proto]; } @@ -441,10 +441,7 @@ CcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, if (end == NULL) end = ""; - if (type < NCFTYPES) - log_Printf(LogCCP, " %s[%d] %s\n", cftypes[type], length, end); - else - log_Printf(LogCCP, " ???[%d] %s\n", length, end); + log_Printf(LogCCP, " %s[%d] %s\n", protoname(type), length, end); if (f == -1) { /* Don't understand that :-( */ diff --git a/usr.sbin/ppp/chap.c b/usr.sbin/ppp/chap.c index 103a2694320b..aee866a42752 100644 --- a/usr.sbin/ppp/chap.c +++ b/usr.sbin/ppp/chap.c @@ -331,7 +331,7 @@ chap_Respond(struct chap *chap, char *name, char *key, u_char type } static int -chap_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) +chap_UpdateSet(struct fdescriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) { struct chap *chap = descriptor2chap(d); @@ -347,7 +347,7 @@ chap_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) } static int -chap_IsSet(struct descriptor *d, const fd_set *fdset) +chap_IsSet(struct fdescriptor *d, const fd_set *fdset) { struct chap *chap = descriptor2chap(d); @@ -355,7 +355,7 @@ chap_IsSet(struct descriptor *d, const fd_set *fdset) } static void -chap_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) +chap_Read(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset) { struct chap *chap = descriptor2chap(d); int got; @@ -411,7 +411,7 @@ chap_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) } static int -chap_Write(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) +chap_Write(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset) { /* We never want to write here ! */ log_Printf(LogALERT, "chap_Write: Internal error: Bad call !\n"); diff --git a/usr.sbin/ppp/chap.h b/usr.sbin/ppp/chap.h index 37d5c6f10e4a..7de61b4714da 100644 --- a/usr.sbin/ppp/chap.h +++ b/usr.sbin/ppp/chap.h @@ -29,7 +29,7 @@ struct physical; #define CHAP_FAILURE 4 struct chap { - struct descriptor desc; + struct fdescriptor desc; struct { pid_t pid; int fd; diff --git a/usr.sbin/ppp/chap_ms.c b/usr.sbin/ppp/chap_ms.c index 6530ef66363e..4333aa16d06c 100644 --- a/usr.sbin/ppp/chap_ms.c +++ b/usr.sbin/ppp/chap_ms.c @@ -26,7 +26,11 @@ #include <sys/types.h> #include <ctype.h> +#ifdef __FreeBSD__ #include <openssl/des.h> +#else +#include <des.h> +#endif #include <string.h> #include "chap_ms.h" diff --git a/usr.sbin/ppp/chat.c b/usr.sbin/ppp/chat.c index 984fb620be90..2f19db209013 100644 --- a/usr.sbin/ppp/chat.c +++ b/usr.sbin/ppp/chat.c @@ -133,7 +133,7 @@ chat_NextChar(char *ptr, char ch) } static int -chat_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) +chat_UpdateSet(struct fdescriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) { struct chat *c = descriptor2chat(d); int special, gotabort, gottimeout, needcr; @@ -316,7 +316,7 @@ chat_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) } static int -chat_IsSet(struct descriptor *d, const fd_set *fdset) +chat_IsSet(struct fdescriptor *d, const fd_set *fdset) { struct chat *c = descriptor2chat(d); return c->argptr && physical_IsSet(&c->physical->desc, fdset); @@ -365,7 +365,7 @@ chat_UpdateLog(struct chat *c, int in) } static void -chat_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) +chat_Read(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset) { struct chat *c = descriptor2chat(d); @@ -479,7 +479,7 @@ chat_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) } static int -chat_Write(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) +chat_Write(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset) { struct chat *c = descriptor2chat(d); int result = 0; diff --git a/usr.sbin/ppp/chat.h b/usr.sbin/ppp/chat.h index 2e40babe073c..b8162bfd33dd 100644 --- a/usr.sbin/ppp/chat.h +++ b/usr.sbin/ppp/chat.h @@ -36,7 +36,7 @@ struct physical; struct chat { - struct descriptor desc; + struct fdescriptor desc; struct physical *physical; int state; /* Our CHAT_* status */ diff --git a/usr.sbin/ppp/command.c b/usr.sbin/ppp/command.c index 120d1a25a415..99753c3cfe0e 100644 --- a/usr.sbin/ppp/command.c +++ b/usr.sbin/ppp/command.c @@ -47,12 +47,13 @@ #include <unistd.h> #ifndef NONAT -#ifdef __FreeBSD__ -#include <alias.h> -#else +#ifdef LOCALNAT #include "alias.h" +#else +#include <alias.h> #endif #endif + #include "layer.h" #include "defs.h" #include "command.h" @@ -435,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; } @@ -553,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[] = { @@ -672,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 +935,18 @@ FindExec(struct bundle *bundle, struct cmdtab const *cmds, int argc, int argn, } 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]) { char *cp; @@ -983,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); @@ -1668,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], @@ -1682,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; @@ -1903,8 +1950,8 @@ static struct cmdtab const SetCommands[] = { {"lcpretry", "lcpretries", SetVariable, LOCAL_AUTH | LOCAL_CX, "LCP retries", "set lcpretry value [attempts]", (const void *)VAR_LCPRETRY}, {"log", NULL, log_SetLevel, LOCAL_AUTH, "log level", - "set log [local] [+|-]async|cbcp|ccp|chat|command|connect|debug|hdlc|id0|" - "ipcp|lcp|lqm|phase|physical|sync|tcp/ip|timer|tun..."}, + "set log [local] [+|-]async|cbcp|ccp|chat|command|connect|debug|dns|hdlc|" + "id0|ipcp|lcp|lqm|phase|physical|sync|tcp/ip|timer|tun..."}, {"login", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX, "login script", "set login chat-script", (const void *) VAR_LOGIN}, {"logout", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX, @@ -1968,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 ? <var>' for" - " syntax help.\n"); + " syntax help.\n"); else log_Printf(LogWARN, "set command must have arguments\n"); @@ -1998,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 { @@ -2007,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]); @@ -2045,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/command.h b/usr.sbin/ppp/command.h index d08f67db7012..afb41dde3fba 100644 --- a/usr.sbin/ppp/command.h +++ b/usr.sbin/ppp/command.h @@ -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/datalink.c b/usr.sbin/ppp/datalink.c index 6648cfed1459..988bdf439264 100644 --- a/usr.sbin/ppp/datalink.c +++ b/usr.sbin/ppp/datalink.c @@ -241,7 +241,7 @@ datalink_LoginDone(struct datalink *dl) } static int -datalink_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, +datalink_UpdateSet(struct fdescriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) { struct datalink *dl = descriptor2datalink(d); @@ -410,7 +410,7 @@ datalink_RemoveFromSet(struct datalink *dl, fd_set *r, fd_set *w, fd_set *e) } static int -datalink_IsSet(struct descriptor *d, const fd_set *fdset) +datalink_IsSet(struct fdescriptor *d, const fd_set *fdset) { struct datalink *dl = descriptor2datalink(d); @@ -437,7 +437,7 @@ datalink_IsSet(struct descriptor *d, const fd_set *fdset) } static void -datalink_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) +datalink_Read(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset) { struct datalink *dl = descriptor2datalink(d); @@ -467,7 +467,7 @@ datalink_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) } static int -datalink_Write(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) +datalink_Write(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset) { struct datalink *dl = descriptor2datalink(d); int result = 0; diff --git a/usr.sbin/ppp/datalink.h b/usr.sbin/ppp/datalink.h index 721b3be18c8b..dc0765130be0 100644 --- a/usr.sbin/ppp/datalink.h +++ b/usr.sbin/ppp/datalink.h @@ -52,7 +52,7 @@ struct physical; struct bundle; struct datalink { - struct descriptor desc; /* We play either a physical or a chat */ + struct fdescriptor desc; /* We play either a physical or a chat */ int state; /* Our DATALINK_* state */ struct physical *physical; /* Our link */ diff --git a/usr.sbin/ppp/defs.c b/usr.sbin/ppp/defs.c index a8eef4dd060a..32e445be9777 100644 --- a/usr.sbin/ppp/defs.c +++ b/usr.sbin/ppp/defs.c @@ -35,6 +35,7 @@ #include <ctype.h> #include <errno.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> #include <termios.h> @@ -315,3 +316,29 @@ MakeArgs(char *script, char **pvect, int maxargs, int flags) *pvect = NULL; return nargs; } + +const char * +NumStr(long val, char *buf, size_t sz) +{ + static char result[23]; /* handles 64 bit numbers */ + + if (buf == NULL || sz == 0) { + buf = result; + sz = sizeof result; + } + snprintf(buf, sz, "<%ld>", val); + return buf; +} + +const char * +HexStr(long val, char *buf, size_t sz) +{ + static char result[21]; /* handles 64 bit numbers */ + + if (buf == NULL || sz == 0) { + buf = result; + sz = sizeof result; + } + snprintf(buf, sz, "<0x%lx>", val); + return buf; +} diff --git a/usr.sbin/ppp/defs.h b/usr.sbin/ppp/defs.h index a47c12eb4cd8..4a1ca1f36a2b 100644 --- a/usr.sbin/ppp/defs.h +++ b/usr.sbin/ppp/defs.h @@ -96,6 +96,8 @@ #define PARSE_REDUCE 1 #define PARSE_NOHASH 2 +#define ROUNDUP(x) ((x) ? (1 + (((x) - 1) | (sizeof(long) - 1))) : sizeof(long)) + extern void randinit(void); extern ssize_t fullread(int, void *, size_t); extern const char *mode2Nam(int); @@ -105,3 +107,5 @@ extern int SpeedToInt(speed_t); extern speed_t IntToSpeed(int); extern char *findblank(char *, int); extern int MakeArgs(char *, char **, int, int); +extern const char *NumStr(long, char *, size_t); +extern const char *HexStr(long, char *, size_t); diff --git a/usr.sbin/ppp/descriptor.h b/usr.sbin/ppp/descriptor.h index 77452ccd3312..a3c1b1075406 100644 --- a/usr.sbin/ppp/descriptor.h +++ b/usr.sbin/ppp/descriptor.h @@ -38,13 +38,13 @@ struct bundle; -struct descriptor { +struct fdescriptor { int type; - int (*UpdateSet)(struct descriptor *, fd_set *, fd_set *, fd_set *, int *); - int (*IsSet)(struct descriptor *, const fd_set *); - void (*Read)(struct descriptor *, struct bundle *, const fd_set *); - int (*Write)(struct descriptor *, struct bundle *, const fd_set *); + int (*UpdateSet)(struct fdescriptor *, fd_set *, fd_set *, fd_set *, int *); + int (*IsSet)(struct fdescriptor *, const fd_set *); + void (*Read)(struct fdescriptor *, struct bundle *, const fd_set *); + int (*Write)(struct fdescriptor *, struct bundle *, const fd_set *); }; #define descriptor_UpdateSet(d, r, w, e, n) ((*(d)->UpdateSet)(d, r, w, e, n)) diff --git a/usr.sbin/ppp/ether.c b/usr.sbin/ppp/ether.c index b06a3c2ba132..ebcbcd3bf39a 100644 --- a/usr.sbin/ppp/ether.c +++ b/usr.sbin/ppp/ether.c @@ -319,7 +319,7 @@ ether_iov2device(int type, struct physical *p, struct iovec *iov, int *niov, } static int -ether_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) +ether_UpdateSet(struct fdescriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) { struct physical *p = descriptor2physical(d); struct etherdevice *dev = device2ether(p->handler); @@ -338,7 +338,7 @@ ether_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) } static int -ether_IsSet(struct descriptor *d, const fd_set *fdset) +ether_IsSet(struct fdescriptor *d, const fd_set *fdset) { struct physical *p = descriptor2physical(d); struct etherdevice *dev = device2ether(p->handler); @@ -351,7 +351,7 @@ ether_IsSet(struct descriptor *d, const fd_set *fdset) } static void -ether_DescriptorRead(struct descriptor *d, struct bundle *bundle, +ether_DescriptorRead(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset) { struct physical *p = descriptor2physical(d); diff --git a/usr.sbin/ppp/filter.c b/usr.sbin/ppp/filter.c index ade48a52d499..6e6f5f9e5d3a 100644 --- a/usr.sbin/ppp/filter.c +++ b/usr.sbin/ppp/filter.c @@ -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/filter.h b/usr.sbin/ppp/filter.h index 03922cd21d13..0bfa56035b5d 100644 --- a/usr.sbin/ppp/filter.h +++ b/usr.sbin/ppp/filter.h @@ -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/iface.c b/usr.sbin/ppp/iface.c index 6d771efee588..2ddd5b0a4052 100644 --- a/usr.sbin/ppp/iface.c +++ b/usr.sbin/ppp/iface.c @@ -94,13 +94,13 @@ bitsinmask(struct in_addr mask) struct iface * iface_Create(const char *name) { - int mib[6], i, s; + int mib[6], s; size_t needed; - char *buf, *ptr, *end, *cp, *lim; + char *buf, *ptr, *end; struct if_msghdr *ifm; struct ifa_msghdr *ifam; struct sockaddr_dl *dl; - struct rt_addrinfo rti; + struct sockaddr *sa[RTAX_MAX]; struct iface *iface; struct iface_addr *addr; @@ -165,29 +165,12 @@ iface_Create(const char *name) if (ifam->ifam_type != RTM_NEWADDR) /* finished this if */ break; - if (iface == NULL) /* Keep wading */ - continue; - - /* Found an address ! */ - - if (ifam->ifam_addrs & (1 << RTAX_IFA)) { - /* *And* it's configured ! */ - rti.rti_addrs = ifam->ifam_addrs; - lim = (char *)ifam + ifam->ifam_msglen; - cp = (char *)(ifam + 1); - memset(rti.rti_info, '\0', sizeof(rti.rti_info)); - for (i = 0; i < RTAX_MAX && cp < lim; i++) { - if ((rti.rti_addrs & (1 << i)) == 0) - continue; - rti.rti_info[i] = (struct sockaddr *)cp; -#define ROUNDUP(x) \ - ((x) > 0 ? (1 + (((x) - 1) | (sizeof(long) - 1))) : sizeof(long)) - cp += ROUNDUP(rti.rti_info[i]->sa_len); - } + if (iface != NULL && ifam->ifam_addrs & RTA_IFA) { + /* Found a configured interface ! */ + iface_ParseHdr(ifam, sa); - if (rti.rti_info[RTAX_IFA] && - rti.rti_info[RTAX_IFA]->sa_family == AF_INET) { - /* Record the iface address rti */ + if (sa[RTAX_IFA] && sa[RTAX_IFA]->sa_family == AF_INET) { + /* Record the address */ addr = (struct iface_addr *)realloc (iface->in_addr, (iface->in_addrs + 1) * sizeof iface->in_addr[0]); @@ -198,14 +181,17 @@ iface_Create(const char *name) addr += iface->in_addrs; iface->in_addrs++; - addr->ifa.s_addr = ((struct sockaddr_in *)rti.rti_info[RTAX_IFA])-> - sin_addr.s_addr; - addr->brd.s_addr = rti.rti_info[RTAX_BRD] ? - ((struct sockaddr_in *)rti.rti_info[RTAX_BRD])->sin_addr.s_addr : - INADDR_ANY; - addr->mask.s_addr = rti.rti_info[RTAX_NETMASK] ? - ((struct sockaddr_in *)rti.rti_info[RTAX_NETMASK])->sin_addr.s_addr: - INADDR_ANY; + addr->ifa = ((struct sockaddr_in *)sa[RTAX_IFA])->sin_addr; + + if (sa[RTAX_BRD]) + addr->brd = ((struct sockaddr_in *)sa[RTAX_BRD])->sin_addr; + else + addr->brd.s_addr = INADDR_ANY; + + if (sa[RTAX_NETMASK]) + addr->mask = ((struct sockaddr_in *)sa[RTAX_NETMASK])->sin_addr; + else + addr->mask.s_addr = INADDR_ANY; addr->bits = bitsinmask(addr->mask); } @@ -540,3 +526,19 @@ iface_Show(struct cmdargs const *arg) return 0; } + +void +iface_ParseHdr(struct ifa_msghdr *ifam, struct sockaddr *sa[RTAX_MAX]) +{ + char *wp; + int rtax; + + wp = (char *)(ifam + 1); + + for (rtax = 0; rtax < RTAX_MAX; rtax++) + if (ifam->ifam_addrs & (1 << rtax)) { + sa[rtax] = (struct sockaddr *)wp; + wp += ROUNDUP(sa[rtax]->sa_len); + } else + sa[rtax] = NULL; +} diff --git a/usr.sbin/ppp/iface.h b/usr.sbin/ppp/iface.h index a42ec0976236..f22883b2fa63 100644 --- a/usr.sbin/ppp/iface.h +++ b/usr.sbin/ppp/iface.h @@ -26,6 +26,8 @@ * $FreeBSD$ */ +struct ifa_msghdr; + struct iface_addr { struct in_addr ifa; /* local address */ struct in_addr mask; /* netmask */ @@ -60,3 +62,4 @@ extern int iface_Show(struct cmdargs const *); extern int iface_SetFlags(struct iface *, int); extern int iface_ClearFlags(struct iface *, int); extern void iface_Destroy(struct iface *); +extern void iface_ParseHdr(struct ifa_msghdr *, struct sockaddr *[RTAX_MAX]); diff --git a/usr.sbin/ppp/ip.c b/usr.sbin/ppp/ip.c index f33c3d93af37..1fdd6c290231 100644 --- a/usr.sbin/ppp/ip.c +++ b/usr.sbin/ppp/ip.c @@ -66,10 +66,74 @@ #include "tun.h" #include "ip.h" -static const char * const TcpFlags[] = { - "FIN", "SYN", "RST", "PSH", "ACK", "URG" + +#define OPCODE_QUERY 0 +#define OPCODE_IQUERY 1 +#define OPCODE_STATUS 2 + +struct dns_header { + u_short id; + unsigned qr : 1; + unsigned opcode : 4; + unsigned aa : 1; + unsigned tc : 1; + unsigned rd : 1; + unsigned ra : 1; + unsigned z : 3; + unsigned rcode : 4; + u_short qdcount; + u_short ancount; + u_short nscount; + u_short arcount; }; +static const char * +dns_Qclass2Txt(u_short qclass) +{ + static char failure[6]; + struct { + u_short id; + const char *txt; + } qtxt[] = { + /* rfc1035 */ + { 1, "IN" }, { 2, "CS" }, { 3, "CH" }, { 4, "HS" }, { 255, "*" } + }; + int f; + + for (f = 0; f < sizeof qtxt / sizeof *qtxt; f++) + if (qtxt[f].id == qclass) + return qtxt[f].txt; + + return HexStr(qclass, failure, sizeof failure); +} + +static const char * +dns_Qtype2Txt(u_short qtype) +{ + static char failure[6]; + struct { + u_short id; + const char *txt; + } qtxt[] = { + /* rfc1035/rfc1700 */ + { 1, "A" }, { 2, "NS" }, { 3, "MD" }, { 4, "MF" }, { 5, "CNAME" }, + { 6, "SOA" }, { 7, "MB" }, { 8, "MG" }, { 9, "MR" }, { 10, "NULL" }, + { 11, "WKS" }, { 12, "PTR" }, { 13, "HINFO" }, { 14, "MINFO" }, + { 15, "MX" }, { 16, "TXT" }, { 17, "RP" }, { 18, "AFSDB" }, + { 19, "X25" }, { 20, "ISDN" }, { 21, "RT" }, { 22, "NSAP" }, + { 23, "NSAP-PTR" }, { 24, "SIG" }, { 25, "KEY" }, { 26, "PX" }, + { 27, "GPOS" }, { 28, "AAAA" }, { 252, "AXFR" }, { 253, "MAILB" }, + { 254, "MAILA" }, { 255, "*" } + }; + int f; + + for (f = 0; f < sizeof qtxt / sizeof *qtxt; f++) + if (qtxt[f].id == qtype) + return qtxt[f].txt; + + return HexStr(qtype, failure, sizeof failure); +} + static __inline int PortMatch(int op, u_short pport, u_short rport) { @@ -309,26 +373,82 @@ IcmpError(struct ip *pip, int code) } #endif +static void +ip_LogDNS(const struct udphdr *uh, const char *direction) +{ + struct dns_header header; + const u_short *pktptr; + const u_char *ptr; + u_short *hptr; + int len; + + ptr = (const char *)uh + sizeof *uh; + len = ntohs(uh->uh_ulen) - sizeof *uh; + if (len < sizeof header + 5) /* rfc1024 */ + return; + + pktptr = (const u_short *)ptr; + hptr = (u_short *)&header; + ptr += sizeof header; + len -= sizeof header; + + while (pktptr < (const u_short *)ptr) { + *hptr++ = ntohs(*pktptr); /* Careful of macro side-effects ! */ + pktptr++; + } + + if (header.opcode == OPCODE_QUERY && header.qr == 0) { + /* rfc1035 */ + char name[MAXHOSTNAMELEN + 1], *n; + const char *qtype, *qclass; + const u_char *end; + + n = name; + end = ptr + len - 4; + if (end - ptr > MAXHOSTNAMELEN) + end = ptr + MAXHOSTNAMELEN; + while (ptr < end) { + len = *ptr++; + if (len > end - ptr) + len = end - ptr; + if (n != name) + *n++ = '.'; + memcpy(n, ptr, len); + ptr += len; + n += len; + } + *n = '\0'; + qtype = dns_Qtype2Txt(ntohs(*(const u_short *)end)); + qclass = dns_Qclass2Txt(ntohs(*(const u_short *)(end + 2))); + + log_Printf(LogDNS, "%sbound query %s %s %s\n", + direction, qclass, qtype, name); + } +} + /* * For debugging aid. */ int PacketCheck(struct bundle *bundle, char *cp, int nb, struct filter *filter) { + static const char *const TcpFlags[] = { + "FIN", "SYN", "RST", "PSH", "ACK", "URG" + }; struct ip *pip; struct tcphdr *th; struct udphdr *uh; struct icmp *icmph; char *ptop; - int mask, len, n; - int pri = 0; - int logit, loglen; + int mask, len, n, pri, logit, loglen, result; char logbuf[200]; - logit = log_IsKept(LogTCPIP) && filter->logok; + logit = (log_IsKept(LogTCPIP) || log_IsKept(LogDNS)) && filter->logok; loglen = 0; + pri = 0; - pip = (struct ip *) cp; + pip = (struct ip *)cp; + uh = NULL; if (logit && loglen < sizeof logbuf) { snprintf(logbuf + loglen, sizeof logbuf - loglen, "%s ", filter->name); @@ -471,17 +591,22 @@ PacketCheck(struct bundle *bundle, char *cp, int nb, struct filter *filter) if (direction == 0) IcmpError(pip, pri); #endif - return (-1); + result = -1; } else { /* Check Keep Alive filter */ - if (logit) { + if (logit && log_IsKept(LogTCPIP)) { if (FilterCheck(pip, &bundle->filter.alive)) log_Printf(LogTCPIP, "%s - NO KEEPALIVE\n", logbuf); else log_Printf(LogTCPIP, "%s\n", logbuf); } - return (pri); + result = pri; } + + if (uh && ntohs(uh->uh_dport) == 53 && log_IsKept(LogDNS)) + ip_LogDNS(uh, filter->name); + + return result; } struct mbuf * diff --git a/usr.sbin/ppp/ipcp.c b/usr.sbin/ppp/ipcp.c index 917d5778ebab..b54cf65a7059 100644 --- a/usr.sbin/ppp/ipcp.c +++ b/usr.sbin/ppp/ipcp.c @@ -38,16 +38,18 @@ #include <resolv.h> #include <stdlib.h> #include <string.h> +#include <sys/stat.h> #include <termios.h> #include <unistd.h> #ifndef NONAT -#ifdef __FreeBSD__ -#include <alias.h> -#else +#ifdef LOCALNAT #include "alias.h" +#else +#include <alias.h> #endif #endif + #include "layer.h" #include "ua.h" #include "defs.h" @@ -208,26 +210,30 @@ static struct fsm_callbacks ipcp_Callbacks = { fsm_NullRecvResetAck }; -static const char * const cftypes[] = { - /* Check out the latest ``Assigned numbers'' rfc (rfc1700.txt) */ - "???", - "IPADDRS", /* 1: IP-Addresses */ /* deprecated */ - "COMPPROTO", /* 2: IP-Compression-Protocol */ - "IPADDR", /* 3: IP-Address */ -}; - -#define NCFTYPES (sizeof cftypes/sizeof cftypes[0]) +static const char * +protoname(int proto) +{ + static struct { + int id; + const char *txt; + } cftypes[] = { + /* Check out the latest ``Assigned numbers'' rfc (rfc1700.txt) */ + { 1, "IPADDRS" }, /* IP-Addresses */ /* deprecated */ + { 2, "COMPPROTO" }, /* IP-Compression-Protocol */ + { 3, "IPADDR" }, /* IP-Address */ + { 129, "PRIDNS" }, /* 129: Primary DNS Server Address */ + { 130, "PRINBNS" }, /* 130: Primary NBNS Server Address */ + { 131, "SECDNS" }, /* 131: Secondary DNS Server Address */ + { 132, "SECNBNS" } /* 132: Secondary NBNS Server Address */ + }; + int f; -static const char * const cftypes128[] = { - /* Check out the latest ``Assigned numbers'' rfc (rfc1700.txt) */ - "???", - "PRIDNS", /* 129: Primary DNS Server Address */ - "PRINBNS", /* 130: Primary NBNS Server Address */ - "SECDNS", /* 131: Secondary DNS Server Address */ - "SECNBNS", /* 132: Secondary NBNS Server Address */ -}; + for (f = 0; f < sizeof cftypes / sizeof *cftypes; f++) + if (cftypes[f].id == proto) + return cftypes[f].txt; -#define NCFTYPES128 (sizeof cftypes128/sizeof cftypes128[0]) + return NumStr(proto, NULL, 0); +} void ipcp_AddInOctets(struct ipcp *ipcp, int n) @@ -241,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; - 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; + ipcp->ns.dns[0].s_addr = ipcp->ns.dns[1].s_addr = INADDR_NONE; + + 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 @@ -366,7 +433,8 @@ ipcp_Show(struct cmdargs const *arg) inet_ntoa(ipcp->peer_ip), vj2asc(ipcp->peer_compproto)); prompt_Printf(arg->prompt, " My side: %s, %s\n", inet_ntoa(ipcp->my_ip), vj2asc(ipcp->my_compproto)); - prompt_Printf(arg->prompt, " Queued packets: %d\n", ip_QueueLen(ipcp)); + prompt_Printf(arg->prompt, " Queued packets: %lu\n", + (unsigned long)ip_QueueLen(ipcp)); } if (ipcp->route) { @@ -398,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])); @@ -483,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; @@ -506,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); @@ -524,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 @@ -605,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 @@ -663,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)) { @@ -767,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); } @@ -941,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; @@ -960,12 +1059,7 @@ IpcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, break; } - if (type < NCFTYPES) - snprintf(tbuff, sizeof tbuff, " %s[%d] ", cftypes[type], length); - else if (type > 128 && type < 128 + NCFTYPES128) - snprintf(tbuff, sizeof tbuff, " %s[%d] ", cftypes128[type-128], length); - else - snprintf(tbuff, sizeof tbuff, " <%d>[%d] ", type, length); + snprintf(tbuff, sizeof tbuff, " %s[%d] ", protoname(type), length); switch (type) { case TY_IPADDR: /* RFC1332 */ @@ -1173,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) { /* @@ -1200,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; @@ -1263,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/ipcp.h b/usr.sbin/ppp/ipcp.h index 6f87eb78354d..38583d87ce66 100644 --- a/usr.sbin/ppp/ipcp.h +++ b/usr.sbin/ppp/ipcp.h @@ -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/lcp.c b/usr.sbin/ppp/lcp.c index 8df2061abdb9..74a284900e6f 100644 --- a/usr.sbin/ppp/lcp.c +++ b/usr.sbin/ppp/lcp.c @@ -104,35 +104,43 @@ static struct fsm_callbacks lcp_Callbacks = { static const char * const lcp_TimerNames[] = {"LCP restart", "LCP openmode", "LCP stopped"}; -static const char * const cftypes[] = { - /* Check out the latest ``Assigned numbers'' rfc (rfc1700.txt) */ - "???", - "MRU", /* 1: Maximum-Receive-Unit */ - "ACCMAP", /* 2: Async-Control-Character-Map */ - "AUTHPROTO", /* 3: Authentication-Protocol */ - "QUALPROTO", /* 4: Quality-Protocol */ - "MAGICNUM", /* 5: Magic-Number */ - "RESERVED", /* 6: RESERVED */ - "PROTOCOMP", /* 7: Protocol-Field-Compression */ - "ACFCOMP", /* 8: Address-and-Control-Field-Compression */ - "FCSALT", /* 9: FCS-Alternatives */ - "SDP", /* 10: Self-Describing-Pad */ - "NUMMODE", /* 11: Numbered-Mode */ - "MULTIPROC", /* 12: Multi-Link-Procedure */ - "CALLBACK", /* 13: Callback */ - "CONTIME", /* 14: Connect-Time */ - "COMPFRAME", /* 15: Compound-Frames */ - "NDE", /* 16: Nominal-Data-Encapsulation */ - "MRRU", /* 17: Multilink-MRRU */ - "SHORTSEQ", /* 18: Multilink-Short-Sequence-Number-Header */ - "ENDDISC", /* 19: Multilink-Endpoint-Discriminator */ - "PROPRIETRY", /* 20: Proprietary */ - "DCEID", /* 21: DCE-Identifier */ - "MULTIPP", /* 22: Multi-Link-Plus-Procedure */ - "LDBACP", /* 23: Link Discriminator for BACP */ -}; - -#define NCFTYPES (sizeof cftypes/sizeof cftypes[0]) +static const char * +protoname(int proto) +{ + static const char * const cftypes[] = { + /* Check out the latest ``Assigned numbers'' rfc (1700) */ + NULL, + "MRU", /* 1: Maximum-Receive-Unit */ + "ACCMAP", /* 2: Async-Control-Character-Map */ + "AUTHPROTO", /* 3: Authentication-Protocol */ + "QUALPROTO", /* 4: Quality-Protocol */ + "MAGICNUM", /* 5: Magic-Number */ + "RESERVED", /* 6: RESERVED */ + "PROTOCOMP", /* 7: Protocol-Field-Compression */ + "ACFCOMP", /* 8: Address-and-Control-Field-Compression */ + "FCSALT", /* 9: FCS-Alternatives */ + "SDP", /* 10: Self-Describing-Pad */ + "NUMMODE", /* 11: Numbered-Mode */ + "MULTIPROC", /* 12: Multi-Link-Procedure */ + "CALLBACK", /* 13: Callback */ + "CONTIME", /* 14: Connect-Time */ + "COMPFRAME", /* 15: Compound-Frames */ + "NDE", /* 16: Nominal-Data-Encapsulation */ + "MRRU", /* 17: Multilink-MRRU */ + "SHORTSEQ", /* 18: Multilink-Short-Sequence-Number-Header */ + "ENDDISC", /* 19: Multilink-Endpoint-Discriminator */ + "PROPRIETRY", /* 20: Proprietary */ + "DCEID", /* 21: DCE-Identifier */ + "MULTIPP", /* 22: Multi-Link-Plus-Procedure */ + "LDBACP", /* 23: Link Discriminator for BACP */ + }; + + if (proto < 0 || proto > sizeof cftypes / sizeof *cftypes || + cftypes[proto] == NULL) + return HexStr(proto, NULL, 0); + + return cftypes[proto]; +} int lcp_ReportStatus(struct cmdargs const *arg) @@ -546,10 +554,7 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, type = *cp; length = cp[1]; - if (type < 0 || type >= NCFTYPES) - snprintf(request, sizeof request, " <%d>[%d]", type, length); - else - snprintf(request, sizeof request, " %s[%d]", cftypes[type], length); + snprintf(request, sizeof request, " %s[%d]", protoname(type), length); if (length < 2) { log_Printf(LogLCP, "%s:%s: Bad LCP length\n", fp->link->name, request); diff --git a/usr.sbin/ppp/log.c b/usr.sbin/ppp/log.c index 5fdcdf6b703b..97ab8530a2a7 100644 --- a/usr.sbin/ppp/log.c +++ b/usr.sbin/ppp/log.c @@ -50,6 +50,7 @@ static const char * const LogNames[] = { "Command", "Connect", "Debug", + "DNS", "HDLC", "ID0", "IPCP", diff --git a/usr.sbin/ppp/log.h b/usr.sbin/ppp/log.h index 70fe4c2e6514..35ccbbb1f7e8 100644 --- a/usr.sbin/ppp/log.h +++ b/usr.sbin/ppp/log.h @@ -34,22 +34,24 @@ #define LogCOMMAND (5) #define LogCONNECT (6) #define LogDEBUG (7) /* syslog(LOG_DEBUG, ....) */ -#define LogHDLC (8) -#define LogID0 (9) -#define LogIPCP (10) -#define LogLCP (11) -#define LogLQM (12) -#define LogPHASE (13) -#define LogPHYSICAL (14) /* syslog(LOG_INFO, ....) */ -#define LogSYNC (15) /* syslog(LOG_INFO, ....) */ -#define LogTCPIP (16) -#define LogTIMER (17) /* syslog(LOG_DEBUG, ....) */ -#define LogTUN (18) /* If set, tun%d is output with each message */ -#define LogMAXCONF (18) -#define LogWARN (19) /* Sent to VarTerm else syslog(LOG_WARNING, ) */ -#define LogERROR (20) /* syslog(LOG_ERR, ....), + sent to VarTerm */ -#define LogALERT (21) /* syslog(LOG_ALERT, ....) */ -#define LogMAX (21) +#define LogDNS (8) +#define LogHDLC (9) +#define LogID0 (10) +#define LogIPCP (11) +#define LogLCP (12) +#define LogLQM (13) +#define LogPHASE (14) +#define LogPHYSICAL (15) /* syslog(LOG_INFO, ....) */ +#define LogSYNC (16) /* syslog(LOG_INFO, ....) */ +#define LogTCPIP (17) +#define LogTIMER (18) /* syslog(LOG_DEBUG, ....) */ +#define LogTUN (19) /* If set, tun%d is output with each message */ +#define LogWARN (20) /* Sent to VarTerm else syslog(LOG_WARNING, ) */ +#define LogERROR (21) /* syslog(LOG_ERR, ....), + sent to VarTerm */ +#define LogALERT (22) /* syslog(LOG_ALERT, ....) */ + +#define LogMAXCONF (19) +#define LogMAX (22) struct mbuf; struct cmdargs; diff --git a/usr.sbin/ppp/main.c b/usr.sbin/ppp/main.c index 10269e6fee4c..6bcfdce1f4fb 100644 --- a/usr.sbin/ppp/main.c +++ b/usr.sbin/ppp/main.c @@ -27,6 +27,8 @@ #include <netinet/in_systm.h> #include <netinet/ip.h> #include <sys/un.h> +#include <sys/socket.h> +#include <net/route.h> #include <errno.h> #include <fcntl.h> @@ -41,12 +43,13 @@ #include <sys/stat.h> #ifndef NONAT -#ifdef __FreeBSD__ -#include <alias.h> -#else +#ifdef LOCALNAT #include "alias.h" +#else +#include <alias.h> #endif #endif + #include "layer.h" #include "probe.h" #include "mbuf.h" diff --git a/usr.sbin/ppp/mbuf.c b/usr.sbin/ppp/mbuf.c index 5bd58dcc6fc9..5d5135847804 100644 --- a/usr.sbin/ppp/mbuf.c +++ b/usr.sbin/ppp/mbuf.c @@ -112,8 +112,8 @@ m_get(size_t m_len, int type) */ *mb = (struct mbucket *)malloc(BUCKET_CHUNK * size); if (*mb == NULL) { - log_Printf(LogALERT, "Failed to allocate memory (%u)\n", - BUCKET_CHUNK * size); + log_Printf(LogALERT, "Failed to allocate memory (%lu)\n", + (unsigned long)BUCKET_CHUNK * size); AbortProgram(EX_OSERR); } bp = &(*mb)->u.m; @@ -354,7 +354,7 @@ m_enqueue(struct mqueue *queue, struct mbuf *bp) } else queue->last = queue->top = bp; queue->len++; - log_Printf(LogDEBUG, "m_enqueue: len = %d\n", queue->len); + log_Printf(LogDEBUG, "m_enqueue: len = %lu\n", (unsigned long)queue->len); } } diff --git a/usr.sbin/ppp/mp.c b/usr.sbin/ppp/mp.c index 16197b0dc149..8f9173abad38 100644 --- a/usr.sbin/ppp/mp.c +++ b/usr.sbin/ppp/mp.c @@ -966,7 +966,7 @@ mp_SetEnddisc(struct cmdargs const *arg) } static int -mpserver_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, +mpserver_UpdateSet(struct fdescriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) { struct mpserver *s = descriptor2mpserver(d); @@ -996,14 +996,14 @@ mpserver_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, } static int -mpserver_IsSet(struct descriptor *d, const fd_set *fdset) +mpserver_IsSet(struct fdescriptor *d, const fd_set *fdset) { struct mpserver *s = descriptor2mpserver(d); return s->fd >= 0 && FD_ISSET(s->fd, fdset); } static void -mpserver_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) +mpserver_Read(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset) { struct mpserver *s = descriptor2mpserver(d); @@ -1011,7 +1011,7 @@ mpserver_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) } static int -mpserver_Write(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) +mpserver_Write(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset) { /* We never want to write here ! */ log_Printf(LogALERT, "mpserver_Write: Internal error: Bad call !\n"); diff --git a/usr.sbin/ppp/mp.h b/usr.sbin/ppp/mp.h index e33a7edd104d..78587eb2cc1a 100644 --- a/usr.sbin/ppp/mp.h +++ b/usr.sbin/ppp/mp.h @@ -60,7 +60,7 @@ struct peerid { }; struct mpserver { - struct descriptor desc; + struct fdescriptor desc; int fd; /* listen()ing or connect()ing here */ struct sockaddr_un socket; /* On this socket */ diff --git a/usr.sbin/ppp/nat_cmd.c b/usr.sbin/ppp/nat_cmd.c index a2fb917b5614..12c1d788c6a4 100644 --- a/usr.sbin/ppp/nat_cmd.c +++ b/usr.sbin/ppp/nat_cmd.c @@ -19,11 +19,12 @@ #include <string.h> #include <termios.h> -#ifdef __FreeBSD__ -#include <alias.h> -#else +#ifdef LOCALNAT #include "alias.h" +#else +#include <alias.h> #endif + #include "layer.h" #include "proto.h" #include "defs.h" @@ -358,8 +359,9 @@ static struct mbuf * nat_LayerPull(struct bundle *bundle, struct link *l, struct mbuf *bp, u_short *proto) { + static int gfrags; struct ip *pip, *piip; - int ret, len; + int ret, len, nfrags; struct mbuf **last; char *fptr; @@ -379,11 +381,12 @@ nat_LayerPull(struct bundle *bundle, struct link *l, struct mbuf *bp, /* Ensure there's a bit of extra buffer for the NAT code... */ bp = m_pullup(m_append(bp, NULL, NAT_EXTRABUF)); ret = PacketAliasIn(MBUF_CTOP(bp), bp->m_len); + pip = (struct ip *)MBUF_CTOP(bp); bp->m_len = ntohs(pip->ip_len); if (bp->m_len > MAX_MRU) { - log_Printf(LogWARN, "nat_LayerPull: Problem with IP header length (%d)\n", - bp->m_len); + log_Printf(LogWARN, "nat_LayerPull: Problem with IP header length (%lu)\n", + (unsigned long)bp->m_len); m_freem(bp); return NULL; } @@ -397,22 +400,31 @@ nat_LayerPull(struct bundle *bundle, struct link *l, struct mbuf *bp, fptr = malloc(bp->m_len); bp = mbuf_Read(bp, fptr, bp->m_len); PacketAliasSaveFragment(fptr); + log_Printf(LogDEBUG, "Store another frag (%lu) - now %d\n", + (unsigned long)((struct ip *)fptr)->ip_id, ++gfrags); break; case PKT_ALIAS_FOUND_HEADER_FRAGMENT: /* Fetch all the saved fragments and chain them on the end of `bp' */ last = &bp->m_nextpkt; + nfrags = 0; while ((fptr = PacketAliasGetFragment(MBUF_CTOP(bp))) != NULL) { - PacketAliasFragmentIn(MBUF_CTOP(bp), fptr); + nfrags++; + PacketAliasFragmentIn(MBUF_CTOP(bp), fptr); len = ntohs(((struct ip *)fptr)->ip_len); *last = m_get(len, MB_NATIN); memcpy(MBUF_CTOP(*last), fptr, len); free(fptr); last = &(*last)->m_nextpkt; } + gfrags -= nfrags; + log_Printf(LogDEBUG, "Found a frag header (%lu) - plus %d more frags (no" + "w %d)\n", (unsigned long)((struct ip *)MBUF_CTOP(bp))->ip_id, + nfrags, gfrags); break; default: + log_Printf(LogWARN, "nat_LayerPull: Dropped a packet....\n"); m_freem(bp); bp = NULL; break; diff --git a/usr.sbin/ppp/physical.c b/usr.sbin/ppp/physical.c index 92d47f8e0d42..611796e27439 100644 --- a/usr.sbin/ppp/physical.c +++ b/usr.sbin/ppp/physical.c @@ -97,7 +97,7 @@ #define PPPOTCPLINE "ppp" -static int physical_DescriptorWrite(struct descriptor *, struct bundle *, +static int physical_DescriptorWrite(struct fdescriptor *, struct bundle *, const fd_set *); static int @@ -128,7 +128,7 @@ struct { #define NDEVICES (sizeof devices / sizeof devices[0]) static int -physical_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, +physical_UpdateSet(struct fdescriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) { return physical_doUpdateSet(d, r, w, e, n, 0); @@ -374,7 +374,7 @@ physical_Destroy(struct physical *p) } static int -physical_DescriptorWrite(struct descriptor *d, struct bundle *bundle, +physical_DescriptorWrite(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset) { struct physical *p = descriptor2physical(d); @@ -385,8 +385,8 @@ physical_DescriptorWrite(struct descriptor *d, struct bundle *bundle, if (p->out) { nw = physical_Write(p, MBUF_CTOP(p->out), p->out->m_len); - log_Printf(LogDEBUG, "%s: DescriptorWrite: wrote %d(%d) to %d\n", - p->link.name, nw, p->out->m_len, p->fd); + log_Printf(LogDEBUG, "%s: DescriptorWrite: wrote %d(%lu) to %d\n", + p->link.name, nw, (unsigned long)p->out->m_len, p->fd); if (nw > 0) { p->out->m_len -= nw; p->out->m_offset += nw; @@ -496,7 +496,7 @@ physical_ShowStatus(struct cmdargs const *arg) } void -physical_DescriptorRead(struct descriptor *d, struct bundle *bundle, +physical_DescriptorRead(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset) { struct physical *p = descriptor2physical(d); @@ -788,7 +788,7 @@ physical_Write(struct physical *p, const void *buf, size_t nbytes) } int -physical_doUpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, +physical_doUpdateSet(struct fdescriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n, int force) { struct physical *p = descriptor2physical(d); @@ -850,7 +850,7 @@ physical_RemoveFromSet(struct physical *p, fd_set *r, fd_set *w, fd_set *e) } int -physical_IsSet(struct descriptor *d, const fd_set *fdset) +physical_IsSet(struct fdescriptor *d, const fd_set *fdset) { struct physical *p = descriptor2physical(d); return p->fd >= 0 && FD_ISSET(p->fd, fdset); diff --git a/usr.sbin/ppp/physical.h b/usr.sbin/ppp/physical.h index c5aaea84360d..74ce890745cd 100644 --- a/usr.sbin/ppp/physical.h +++ b/usr.sbin/ppp/physical.h @@ -73,7 +73,7 @@ struct device { struct physical { struct link link; - struct descriptor desc; + struct fdescriptor desc; int type; /* What sort of PHYS_* link are we ? */ struct async async; /* Our async state */ struct hdlc hdlc; /* Our hdlc state */ @@ -148,10 +148,10 @@ extern void physical_SetDevice(struct physical *, const char *); extern ssize_t physical_Read(struct physical *, void *, size_t); extern ssize_t physical_Write(struct physical *, const void *, size_t); -extern int physical_doUpdateSet(struct descriptor *, fd_set *, fd_set *, +extern int physical_doUpdateSet(struct fdescriptor *, fd_set *, fd_set *, fd_set *, int *, int); -extern int physical_IsSet(struct descriptor *, const fd_set *); -extern void physical_DescriptorRead(struct descriptor *, struct bundle *, +extern int physical_IsSet(struct fdescriptor *, const fd_set *); +extern void physical_DescriptorRead(struct fdescriptor *, struct bundle *, const fd_set *); extern void physical_Login(struct physical *, const char *); extern int physical_RemoveFromSet(struct physical *, fd_set *, fd_set *, diff --git a/usr.sbin/ppp/ppp.8 b/usr.sbin/ppp/ppp.8 index b14363167aac..c384be404ac7 100644 --- a/usr.sbin/ppp/ppp.8 +++ b/usr.sbin/ppp/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. @@ -327,7 +327,7 @@ minimum. Name Server Addresses and NetBIOS Name Server Addresses can be negotiated with clients using the Microsoft .Em PPP -stack (ie. Win95, WinNT) +stack (i.e., Win95, WinNT) .It Supports Multi-link PPP (rfc 1990) It is possible to configure .Nm @@ -394,7 +394,7 @@ Make sure that your system has a group named .Dq network in the .Pa /etc/group -file and that that group contains the names of all users expected to use +file and that the group contains the names of all users expected to use .Nm ppp . Refer to the .Xr group 5 @@ -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 @@ -1134,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 @@ -1260,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 @@ -1558,7 +1560,7 @@ and represent the TH_ACK, TH_SYN and TH_FIN or TH_RST TCP flags respectively. .It Each filter can hold up to 40 rules, starting from rule 0. The entire rule set is not effective until rule 0 is defined, -ie. the default is to allow everything through. +i.e., the default is to allow everything through. .It If no rule is matched to a packet, that packet will be discarded (blocked). @@ -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 . @@ -2020,6 +2029,8 @@ files. Log Chat lines containing the string "CONNECT". .It Li Debug Log debug information. +.It Li DNS +Log DNS QUERY packets. .It Li HDLC Dump HDLC packet in hex. .It Li ID0 @@ -2068,7 +2079,7 @@ should immediately follow .Dq set log . The default is .Dq set log local -(ie. only the un-maskable warning, error and alert output). +(i.e., only the un-maskable warning, error and alert output). .Pp If The first argument to .Dq set log Op local @@ -2267,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 @@ -2584,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 @@ -2773,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 . @@ -3033,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 @@ -3354,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 @@ -3527,7 +3608,7 @@ is the callee, the number should be specified as the fifth field of the peers entry in .Pa /etc/ppp/ppp.secret . .It cbcp -Microsofts callback control protocol is used. See +Microsoft's callback control protocol is used. See .Dq set cbcp below. .Pp @@ -3578,7 +3659,7 @@ options) if you wish callback to be optional. .Op Ar delay Op Ar retry .Oc .Xc -If no arguments are given, CBCP (Microsofts CallBack Control Protocol) +If no arguments are given, CBCP (Microsoft's CallBack Control Protocol) is disabled - ie, configuring CBCP in the .Dq set callback command will result in @@ -3639,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/prompt.c b/usr.sbin/ppp/prompt.c index 565245328e45..debd7ca1483b 100644 --- a/usr.sbin/ppp/prompt.c +++ b/usr.sbin/ppp/prompt.c @@ -120,7 +120,7 @@ prompt_Display(struct prompt *p) } static int -prompt_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) +prompt_UpdateSet(struct fdescriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) { struct prompt *p = descriptor2prompt(d); int sets; @@ -151,7 +151,7 @@ prompt_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) } static int -prompt_IsSet(struct descriptor *d, const fd_set *fdset) +prompt_IsSet(struct fdescriptor *d, const fd_set *fdset) { struct prompt *p = descriptor2prompt(d); return p->fd_in >= 0 && FD_ISSET(p->fd_in, fdset); @@ -170,7 +170,7 @@ prompt_ShowHelp(struct prompt *p) } static void -prompt_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) +prompt_Read(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset) { struct prompt *p = descriptor2prompt(d); struct prompt *op; @@ -291,7 +291,7 @@ prompt_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) } static int -prompt_Write(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) +prompt_Write(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset) { /* We never want to write here ! */ log_Printf(LogALERT, "prompt_Write: Internal error: Bad call !\n"); diff --git a/usr.sbin/ppp/prompt.h b/usr.sbin/ppp/prompt.h index cd8edc7a5de1..6e3bc3221da4 100644 --- a/usr.sbin/ppp/prompt.h +++ b/usr.sbin/ppp/prompt.h @@ -38,7 +38,7 @@ struct bundle; struct cmdargs; struct prompt { - struct descriptor desc; + struct fdescriptor desc; int fd_in, fd_out; struct datalink *TermMode; /* The modem we're talking directly to */ FILE *Term; /* sits on top of fd_out */ diff --git a/usr.sbin/ppp/radius.c b/usr.sbin/ppp/radius.c index e46baee80717..c868a6725036 100644 --- a/usr.sbin/ppp/radius.c +++ b/usr.sbin/ppp/radius.c @@ -28,14 +28,21 @@ */ #include <sys/param.h> +#include <sys/socket.h> #include <netinet/in_systm.h> #include <netinet/in.h> #include <netinet/ip.h> #include <arpa/inet.h> #include <sys/un.h> +#include <net/route.h> -#include <errno.h> +#ifdef LOCALRAD +#include "radlib.h" +#else #include <radlib.h> +#endif + +#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -257,16 +264,16 @@ radius_Timeout(void *v) * Time to call rad_continue_send_request() - something to read. */ static void -radius_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) +radius_Read(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset) { radius_Continue(descriptor2radius(d), 1); } /* - * Behave as a struct descriptor (descriptor.h) + * Behave as a struct fdescriptor (descriptor.h) */ static int -radius_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) +radius_UpdateSet(struct fdescriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) { struct radius *rad = descriptor2radius(d); @@ -282,10 +289,10 @@ radius_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) } /* - * Behave as a struct descriptor (descriptor.h) + * Behave as a struct fdescriptor (descriptor.h) */ static int -radius_IsSet(struct descriptor *d, const fd_set *fdset) +radius_IsSet(struct fdescriptor *d, const fd_set *fdset) { struct radius *r = descriptor2radius(d); @@ -293,10 +300,10 @@ radius_IsSet(struct descriptor *d, const fd_set *fdset) } /* - * Behave as a struct descriptor (descriptor.h) + * Behave as a struct fdescriptor (descriptor.h) */ static int -radius_Write(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) +radius_Write(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset) { /* We never want to write here ! */ log_Printf(LogALERT, "radius_Write: Internal error: Bad call !\n"); diff --git a/usr.sbin/ppp/radius.h b/usr.sbin/ppp/radius.h index ea0235fc15e8..f9fdf3b25597 100644 --- a/usr.sbin/ppp/radius.h +++ b/usr.sbin/ppp/radius.h @@ -27,7 +27,7 @@ */ struct radius { - struct descriptor desc; /* We're a sort of (selectable) descriptor */ + struct fdescriptor desc; /* We're a sort of (selectable) fdescriptor */ struct { int fd; /* We're selecting on this */ struct rad_handle *rad; /* Using this to talk to our lib */ diff --git a/usr.sbin/ppp/route.c b/usr.sbin/ppp/route.c index 688bcfe205b0..e1471016376c 100644 --- a/usr.sbin/ppp/route.c +++ b/usr.sbin/ppp/route.c @@ -32,6 +32,7 @@ #include <netinet/in_systm.h> #include <netinet/ip.h> #include <sys/un.h> +#include <netdb.h> #include <errno.h> #include <stdio.h> @@ -67,31 +68,46 @@ #include "prompt.h" #include "iface.h" + static void p_sockaddr(struct prompt *prompt, struct sockaddr *phost, struct sockaddr *pmask, int width) { char buf[29]; - struct sockaddr_in *ihost = (struct sockaddr_in *)phost; - struct sockaddr_in *mask = (struct sockaddr_in *)pmask; + struct sockaddr_in *ihost4 = (struct sockaddr_in *)phost; + struct sockaddr_in *mask4 = (struct sockaddr_in *)pmask; struct sockaddr_dl *dl = (struct sockaddr_dl *)phost; + if (log_IsKept(LogDEBUG)) { + char tmp[50]; + + log_Printf(LogDEBUG, "Found the following sockaddr:\n"); + log_Printf(LogDEBUG, " Family %d, len %d\n", + (int)phost->sa_family, (int)phost->sa_len); + inet_ntop(phost->sa_family, phost->sa_data, tmp, sizeof tmp); + log_Printf(LogDEBUG, " Addr %s\n", tmp); + if (pmask) { + inet_ntop(pmask->sa_family, pmask->sa_data, tmp, sizeof tmp); + log_Printf(LogDEBUG, " Mask %s\n", tmp); + } + } + switch (phost->sa_family) { case AF_INET: if (!phost) buf[0] = '\0'; - else if (ihost->sin_addr.s_addr == INADDR_ANY) + else if (ihost4->sin_addr.s_addr == INADDR_ANY) strcpy(buf, "default"); - else if (!mask) - strcpy(buf, inet_ntoa(ihost->sin_addr)); + else if (!pmask) + strcpy(buf, inet_ntoa(ihost4->sin_addr)); else { - u_int32_t msk = ntohl(mask->sin_addr.s_addr); + u_int32_t msk = ntohl(mask4->sin_addr.s_addr); u_int32_t tst; int bits; int len; struct sockaddr_in net; - for (tst = 1, bits=32; tst; tst <<= 1, bits--) + for (tst = 1, bits = 32; tst; tst <<= 1, bits--) if (msk & tst) break; @@ -99,7 +115,7 @@ p_sockaddr(struct prompt *prompt, struct sockaddr *phost, if (!(msk & tst)) break; - net.sin_addr.s_addr = ihost->sin_addr.s_addr & mask->sin_addr.s_addr; + net.sin_addr.s_addr = ihost4->sin_addr.s_addr & mask4->sin_addr.s_addr; strcpy(buf, inet_ntoa(net.sin_addr)); for (len = strlen(buf); len > 3; buf[len -= 2] = '\0') if (strcmp(buf + len - 2, ".0")) @@ -135,6 +151,55 @@ p_sockaddr(struct prompt *prompt, struct sockaddr *phost, sprintf(buf, "link#%d", dl->sdl_index); break; +#ifndef NOINET6 + case AF_INET6: + if (!phost) + buf[0] = '\0'; + else { + const u_char masks[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe }; + struct sockaddr_in6 *ihost6 = (struct sockaddr_in6 *)phost; + struct sockaddr_in6 *mask6 = (struct sockaddr_in6 *)pmask; + int masklen, len; + const u_char *c; + + /* XXX: ?????!?!?!!!!! This is horrible ! */ + if (IN6_IS_ADDR_LINKLOCAL(&ihost6->sin6_addr) || + IN6_IS_ADDR_MC_LINKLOCAL(&ihost6->sin6_addr)) { + ihost6->sin6_scope_id = + ntohs(*(u_short *)&ihost6->sin6_addr.s6_addr[2]); + *(u_short *)&ihost6->sin6_addr.s6_addr[2] = 0; + } + + if (mask6) { + const u_char *p, *end; + + p = (const u_char *)&mask6->sin6_addr; + end = p + 16; + for (masklen = 0, end = p + 16; p < end && *p == 0xff; p++) + masklen += 8; + + if (p < end) { + for (c = masks; c < masks + sizeof masks; c++) + if (*c == *p) { + masklen += c - masks; + break; + } + } + } else + masklen = 128; + + if (masklen == 0 && IN6_IS_ADDR_UNSPECIFIED(&ihost6->sin6_addr)) + snprintf(buf, sizeof buf, "default"); + else { + getnameinfo(phost, ihost6->sin6_len, buf, sizeof buf, + NULL, 0, NI_WITHSCOPEID | NI_NUMERICHOST); + if (mask6 && (len = strlen(buf)) < sizeof buf - 1) + snprintf(buf + len, sizeof buf - len, "/%d", masklen); + } + } + break; +#endif + default: sprintf(buf, "<AF type %d>", phost->sa_family); break; @@ -232,19 +297,21 @@ Index2Nam(int idx) if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) { log_Printf(LogERROR, "Index2Nam: sysctl: estimate: %s\n", strerror(errno)); - return "???"; + return NumStr(idx, NULL, 0); } if ((buf = malloc(needed)) == NULL) - return "???"; + return NumStr(idx, NULL, 0); if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { free(buf); - return "???"; + return NumStr(idx, NULL, 0); } end = buf + needed; have = 0; for (ptr = buf; ptr < end; ptr += ifm->ifm_msglen) { ifm = (struct if_msghdr *)ptr; + if (ifm->ifm_type != RTM_IFINFO) + continue; dl = (struct sockaddr_dl *)(ifm + 1); if (ifm->ifm_index > 0) { if (ifm->ifm_index > have) { @@ -264,7 +331,7 @@ Index2Nam(int idx) ifs = NULL; } free(buf); - return "???"; + return NumStr(idx, NULL, 0); } ifs = newifs; memset(ifs + had, '\0', sizeof(char *) * (have - had)); @@ -294,17 +361,33 @@ Index2Nam(int idx) } if (idx < 1 || idx > nifs || ifs[idx-1] == NULL) - return "???"; + return NumStr(idx, NULL, 0); return ifs[idx-1]; } +void +route_ParseHdr(struct rt_msghdr *rtm, struct sockaddr *sa[RTAX_MAX]) +{ + char *wp; + int rtax; + + wp = (char *)(rtm + 1); + + for (rtax = 0; rtax < RTAX_MAX; rtax++) + if (rtm->rtm_addrs & (1 << rtax)) { + sa[rtax] = (struct sockaddr *)wp; + wp += ROUNDUP(sa[rtax]->sa_len); + } else + sa[rtax] = NULL; +} + int route_Show(struct cmdargs const *arg) { struct rt_msghdr *rtm; - struct sockaddr *sa_dst, *sa_gw, *sa_mask; - char *sp, *ep, *cp, *wp; + struct sockaddr *sa[RTAX_MAX]; + char *sp, *ep, *cp; size_t needed; int mib[6]; @@ -331,32 +414,18 @@ route_Show(struct cmdargs const *arg) prompt_Printf(arg->prompt, "%-20s%-20sFlags Netif\n", "Destination", "Gateway"); for (cp = sp; cp < ep; cp += rtm->rtm_msglen) { - rtm = (struct rt_msghdr *) cp; - wp = (char *)(rtm+1); + rtm = (struct rt_msghdr *)cp; - if (rtm->rtm_addrs & RTA_DST) { - sa_dst = (struct sockaddr *)wp; - wp += sa_dst->sa_len; - } else - sa_dst = NULL; + route_ParseHdr(rtm, sa); - if (rtm->rtm_addrs & RTA_GATEWAY) { - sa_gw = (struct sockaddr *)wp; - wp += sa_gw->sa_len; - } else - sa_gw = NULL; + if (sa[RTAX_DST] && sa[RTAX_GATEWAY]) { + p_sockaddr(arg->prompt, sa[RTAX_DST], sa[RTAX_NETMASK], 20); + p_sockaddr(arg->prompt, sa[RTAX_GATEWAY], NULL, 20); - if (rtm->rtm_addrs & RTA_NETMASK) { - sa_mask = (struct sockaddr *)wp; - wp += sa_mask->sa_len; + p_flags(arg->prompt, rtm->rtm_flags, 6); + prompt_Printf(arg->prompt, " %s\n", Index2Nam(rtm->rtm_index)); } else - sa_mask = NULL; - - p_sockaddr(arg->prompt, sa_dst, sa_mask, 20); - p_sockaddr(arg->prompt, sa_gw, NULL, 20); - - p_flags(arg->prompt, rtm->rtm_flags, 6); - prompt_Printf(arg->prompt, " %s\n", Index2Nam(rtm->rtm_index)); + prompt_Printf(arg->prompt, "<can't parse routing entry>\n"); } free(sp); return 0; @@ -369,8 +438,9 @@ void route_IfDelete(struct bundle *bundle, int all) { struct rt_msghdr *rtm; - struct sockaddr *sa; - struct in_addr sa_dst, sa_none; + struct sockaddr *sa[RTAX_MAX]; + struct sockaddr_in **in; + struct in_addr sa_none; int pass; size_t needed; char *sp, *cp, *ep; @@ -378,6 +448,7 @@ route_IfDelete(struct bundle *bundle, int all) log_Printf(LogDEBUG, "route_IfDelete (%d)\n", bundle->iface->index); sa_none.s_addr = INADDR_ANY; + in = (struct sockaddr_in **)sa; mib[0] = CTL_NET; mib[1] = PF_ROUTE; @@ -406,7 +477,7 @@ route_IfDelete(struct bundle *bundle, int all) for (pass = 0; pass < 2; pass++) { /* * We do 2 passes. The first deletes all cloned routes. The second - * deletes all non-cloned routes. This is necessary to avoid + * deletes all non-cloned routes. This is done to avoid * potential errors from trying to delete route X after route Y where * route X was cloned from route Y (and is no longer there 'cos it * may have gone with route Y). @@ -415,28 +486,30 @@ route_IfDelete(struct bundle *bundle, int all) /* So we can't tell ! */ continue; for (cp = sp; cp < ep; cp += rtm->rtm_msglen) { - rtm = (struct rt_msghdr *) cp; - sa = (struct sockaddr *) (rtm + 1); - log_Printf(LogDEBUG, "route_IfDelete: addrs: %x, Netif: %d (%s)," - " flags: %x, dst: %s ?\n", rtm->rtm_addrs, rtm->rtm_index, - Index2Nam(rtm->rtm_index), rtm->rtm_flags, - inet_ntoa(((struct sockaddr_in *) sa)->sin_addr)); - if (rtm->rtm_addrs & RTA_DST && rtm->rtm_addrs & RTA_GATEWAY && - rtm->rtm_index == bundle->iface->index && - (all || (rtm->rtm_flags & RTF_GATEWAY))) { - sa_dst.s_addr = ((struct sockaddr_in *)sa)->sin_addr.s_addr; - sa = (struct sockaddr *)((char *)sa + sa->sa_len); - if (sa->sa_family == AF_INET || sa->sa_family == AF_LINK) { - if ((pass == 0 && (rtm->rtm_flags & RTF_WASCLONED)) || - (pass == 1 && !(rtm->rtm_flags & RTF_WASCLONED))) { - log_Printf(LogDEBUG, "route_IfDelete: Remove it (pass %d)\n", pass); - bundle_SetRoute(bundle, RTM_DELETE, sa_dst, sa_none, sa_none, 0, 0); + rtm = (struct rt_msghdr *)cp; + route_ParseHdr(rtm, sa); + if (sa[RTAX_DST]) { + log_Printf(LogDEBUG, "route_IfDelete: addrs: %x, Netif: %d (%s)," + " flags: %x, dst: %s ?\n", rtm->rtm_addrs, rtm->rtm_index, + Index2Nam(rtm->rtm_index), rtm->rtm_flags, + inet_ntoa(((struct sockaddr_in *)sa[RTAX_DST])->sin_addr)); + if (sa[RTAX_GATEWAY] && rtm->rtm_index == bundle->iface->index && + (all || (rtm->rtm_flags & RTF_GATEWAY))) { + if (sa[RTAX_GATEWAY]->sa_family == AF_INET || + sa[RTAX_GATEWAY]->sa_family == AF_LINK) { + if ((pass == 0 && (rtm->rtm_flags & RTF_WASCLONED)) || + (pass == 1 && !(rtm->rtm_flags & RTF_WASCLONED))) { + log_Printf(LogDEBUG, "route_IfDelete: Remove it (pass %d)\n", + pass); + bundle_SetRoute(bundle, RTM_DELETE, in[RTAX_DST]->sin_addr, + sa_none, sa_none, 0, 0); + } else + log_Printf(LogDEBUG, "route_IfDelete: Skip it (pass %d)\n", pass); } else - log_Printf(LogDEBUG, "route_IfDelete: Skip it (pass %d)\n", pass); - } else - log_Printf(LogDEBUG, - "route_IfDelete: Can't remove routes of %d family !\n", - sa->sa_family); + log_Printf(LogDEBUG, + "route_IfDelete: Can't remove routes of %d family !\n", + sa[RTAX_GATEWAY]->sa_family); + } } } } @@ -460,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; @@ -478,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); @@ -575,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/route.h b/usr.sbin/ppp/route.h index 86a3d4edb13e..dc95871ceda3 100644 --- a/usr.sbin/ppp/route.h +++ b/usr.sbin/ppp/route.h @@ -23,12 +23,16 @@ struct bundle; 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) */ @@ -44,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); @@ -52,3 +56,4 @@ extern void route_DeleteAll(struct sticky_route **); extern void route_Clean(struct bundle *, struct sticky_route *); extern void route_ShowSticky(struct prompt *, struct sticky_route *, const char *, int); +extern void route_ParseHdr(struct rt_msghdr *, struct sockaddr *[RTAX_MAX]); diff --git a/usr.sbin/ppp/server.c b/usr.sbin/ppp/server.c index 0f6cb513e1a2..869d1367d548 100644 --- a/usr.sbin/ppp/server.c +++ b/usr.sbin/ppp/server.c @@ -46,7 +46,7 @@ #include "prompt.h" static int -server_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) +server_UpdateSet(struct fdescriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) { struct server *s = descriptor2server(d); struct prompt *p; @@ -68,7 +68,7 @@ server_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) } static int -server_IsSet(struct descriptor *d, const fd_set *fdset) +server_IsSet(struct fdescriptor *d, const fd_set *fdset) { struct server *s = descriptor2server(d); struct prompt *p; @@ -84,11 +84,11 @@ server_IsSet(struct descriptor *d, const fd_set *fdset) } #define IN_SIZE sizeof(struct sockaddr_in) -#define UN_SIZE sizeof(struct sockaddr_in) +#define UN_SIZE sizeof(struct sockaddr_un) #define ADDRSZ (IN_SIZE > UN_SIZE ? IN_SIZE : UN_SIZE) static void -server_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) +server_Read(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset) { struct server *s = descriptor2server(d); char hisaddr[ADDRSZ]; @@ -162,7 +162,7 @@ server_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) } static int -server_Write(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) +server_Write(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset) { /* We never want to write here ! */ log_Printf(LogALERT, "server_Write: Internal error: Bad call !\n"); diff --git a/usr.sbin/ppp/server.h b/usr.sbin/ppp/server.h index 860f43225a50..509099d0279d 100644 --- a/usr.sbin/ppp/server.h +++ b/usr.sbin/ppp/server.h @@ -29,7 +29,7 @@ struct bundle; struct server { - struct descriptor desc; + struct fdescriptor desc; int fd; char passwd[50]; diff --git a/usr.sbin/ppp/slcompress.c b/usr.sbin/ppp/slcompress.c index d5fa74c21391..75b952eae976 100644 --- a/usr.sbin/ppp/slcompress.c +++ b/usr.sbin/ppp/slcompress.c @@ -154,8 +154,8 @@ sl_compress_tcp(struct mbuf * m, * the caller has already made sure the packet is IP proto TCP). */ if ((ip->ip_off & htons(0x3fff)) || m->m_len < 40) { - log_Printf(LogDEBUG, "??? 1 ip_off = %x, m_len = %d\n", - ip->ip_off, m->m_len); + log_Printf(LogDEBUG, "??? 1 ip_off = %x, m_len = %lu\n", + ip->ip_off, (unsigned long)m->m_len); log_DumpBp(LogDEBUG, "", m); return (TYPE_IP); } diff --git a/usr.sbin/ppp/systems.c b/usr.sbin/ppp/systems.c index 18a9df07ee34..e00009772d50 100644 --- a/usr.sbin/ppp/systems.c +++ b/usr.sbin/ppp/systems.c @@ -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/systems.h b/usr.sbin/ppp/systems.h index 39130d642cb1..969e4ab59933 100644 --- a/usr.sbin/ppp/systems.h +++ b/usr.sbin/ppp/systems.h @@ -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 *); diff --git a/usr.sbin/ppp/timer.c b/usr.sbin/ppp/timer.c index 144c306fa740..9e69aea6e87b 100644 --- a/usr.sbin/ppp/timer.c +++ b/usr.sbin/ppp/timer.c @@ -35,6 +35,11 @@ #include "descriptor.h" #include "prompt.h" + +#define RESTVAL(t) \ + ((t).it_value.tv_sec * SECTICKS + (t).it_value.tv_usec / TICKUNIT + \ + ((((t).it_value.tv_usec % TICKUNIT) >= (TICKUNIT >> 1)) ? 1 : 0)) + static struct pppTimer *TimerList = NULL, *ExpiredList = NULL; static void StopTimerNoBlock(struct pppTimer *); @@ -80,8 +85,7 @@ timer_Start(struct pppTimer *tp) /* Adjust our first delta so that it reflects what's really happening */ if (TimerList && getitimer(ITIMER_REAL, &itimer) == 0) - TimerList->rest = itimer.it_value.tv_sec * SECTICKS + - itimer.it_value.tv_usec / TICKUNIT; + TimerList->rest = RESTVAL(itimer); pt = NULL; for (t = TimerList; t; t = t->next) { @@ -133,15 +137,24 @@ StopTimerNoBlock(struct pppTimer *tp) pt = t; if (t) { - if (pt) { + if (pt) pt->next = t->next; - } else { + else { TimerList = t->next; if (TimerList == NULL) /* Last one ? */ timer_TermService(); /* Terminate Timer Service */ } - if (t->next) - t->next->rest += tp->rest; + if (t->next) { + if (!pt) { /* t (tp) was the first in the list */ + struct itimerval itimer; + + if (getitimer(ITIMER_REAL, &itimer) == 0) + t->rest = RESTVAL(itimer); + } + t->next->rest += t->rest; + if (!pt) /* t->next is now the first in the list */ + timer_InitService(1); + } } else { /* Search for any pending expired timers */ pt = NULL; @@ -215,8 +228,7 @@ timer_Show(int LogLevel, struct prompt *prompt) /* Adjust our first delta so that it reflects what's really happening */ if (TimerList && getitimer(ITIMER_REAL, &itimer) == 0) - TimerList->rest = itimer.it_value.tv_sec * SECTICKS + - itimer.it_value.tv_usec / TICKUNIT; + TimerList->rest = RESTVAL(itimer); #define SECS(val) ((val) / SECTICKS) #define HSECS(val) (((val) % SECTICKS) * 100 / SECTICKS) |
