summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/netinet/tcp_usrreq.c65
-rw-r--r--sys/netinet/tcp_var.h6
2 files changed, 57 insertions, 14 deletions
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index 4bf944242ca..5b334d36cd4 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_usrreq.c,v 1.41 2000/06/18 02:02:01 itojun Exp $ */
+/* $OpenBSD: tcp_usrreq.c,v 1.42 2000/06/18 04:42:43 beck Exp $ */
/* $NetBSD: tcp_usrreq.c,v 1.20 1996/02/13 23:44:16 christos Exp $ */
/*
@@ -809,9 +809,14 @@ tcp_ident(oldp, oldlenp, newp, newlen)
size_t newlen;
{
int error = 0, s;
+ int is_ipv6 = 0;
struct tcp_ident_mapping tir;
struct inpcb *inp;
struct sockaddr_in *fin, *lin;
+#ifdef INET6
+ struct sockaddr_in6 *fin6, *lin6;
+ struct in6_addr f6, l6;
+#endif
if (oldp == NULL || newp != NULL || newlen != 0)
return (EINVAL);
@@ -819,20 +824,58 @@ tcp_ident(oldp, oldlenp, newp, newlen)
return (ENOMEM);
if ((error = copyin(oldp, &tir, sizeof (tir))) != 0 )
return (error);
- if (tir.faddr.sa_len != sizeof (struct sockaddr) ||
- tir.faddr.sa_family != AF_INET)
- return (EINVAL);
- fin = (struct sockaddr_in *)&tir.faddr;
- lin = (struct sockaddr_in *)&tir.laddr;
+ switch (tir.faddr.ss_family) {
+#ifdef INET6
+ case AF_INET6:
+ is_ipv6 = 1;
+ fin6 = (struct sockaddr_in6 *)&tir.faddr;
+ error = in6_embedscope(&f6, fin6, NULL, NULL);
+ if (error)
+ return EINVAL; /*?*/
+ lin6 = (struct sockaddr_in6 *)&tir.laddr;
+ error = in6_embedscope(&l6, lin6, NULL, NULL);
+ if (error)
+ return EINVAL; /*?*/
+ break;
+#endif
+ case AF_INET:
+ fin = (struct sockaddr_in *)&tir.faddr;
+ lin = (struct sockaddr_in *)&tir.laddr;
+ break;
+ default:
+ return(EINVAL);
+ }
s = splsoftnet();
- inp = in_pcbhashlookup(&tcbtable, fin->sin_addr, fin->sin_port,
- lin->sin_addr, lin->sin_port);
+ if (is_ipv6) {
+#ifdef INET6
+ inp = in6_pcbhashlookup(&tcbtable, &f6,
+ fin6->sin6_port, &l6, lin6->sin6_port);
+#else
+ panic("tcp_ident: cannot happen");
+#endif
+ }
+ else
+ inp = in_pcbhashlookup(&tcbtable, fin->sin_addr,
+ fin->sin_port, lin->sin_addr, lin->sin_port);
+
if (inp == NULL) {
++tcpstat.tcps_pcbhashmiss;
- inp = in_pcblookup(&tcbtable, &fin->sin_addr, fin->sin_port,
- &lin->sin_addr, lin->sin_port, 0);
- }
+ if (is_ipv6) {
+#ifdef INET6
+ inp = in_pcblookup(&tcbtable, &f6,
+ fin6->sin6_port, &l6, lin6->sin6_port,
+ INPLOOKUP_WILDCARD | INPLOOKUP_IPV6);
+#else
+ panic("tcp_ident: cannot happen");
+#endif
+ }
+ else
+ inp = in_pcblookup(&tcbtable, &fin->sin_addr,
+ fin->sin_port, &lin->sin_addr, lin->sin_port,
+ INPLOOKUP_WILDCARD);
+ }
+
if (inp != NULL && (inp->inp_socket->so_state & SS_CONNECTOUT)) {
tir.ruid = inp->inp_socket->so_ruid;
tir.euid = inp->inp_socket->so_euid;
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index 47c8ecd06c5..2b46e6f3323 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_var.h,v 1.26 1999/12/21 17:49:28 provos Exp $ */
+/* $OpenBSD: tcp_var.h,v 1.27 2000/06/18 04:42:43 beck Exp $ */
/* $NetBSD: tcp_var.h,v 1.17 1996/02/13 23:44:24 christos Exp $ */
/*
@@ -300,13 +300,13 @@ struct tcpstat {
{ "baddynamic", CTLTYPE_STRUCT }, \
{ "recvspace", CTLTYPE_INT }, \
{ "sendspace", CTLTYPE_INT }, \
- { "ident", CTLTYPE_STRUCT }, \
+ { "ident", CTLTYPE_STRUCT }, \
{ "sack", CTLTYPE_INT }, \
{ "mssdflt", CTLTYPE_INT }, \
}
struct tcp_ident_mapping {
- struct sockaddr faddr, laddr;
+ struct sockaddr_storage faddr, laddr;
int euid, ruid;
};