Deleted Added
full compact
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 ---