in6_pcb.c (71350) | in6_pcb.c (78064) |
---|---|
1/* $FreeBSD: head/sys/netinet6/in6_pcb.c 71350 2001-01-21 22:23:11Z des $ */ 2/* $KAME: in6_pcb.c,v 1.8 2000/06/09 00:37:02 itojun Exp $ */ | 1/* $FreeBSD: head/sys/netinet6/in6_pcb.c 78064 2001-06-11 12:39:29Z ume $ */ 2/* $KAME: in6_pcb.c,v 1.31 2001/05/21 05:45:10 jinmei Exp $ */ |
3 4/* 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: --- 50 unchanged lines hidden (view full) --- 61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 64 * SUCH DAMAGE. 65 * 66 * @(#)in_pcb.c 8.2 (Berkeley) 1/4/94 67 */ 68 | 3 4/* 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: --- 50 unchanged lines hidden (view full) --- 61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 64 * SUCH DAMAGE. 65 * 66 * @(#)in_pcb.c 8.2 (Berkeley) 1/4/94 67 */ 68 |
69#include "opt_inet.h" 70#include "opt_inet6.h" |
|
69#include "opt_ipsec.h" 70 71#include <sys/param.h> 72#include <sys/systm.h> 73#include <sys/malloc.h> 74#include <sys/mbuf.h> 75#include <sys/domain.h> 76#include <sys/protosw.h> --- 17 unchanged lines hidden (view full) --- 94#include <netinet/ip6.h> 95#include <netinet/ip_var.h> 96#include <netinet6/ip6_var.h> 97#include <netinet6/nd6.h> 98#include <netinet/in_pcb.h> 99#include <netinet6/in6_pcb.h> 100 101#include "faith.h" | 71#include "opt_ipsec.h" 72 73#include <sys/param.h> 74#include <sys/systm.h> 75#include <sys/malloc.h> 76#include <sys/mbuf.h> 77#include <sys/domain.h> 78#include <sys/protosw.h> --- 17 unchanged lines hidden (view full) --- 96#include <netinet/ip6.h> 97#include <netinet/ip_var.h> 98#include <netinet6/ip6_var.h> 99#include <netinet6/nd6.h> 100#include <netinet/in_pcb.h> 101#include <netinet6/in6_pcb.h> 102 103#include "faith.h" |
104#if defined(NFAITH) && NFAITH > 0 105#include <net/if_faith.h> 106#endif |
|
102 103#ifdef IPSEC 104#include <netinet6/ipsec.h> | 107 108#ifdef IPSEC 109#include <netinet6/ipsec.h> |
105#include <netinet6/ah.h> | 110#ifdef INET6 |
106#include <netinet6/ipsec6.h> | 111#include <netinet6/ipsec6.h> |
112#endif 113#include <netinet6/ah.h> 114#ifdef INET6 |
|
107#include <netinet6/ah6.h> | 115#include <netinet6/ah6.h> |
116#endif |
|
108#include <netkey/key.h> 109#endif /* IPSEC */ 110 111struct in6_addr zeroin6_addr; 112 113int 114in6_pcbbind(inp, nam, p) 115 register struct inpcb *inp; --- 44 unchanged lines hidden (view full) --- 160 161 sin6->sin6_port = 0; /* yech... */ 162 if ((ia = ifa_ifwithaddr((struct sockaddr *)sin6)) == 0) 163 return(EADDRNOTAVAIL); 164 165 /* 166 * XXX: bind to an anycast address might accidentally 167 * cause sending a packet with anycast source address. | 117#include <netkey/key.h> 118#endif /* IPSEC */ 119 120struct in6_addr zeroin6_addr; 121 122int 123in6_pcbbind(inp, nam, p) 124 register struct inpcb *inp; --- 44 unchanged lines hidden (view full) --- 169 170 sin6->sin6_port = 0; /* yech... */ 171 if ((ia = ifa_ifwithaddr((struct sockaddr *)sin6)) == 0) 172 return(EADDRNOTAVAIL); 173 174 /* 175 * XXX: bind to an anycast address might accidentally 176 * cause sending a packet with anycast source address. |
177 * We should allow to bind to a deprecated address, since 178 * the application dare to use it. |
|
168 */ 169 if (ia && 170 ((struct in6_ifaddr *)ia)->ia6_flags & | 179 */ 180 if (ia && 181 ((struct in6_ifaddr *)ia)->ia6_flags & |
171 (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY| 172 IN6_IFF_DETACHED|IN6_IFF_DEPRECATED)) { | 182 (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY|IN6_IFF_DETACHED)) { |
173 return(EADDRNOTAVAIL); 174 } 175 } 176 if (lport) { 177 struct inpcb *t; 178 179 /* GROSS */ 180 if (ntohs(lport) < IPV6PORT_RESERVED && p && --- 7 unchanged lines hidden (view full) --- 188 if (t && 189 (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) || 190 !IN6_IS_ADDR_UNSPECIFIED(&t->in6p_laddr) || 191 (t->inp_socket->so_options & 192 SO_REUSEPORT) == 0) && 193 (so->so_cred->cr_uid != 194 t->inp_socket->so_cred->cr_uid)) 195 return (EADDRINUSE); | 183 return(EADDRNOTAVAIL); 184 } 185 } 186 if (lport) { 187 struct inpcb *t; 188 189 /* GROSS */ 190 if (ntohs(lport) < IPV6PORT_RESERVED && p && --- 7 unchanged lines hidden (view full) --- 198 if (t && 199 (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) || 200 !IN6_IS_ADDR_UNSPECIFIED(&t->in6p_laddr) || 201 (t->inp_socket->so_options & 202 SO_REUSEPORT) == 0) && 203 (so->so_cred->cr_uid != 204 t->inp_socket->so_cred->cr_uid)) 205 return (EADDRINUSE); |
196 if (ip6_mapped_addr_on != 0 && | 206 if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0 && |
197 IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 198 struct sockaddr_in sin; 199 200 in6_sin6_2_sin(&sin, sin6); 201 t = in_pcblookup_local(pcbinfo, 202 sin.sin_addr, lport, 203 INPLOOKUP_WILDCARD); 204 if (t && --- 5 unchanged lines hidden (view full) --- 210 INP_SOCKAF(t->inp_socket))) 211 return (EADDRINUSE); 212 } 213 } 214 t = in6_pcblookup_local(pcbinfo, &sin6->sin6_addr, 215 lport, wild); 216 if (t && (reuseport & t->inp_socket->so_options) == 0) 217 return(EADDRINUSE); | 207 IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 208 struct sockaddr_in sin; 209 210 in6_sin6_2_sin(&sin, sin6); 211 t = in_pcblookup_local(pcbinfo, 212 sin.sin_addr, lport, 213 INPLOOKUP_WILDCARD); 214 if (t && --- 5 unchanged lines hidden (view full) --- 220 INP_SOCKAF(t->inp_socket))) 221 return (EADDRINUSE); 222 } 223 } 224 t = in6_pcblookup_local(pcbinfo, &sin6->sin6_addr, 225 lport, wild); 226 if (t && (reuseport & t->inp_socket->so_options) == 0) 227 return(EADDRINUSE); |
218 if (ip6_mapped_addr_on != 0 && | 228 if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0 && |
219 IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 220 struct sockaddr_in sin; 221 222 in6_sin6_2_sin(&sin, sin6); 223 t = in_pcblookup_local(pcbinfo, sin.sin_addr, 224 lport, wild); 225 if (t && 226 (reuseport & t->inp_socket->so_options) --- 15 unchanged lines hidden (view full) --- 242 else { 243 inp->inp_lport = lport; 244 if (in_pcbinshash(inp) != 0) { 245 inp->in6p_laddr = in6addr_any; 246 inp->inp_lport = 0; 247 return (EAGAIN); 248 } 249 } | 229 IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 230 struct sockaddr_in sin; 231 232 in6_sin6_2_sin(&sin, sin6); 233 t = in_pcblookup_local(pcbinfo, sin.sin_addr, 234 lport, wild); 235 if (t && 236 (reuseport & t->inp_socket->so_options) --- 15 unchanged lines hidden (view full) --- 252 else { 253 inp->inp_lport = lport; 254 if (in_pcbinshash(inp) != 0) { 255 inp->in6p_laddr = in6addr_any; 256 inp->inp_lport = 0; 257 return (EAGAIN); 258 } 259 } |
250 inp->in6p_flowinfo = sin6 ? sin6->sin6_flowinfo : 0; /*XXX*/ | |
251 return(0); 252} 253 254/* 255 * Transform old in6_pcbconnect() into an inner subroutine for new 256 * in6_pcbconnect(): Do some validity-checking on the remote 257 * address (in mbuf 'nam') and then determine local host address 258 * (i.e., which interface) to use to access that remote host. --- 6 unchanged lines hidden (view full) --- 265 266int 267in6_pcbladdr(inp, nam, plocal_addr6) 268 register struct inpcb *inp; 269 struct sockaddr *nam; 270 struct in6_addr **plocal_addr6; 271{ 272 register struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam; | 260 return(0); 261} 262 263/* 264 * Transform old in6_pcbconnect() into an inner subroutine for new 265 * in6_pcbconnect(): Do some validity-checking on the remote 266 * address (in mbuf 'nam') and then determine local host address 267 * (i.e., which interface) to use to access that remote host. --- 6 unchanged lines hidden (view full) --- 274 275int 276in6_pcbladdr(inp, nam, plocal_addr6) 277 register struct inpcb *inp; 278 struct sockaddr *nam; 279 struct in6_addr **plocal_addr6; 280{ 281 register struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam; |
273 struct in6_pktinfo *pi; | |
274 struct ifnet *ifp = NULL; 275 int error = 0; 276 277 if (nam->sa_len != sizeof (*sin6)) 278 return (EINVAL); 279 if (sin6->sin6_family != AF_INET6) 280 return (EAFNOSUPPORT); 281 if (sin6->sin6_port == 0) --- 74 unchanged lines hidden (view full) --- 356 error = in6_pcbbind(inp, (struct sockaddr *)0, p); 357 if (error) 358 return (error); 359 } 360 inp->in6p_laddr = *addr6; 361 } 362 inp->in6p_faddr = sin6->sin6_addr; 363 inp->inp_fport = sin6->sin6_port; | 282 struct ifnet *ifp = NULL; 283 int error = 0; 284 285 if (nam->sa_len != sizeof (*sin6)) 286 return (EINVAL); 287 if (sin6->sin6_family != AF_INET6) 288 return (EAFNOSUPPORT); 289 if (sin6->sin6_port == 0) --- 74 unchanged lines hidden (view full) --- 364 error = in6_pcbbind(inp, (struct sockaddr *)0, p); 365 if (error) 366 return (error); 367 } 368 inp->in6p_laddr = *addr6; 369 } 370 inp->in6p_faddr = sin6->sin6_addr; 371 inp->inp_fport = sin6->sin6_port; |
364 /* 365 * xxx kazu flowlabel is necessary for connect? 366 * but if this line is missing, the garbage value remains. 367 */ 368 inp->in6p_flowinfo = sin6->sin6_flowinfo; 369 if ((inp->in6p_flowinfo & IPV6_FLOWLABEL_MASK) == 0 && 370 ip6_auto_flowlabel != 0) | 372 /* update flowinfo - draft-itojun-ipv6-flowlabel-api-00 */ 373 inp->in6p_flowinfo &= ~IPV6_FLOWLABEL_MASK; 374 if (inp->in6p_flags & IN6P_AUTOFLOWLABEL) |
371 inp->in6p_flowinfo |= | 375 inp->in6p_flowinfo |= |
372 (htonl(ip6_flow_seq++) & IPV6_FLOWLABEL_MASK); | 376 (htonl(ip6_flow_seq++) & IPV6_FLOWLABEL_MASK); |
373 374 in_pcbrehash(inp); 375 return (0); 376} 377 378#if 0 379/* 380 * Return an IPv6 address, which is the most appropriate for given --- 135 unchanged lines hidden (view full) --- 516 if (ro) { 517 if (ro->ro_rt && 518 !IN6_ARE_ADDR_EQUAL(&satosin6(&ro->ro_dst)->sin6_addr, dst)) { 519 RTFREE(ro->ro_rt); 520 ro->ro_rt = (struct rtentry *)0; 521 } 522 if (ro->ro_rt == (struct rtentry *)0 || 523 ro->ro_rt->rt_ifp == (struct ifnet *)0) { | 377 378 in_pcbrehash(inp); 379 return (0); 380} 381 382#if 0 383/* 384 * Return an IPv6 address, which is the most appropriate for given --- 135 unchanged lines hidden (view full) --- 520 if (ro) { 521 if (ro->ro_rt && 522 !IN6_ARE_ADDR_EQUAL(&satosin6(&ro->ro_dst)->sin6_addr, dst)) { 523 RTFREE(ro->ro_rt); 524 ro->ro_rt = (struct rtentry *)0; 525 } 526 if (ro->ro_rt == (struct rtentry *)0 || 527 ro->ro_rt->rt_ifp == (struct ifnet *)0) { |
528 struct sockaddr_in6 *dst6; 529 |
|
524 /* No route yet, so try to acquire one */ 525 bzero(&ro->ro_dst, sizeof(struct sockaddr_in6)); | 530 /* No route yet, so try to acquire one */ 531 bzero(&ro->ro_dst, sizeof(struct sockaddr_in6)); |
526 ro->ro_dst.sin6_family = AF_INET6; 527 ro->ro_dst.sin6_len = sizeof(struct sockaddr_in6); 528 ro->ro_dst.sin6_addr = *dst; | 532 dst6 = (struct sockaddr_in6 *)&ro->ro_dst; 533 dst6->sin6_family = AF_INET6; 534 dst6->sin6_len = sizeof(struct sockaddr_in6); 535 dst6->sin6_addr = *dst; |
529 if (IN6_IS_ADDR_MULTICAST(dst)) { 530 ro->ro_rt = rtalloc1(&((struct route *)ro) 531 ->ro_dst, 0, 0UL); 532 } else { 533 rtalloc((struct route *)ro); 534 } 535 } 536 --- 42 unchanged lines hidden (view full) --- 579#endif 580 581void 582in6_pcbdisconnect(inp) 583 struct inpcb *inp; 584{ 585 bzero((caddr_t)&inp->in6p_faddr, sizeof(inp->in6p_faddr)); 586 inp->inp_fport = 0; | 536 if (IN6_IS_ADDR_MULTICAST(dst)) { 537 ro->ro_rt = rtalloc1(&((struct route *)ro) 538 ->ro_dst, 0, 0UL); 539 } else { 540 rtalloc((struct route *)ro); 541 } 542 } 543 --- 42 unchanged lines hidden (view full) --- 586#endif 587 588void 589in6_pcbdisconnect(inp) 590 struct inpcb *inp; 591{ 592 bzero((caddr_t)&inp->in6p_faddr, sizeof(inp->in6p_faddr)); 593 inp->inp_fport = 0; |
594 /* clear flowinfo - draft-itojun-ipv6-flowlabel-api-00 */ 595 inp->in6p_flowinfo &= ~IPV6_FLOWLABEL_MASK; |
|
587 in_pcbrehash(inp); 588 if (inp->inp_socket->so_state & SS_NOFDREF) 589 in6_pcbdetach(inp); 590} 591 592void 593in6_pcbdetach(inp) 594 struct inpcb *inp; --- 4 unchanged lines hidden (view full) --- 599#ifdef IPSEC 600 if (inp->in6p_sp != NULL) 601 ipsec6_delete_pcbpolicy(inp); 602#endif /* IPSEC */ 603 inp->inp_gencnt = ++ipi->ipi_gencnt; 604 in_pcbremlists(inp); 605 sotoinpcb(so) = 0; 606 sofree(so); | 596 in_pcbrehash(inp); 597 if (inp->inp_socket->so_state & SS_NOFDREF) 598 in6_pcbdetach(inp); 599} 600 601void 602in6_pcbdetach(inp) 603 struct inpcb *inp; --- 4 unchanged lines hidden (view full) --- 608#ifdef IPSEC 609 if (inp->in6p_sp != NULL) 610 ipsec6_delete_pcbpolicy(inp); 611#endif /* IPSEC */ 612 inp->inp_gencnt = ++ipi->ipi_gencnt; 613 in_pcbremlists(inp); 614 sotoinpcb(so) = 0; 615 sofree(so); |
616 |
|
607 if (inp->in6p_options) 608 m_freem(inp->in6p_options); | 617 if (inp->in6p_options) 618 m_freem(inp->in6p_options); |
609 if (inp->in6p_outputopts) { 610 if (inp->in6p_outputopts->ip6po_rthdr && 611 inp->in6p_outputopts->ip6po_route.ro_rt) 612 RTFREE(inp->in6p_outputopts->ip6po_route.ro_rt); 613 if (inp->in6p_outputopts->ip6po_m) 614 (void)m_free(inp->in6p_outputopts->ip6po_m); 615 free(inp->in6p_outputopts, M_IP6OPT); 616 } | 619 ip6_freepcbopts(inp->in6p_outputopts); 620 ip6_freemoptions(inp->in6p_moptions); |
617 if (inp->in6p_route.ro_rt) 618 rtfree(inp->in6p_route.ro_rt); | 621 if (inp->in6p_route.ro_rt) 622 rtfree(inp->in6p_route.ro_rt); |
619 ip6_freemoptions(inp->in6p_moptions); 620 | |
621 /* Check and free IPv4 related resources in case of mapped addr */ 622 if (inp->inp_options) 623 (void)m_free(inp->inp_options); 624 ip_freemoptions(inp->inp_moptions); 625 626 inp->inp_vflag = 0; 627 zfree(ipi->ipi_zone, inp); 628} --- 127 unchanged lines hidden (view full) --- 756 * taken, depending on the ctlinput cmd. The caller must filter any 757 * cmds that are uninteresting (e.g., no error in the map). 758 * Call the protocol specific routine (if any) to report 759 * any errors for each matching socket. 760 * 761 * Must be called at splnet. 762 */ 763void | 623 /* Check and free IPv4 related resources in case of mapped addr */ 624 if (inp->inp_options) 625 (void)m_free(inp->inp_options); 626 ip_freemoptions(inp->inp_moptions); 627 628 inp->inp_vflag = 0; 629 zfree(ipi->ipi_zone, inp); 630} --- 127 unchanged lines hidden (view full) --- 758 * taken, depending on the ctlinput cmd. The caller must filter any 759 * cmds that are uninteresting (e.g., no error in the map). 760 * Call the protocol specific routine (if any) to report 761 * any errors for each matching socket. 762 * 763 * Must be called at splnet. 764 */ 765void |
764in6_pcbnotify(head, dst, fport_arg, laddr6, lport_arg, cmd, notify) | 766in6_pcbnotify(head, dst, fport_arg, src, lport_arg, cmd, notify) |
765 struct inpcbhead *head; | 767 struct inpcbhead *head; |
766 struct sockaddr *dst; | 768 struct sockaddr *dst, *src; |
767 u_int fport_arg, lport_arg; | 769 u_int fport_arg, lport_arg; |
768 struct in6_addr *laddr6; | |
769 int cmd; 770 void (*notify) __P((struct inpcb *, int)); 771{ 772 struct inpcb *inp, *ninp; | 770 int cmd; 771 void (*notify) __P((struct inpcb *, int)); 772{ 773 struct inpcb *inp, *ninp; |
773 struct in6_addr faddr6; | 774 struct sockaddr_in6 sa6_src, *sa6_dst; |
774 u_short fport = fport_arg, lport = lport_arg; | 775 u_short fport = fport_arg, lport = lport_arg; |
776 u_int32_t flowinfo; |
|
775 int errno, s; | 777 int errno, s; |
776 int do_rtchange = (notify == in6_rtchange); | |
777 778 if ((unsigned)cmd > PRC_NCMDS || dst->sa_family != AF_INET6) 779 return; | 778 779 if ((unsigned)cmd > PRC_NCMDS || dst->sa_family != AF_INET6) 780 return; |
780 faddr6 = ((struct sockaddr_in6 *)dst)->sin6_addr; 781 if (IN6_IS_ADDR_UNSPECIFIED(&faddr6)) | 781 782 sa6_dst = (struct sockaddr_in6 *)dst; 783 if (IN6_IS_ADDR_UNSPECIFIED(&sa6_dst->sin6_addr)) |
782 return; 783 784 /* | 784 return; 785 786 /* |
787 * note that src can be NULL when we get notify by local fragmentation. 788 */ 789 sa6_src = (src == NULL) ? sa6_any : *(struct sockaddr_in6 *)src; 790 flowinfo = sa6_src.sin6_flowinfo; 791 792 /* |
|
785 * Redirects go to all references to the destination, 786 * and use in6_rtchange to invalidate the route cache. 787 * Dead host indications: also use in6_rtchange to invalidate 788 * the cache, and deliver the error to all the sockets. 789 * Otherwise, if we have knowledge of the local port and address, 790 * deliver only to that socket. 791 */ 792 if (PRC_IS_REDIRECT(cmd) || cmd == PRC_HOSTDEAD) { 793 fport = 0; 794 lport = 0; | 793 * Redirects go to all references to the destination, 794 * and use in6_rtchange to invalidate the route cache. 795 * Dead host indications: also use in6_rtchange to invalidate 796 * the cache, and deliver the error to all the sockets. 797 * Otherwise, if we have knowledge of the local port and address, 798 * deliver only to that socket. 799 */ 800 if (PRC_IS_REDIRECT(cmd) || cmd == PRC_HOSTDEAD) { 801 fport = 0; 802 lport = 0; |
795 bzero((caddr_t)laddr6, sizeof(*laddr6)); | 803 bzero((caddr_t)&sa6_src.sin6_addr, sizeof(sa6_src.sin6_addr)); |
796 | 804 |
797 do_rtchange = 1; | 805 if (cmd != PRC_HOSTDEAD) 806 notify = in6_rtchange; |
798 } 799 errno = inet6ctlerrmap[cmd]; 800 s = splnet(); 801 for (inp = LIST_FIRST(head); inp != NULL; inp = ninp) { 802 ninp = LIST_NEXT(inp, inp_list); 803 | 807 } 808 errno = inet6ctlerrmap[cmd]; 809 s = splnet(); 810 for (inp = LIST_FIRST(head); inp != NULL; inp = ninp) { 811 ninp = LIST_NEXT(inp, inp_list); 812 |
804 if ((inp->inp_vflag & INP_IPV6) == NULL) | 813 if ((inp->inp_vflag & INP_IPV6) == 0) |
805 continue; 806 | 814 continue; 815 |
807 if (do_rtchange) { 808 /* 809 * Since a non-connected PCB might have a cached route, 810 * we always call in6_rtchange without matching 811 * the PCB to the src/dst pair. 812 * 813 * XXX: we assume in6_rtchange does not free the PCB. 814 */ 815 if (IN6_ARE_ADDR_EQUAL(&inp->in6p_route.ro_dst.sin6_addr, 816 &faddr6)) 817 in6_rtchange(inp, errno); 818 819 if (notify == in6_rtchange) 820 continue; /* there's nothing to do any more */ 821 } 822 823 if (!IN6_ARE_ADDR_EQUAL(&inp->in6p_faddr, &faddr6) || 824 inp->inp_socket == 0 || 825 (lport && inp->inp_lport != lport) || 826 (!IN6_IS_ADDR_UNSPECIFIED(laddr6) && 827 !IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, laddr6)) || 828 (fport && inp->inp_fport != fport)) | 816 /* 817 * Detect if we should notify the error. If no source and 818 * destination ports are specifed, but non-zero flowinfo and 819 * local address match, notify the error. This is the case 820 * when the error is delivered with an encrypted buffer 821 * by ESP. Otherwise, just compare addresses and ports 822 * as usual. 823 */ 824 if (lport == 0 && fport == 0 && flowinfo && 825 inp->inp_socket != NULL && 826 flowinfo == (inp->in6p_flowinfo & IPV6_FLOWLABEL_MASK) && 827 IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, &sa6_src.sin6_addr)) 828 goto do_notify; 829 else if (!IN6_ARE_ADDR_EQUAL(&inp->in6p_faddr, 830 &sa6_dst->sin6_addr) || 831 inp->inp_socket == 0 || 832 (lport && inp->inp_lport != lport) || 833 (!IN6_IS_ADDR_UNSPECIFIED(&sa6_src.sin6_addr) && 834 !IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, 835 &sa6_src.sin6_addr)) || 836 (fport && inp->inp_fport != fport)) |
829 continue; 830 | 837 continue; 838 |
839 do_notify: |
|
831 if (notify) | 840 if (notify) |
832 (*notify)(inp, errno); | 841 (*notify)(inp, errno); |
833 } 834 splx(s); 835} 836 837/* 838 * Lookup a PCB based on the local address and port. 839 */ 840struct inpcb * --- 144 unchanged lines hidden (view full) --- 985 struct in6_addr *faddr, *laddr; 986 u_int fport_arg, lport_arg; 987 int wildcard; 988 struct ifnet *ifp; 989{ 990 struct inpcbhead *head; 991 register struct inpcb *inp; 992 u_short fport = fport_arg, lport = lport_arg; | 842 } 843 splx(s); 844} 845 846/* 847 * Lookup a PCB based on the local address and port. 848 */ 849struct inpcb * --- 144 unchanged lines hidden (view full) --- 994 struct in6_addr *faddr, *laddr; 995 u_int fport_arg, lport_arg; 996 int wildcard; 997 struct ifnet *ifp; 998{ 999 struct inpcbhead *head; 1000 register struct inpcb *inp; 1001 u_short fport = fport_arg, lport = lport_arg; |
1002 int faith; |
|
993 | 1003 |
1004#if defined(NFAITH) && NFAITH > 0 1005 faith = faithprefix(laddr); 1006#else 1007 faith = 0; 1008#endif 1009 |
|
994 /* 995 * First look for an exact match. 996 */ 997 head = &pcbinfo->hashbase[INP_PCBHASH(faddr->s6_addr32[3] /* XXX */, 998 lport, fport, 999 pcbinfo->hashmask)]; 1000 LIST_FOREACH(inp, head, inp_hash) { 1001 if ((inp->inp_vflag & INP_IPV6) == 0) --- 13 unchanged lines hidden (view full) --- 1015 1016 head = &pcbinfo->hashbase[INP_PCBHASH(INADDR_ANY, lport, 0, 1017 pcbinfo->hashmask)]; 1018 LIST_FOREACH(inp, head, inp_hash) { 1019 if ((inp->inp_vflag & INP_IPV6) == 0) 1020 continue; 1021 if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr) && 1022 inp->inp_lport == lport) { | 1010 /* 1011 * First look for an exact match. 1012 */ 1013 head = &pcbinfo->hashbase[INP_PCBHASH(faddr->s6_addr32[3] /* XXX */, 1014 lport, fport, 1015 pcbinfo->hashmask)]; 1016 LIST_FOREACH(inp, head, inp_hash) { 1017 if ((inp->inp_vflag & INP_IPV6) == 0) --- 13 unchanged lines hidden (view full) --- 1031 1032 head = &pcbinfo->hashbase[INP_PCBHASH(INADDR_ANY, lport, 0, 1033 pcbinfo->hashmask)]; 1034 LIST_FOREACH(inp, head, inp_hash) { 1035 if ((inp->inp_vflag & INP_IPV6) == 0) 1036 continue; 1037 if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr) && 1038 inp->inp_lport == lport) { |
1023#if defined(NFAITH) && NFAITH > 0 1024 if (ifp && ifp->if_type == IFT_FAITH && 1025 (inp->inp_flags & INP_FAITH) == 0) | 1039 if (faith && (inp->inp_flags & INP_FAITH) == 0) |
1026 continue; | 1040 continue; |
1027#endif | |
1028 if (IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, 1029 laddr)) 1030 return (inp); 1031 else if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) 1032 local_wild = inp; 1033 } 1034 } 1035 return (local_wild); --- 26 unchanged lines hidden --- | 1041 if (IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, 1042 laddr)) 1043 return (inp); 1044 else if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) 1045 local_wild = inp; 1046 } 1047 } 1048 return (local_wild); --- 26 unchanged lines hidden --- |