diff options
-rw-r--r-- | sys/netinet/tcp_usrreq.c | 65 | ||||
-rw-r--r-- | sys/netinet/tcp_var.h | 6 |
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; }; |