diff options
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/ip_ipsp.c | 29 | ||||
-rw-r--r-- | sys/netinet/ip_ipsp.h | 4 | ||||
-rw-r--r-- | sys/netinet/tcp_input.c | 49 | ||||
-rw-r--r-- | sys/netinet/tcp_output.c | 29 |
4 files changed, 79 insertions, 32 deletions
diff --git a/sys/netinet/ip_ipsp.c b/sys/netinet/ip_ipsp.c index a8f7e85aea5..e643b6f3d8b 100644 --- a/sys/netinet/ip_ipsp.c +++ b/sys/netinet/ip_ipsp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ipsp.c,v 1.153 2003/12/02 23:16:28 markus Exp $ */ +/* $OpenBSD: ip_ipsp.c,v 1.154 2004/01/22 14:38:28 markus Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr), @@ -299,6 +299,33 @@ gettdb(u_int32_t spi, union sockaddr_union *dst, u_int8_t proto) return tdbp; } +#ifdef TCP_SIGNATURE +/* + * Same as gettdb() but compare SRC as well. + */ +struct tdb * +gettdbbysrcdst(u_int32_t spi, union sockaddr_union *src, + union sockaddr_union *dst, u_int8_t proto) +{ + u_int32_t hashval; + struct tdb *tdbp; + + if (tdbh == NULL) + return (struct tdb *) NULL; + + hashval = tdb_hash(spi, dst, proto); + + for (tdbp = tdbh[hashval]; tdbp != NULL; tdbp = tdbp->tdb_hnext) + if ((tdbp->tdb_spi == spi) && + !bcmp(&tdbp->tdb_dst, dst, SA_LEN(&dst->sa)) && + !bcmp(&tdbp->tdb_src, src, SA_LEN(&src->sa)) && + (tdbp->tdb_sproto == proto)) + break; + + return tdbp; +} +#endif + /* * Check that credentials and IDs match. Return true if so. The t* * range of arguments contains information from TDBs; the p* diff --git a/sys/netinet/ip_ipsp.h b/sys/netinet/ip_ipsp.h index 7db27a39335..60c29da701c 100644 --- a/sys/netinet/ip_ipsp.h +++ b/sys/netinet/ip_ipsp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ipsp.h,v 1.125 2003/12/10 07:22:43 itojun Exp $ */ +/* $OpenBSD: ip_ipsp.h,v 1.126 2004/01/22 14:38:28 markus Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr), @@ -533,6 +533,8 @@ extern struct tdb *gettdbbyaddr(union sockaddr_union *, u_int8_t, extern struct tdb *gettdbbysrc(union sockaddr_union *, u_int8_t, struct ipsec_ref *, struct ipsec_ref *, struct mbuf *, int, struct sockaddr_encap *, struct sockaddr_encap *); +extern struct tdb *gettdbbysrcdst(u_int32_t, union sockaddr_union *, + union sockaddr_union *, u_int8_t); extern void puttdb(struct tdb *); extern void tdb_delete(struct tdb *); extern struct tdb *tdb_alloc(void); diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index a0b2cbde77b..4a626b263cd 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_input.c,v 1.146 2004/01/15 17:04:59 markus Exp $ */ +/* $OpenBSD: tcp_input.c,v 1.147 2004/01/22 14:38:28 markus Exp $ */ /* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */ /* @@ -2285,35 +2285,41 @@ tcp_dooptions(tp, cp, cnt, th, m, iphlen, oi) if (sigp) { MD5_CTX ctx; - union sockaddr_union sa; + union sockaddr_union src, dst; struct tdb *tdb; char sig[16]; - memset(&sa, 0, sizeof(union sockaddr_union)); + memset(&src, 0, sizeof(union sockaddr_union)); + memset(&dst, 0, sizeof(union sockaddr_union)); switch (tp->pf) { case 0: #ifdef INET case AF_INET: - sa.sa.sa_len = sizeof(struct sockaddr_in); - sa.sa.sa_family = AF_INET; - sa.sin.sin_addr = mtod(m, struct ip *)->ip_dst; + src.sa.sa_len = sizeof(struct sockaddr_in); + src.sa.sa_family = AF_INET; + src.sin.sin_addr = mtod(m, struct ip *)->ip_src; + dst.sa.sa_len = sizeof(struct sockaddr_in); + dst.sa.sa_family = AF_INET; + dst.sin.sin_addr = mtod(m, struct ip *)->ip_dst; break; #endif #ifdef INET6 case AF_INET6: - sa.sa.sa_len = sizeof(struct sockaddr_in6); - sa.sa.sa_family = AF_INET6; - sa.sin6.sin6_addr = mtod(m, struct ip6_hdr *)->ip6_dst; + src.sa.sa_len = sizeof(struct sockaddr_in6); + src.sa.sa_family = AF_INET6; + src.sin6.sin6_addr = mtod(m, struct ip6_hdr *)->ip6_src; + dst.sa.sa_len = sizeof(struct sockaddr_in6); + dst.sa.sa_family = AF_INET6; + dst.sin6.sin6_addr = mtod(m, struct ip6_hdr *)->ip6_dst; break; #endif /* INET6 */ } - tdb = gettdb(0, &sa, IPPROTO_TCP); + tdb = gettdbbysrcdst(0, &src, &dst, IPPROTO_TCP); if (tdb == NULL) { - printf("tdb miss\n"); tcpstat.tcps_rcvbadsig++; - return -1; + return (-1); } MD5Init(&ctx); @@ -4223,28 +4229,33 @@ syn_cache_respond(sc, m) #ifdef TCP_SIGNATURE if (sc->sc_flags & SCF_SIGNATURE) { MD5_CTX ctx; - union sockaddr_union sa; + union sockaddr_union src, dst; struct tdb *tdb; - bzero(&sa, sizeof(union sockaddr_union)); - sa.sa.sa_len = sc->sc_dst.sa.sa_len; - sa.sa.sa_family = sc->sc_dst.sa.sa_family; + bzero(&src, sizeof(union sockaddr_union)); + bzero(&dst, sizeof(union sockaddr_union)); + src.sa.sa_len = sc->sc_src.sa.sa_len; + src.sa.sa_family = sc->sc_src.sa.sa_family; + dst.sa.sa_len = sc->sc_dst.sa.sa_len; + dst.sa.sa_family = sc->sc_dst.sa.sa_family; switch (sc->sc_src.sa.sa_family) { case 0: /*default to PF_INET*/ #ifdef INET case AF_INET: - sa.sin.sin_addr = mtod(m, struct ip *)->ip_dst; + src.sin.sin_addr = mtod(m, struct ip *)->ip_src; + dst.sin.sin_addr = mtod(m, struct ip *)->ip_dst; break; #endif /* INET */ #ifdef INET6 case AF_INET6: - sa.sin6.sin6_addr = mtod(m, struct ip6_hdr *)->ip6_dst; + src.sin6.sin6_addr = mtod(m, struct ip6_hdr *)->ip6_src; + dst.sin6.sin6_addr = mtod(m, struct ip6_hdr *)->ip6_dst; break; #endif /* INET6 */ } - tdb = gettdb(0, &sa, IPPROTO_TCP); + tdb = gettdbbysrcdst(0, &src, &dst, IPPROTO_TCP); if (tdb == NULL) { if (m) m_freem(m); diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c index 003fef097ef..c641a21b21f 100644 --- a/sys/netinet/tcp_output.c +++ b/sys/netinet/tcp_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_output.c,v 1.61 2004/01/15 17:04:59 markus Exp $ */ +/* $OpenBSD: tcp_output.c,v 1.62 2004/01/22 14:38:28 markus Exp $ */ /* $NetBSD: tcp_output.c,v 1.16 1997/06/03 16:17:09 kml Exp $ */ /* @@ -890,32 +890,39 @@ send: #ifdef TCP_SIGNATURE if (tp->t_flags & TF_SIGNATURE) { MD5_CTX ctx; - union sockaddr_union sa; + union sockaddr_union src, dst; struct tdb *tdb; - bzero(&sa, sizeof(union sockaddr_union)); + bzero(&src, sizeof(union sockaddr_union)); + bzero(&dst, sizeof(union sockaddr_union)); switch (tp->pf) { case 0: /*default to PF_INET*/ #ifdef INET case AF_INET: - sa.sa.sa_len = sizeof(struct sockaddr_in); - sa.sa.sa_family = AF_INET; - sa.sin.sin_addr = mtod(m, struct ip *)->ip_dst; + src.sa.sa_len = sizeof(struct sockaddr_in); + src.sa.sa_family = AF_INET; + src.sin.sin_addr = mtod(m, struct ip *)->ip_src; + dst.sa.sa_len = sizeof(struct sockaddr_in); + dst.sa.sa_family = AF_INET; + dst.sin.sin_addr = mtod(m, struct ip *)->ip_dst; break; #endif /* INET */ #ifdef INET6 case AF_INET6: - sa.sa.sa_len = sizeof(struct sockaddr_in6); - sa.sa.sa_family = AF_INET6; - sa.sin6.sin6_addr = mtod(m, struct ip6_hdr *)->ip6_dst; + src.sa.sa_len = sizeof(struct sockaddr_in6); + src.sa.sa_family = AF_INET6; + src.sin6.sin6_addr = mtod(m, struct ip6_hdr *)->ip6_src; + dst.sa.sa_len = sizeof(struct sockaddr_in6); + dst.sa.sa_family = AF_INET6; + dst.sin6.sin6_addr = mtod(m, struct ip6_hdr *)->ip6_dst; break; #endif /* INET6 */ } - /* XXX gettdb() should really be called at spltdb(). */ + /* XXX gettdbbysrcdst() should really be called at spltdb(). */ /* XXX this is splsoftnet(), currently they are the same. */ - tdb = gettdb(0, &sa, IPPROTO_TCP); + tdb = gettdbbysrcdst(0, &src, &dst, IPPROTO_TCP); if (tdb == NULL) return (EPERM); |