diff options
author | brian <brian@cvs.openbsd.org> | 2000-07-07 14:47:55 +0000 |
---|---|---|
committer | brian <brian@cvs.openbsd.org> | 2000-07-07 14:47:55 +0000 |
commit | cac590774c6243713f544d2ad4b7b9e4d79d8232 (patch) | |
tree | d4c34fe95c9ceb8c62ab109a77462673ff083a11 /usr.sbin/ppp | |
parent | 87c1d2af938e8acac68a66db936cbdef2a42fe61 (diff) |
o Log the (payload/size) of all packet types, not just TCP packets
o If the new ``filter-decapsulation'' is enabled, delve into UDP packets
that contain 0xff 0x03 as the first two bytes, and if we recognise it
as PROTO_IP, decapsulate it for the purpose of filter checking.
If we recognise it as PROTO_<anything else> mention this for logging
purposes only.
This change is aimed at people running PPPoUDP where the UDP traffic is
being sent over another PPP link. It's desireable to have the top level
link connected all the time, but to have the bottom level link capable
of decapsulating the traffic and comparing the payload against the filters,
thus allowing ``set filter dial ...'' to work in tunnelled environments.
The caveat here is that the top ppp cannot employ any compression layers
without making the data unreadable for the bottom ppp. ``disable deflate
pred1 vj'' and ``deny deflate pred1 vj'' is suggested.
Diffstat (limited to 'usr.sbin/ppp')
-rw-r--r-- | usr.sbin/ppp/ppp/bundle.c | 27 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/bundle.h | 23 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/command.c | 9 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/ip.c | 70 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/ip.h | 5 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/nat_cmd.c | 4 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/ppp.8 | 34 |
7 files changed, 132 insertions, 40 deletions
diff --git a/usr.sbin/ppp/ppp/bundle.c b/usr.sbin/ppp/ppp/bundle.c index 09ba7230cf5..59748dbdbe8 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.39 2000/06/23 09:47:30 brian Exp $ + * $OpenBSD: bundle.c,v 1.40 2000/07/07 14:47:53 brian Exp $ */ #include <sys/param.h> @@ -570,7 +570,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); + pri = PacketCheck(bundle, tun.data, n, &bundle->filter.in, NULL); if (pri >= 0) { n += sz - sizeof tun.data; write(bundle->dev.fd, data, n); @@ -591,7 +591,8 @@ 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 */ - if ((pri = PacketCheck(bundle, tun.data, n, &bundle->filter.dial)) >= 0) + pri = PacketCheck(bundle, tun.data, n, &bundle->filter.dial, NULL); + if (pri > 0) bundle_Open(bundle, NULL, PHYS_AUTO, 0); else /* @@ -604,7 +605,7 @@ bundle_DescriptorRead(struct fdescriptor *d, struct bundle *bundle, return; } - pri = PacketCheck(bundle, tun.data, n, &bundle->filter.out); + pri = PacketCheck(bundle, tun.data, n, &bundle->filter.out, NULL); if (pri >= 0) ip_Enqueue(&bundle->ncp.ipcp, pri, tun.data, n); } @@ -1206,21 +1207,23 @@ bundle_ShowStatus(struct cmdargs const *arg) prompt_Printf(arg->prompt, " Sticky Routes: %-20.20s", optval(arg->bundle, OPT_SROUTES)); - prompt_Printf(arg->prompt, " ID check: %s\n", + prompt_Printf(arg->prompt, " Filter Decap: %s\n", + optval(arg->bundle, OPT_FILTERDECAP)); + prompt_Printf(arg->prompt, " ID check: %-20.20s", optval(arg->bundle, OPT_IDCHECK)); - prompt_Printf(arg->prompt, " Keep-Session: %-20.20s", + prompt_Printf(arg->prompt, " Keep-Session: %s\n", optval(arg->bundle, OPT_KEEPSESSION)); - prompt_Printf(arg->prompt, " Loopback: %s\n", + prompt_Printf(arg->prompt, " Loopback: %-20.20s", optval(arg->bundle, OPT_LOOPBACK)); - prompt_Printf(arg->prompt, " PasswdAuth: %-20.20s", + prompt_Printf(arg->prompt, " PasswdAuth: %s\n", optval(arg->bundle, OPT_PASSWDAUTH)); - prompt_Printf(arg->prompt, " Proxy: %s\n", + prompt_Printf(arg->prompt, " Proxy: %-20.20s", optval(arg->bundle, OPT_PROXY)); - prompt_Printf(arg->prompt, " Proxyall: %-20.20s", + prompt_Printf(arg->prompt, " Proxyall: %s\n", optval(arg->bundle, OPT_PROXYALL)); - prompt_Printf(arg->prompt, " Throughput: %s\n", + prompt_Printf(arg->prompt, " Throughput: %-20.20s", optval(arg->bundle, OPT_THROUGHPUT)); - prompt_Printf(arg->prompt, " Utmp Logging: %-20.20s", + prompt_Printf(arg->prompt, " Utmp Logging: %s\n", optval(arg->bundle, OPT_UTMP)); prompt_Printf(arg->prompt, " Iface-Alias: %s\n", optval(arg->bundle, OPT_IFACEALIAS)); diff --git a/usr.sbin/ppp/ppp/bundle.h b/usr.sbin/ppp/ppp/bundle.h index d426269dbeb..6f5d131fdad 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.15 2000/06/13 09:57:50 brian Exp $ + * $OpenBSD: bundle.h,v 1.16 2000/07/07 14:47:54 brian Exp $ */ #define PHASE_DEAD 0 /* Link is dead */ @@ -33,16 +33,17 @@ #define PHASE_TERMINATE 4 /* Terminating link */ /* cfg.opt bit settings */ -#define OPT_IDCHECK 0x0001 -#define OPT_IFACEALIAS 0x0002 -#define OPT_KEEPSESSION 0x0004 -#define OPT_LOOPBACK 0x0008 -#define OPT_PASSWDAUTH 0x0010 -#define OPT_PROXY 0x0020 -#define OPT_PROXYALL 0x0040 -#define OPT_SROUTES 0x0080 -#define OPT_THROUGHPUT 0x0100 -#define OPT_UTMP 0x0200 +#define OPT_FILTERDECAP 0x0001 +#define OPT_IDCHECK 0x0002 +#define OPT_IFACEALIAS 0x0004 +#define OPT_KEEPSESSION 0x0008 +#define OPT_LOOPBACK 0x0010 +#define OPT_PASSWDAUTH 0x0020 +#define OPT_PROXY 0x0040 +#define OPT_PROXYALL 0x0080 +#define OPT_SROUTES 0x0100 +#define OPT_THROUGHPUT 0x0200 +#define OPT_UTMP 0x0400 #define MAX_ENDDISC_CLASS 5 diff --git a/usr.sbin/ppp/ppp/command.c b/usr.sbin/ppp/ppp/command.c index 457c0be8275..74a0d164a2e 100644 --- a/usr.sbin/ppp/ppp/command.c +++ b/usr.sbin/ppp/ppp/command.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $OpenBSD: command.c,v 1.43 2000/06/23 09:47:05 brian Exp $ + * $OpenBSD: command.c,v 1.44 2000/07/07 14:47:54 brian Exp $ * */ #include <sys/param.h> @@ -2437,11 +2437,14 @@ NegotiateSet(struct cmdargs const *arg) } static struct cmdtab const NegotiateCommands[] = { + {"filter-decapsulation", NULL, OptSet, LOCAL_AUTH, + "filter on PPPoUDP payloads", "disable|enable", + (const void *)OPT_FILTERDECAP}, {"idcheck", NULL, OptSet, LOCAL_AUTH, "Check FSM reply ids", "disable|enable", (const void *)OPT_IDCHECK}, {"iface-alias", NULL, IfaceAliasOptSet, LOCAL_AUTH, - "retain interface addresses", "disable|enable", - (const void *)OPT_IFACEALIAS}, + "retain interface addresses", "disable|enable", + (const void *)OPT_IFACEALIAS}, {"keep-session", NULL, OptSet, LOCAL_AUTH, "Retain device session leader", "disable|enable", (const void *)OPT_KEEPSESSION}, {"loopback", NULL, OptSet, LOCAL_AUTH, "Loop packets for local iface", diff --git a/usr.sbin/ppp/ppp/ip.c b/usr.sbin/ppp/ppp/ip.c index 2974122d09c..4ed89f61874 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.23 2000/06/13 09:57:51 brian Exp $ + * $OpenBSD: ip.c,v 1.24 2000/07/07 14:47:54 brian Exp $ * * TODO: * o Return ICMP message for filterd packet @@ -430,7 +430,8 @@ ip_LogDNS(const struct udphdr *uh, const char *direction) * For debugging aid. */ int -PacketCheck(struct bundle *bundle, char *cp, int nb, struct filter *filter) +PacketCheck(struct bundle *bundle, unsigned char *cp, int nb, + struct filter *filter, const char *prefix) { static const char *const TcpFlags[] = { "FIN", "SYN", "RST", "PSH", "ACK", "URG" @@ -439,7 +440,7 @@ PacketCheck(struct bundle *bundle, char *cp, int nb, struct filter *filter) struct tcphdr *th; struct udphdr *uh; struct icmp *icmph; - char *ptop; + unsigned char *ptop; int mask, len, n, pri, logit, loglen, result; char logbuf[200]; @@ -452,7 +453,9 @@ PacketCheck(struct bundle *bundle, char *cp, int nb, struct filter *filter) uh = NULL; if (logit && loglen < sizeof logbuf) { - if (filter) + if (prefix) + snprintf(logbuf + loglen, sizeof logbuf - loglen, "%s", prefix); + else if (filter) snprintf(logbuf + loglen, sizeof logbuf - loglen, "%s ", filter->name); else snprintf(logbuf + loglen, sizeof logbuf - loglen, " "); @@ -463,12 +466,14 @@ PacketCheck(struct bundle *bundle, char *cp, int nb, struct filter *filter) switch (pip->ip_p) { case IPPROTO_ICMP: if (logit && loglen < sizeof logbuf) { + 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); loglen += strlen(logbuf + loglen); snprintf(logbuf + loglen, sizeof logbuf - loglen, - "%s:%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); } break; @@ -484,23 +489,65 @@ PacketCheck(struct bundle *bundle, char *cp, int nb, struct filter *filter) pri++; 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)); loglen += strlen(logbuf + loglen); snprintf(logbuf + loglen, sizeof logbuf - loglen, - "%s:%d", inet_ntoa(pip->ip_dst), ntohs(uh->uh_dport)); + "%s:%d (%d/%d)", inet_ntoa(pip->ip_dst), ntohs(uh->uh_dport), + len, nb); loglen += strlen(logbuf + loglen); } + + if (Enabled(bundle, OPT_FILTERDECAP) && + ptop[sizeof *uh] == HDLC_ADDR && ptop[sizeof *uh + 1] == HDLC_UI) { + u_short proto; + const char *type; + + memcpy(&proto, ptop + sizeof *uh + 2, sizeof proto); + type = NULL; + + switch (ntohs(proto)) { + case PROTO_IP: + snprintf(logbuf + loglen, sizeof logbuf - loglen, " contains "); + result = PacketCheck(bundle, ptop + sizeof *uh + 4, + nb - (ptop - cp) - sizeof *uh - 4, filter, + logbuf); + if (result != -2) + return result; + type = "IP"; + break; + + case PROTO_VJUNCOMP: type = "compressed VJ"; break; + case PROTO_VJCOMP: type = "uncompressed VJ"; break; + case PROTO_MP: type = "Multi-link"; break; + case PROTO_ICOMPD: type = "Individual link CCP"; break; + case PROTO_COMPD: type = "CCP"; break; + case PROTO_IPCP: type = "IPCP"; break; + case PROTO_LCP: type = "LCP"; break; + case PROTO_PAP: type = "PAP"; break; + case PROTO_CBCP: type = "CBCP"; break; + case PROTO_LQR: type = "LQR"; break; + case PROTO_CHAP: type = "CHAP"; break; + } + if (type) { + snprintf(logbuf + loglen, sizeof logbuf - loglen, + " - %s data", type); + loglen += strlen(logbuf + loglen); + } + } + break; #ifdef IPPROTO_GRE case IPPROTO_GRE: if (logit && loglen < sizeof logbuf) { + len = ntohs(pip->ip_len) - (pip->ip_hl << 2); snprintf(logbuf + loglen, sizeof logbuf - loglen, "GRE: %s ---> ", inet_ntoa(pip->ip_src)); loglen += strlen(logbuf + loglen); snprintf(logbuf + loglen, sizeof logbuf - loglen, - "%s", inet_ntoa(pip->ip_dst)); + "%s (%d/%d)", inet_ntoa(pip->ip_dst), len, nb); loglen += strlen(logbuf + loglen); } break; @@ -509,11 +556,12 @@ PacketCheck(struct bundle *bundle, char *cp, int nb, struct filter *filter) #ifdef IPPROTO_OSPFIGP case IPPROTO_OSPFIGP: 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)); loglen += strlen(logbuf + loglen); snprintf(logbuf + loglen, sizeof logbuf - loglen, - "%s", inet_ntoa(pip->ip_dst)); + "%s (%d/%d)", inet_ntoa(pip->ip_dst), len, nb); loglen += strlen(logbuf + loglen); } break; @@ -586,6 +634,10 @@ PacketCheck(struct bundle *bundle, char *cp, int nb, struct filter *filter) } } break; + + default: + if (prefix) + return -2; } if (filter && FilterCheck(pip, filter)) { @@ -637,7 +689,7 @@ 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) < 0) + if (PacketCheck(bundle, tun.data, nb, &bundle->filter.in, NULL) < 0) return NULL; pip = (struct ip *)tun.data; diff --git a/usr.sbin/ppp/ppp/ip.h b/usr.sbin/ppp/ppp/ip.h index 9df0a0600ee..3e366d693fa 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.5 2000/02/27 01:38:26 brian Exp $ + * $OpenBSD: ip.h,v 1.6 2000/07/07 14:47:54 brian Exp $ * */ @@ -27,7 +27,8 @@ struct link; struct bundle; extern int ip_PushPacket(struct link *, struct bundle *); -extern int PacketCheck(struct bundle *, char *, int, struct filter *); +extern int PacketCheck(struct bundle *, unsigned char *, int, struct filter *, + const char *); 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 a1814c8a775..ef9e1f5877b 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.12 2000/06/23 09:47:05 brian Exp $ + * $OpenBSD: nat_cmd.c,v 1.13 2000/07/07 14:47:54 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); + PacketCheck(bundle, MBUF_CTOP(bp), bp->m_len, NULL, NULL); } break; diff --git a/usr.sbin/ppp/ppp/ppp.8 b/usr.sbin/ppp/ppp/ppp.8 index 25e72c0e6df..cfabfc65c2d 100644 --- a/usr.sbin/ppp/ppp/ppp.8 +++ b/usr.sbin/ppp/ppp/ppp.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ppp.8,v 1.85 2000/06/23 09:47:05 brian Exp $ +.\" $OpenBSD: ppp.8,v 1.86 2000/07/07 14:47:54 brian Exp $ .Dd 20 September 1995 .nr XX \w'\fC00' .Dt PPP 8 @@ -1654,6 +1654,14 @@ i.e., the default is to allow everything through. If no rule is matched to a packet, that packet will be discarded (blocked). .It +It's possible to filter based on the payload of UDP frames where those +frames contain a +.Em PROTO_IP +.Em PPP +frame header. See the +.Ar filter-decapsulation +option below for further details. +.It Use .Dq set filter Ar name No -1 to flush all rules. @@ -2722,6 +2730,30 @@ This option determines if Van Jacobson header compression will be used. The following options are not actually negotiated with the peer. Therefore, accepting or denying them makes no sense. .Bl -tag -width XX +.It filter-decapsulation +Default: Disabled. +When this option is enabled, +.Nm +will examine UDP frames to see if they actually contain a +.Em PPP +frame as their payload. If this is the case, all filters will operate +on the payload rather than the actual packet. +.Pp +This is useful if you want to send PPPoUDP traffic over a +.Em PPP +link, but want that link to do smart things with the real data rather than +the UDP wrapper. +.Pp +The UDP frame payload must not be compressed in any way, otherwise +.Nm +will not be able to interpret it. It's therefore recommended that +you +.Ic disable vj pred1 deflate +and +.Ic deny vj pred1 deflate +in the configuration for the +.Nm +invocation with the udp link. .It idcheck Default: Enabled. When |