summaryrefslogtreecommitdiffstats
path: root/sys/netinet/tcp_input.c
diff options
context:
space:
mode:
authormarkus <markus@openbsd.org>2004-01-13 13:26:14 +0000
committermarkus <markus@openbsd.org>2004-01-13 13:26:14 +0000
commit5e7a4484677f10e330e981810fdf3a1edee5baf8 (patch)
treede7d301b0469706cc54b252b6898147b98134695 /sys/netinet/tcp_input.c
parentDump and send RIB to the neighbor if his session is comming up. (diff)
downloadwireguard-openbsd-5e7a4484677f10e330e981810fdf3a1edee5baf8.tar.xz
wireguard-openbsd-5e7a4484677f10e330e981810fdf3a1edee5baf8.zip
bring back the old TCP_SIGNATURE code from tcp_input.c rev 1.45
and make it compile (does not work yet); ok deraadt@
Diffstat (limited to 'sys/netinet/tcp_input.c')
-rw-r--r--sys/netinet/tcp_input.c156
1 files changed, 148 insertions, 8 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index e47b38a2559..5818f01e91d 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_input.c,v 1.142 2004/01/13 09:22:52 markus Exp $ */
+/* $OpenBSD: tcp_input.c,v 1.143 2004/01/13 13:26:14 markus Exp $ */
/* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */
/*
@@ -108,6 +108,10 @@ struct tcpipv6hdr tcp_saveti6;
#define M_V4_LEN(m) (M_PH_LEN(m) - sizeof(struct ip))
#endif /* INET6 */
+#ifdef TCP_SIGNATURE
+#include <sys/md5k.h>
+#endif
+
int tcprexmtthresh = 3;
struct tcpiphdr tcp_saveti;
int tcptv_keep_init = TCPTV_KEEP_INIT;
@@ -860,7 +864,7 @@ findpcb:
* state for it.
*/
if (so->so_qlen <= so->so_qlimit &&
- syn_cache_add(&src.sa, &dst.sa, th, tlen,
+ syn_cache_add(&src.sa, &dst.sa, th, iphlen,
so, m, optp, optlen, &opti))
m = NULL;
}
@@ -948,8 +952,13 @@ after_listen:
/*
* Process options.
*/
+#ifdef TCP_SIGNATURE
+ if (optp || (tp->t_flags & TF_SIGNATURE))
+#else
if (optp)
- tcp_dooptions(tp, optp, optlen, th, &opti);
+#endif
+ if (tcp_dooptions(tp, optp, optlen, th, m, iphlen, &opti))
+ goto drop;
#ifdef TCP_SACK
if (!tp->sack_disable) {
@@ -2165,16 +2174,21 @@ drop:
#ifndef TUBA_INCLUDE
}
-void
-tcp_dooptions(tp, cp, cnt, th, oi)
+int
+tcp_dooptions(tp, cp, cnt, th, m, iphlen, oi)
struct tcpcb *tp;
u_char *cp;
int cnt;
struct tcphdr *th;
+ struct mbuf *m;
+ int iphlen;
struct tcp_opt_info *oi;
{
u_int16_t mss = 0;
int opt, optlen;
+#ifdef TCP_SIGNATURE
+ caddr_t sigp = NULL;
+#endif /* TCP_SIGNATURE */
for (; cnt > 0; cnt -= optlen, cp += optlen) {
opt = cp[0];
@@ -2246,8 +2260,133 @@ tcp_dooptions(tp, cp, cnt, th, oi)
continue;
break;
#endif
+#ifdef TCP_SIGNATURE
+ case TCPOPT_SIGNATURE:
+ if (optlen != TCPOLEN_SIGNATURE)
+ continue;
+
+ if (sigp && bcmp(sigp, cp + 2, 16))
+ return -1;
+
+ sigp = cp + 2;
+ break;
+#endif /* TCP_SIGNATURE */
}
}
+
+#ifdef TCP_SIGNATURE
+ if ((sigp ? TF_SIGNATURE : 0) ^ (tp->t_flags & TF_SIGNATURE)) {
+ tcpstat.tcps_rcvbadsig++;
+ return -1;
+ }
+
+ if (sigp) {
+ MD5_CTX ctx;
+ union sockaddr_union sa;
+ struct tdb *tdb;
+ char sig[16];
+
+ memset(&sa, 0, sizeof(union sockaddr_union));
+
+ switch (tp->pf) {
+ case 0:
+ case AF_INET:
+ sa.sa.sa_len = sizeof(struct sockaddr_in);
+ sa.sa.sa_family = AF_INET;
+ sa.sin.sin_addr = tp->t_inpcb->inp_laddr;
+ break;
+#ifdef INET6
+ case AF_INET6:
+ sa.sa.sa_len = sizeof(struct sockaddr_in6);
+ sa.sa.sa_family = AF_INET6;
+ sa.sin6.sin6_addr = tp->t_inpcb->inp_laddr6;
+ break;
+#endif /* INET6 */
+ }
+
+ tdb = gettdb(0, &sa, IPPROTO_TCP);
+ if (tdb == NULL) {
+ printf("tdb miss\n");
+ tcpstat.tcps_rcvbadsig++;
+ return -1;
+ }
+
+ MD5Init(&ctx);
+
+ switch(tp->pf) {
+ case 0:
+#ifdef INET
+ case AF_INET:
+ {
+ struct ippseudo ippseudo;
+
+ ippseudo.ippseudo_src =
+ tp->t_inpcb->inp_faddr;
+ ippseudo.ippseudo_dst =
+ tp->t_inpcb->inp_laddr;
+ ippseudo.ippseudo_pad = 0;
+ ippseudo.ippseudo_p = IPPROTO_TCP;
+ ippseudo.ippseudo_len = htons(
+ m->m_pkthdr.len - iphlen);
+
+ MD5Update(&ctx, (char *)&ippseudo,
+ sizeof(struct ippseudo));
+ }
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ {
+ static int printed = 0;
+
+ if (!printed) {
+ printf("error: TCP MD5 support"
+ " for IPv6 not yet"
+ " implemented.\n");
+ printed = 1;
+ }
+ }
+ break;
+#endif /* INET6 */
+ }
+
+ {
+ struct tcphdr tcphdr;
+
+ tcphdr.th_sport = th->th_sport;
+ tcphdr.th_dport = th->th_dport;
+ tcphdr.th_seq = htonl(th->th_seq);
+ tcphdr.th_ack = htonl(th->th_ack);
+ tcphdr.th_off = th->th_off;
+ tcphdr.th_x2 = th->th_x2;
+ tcphdr.th_flags = th->th_flags;
+ tcphdr.th_win = htons(th->th_win);
+ tcphdr.th_sum = 0;
+ tcphdr.th_urp = htons(th->th_urp);
+
+ MD5Update(&ctx, (char *)&tcphdr,
+ sizeof(struct tcphdr));
+ }
+
+ if (m_apply(m, iphlen + th->th_off * sizeof(uint32_t),
+ m->m_pkthdr.len - (iphlen + th->th_off *
+ sizeof(uint32_t)), tcp_signature_apply,
+ (caddr_t)&ctx))
+ return (-1);
+
+ MD5Update(&ctx, tdb->tdb_amxkey, tdb->tdb_amxkeylen);
+ MD5Final(sig, &ctx);
+
+ if (bcmp(sig, sigp, 16)) {
+ tcpstat.tcps_rcvbadsig++;
+ return (-1);
+ }
+
+ tcpstat.tcps_rcvgoodsig++;
+ }
+#endif /* TCP_SIGNATURE */
+
+ return (0);
}
#if defined(TCP_SACK)
@@ -3758,11 +3897,11 @@ syn_cache_unreach(src, dst, th)
*/
int
-syn_cache_add(src, dst, th, hlen, so, m, optp, optlen, oi)
+syn_cache_add(src, dst, th, iphlen, so, m, optp, optlen, oi)
struct sockaddr *src;
struct sockaddr *dst;
struct tcphdr *th;
- unsigned int hlen;
+ unsigned int iphlen;
struct socket *so;
struct mbuf *m;
u_char *optp;
@@ -3810,7 +3949,8 @@ syn_cache_add(src, dst, th, hlen, so, m, optp, optlen, oi)
tb.sack_disable = tcp_do_sack ? 0 : 1;
#endif
tb.t_flags = tcp_do_rfc1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0;
- tcp_dooptions(&tb, optp, optlen, th, oi);
+ if (tcp_dooptions(&tb, optp, optlen, th, m, iphlen, oi))
+ return (0);
/* Update t_maxopd and t_maxseg after all options are processed */
(void) tcp_mss(tp, oi->maxseg); /* sets t_maxseg */