diff options
author | brian <brian@cvs.openbsd.org> | 2000-07-11 22:13:05 +0000 |
---|---|---|
committer | brian <brian@cvs.openbsd.org> | 2000-07-11 22:13:05 +0000 |
commit | ae5d88eacbc79e97f7d245c576b49dcdfed530ce (patch) | |
tree | 97137ea451d44724d7a3deeec42e0f0c9950f477 /usr.sbin/ppp | |
parent | aaba2cdf720b9df4707b1cbbc5631bdf27b0f8a5 (diff) |
Allow a ``timeout secs'' filter option to let specific packet types
effect the idle timer in different ways.
Submitted by: Stefan Esser <se@freebsd.org>
With adjustments by me to document the option in the man page and to
give the same semantics for outgoing traffic as incoming.
I made the style more consistent in ip.c - this should really have
been done as a separate commit.
Diffstat (limited to 'usr.sbin/ppp')
-rw-r--r-- | usr.sbin/ppp/ppp/bundle.c | 39 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/bundle.h | 4 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/filter.c | 9 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/filter.h | 3 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/ip.c | 397 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/ip.h | 4 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/nat_cmd.c | 4 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/ppp.8 | 30 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/tun.h | 7 |
9 files changed, 283 insertions, 214 deletions
diff --git a/usr.sbin/ppp/ppp/bundle.c b/usr.sbin/ppp/ppp/bundle.c index c70f8fb115d..d4b1cca72e2 100644 --- a/usr.sbin/ppp/ppp/bundle.c +++ b/usr.sbin/ppp/ppp/bundle.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: bundle.c,v 1.41 2000/07/11 09:27:32 brian Exp $ + * $OpenBSD: bundle.c,v 1.42 2000/07/11 22:13:02 brian Exp $ */ #include <sys/param.h> @@ -222,7 +222,7 @@ bundle_LinkAdded(struct bundle *bundle, struct datalink *dl) if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL)) != bundle->phys_type.open && bundle->idle.timer.state == TIMER_STOPPED) /* We may need to start our idle timer */ - bundle_StartIdleTimer(bundle); + bundle_StartIdleTimer(bundle, 0); } void @@ -265,7 +265,7 @@ bundle_LayerUp(void *v, struct fsm *fp) } else if (fp->proto == PROTO_IPCP) { bundle_CalculateBandwidth(fp->bundle); time(&bundle->upat); - bundle_StartIdleTimer(bundle); + bundle_StartIdleTimer(bundle, 0); bundle_Notify(bundle, EX_NORMAL); mp_CheckAutoloadTimer(&fp->bundle->ncp.mp); } @@ -519,6 +519,7 @@ bundle_DescriptorRead(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset) { struct datalink *dl; + unsigned secs; if (descriptor_IsSet(&bundle->ncp.mp.server.desc, fdset)) descriptor_Read(&bundle->ncp.mp.server.desc, bundle, fdset); @@ -561,7 +562,7 @@ bundle_DescriptorRead(struct fdescriptor *d, struct bundle *bundle, bundle->dev.Name, n); return; } - if (ntohl(tun.family) != AF_INET) + if (ntohl(tun.header.family) != AF_INET) /* XXX: Should be maintaining drop/family counts ! */ return; } @@ -570,7 +571,7 @@ bundle_DescriptorRead(struct fdescriptor *d, struct bundle *bundle, bundle->ncp.ipcp.my_ip.s_addr) { /* we've been asked to send something addressed *to* us :( */ if (Enabled(bundle, OPT_LOOPBACK)) { - pri = PacketCheck(bundle, tun.data, n, &bundle->filter.in, NULL); + pri = PacketCheck(bundle, tun.data, n, &bundle->filter.in, NULL, NULL); if (pri >= 0) { n += sz - sizeof tun.data; write(bundle->dev.fd, data, n); @@ -591,7 +592,7 @@ bundle_DescriptorRead(struct fdescriptor *d, struct bundle *bundle, * Note, we must be in AUTO mode :-/ otherwise our interface should * *not* be UP and we can't receive data */ - pri = PacketCheck(bundle, tun.data, n, &bundle->filter.dial, NULL); + pri = PacketCheck(bundle, tun.data, n, &bundle->filter.dial, NULL, NULL); if (pri >= 0) bundle_Open(bundle, NULL, PHYS_AUTO, 0); else @@ -605,9 +606,13 @@ bundle_DescriptorRead(struct fdescriptor *d, struct bundle *bundle, return; } - pri = PacketCheck(bundle, tun.data, n, &bundle->filter.out, NULL); - if (pri >= 0) - ip_Enqueue(&bundle->ncp.ipcp, pri, tun.data, n); + secs = 0; + pri = PacketCheck(bundle, tun.data, n, &bundle->filter.out, NULL, &secs); + if (pri >= 0) { + /* Prepend the number of seconds timeout given in the filter */ + tun.header.timeout = secs; + ip_Enqueue(&bundle->ncp.ipcp, pri, (char *)&tun, n + sizeof tun.header); + } } } @@ -1246,18 +1251,22 @@ bundle_IdleTimeout(void *v) * close LCP and link. */ void -bundle_StartIdleTimer(struct bundle *bundle) +bundle_StartIdleTimer(struct bundle *bundle, unsigned secs) { timer_Stop(&bundle->idle.timer); if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL)) != bundle->phys_type.open && bundle->cfg.idle.timeout) { - int secs; + time_t now = time(NULL); + + if (secs == 0) + secs = bundle->cfg.idle.timeout; - secs = bundle->cfg.idle.timeout; + /* We want at least `secs' */ if (bundle->cfg.idle.min_timeout > secs && bundle->upat) { - int up = time(NULL) - bundle->upat; + int up = now - bundle->upat; if ((long long)bundle->cfg.idle.min_timeout - up > (long long)secs) + /* Only increase from the current `remaining' value */ secs = bundle->cfg.idle.min_timeout - up; } bundle->idle.timer.func = bundle_IdleTimeout; @@ -1265,7 +1274,7 @@ bundle_StartIdleTimer(struct bundle *bundle) bundle->idle.timer.load = secs * SECTICKS; bundle->idle.timer.arg = bundle; timer_Start(&bundle->idle.timer); - bundle->idle.done = time(NULL) + secs; + bundle->idle.done = now + secs; } } @@ -1276,7 +1285,7 @@ bundle_SetIdleTimer(struct bundle *bundle, int timeout, int min_timeout) if (min_timeout >= 0) bundle->cfg.idle.min_timeout = min_timeout; if (bundle_LinkIsUp(bundle)) - bundle_StartIdleTimer(bundle); + bundle_StartIdleTimer(bundle, 0); } void diff --git a/usr.sbin/ppp/ppp/bundle.h b/usr.sbin/ppp/ppp/bundle.h index 6f5d131fdad..37b793a0efc 100644 --- a/usr.sbin/ppp/ppp/bundle.h +++ b/usr.sbin/ppp/ppp/bundle.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: bundle.h,v 1.16 2000/07/07 14:47:54 brian Exp $ + * $OpenBSD: bundle.h,v 1.17 2000/07/11 22:13:02 brian Exp $ */ #define PHASE_DEAD 0 /* Link is dead */ @@ -158,7 +158,7 @@ extern void bundle_LinkClosed(struct bundle *, struct datalink *); extern int bundle_ShowLinks(struct cmdargs const *); extern int bundle_ShowStatus(struct cmdargs const *); -extern void bundle_StartIdleTimer(struct bundle *); +extern void bundle_StartIdleTimer(struct bundle *, unsigned secs); extern void bundle_SetIdleTimer(struct bundle *, int, int); extern void bundle_StopIdleTimer(struct bundle *); extern int bundle_IsDead(struct bundle *); diff --git a/usr.sbin/ppp/ppp/filter.c b/usr.sbin/ppp/ppp/filter.c index fdc4628f9c9..5c2fe6dd241 100644 --- a/usr.sbin/ppp/ppp/filter.c +++ b/usr.sbin/ppp/ppp/filter.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $OpenBSD: filter.c,v 1.15 2000/03/30 10:46:18 brian Exp $ + * $OpenBSD: filter.c,v 1.16 2000/07/11 22:13:03 brian Exp $ * * TODO: Should send ICMP error message when we discard packets. */ @@ -468,6 +468,11 @@ Parse(struct ipcp *ipcp, int argc, char const *const *argv, argv++; } + if (argc >= 2 && strcmp(argv[argc - 2], "timeout") == 0) { + filterdata.timeout = strtoul(argv[argc - 1], NULL, 10); + argc -= 2; + } + val = 1; filterdata.f_proto = proto; @@ -587,6 +592,8 @@ doShowFilter(struct filterent *fp, struct prompt *prompt) if (fp->f_finrst) prompt_Printf(prompt, " finrst"); } + if (fp->timeout != 0) + prompt_Printf(prompt, " timeout %u", fp->timeout); prompt_Printf(prompt, "\n"); } } diff --git a/usr.sbin/ppp/ppp/filter.h b/usr.sbin/ppp/ppp/filter.h index 88c6c638af3..956711ad7f1 100644 --- a/usr.sbin/ppp/ppp/filter.h +++ b/usr.sbin/ppp/ppp/filter.h @@ -15,7 +15,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $OpenBSD: filter.h,v 1.10 2000/03/19 10:33:33 brian Exp $ + * $OpenBSD: filter.h,v 1.11 2000/07/11 22:13:03 brian Exp $ * * TODO: */ @@ -75,6 +75,7 @@ struct filterent { struct in_range f_dst; /* Destination address and mask */ u_short f_srcport; /* Source port, compared with f_srcop */ u_short f_dstport; /* Destination port, compared with f_dstop */ + unsigned timeout; /* Keep alive value for passed packet */ }; #define MAXFILTERS 40 /* in each filter set */ diff --git a/usr.sbin/ppp/ppp/ip.c b/usr.sbin/ppp/ppp/ip.c index 4ed89f61874..30efdce85fe 100644 --- a/usr.sbin/ppp/ppp/ip.c +++ b/usr.sbin/ppp/ppp/ip.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $OpenBSD: ip.c,v 1.24 2000/07/07 14:47:54 brian Exp $ + * $OpenBSD: ip.c,v 1.25 2000/07/11 22:13:03 brian Exp $ * * TODO: * o Return ICMP message for filterd packet @@ -139,13 +139,13 @@ PortMatch(int op, u_short pport, u_short rport) { switch (op) { case OP_EQ: - return (pport == rport); + return pport == rport; case OP_GT: - return (pport > rport); + return pport > rport; case OP_LT: - return (pport < rport); + return pport < rport; default: - return (0); + return 0; } } @@ -158,7 +158,7 @@ PortMatch(int op, u_short pport, u_short rport) * must not attempt to over-write it. */ static int -FilterCheck(const struct ip *pip, const struct filter *filter) +FilterCheck(const struct ip *pip, const struct filter *filter, unsigned *psecs) { int gotinfo; /* true if IP payload decoded */ int cproto; /* P_* protocol type if (gotinfo) */ @@ -172,20 +172,22 @@ FilterCheck(const struct ip *pip, const struct filter *filter) char dbuff[100]; if (fp->f_action == A_NONE) - return (0); /* No rule is given. Permit this packet */ + return 0; /* No rule is given. Permit this packet */ - /* Deny any packet fragment that tries to over-write the header. + /* + * Deny any packet fragment that tries to over-write the header. * Since we no longer have the real header available, punt on the * largest normal header - 20 bytes for TCP without options, rounded * up to the next possible fragment boundary. Since the smallest * `legal' MTU is 576, and the smallest recommended MTU is 296, any - * fragmentation within this range is dubious at best */ + * fragmentation within this range is dubious at best + */ len = ntohs(pip->ip_off) & IP_OFFMASK; /* fragment offset */ if (len > 0) { /* Not first fragment within datagram */ if (len < (24 >> 3)) /* don't allow fragment to over-write header */ - return (1); + return 1; /* permit fragments on in and out filter */ - return (!filter->fragok); + return !filter->fragok; } cproto = gotinfo = estab = syn = finrst = didname = 0; @@ -204,142 +206,142 @@ FilterCheck(const struct ip *pip, const struct filter *filter) match = 0; if (!((pip->ip_src.s_addr ^ fp->f_src.ipaddr.s_addr) & - fp->f_src.mask.s_addr) && - !((pip->ip_dst.s_addr ^ fp->f_dst.ipaddr.s_addr) & - fp->f_dst.mask.s_addr)) { + fp->f_src.mask.s_addr) && + !((pip->ip_dst.s_addr ^ fp->f_dst.ipaddr.s_addr) & + fp->f_dst.mask.s_addr)) { if (fp->f_proto != P_NONE) { - if (!gotinfo) { - const char *ptop = (const char *) pip + (pip->ip_hl << 2); - const struct tcphdr *th; - const struct udphdr *uh; - const struct icmp *ih; - int datalen; /* IP datagram length */ - - datalen = ntohs(pip->ip_len) - (pip->ip_hl << 2); - switch (pip->ip_p) { - case IPPROTO_ICMP: - cproto = P_ICMP; - if (datalen < 8) /* ICMP must be at least 8 octets */ - return (1); - ih = (const struct icmp *) ptop; - sport = ih->icmp_type; - estab = syn = finrst = -1; - if (log_IsKept(LogDEBUG)) - snprintf(dbuff, sizeof dbuff, "sport = %d", sport); - break; - case IPPROTO_IGMP: - cproto = P_IGMP; - if (datalen < 8) /* IGMP uses 8-octet messages */ - return (1); - estab = syn = finrst = -1; - sport = ntohs(0); - break; + if (!gotinfo) { + const char *ptop = (const char *) pip + (pip->ip_hl << 2); + const struct tcphdr *th; + const struct udphdr *uh; + const struct icmp *ih; + int datalen; /* IP datagram length */ + + datalen = ntohs(pip->ip_len) - (pip->ip_hl << 2); + switch (pip->ip_p) { + case IPPROTO_ICMP: + cproto = P_ICMP; + if (datalen < 8) /* ICMP must be at least 8 octets */ + return 1; + ih = (const struct icmp *) ptop; + sport = ih->icmp_type; + estab = syn = finrst = -1; + if (log_IsKept(LogDEBUG)) + snprintf(dbuff, sizeof dbuff, "sport = %d", sport); + break; + case IPPROTO_IGMP: + cproto = P_IGMP; + if (datalen < 8) /* IGMP uses 8-octet messages */ + return 1; + estab = syn = finrst = -1; + sport = ntohs(0); + break; #ifdef IPPROTO_GRE case IPPROTO_GRE: cproto = P_GRE; if (datalen < 2) /* GRE uses 2-octet+ messages */ - return (1); + return 1; estab = syn = finrst = -1; sport = ntohs(0); break; #endif #ifdef IPPROTO_OSPFIGP - case IPPROTO_OSPFIGP: - cproto = P_OSPF; - if (datalen < 8) /* IGMP uses 8-octet messages */ - return (1); - estab = syn = finrst = -1; - sport = ntohs(0); - break; + case IPPROTO_OSPFIGP: + cproto = P_OSPF; + if (datalen < 8) /* IGMP uses 8-octet messages */ + return 1; + estab = syn = finrst = -1; + sport = ntohs(0); + break; #endif - case IPPROTO_UDP: - case IPPROTO_IPIP: - cproto = P_UDP; - if (datalen < 8) /* UDP header is 8 octets */ - return (1); - uh = (const struct udphdr *) ptop; - sport = ntohs(uh->uh_sport); - dport = ntohs(uh->uh_dport); - estab = syn = finrst = -1; - if (log_IsKept(LogDEBUG)) - snprintf(dbuff, sizeof dbuff, "sport = %d, dport = %d", - sport, dport); - break; - case IPPROTO_TCP: - cproto = P_TCP; - th = (const struct tcphdr *) ptop; - /* TCP headers are variable length. The following code - * ensures that the TCP header length isn't de-referenced if - * the datagram is too short - */ - if (datalen < 20 || datalen < (th->th_off << 2)) - return (1); - sport = ntohs(th->th_sport); - dport = ntohs(th->th_dport); - estab = (th->th_flags & TH_ACK); - syn = (th->th_flags & TH_SYN); - finrst = (th->th_flags & (TH_FIN|TH_RST)); - if (log_IsKept(LogDEBUG)) { - if (!estab) - snprintf(dbuff, sizeof dbuff, - "flags = %02x, sport = %d, dport = %d", - th->th_flags, sport, dport); - else - *dbuff = '\0'; - } - break; - default: - return (1); /* We'll block unknown type of packet */ - } - - if (log_IsKept(LogDEBUG)) { - if (estab != -1) { - len = strlen(dbuff); - snprintf(dbuff + len, sizeof dbuff - len, - ", estab = %d, syn = %d, finrst = %d", - estab, syn, finrst); - } - log_Printf(LogDEBUG, " Filter: proto = %s, %s\n", - filter_Proto2Nam(cproto), dbuff); - } - gotinfo = 1; - } - if (log_IsKept(LogDEBUG)) { - if (fp->f_srcop != OP_NONE) { - snprintf(dbuff, sizeof dbuff, ", src %s %d", - filter_Op2Nam(fp->f_srcop), fp->f_srcport); - len = strlen(dbuff); - } else - len = 0; - if (fp->f_dstop != OP_NONE) { - snprintf(dbuff + len, sizeof dbuff - len, - ", dst %s %d", filter_Op2Nam(fp->f_dstop), - fp->f_dstport); - } else if (!len) - *dbuff = '\0'; - - log_Printf(LogDEBUG, " rule = %d: Address match, " - "check against proto %s%s, action = %s\n", - n, filter_Proto2Nam(fp->f_proto), - dbuff, filter_Action2Nam(fp->f_action)); - } - - if (cproto == fp->f_proto) { - if ((fp->f_srcop == OP_NONE || - PortMatch(fp->f_srcop, sport, fp->f_srcport)) && - (fp->f_dstop == OP_NONE || - PortMatch(fp->f_dstop, dport, fp->f_dstport)) && - (fp->f_estab == 0 || estab) && - (fp->f_syn == 0 || syn) && - (fp->f_finrst == 0 || finrst)) { - match = 1; - } - } + case IPPROTO_UDP: + case IPPROTO_IPIP: + cproto = P_UDP; + if (datalen < 8) /* UDP header is 8 octets */ + return 1; + uh = (const struct udphdr *) ptop; + sport = ntohs(uh->uh_sport); + dport = ntohs(uh->uh_dport); + estab = syn = finrst = -1; + if (log_IsKept(LogDEBUG)) + snprintf(dbuff, sizeof dbuff, "sport = %d, dport = %d", + sport, dport); + break; + case IPPROTO_TCP: + cproto = P_TCP; + th = (const struct tcphdr *) ptop; + /* TCP headers are variable length. The following code + * ensures that the TCP header length isn't de-referenced if + * the datagram is too short + */ + if (datalen < 20 || datalen < (th->th_off << 2)) + return 1; + sport = ntohs(th->th_sport); + dport = ntohs(th->th_dport); + estab = (th->th_flags & TH_ACK); + syn = (th->th_flags & TH_SYN); + finrst = (th->th_flags & (TH_FIN|TH_RST)); + if (log_IsKept(LogDEBUG)) { + if (!estab) + snprintf(dbuff, sizeof dbuff, + "flags = %02x, sport = %d, dport = %d", + th->th_flags, sport, dport); + else + *dbuff = '\0'; + } + break; + default: + return 1; /* We'll block unknown type of packet */ + } + + if (log_IsKept(LogDEBUG)) { + if (estab != -1) { + len = strlen(dbuff); + snprintf(dbuff + len, sizeof dbuff - len, + ", estab = %d, syn = %d, finrst = %d", + estab, syn, finrst); + } + log_Printf(LogDEBUG, " Filter: proto = %s, %s\n", + filter_Proto2Nam(cproto), dbuff); + } + gotinfo = 1; + } + if (log_IsKept(LogDEBUG)) { + if (fp->f_srcop != OP_NONE) { + snprintf(dbuff, sizeof dbuff, ", src %s %d", + filter_Op2Nam(fp->f_srcop), fp->f_srcport); + len = strlen(dbuff); + } else + len = 0; + if (fp->f_dstop != OP_NONE) { + snprintf(dbuff + len, sizeof dbuff - len, + ", dst %s %d", filter_Op2Nam(fp->f_dstop), + fp->f_dstport); + } else if (!len) + *dbuff = '\0'; + + log_Printf(LogDEBUG, " rule = %d: Address match, " + "check against proto %s%s, action = %s\n", + n, filter_Proto2Nam(fp->f_proto), + dbuff, filter_Action2Nam(fp->f_action)); + } + + if (cproto == fp->f_proto) { + if ((fp->f_srcop == OP_NONE || + PortMatch(fp->f_srcop, sport, fp->f_srcport)) && + (fp->f_dstop == OP_NONE || + PortMatch(fp->f_dstop, dport, fp->f_dstport)) && + (fp->f_estab == 0 || estab) && + (fp->f_syn == 0 || syn) && + (fp->f_finrst == 0 || finrst)) { + match = 1; + } + } } else { - /* Address is matched and no protocol specified. Make a decision. */ - log_Printf(LogDEBUG, " rule = %d: Address match, action = %s\n", n, - filter_Action2Nam(fp->f_action)); - match = 1; + /* Address is matched and no protocol specified. Make a decision. */ + log_Printf(LogDEBUG, " rule = %d: Address match, action = %s\n", n, + filter_Action2Nam(fp->f_action)); + match = 1; } } else log_Printf(LogDEBUG, " rule = %d: Address mismatch\n", n); @@ -347,15 +349,20 @@ FilterCheck(const struct ip *pip, const struct filter *filter) if (match != fp->f_invert) { /* Take specified action */ if (fp->f_action < A_NONE) - fp = &filter->rule[n = fp->f_action]; + fp = &filter->rule[n = fp->f_action]; else - return (fp->f_action != A_PERMIT); + if (fp->f_action == A_PERMIT) { + if (psecs != NULL) + *psecs = fp->timeout; + return 0; + } else + return 1; } else { n++; fp++; } } - return (1); /* No rule is mached. Deny this packet */ + return 1; /* No rule is mached. Deny this packet */ } #ifdef notdef @@ -393,7 +400,7 @@ ip_LogDNS(const struct udphdr *uh, const char *direction) len -= sizeof header; while (pktptr < (const u_short *)ptr) { - *hptr++ = ntohs(*pktptr); /* Careful of macro side-effects ! */ + *hptr++ = ntohs(*pktptr); /* Careful of macro side-effects ! */ pktptr++; } @@ -431,7 +438,7 @@ ip_LogDNS(const struct udphdr *uh, const char *direction) */ int PacketCheck(struct bundle *bundle, unsigned char *cp, int nb, - struct filter *filter, const char *prefix) + struct filter *filter, const char *prefix, unsigned *psecs) { static const char *const TcpFlags[] = { "FIN", "SYN", "RST", "PSH", "ACK", "URG" @@ -469,10 +476,10 @@ PacketCheck(struct bundle *bundle, unsigned char *cp, int nb, len = ntohs(pip->ip_len) - (pip->ip_hl << 2) - sizeof *icmph; icmph = (struct icmp *) ptop; snprintf(logbuf + loglen, sizeof logbuf - loglen, - "ICMP: %s:%d ---> ", inet_ntoa(pip->ip_src), icmph->icmp_type); + "ICMP: %s:%d ---> ", inet_ntoa(pip->ip_src), icmph->icmp_type); loglen += strlen(logbuf + loglen); snprintf(logbuf + loglen, sizeof logbuf - loglen, - "%s:%d (%d/%d)", inet_ntoa(pip->ip_dst), icmph->icmp_type, + "%s:%d (%d/%d)", inet_ntoa(pip->ip_dst), icmph->icmp_type, len, nb); loglen += strlen(logbuf + loglen); } @@ -491,11 +498,11 @@ PacketCheck(struct bundle *bundle, unsigned char *cp, int nb, if (logit && loglen < sizeof logbuf) { len = ntohs(pip->ip_len) - (pip->ip_hl << 2) - sizeof *uh; snprintf(logbuf + loglen, sizeof logbuf - loglen, - "UDP: %s:%d ---> ", inet_ntoa(pip->ip_src), ntohs(uh->uh_sport)); + "UDP: %s:%d ---> ", inet_ntoa(pip->ip_src), ntohs(uh->uh_sport)); loglen += strlen(logbuf + loglen); snprintf(logbuf + loglen, sizeof logbuf - loglen, - "%s:%d (%d/%d)", inet_ntoa(pip->ip_dst), ntohs(uh->uh_dport), - len, nb); + "%s:%d (%d/%d)", inet_ntoa(pip->ip_dst), ntohs(uh->uh_dport), + len, nb); loglen += strlen(logbuf + loglen); } @@ -512,7 +519,7 @@ PacketCheck(struct bundle *bundle, unsigned char *cp, int nb, snprintf(logbuf + loglen, sizeof logbuf - loglen, " contains "); result = PacketCheck(bundle, ptop + sizeof *uh + 4, nb - (ptop - cp) - sizeof *uh - 4, filter, - logbuf); + logbuf, psecs); if (result != -2) return result; type = "IP"; @@ -558,10 +565,10 @@ PacketCheck(struct bundle *bundle, unsigned char *cp, int nb, if (logit && loglen < sizeof logbuf) { len = ntohs(pip->ip_len) - (pip->ip_hl << 2); snprintf(logbuf + loglen, sizeof logbuf - loglen, - "OSPF: %s ---> ", inet_ntoa(pip->ip_src)); + "OSPF: %s ---> ", inet_ntoa(pip->ip_src)); loglen += strlen(logbuf + loglen); snprintf(logbuf + loglen, sizeof logbuf - loglen, - "%s (%d/%d)", inet_ntoa(pip->ip_dst), len, nb); + "%s (%d/%d)", inet_ntoa(pip->ip_dst), len, nb); loglen += strlen(logbuf + loglen); } break; @@ -571,10 +578,11 @@ PacketCheck(struct bundle *bundle, unsigned char *cp, int nb, if (logit && loglen < sizeof logbuf) { uh = (struct udphdr *) ptop; snprintf(logbuf + loglen, sizeof logbuf - loglen, - "IPIP: %s:%d ---> ", inet_ntoa(pip->ip_src), ntohs(uh->uh_sport)); + "IPIP: %s:%d ---> ", inet_ntoa(pip->ip_src), + ntohs(uh->uh_sport)); loglen += strlen(logbuf + loglen); snprintf(logbuf + loglen, sizeof logbuf - loglen, - "%s:%d", inet_ntoa(pip->ip_dst), ntohs(uh->uh_dport)); + "%s:%d", inet_ntoa(pip->ip_dst), ntohs(uh->uh_dport)); loglen += strlen(logbuf + loglen); } break; @@ -583,10 +591,11 @@ PacketCheck(struct bundle *bundle, unsigned char *cp, int nb, if (logit && loglen < sizeof logbuf) { uh = (struct udphdr *) ptop; snprintf(logbuf + loglen, sizeof logbuf - loglen, - "IGMP: %s:%d ---> ", inet_ntoa(pip->ip_src), ntohs(uh->uh_sport)); + "IGMP: %s:%d ---> ", inet_ntoa(pip->ip_src), + ntohs(uh->uh_sport)); loglen += strlen(logbuf + loglen); snprintf(logbuf + loglen, sizeof logbuf - loglen, - "%s:%d", inet_ntoa(pip->ip_dst), ntohs(uh->uh_dport)); + "%s:%d", inet_ntoa(pip->ip_dst), ntohs(uh->uh_dport)); loglen += strlen(logbuf + loglen); } break; @@ -604,33 +613,33 @@ PacketCheck(struct bundle *bundle, unsigned char *cp, int nb, if (logit && loglen < sizeof logbuf) { len = ntohs(pip->ip_len) - (pip->ip_hl << 2) - (th->th_off << 2); snprintf(logbuf + loglen, sizeof logbuf - loglen, - "TCP: %s:%d ---> ", inet_ntoa(pip->ip_src), ntohs(th->th_sport)); + "TCP: %s:%d ---> ", inet_ntoa(pip->ip_src), ntohs(th->th_sport)); loglen += strlen(logbuf + loglen); snprintf(logbuf + loglen, sizeof logbuf - loglen, - "%s:%d", inet_ntoa(pip->ip_dst), ntohs(th->th_dport)); + "%s:%d", inet_ntoa(pip->ip_dst), ntohs(th->th_dport)); loglen += strlen(logbuf + loglen); n = 0; for (mask = TH_FIN; mask != 0x40; mask <<= 1) { - if (th->th_flags & mask) { - snprintf(logbuf + loglen, sizeof logbuf - loglen, " %s", TcpFlags[n]); - loglen += strlen(logbuf + loglen); - } - n++; + if (th->th_flags & mask) { + snprintf(logbuf + loglen, sizeof logbuf - loglen, " %s", TcpFlags[n]); + loglen += strlen(logbuf + loglen); + } + n++; } snprintf(logbuf + loglen, sizeof logbuf - loglen, - " seq:%lx ack:%lx (%d/%d)", - (u_long)ntohl(th->th_seq), (u_long)ntohl(th->th_ack), len, nb); + " seq:%lx ack:%lx (%d/%d)", + (u_long)ntohl(th->th_seq), (u_long)ntohl(th->th_ack), len, nb); loglen += strlen(logbuf + loglen); if ((th->th_flags & TH_SYN) && nb > 40) { - u_short *sp; - - ptop += 20; - sp = (u_short *) ptop; - if (ntohs(sp[0]) == 0x0204) { - snprintf(logbuf + loglen, sizeof logbuf - loglen, - " MSS = %d", ntohs(sp[1])); - loglen += strlen(logbuf + loglen); - } + u_short *sp; + + ptop += 20; + sp = (u_short *) ptop; + if (ntohs(sp[0]) == 0x0204) { + snprintf(logbuf + loglen, sizeof logbuf - loglen, + " MSS = %d", ntohs(sp[1])); + loglen += strlen(logbuf + loglen); + } } } break; @@ -640,7 +649,7 @@ PacketCheck(struct bundle *bundle, unsigned char *cp, int nb, return -2; } - if (filter && FilterCheck(pip, filter)) { + if (filter && FilterCheck(pip, filter, psecs)) { if (logit) log_Printf(LogTCPIP, "%s - BLOCKED\n", logbuf); #ifdef notdef @@ -651,10 +660,23 @@ PacketCheck(struct bundle *bundle, unsigned char *cp, int nb, } else { /* Check Keep Alive filter */ if (logit && log_IsKept(LogTCPIP)) { - if (filter && FilterCheck(pip, &bundle->filter.alive)) + unsigned alivesecs; + + alivesecs = 0; + if (filter && FilterCheck(pip, &bundle->filter.alive, &alivesecs)) log_Printf(LogTCPIP, "%s - NO KEEPALIVE\n", logbuf); - else - log_Printf(LogTCPIP, "%s\n", logbuf); + else if (psecs != NULL) { + if(*psecs == 0) + *psecs = alivesecs; + if (*psecs) { + if (*psecs != alivesecs) + log_Printf(LogTCPIP, "%s - (timeout = %d / ALIVE = %d secs)\n", + logbuf, *psecs, alivesecs); + else + log_Printf(LogTCPIP, "%s - (timeout = %d secs)\n", logbuf, *psecs); + } else + log_Printf(LogTCPIP, "%s\n", logbuf); + } } result = pri; } @@ -672,6 +694,7 @@ ip_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) struct tun_data tun; struct ip *pip; char *data; + unsigned secs, alivesecs; if (bundle->ncp.ipcp.fsm.state != ST_OPENED) { log_Printf(LogWARN, "ip_Input: IPCP not open - packet dropped\n"); @@ -689,17 +712,22 @@ ip_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) } mbuf_Read(bp, tun.data, nb); - if (PacketCheck(bundle, tun.data, nb, &bundle->filter.in, NULL) < 0) + secs = 0; + if (PacketCheck(bundle, tun.data, nb, &bundle->filter.in, NULL, &secs) < 0) return NULL; pip = (struct ip *)tun.data; - if (!FilterCheck(pip, &bundle->filter.alive)) - bundle_StartIdleTimer(bundle); + alivesecs = 0; + if (!FilterCheck(pip, &bundle->filter.alive, &alivesecs)) { + if (secs == 0) + secs = alivesecs; + bundle_StartIdleTimer(bundle, secs); + } ipcp_AddInOctets(&bundle->ncp.ipcp, nb); if (bundle->dev.header) { - tun.family = htonl(AF_INET); + tun.header.family = htonl(AF_INET); nb += sizeof tun - sizeof tun.data; data = (char *)&tun; } else @@ -770,6 +798,8 @@ ip_PushPacket(struct link *l, struct bundle *bundle) struct mbuf *bp; struct ip *pip; int m_len; + u_int32_t secs = 0; + unsigned alivesecs = 0; if (ipcp->fsm.state != ST_OPENED) return 0; @@ -777,11 +807,16 @@ ip_PushPacket(struct link *l, struct bundle *bundle) queue = ipcp->Queue + IPCP_QUEUES(ipcp) - 1; do { if (queue->top) { - bp = m_pullup(m_dequeue(queue)); + bp = m_dequeue(queue); + bp = mbuf_Read(bp, &secs, sizeof secs); + bp = m_pullup(bp); m_len = m_length(bp); pip = (struct ip *)MBUF_CTOP(bp); - if (!FilterCheck(pip, &bundle->filter.alive)) - bundle_StartIdleTimer(bundle); + if (!FilterCheck(pip, &bundle->filter.alive, &alivesecs)) { + if (secs == 0) + secs = alivesecs; + bundle_StartIdleTimer(bundle, secs); + } link_PushPacket(l, bp, bundle, 0, PROTO_IP); ipcp_AddOutOctets(ipcp, m_len); return 1; diff --git a/usr.sbin/ppp/ppp/ip.h b/usr.sbin/ppp/ppp/ip.h index 3e366d693fa..46bffb005bf 100644 --- a/usr.sbin/ppp/ppp/ip.h +++ b/usr.sbin/ppp/ppp/ip.h @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $OpenBSD: ip.h,v 1.6 2000/07/07 14:47:54 brian Exp $ + * $OpenBSD: ip.h,v 1.7 2000/07/11 22:13:03 brian Exp $ * */ @@ -28,7 +28,7 @@ struct bundle; extern int ip_PushPacket(struct link *, struct bundle *); extern int PacketCheck(struct bundle *, unsigned char *, int, struct filter *, - const char *); + const char *, unsigned *secs); extern void ip_Enqueue(struct ipcp *, int, char *, int); extern struct mbuf *ip_Input(struct bundle *, struct link *, struct mbuf *); extern void ip_DeleteQueue(struct ipcp *); diff --git a/usr.sbin/ppp/ppp/nat_cmd.c b/usr.sbin/ppp/ppp/nat_cmd.c index ef9e1f5877b..0d7a797cf67 100644 --- a/usr.sbin/ppp/ppp/nat_cmd.c +++ b/usr.sbin/ppp/ppp/nat_cmd.c @@ -2,7 +2,7 @@ * The code in this file was written by Eivind Eklund <perhaps@yes.no>, * who places it in the public domain without restriction. * - * $OpenBSD: nat_cmd.c,v 1.13 2000/07/07 14:47:54 brian Exp $ + * $OpenBSD: nat_cmd.c,v 1.14 2000/07/11 22:13:03 brian Exp $ */ #include <sys/param.h> @@ -423,7 +423,7 @@ nat_LayerPull(struct bundle *bundle, struct link *l, struct mbuf *bp, case PKT_ALIAS_IGNORED: if (log_IsKept(LogTCPIP)) { log_Printf(LogTCPIP, "NAT engine ignored data:\n"); - PacketCheck(bundle, MBUF_CTOP(bp), bp->m_len, NULL, NULL); + PacketCheck(bundle, MBUF_CTOP(bp), bp->m_len, NULL, NULL, NULL); } break; diff --git a/usr.sbin/ppp/ppp/ppp.8 b/usr.sbin/ppp/ppp/ppp.8 index cfabfc65c2d..7032dda7b90 100644 --- a/usr.sbin/ppp/ppp/ppp.8 +++ b/usr.sbin/ppp/ppp/ppp.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ppp.8,v 1.86 2000/07/07 14:47:54 brian Exp $ +.\" $OpenBSD: ppp.8,v 1.87 2000/07/11 22:13:03 brian Exp $ .Dd 20 September 1995 .nr XX \w'\fC00' .Dt PPP 8 @@ -1541,7 +1541,7 @@ set filter .Op estab .Op syn .Op finrst -.Oc +.Oc Op timeout Ar secs .Bl -enum .It .Ar Name @@ -1644,6 +1644,15 @@ flags are only allowed when is set to .Sq tcp , and represent the TH_ACK, TH_SYN and TH_FIN or TH_RST TCP flags respectively. +.It +The timeout value adjusts the current idle timeout to at least +.Ar secs +seconds. +If a timeout is given in the alive filter as well as in the in/out +filter, the in/out value is used. If no timeout is given, the default +timeout (set using +.Ic set timeout +and defaulting to 180 seconds) is used. .El .Pp .It @@ -1651,8 +1660,9 @@ Each filter can hold up to 40 rules, starting from rule 0. The entire rule set is not effective until rule 0 is defined, i.e., the default is to allow everything through. .It -If no rule is matched to a packet, that packet will be discarded -(blocked). +If no rule in a defined set of rules matches a packet, that packet will +be discarded (blocked). +If there are no rules in a given filter, the packet will be permitted. .It It's possible to filter based on the payload of UDP frames where those frames contain a @@ -4385,7 +4395,7 @@ as they travel across the link. .Op estab .Op syn .Op finrst -.Oc +.Oc Op timeout Ar secs .Xc .Nm supports four filter sets. @@ -4410,7 +4420,7 @@ filter specifies packets that are allowed out of the machine. Filtering is done prior to any IP alterations that might be done by the NAT engine on outgoing packets and after any IP alterations that might be done by the NAT engine on incoming packets. -By default all filter sets allow all packets to pass. +By default all empty filter sets allow all packets to pass. Rules are processed in order according to .Ar rule-no (unless skipped by specifying a rule number as the @@ -4425,8 +4435,12 @@ and filters, this means that the packet is dropped. In the case of .Em alive -filters it means that the packet will not reset the idle timer and in -the case of +filters it means that the packet will not reset the idle timer (even if +the +.Ar in Ns No / Ns Ar out +filter has a +.Dq timeout +value) and in the case of .Em dial filters it means that the packet will not trigger a dial. A packet failing to trigger a dial will be dropped rather than queued. diff --git a/usr.sbin/ppp/ppp/tun.h b/usr.sbin/ppp/ppp/tun.h index ac83e1d7765..cdd0f30b340 100644 --- a/usr.sbin/ppp/ppp/tun.h +++ b/usr.sbin/ppp/ppp/tun.h @@ -23,11 +23,14 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: tun.h,v 1.4 2000/02/27 01:38:29 brian Exp $ + * $OpenBSD: tun.h,v 1.5 2000/07/11 22:13:04 brian Exp $ */ struct tun_data { - u_int32_t family; + union { + u_int32_t family; + u_int32_t timeout; + } header; u_char data[MAX_MRU]; }; |