summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorMike Frantzen <frantzen@cvs.openbsd.org>2001-08-25 21:54:27 +0000
committerMike Frantzen <frantzen@cvs.openbsd.org>2001-08-25 21:54:27 +0000
commitf00d16aa4fbd32becd24a08c97723cc515d6e839 (patch)
treee0feb293994276b51611926e71e518b4844c1084 /sys/net
parentab1d7a2717833d8c2829339059cfe38422f0ca31 (diff)
PF ISN randomization. Or in trekkie techno-babble, ISN phase modulation.
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/pf.c99
-rw-r--r--sys/net/pfvar.h5
2 files changed, 80 insertions, 24 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c
index 3cc5fd10144..50f1f747568 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.137 2001/08/22 03:02:25 frantzen Exp $ */
+/* $OpenBSD: pf.c,v 1.138 2001/08/25 21:54:25 frantzen Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -692,10 +692,10 @@ pf_print_state(struct pf_state *s)
pf_print_host(s->gwy.addr, s->gwy.port);
printf(" ");
pf_print_host(s->ext.addr, s->ext.port);
- printf(" [lo=%lu high=%lu win=%u]", s->src.seqlo, s->src.seqhi,
- s->src.max_win);
- printf(" [lo=%lu high=%lu win=%u]", s->dst.seqlo, s->dst.seqhi,
- s->dst.max_win);
+ printf(" [lo=%lu high=%lu win=%u modulator=%u]", s->src.seqlo,
+ s->src.seqhi, s->src.max_win, s->src.seqdiff);
+ printf(" [lo=%lu high=%lu win=%u modulator=%u]", s->dst.seqlo,
+ s->dst.seqhi, s->dst.max_win, s->dst.seqdiff);
printf(" %u:%u", s->src.state, s->dst.state);
}
@@ -2086,17 +2086,28 @@ pf_test_tcp(int direction, struct ifnet *ifp, struct mbuf *m,
s->gwy.port = s->lan.port;
}
}
- s->src.seqlo = ntohl(th->th_seq) + len;
- s->src.seqhi = s->src.seqlo + 1;
+
+ s->src.seqlo = ntohl(th->th_seq);
+ s->src.seqhi = s->src.seqlo + len + 1;
+ if (th->th_flags == TH_SYN && rm != NULL
+ && rm->keep_state == PF_STATE_MODULATE) {
+ /* Generate sequence number modulator */
+ while ((s->src.seqdiff = arc4random()) == 0)
+ ;
+ pf_change_a(&th->th_seq, &th->th_sum,
+ htonl(s->src.seqlo + s->src.seqdiff));
+ rewrite = 1;
+ } else
+ s->src.seqdiff = 0;
if (th->th_flags & TH_SYN)
s->src.seqhi++;
if (th->th_flags & TH_FIN)
s->src.seqhi++;
s->src.max_win = MAX(ntohs(th->th_win), 1);
-
s->dst.seqlo = 0; /* Haven't seen these yet */
s->dst.seqhi = 1;
s->dst.max_win = 1;
+ s->dst.seqdiff = 0; /* Defer random generation */
s->src.state = TCPS_SYN_SENT;
s->dst.state = TCPS_CLOSED;
s->creation = pftv.tv_sec;
@@ -2266,10 +2277,12 @@ pf_test_udp(int direction, struct ifnet *ifp, struct mbuf *m,
}
s->src.seqlo = 0;
s->src.seqhi = 0;
+ s->src.seqdiff = 0;
s->src.max_win = 0;
s->src.state = 1;
s->dst.seqlo = 0;
s->dst.seqhi = 0;
+ s->dst.seqdiff = 0;
s->dst.max_win = 0;
s->dst.state = 0;
s->creation = pftv.tv_sec;
@@ -2384,10 +2397,12 @@ pf_test_icmp(int direction, struct ifnet *ifp, struct mbuf *m,
}
s->src.seqlo = 0;
s->src.seqhi = 0;
+ s->src.seqdiff = 0;
s->src.max_win = 0;
s->src.state = 0;
s->dst.seqlo = 0;
s->dst.seqhi = 0;
+ s->dst.seqdiff = 0;
s->dst.max_win = 0;
s->dst.state = 0;
s->creation = pftv.tv_sec;
@@ -2454,17 +2469,10 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct ifnet *ifp,
struct pf_tree_key key;
u_int16_t len = h->ip_len - off - (th->th_off << 2);
u_int16_t win = ntohs(th->th_win);
- u_int32_t seq = ntohl(th->th_seq), ack = ntohl(th->th_ack);
- u_int32_t end;
+ u_int32_t ack, end, seq;
int ackskew;
struct pf_state_peer *src, *dst;
- end = seq + len;
- if (th->th_flags & TH_SYN)
- end++;
- if (th->th_flags & TH_FIN)
- end++;
-
key.proto = IPPROTO_TCP;
key.addr[0] = h->ip_src;
key.port[0] = th->th_sport;
@@ -2492,9 +2500,29 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct ifnet *ifp,
* tcp_filtering.ps
*/
+ seq = ntohl(th->th_seq);
if (src->seqlo == 0) {
/* First packet from this end. Set its state */
- src->seqlo = end;
+
+ /* Deferred generation of sequence number modulator */
+ if (dst->seqdiff) {
+ while ((src->seqdiff = arc4random()) == 0)
+ ;
+ ack = ntohl(th->th_ack) - dst->seqdiff;
+ pf_change_a(&th->th_seq, &th->th_sum, htonl(seq +
+ src->seqdiff));
+ pf_change_a(&th->th_ack, &th->th_sum, htonl(ack));
+ } else {
+ ack = ntohl(th->th_ack);
+ }
+
+ end = seq + len;
+ if (th->th_flags & TH_SYN)
+ end++;
+ if (th->th_flags & TH_FIN)
+ end++;
+
+ src->seqlo = seq;
if (src->state < TCPS_SYN_SENT)
src->state = TCPS_SYN_SENT;
@@ -2507,6 +2535,20 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct ifnet *ifp,
src->seqhi = end + MAX(1, dst->max_win);
if (win > src->max_win)
src->max_win = win;
+
+ } else {
+ ack = ntohl(th->th_ack) - dst->seqdiff;
+ if (src->seqdiff) {
+ /* Modulate sequence numbers */
+ pf_change_a(&th->th_seq, &th->th_sum, htonl(seq +
+ src->seqdiff));
+ pf_change_a(&th->th_ack, &th->th_sum, htonl(ack));
+ }
+ end = seq + len;
+ if (th->th_flags & TH_SYN)
+ end++;
+ if (th->th_flags & TH_FIN)
+ end++;
}
if ((th->th_flags & TH_ACK) == 0) {
@@ -2571,9 +2613,12 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct ifnet *ifp,
src->state = dst->state = TCPS_TIME_WAIT;
/* update expire time */
- if (src->state >= TCPS_FIN_WAIT_2 ||
+ if (src->state >= TCPS_FIN_WAIT_2 &&
dst->state >= TCPS_FIN_WAIT_2)
(*state)->expire = pftv.tv_sec + 5;
+ else if (src->state >= TCPS_FIN_WAIT_2 ||
+ dst->state >= TCPS_FIN_WAIT_2)
+ (*state)->expire = pftv.tv_sec + 15;
else if (src->state >= TCPS_CLOSING &&
dst->state >= TCPS_CLOSING)
(*state)->expire = pftv.tv_sec + 300;
@@ -2684,7 +2729,11 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct ifnet *ifp,
&th->th_sum, (*state)->lan.addr,
(*state)->lan.port);
m_copyback(m, off, sizeof(*th), (caddr_t)th);
+ } else if (src->seqdiff) {
+ /* Copyback sequence modulation */
+ m_copyback(m, off, sizeof(*th), (caddr_t)th);
}
+
if ((*state)->rule != NULL) {
(*state)->rule->packets++;
(*state)->rule->bytes += h->ip_len;
@@ -2842,7 +2891,6 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct ifnet *ifp,
("pf: ICMP error message too short (tcp)\n"));
return (PF_DROP);
}
- seq = ntohl(th.th_seq);
key.proto = IPPROTO_TCP;
key.addr[0] = h2.ip_dst;
@@ -2865,6 +2913,11 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct ifnet *ifp,
dst = &(*state)->dst;
}
+ /* Demodulate sequence number */
+ seq = ntohl(th.th_seq) - src->seqdiff;
+ if (src->seqdiff)
+ pf_change_a(&th.th_seq, &th.th_sum, htonl(seq));
+
if (!SEQ_GEQ(src->seqhi, seq) ||
!SEQ_GEQ(seq, src->seqlo - dst->max_win)) {
if (pf_status.debug >= PF_DEBUG_MISC) {
@@ -2892,10 +2945,10 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct ifnet *ifp,
&h->ip_sum);
}
m_copyback(m, off, ICMP_MINLEN, (caddr_t)ih);
- m_copyback(m, ipoff2, sizeof(h2),
- (caddr_t)&h2);
- m_copyback(m, off2, 8,
- (caddr_t)&th);
+ m_copyback(m, ipoff2, sizeof(h2), (caddr_t)&h2);
+ m_copyback(m, off2, 8, (caddr_t)&th);
+ } else if (src->seqdiff) {
+ m_copyback(m, off2, 8, (caddr_t)&th);
}
return (PF_PASS);
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index c9656de395d..a5f18ce96c7 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfvar.h,v 1.45 2001/08/21 17:25:59 deraadt Exp $ */
+/* $OpenBSD: pfvar.h,v 1.46 2001/08/25 21:54:26 frantzen Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -73,6 +73,8 @@ struct pf_rule {
u_int8_t log;
u_int8_t quick;
+#define PF_STATE_NORMAL 0x1
+#define PF_STATE_MODULATE 0x2
u_int8_t keep_state;
u_int8_t proto;
u_int8_t type;
@@ -96,6 +98,7 @@ struct pf_state_host {
struct pf_state_peer {
u_int32_t seqlo; /* Max sequence number sent */
u_int32_t seqhi; /* Max the other end ACKd + win */
+ u_int32_t seqdiff; /* Sequence number modulator */
u_int16_t max_win;
u_int8_t state;
};