summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Somers <brian@FreeBSD.org>2000-03-21 10:23:20 +0000
committerBrian Somers <brian@FreeBSD.org>2000-03-21 10:23:20 +0000
commita8f574395cd8235daba4282e257d05aa7c171d80 (patch)
tree7d21303815fed699a13209e3f532410d9834072a
parent9fc98f33802cb0d361238409c621a6966c85c294 (diff)
Notes
-rw-r--r--usr.sbin/ppp/Makefile4
-rw-r--r--usr.sbin/ppp/README.changes1
-rw-r--r--usr.sbin/ppp/arp.c66
-rw-r--r--usr.sbin/ppp/bundle.c41
-rw-r--r--usr.sbin/ppp/bundle.h7
-rw-r--r--usr.sbin/ppp/cbcp.c4
-rw-r--r--usr.sbin/ppp/ccp.c57
-rw-r--r--usr.sbin/ppp/chap.c8
-rw-r--r--usr.sbin/ppp/chap.h2
-rw-r--r--usr.sbin/ppp/chap_ms.c4
-rw-r--r--usr.sbin/ppp/chat.c8
-rw-r--r--usr.sbin/ppp/chat.h2
-rw-r--r--usr.sbin/ppp/command.c91
-rw-r--r--usr.sbin/ppp/command.h2
-rw-r--r--usr.sbin/ppp/datalink.c8
-rw-r--r--usr.sbin/ppp/datalink.h2
-rw-r--r--usr.sbin/ppp/defs.c27
-rw-r--r--usr.sbin/ppp/defs.h4
-rw-r--r--usr.sbin/ppp/descriptor.h10
-rw-r--r--usr.sbin/ppp/ether.c6
-rw-r--r--usr.sbin/ppp/filter.c24
-rw-r--r--usr.sbin/ppp/filter.h8
-rw-r--r--usr.sbin/ppp/iface.c68
-rw-r--r--usr.sbin/ppp/iface.h3
-rw-r--r--usr.sbin/ppp/ip.c145
-rw-r--r--usr.sbin/ppp/ipcp.c396
-rw-r--r--usr.sbin/ppp/ipcp.h13
-rw-r--r--usr.sbin/ppp/lcp.c71
-rw-r--r--usr.sbin/ppp/log.c1
-rw-r--r--usr.sbin/ppp/log.h34
-rw-r--r--usr.sbin/ppp/main.c9
-rw-r--r--usr.sbin/ppp/mbuf.c6
-rw-r--r--usr.sbin/ppp/mp.c8
-rw-r--r--usr.sbin/ppp/mp.h2
-rw-r--r--usr.sbin/ppp/nat_cmd.c26
-rw-r--r--usr.sbin/ppp/physical.c16
-rw-r--r--usr.sbin/ppp/physical.h8
-rw-r--r--usr.sbin/ppp/ppp.8125
-rw-r--r--usr.sbin/ppp/prompt.c8
-rw-r--r--usr.sbin/ppp/prompt.h2
-rw-r--r--usr.sbin/ppp/radius.c23
-rw-r--r--usr.sbin/ppp/radius.h2
-rw-r--r--usr.sbin/ppp/route.c213
-rw-r--r--usr.sbin/ppp/route.h17
-rw-r--r--usr.sbin/ppp/server.c10
-rw-r--r--usr.sbin/ppp/server.h2
-rw-r--r--usr.sbin/ppp/slcompress.c4
-rw-r--r--usr.sbin/ppp/systems.c146
-rw-r--r--usr.sbin/ppp/systems.h1
-rw-r--r--usr.sbin/ppp/timer.c28
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)