summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ppp
diff options
context:
space:
mode:
authorbrian <brian@FreeBSD.org>2000-07-07 14:22:08 +0000
committerbrian <brian@FreeBSD.org>2000-07-07 14:22:08 +0000
commit9f59f2175ab076dbd4cab78cb3e6291be843d462 (patch)
tree2993d4a2e9e8023e6205e2ee1621a1aa1480ef11 /usr.sbin/ppp
parent8a86977869e76ed98bb49dd38a784f62b080ffb7 (diff)
downloadFreeBSD-src-9f59f2175ab076dbd4cab78cb3e6291be843d462.zip
FreeBSD-src-9f59f2175ab076dbd4cab78cb3e6291be843d462.tar.gz
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/bundle.c25
-rw-r--r--usr.sbin/ppp/bundle.h21
-rw-r--r--usr.sbin/ppp/command.c7
-rw-r--r--usr.sbin/ppp/ip.c68
-rw-r--r--usr.sbin/ppp/ip.h3
-rw-r--r--usr.sbin/ppp/nat_cmd.c2
-rw-r--r--usr.sbin/ppp/ppp.832
-rw-r--r--usr.sbin/ppp/ppp.8.m432
8 files changed, 157 insertions, 33 deletions
diff --git a/usr.sbin/ppp/bundle.c b/usr.sbin/ppp/bundle.c
index 36fb9be..4f9a684 100644
--- a/usr.sbin/ppp/bundle.c
+++ b/usr.sbin/ppp/bundle.c
@@ -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/bundle.h b/usr.sbin/ppp/bundle.h
index 7007d78..5f0efc3 100644
--- a/usr.sbin/ppp/bundle.h
+++ b/usr.sbin/ppp/bundle.h
@@ -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/command.c b/usr.sbin/ppp/command.c
index 04c71ea..2553f42 100644
--- a/usr.sbin/ppp/command.c
+++ b/usr.sbin/ppp/command.c
@@ -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/ip.c b/usr.sbin/ppp/ip.c
index 9552ccc..7d2a082 100644
--- a/usr.sbin/ppp/ip.c
+++ b/usr.sbin/ppp/ip.c
@@ -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/ip.h b/usr.sbin/ppp/ip.h
index 4c493cc..6ef9872 100644
--- a/usr.sbin/ppp/ip.h
+++ b/usr.sbin/ppp/ip.h
@@ -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/nat_cmd.c b/usr.sbin/ppp/nat_cmd.c
index 0061022..4024bfe 100644
--- a/usr.sbin/ppp/nat_cmd.c
+++ b/usr.sbin/ppp/nat_cmd.c
@@ -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.8 b/usr.sbin/ppp/ppp.8
index 636465f..3cc6203 100644
--- a/usr.sbin/ppp/ppp.8
+++ b/usr.sbin/ppp/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
diff --git a/usr.sbin/ppp/ppp.8.m4 b/usr.sbin/ppp/ppp.8.m4
index 636465f..3cc6203 100644
--- a/usr.sbin/ppp/ppp.8.m4
+++ b/usr.sbin/ppp/ppp.8.m4
@@ -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
OpenPOWER on IntegriCloud