diff options
author | Bob Beck <beck@cvs.openbsd.org> | 2000-06-18 04:42:44 +0000 |
---|---|---|
committer | Bob Beck <beck@cvs.openbsd.org> | 2000-06-18 04:42:44 +0000 |
commit | d477e9081bc1a485bcb3370f9358f9a3e0e9a6f8 (patch) | |
tree | 11d5b19c2204db2370c6e2a73555fc4ea59039f5 /sys/netinet/tcp_usrreq.c | |
parent | 3cde0784463d6147ad67bb9f6d01c7d30a010a6b (diff) |
support ipv6 for tcp_ident
Diffstat (limited to 'sys/netinet/tcp_usrreq.c')
-rw-r--r-- | sys/netinet/tcp_usrreq.c | 65 |
1 files changed, 54 insertions, 11 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; |