summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/netinet6/in6_pcb.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
index 9fcdff824f8..fcfecb8ee3f 100644
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in6_pcb.c,v 1.21 2000/12/21 00:54:11 itojun Exp $ */
+/* $OpenBSD: in6_pcb.c,v 1.22 2001/01/06 16:07:45 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -203,6 +203,30 @@ in6_pcbbind(inp, nam)
*/
if (so->so_options & SO_REUSEADDR)
reuseport = SO_REUSEADDR | SO_REUSEPORT;
+ } else if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
+ struct ifaddr *ia = NULL;
+
+ sin6->sin6_port = 0; /*
+ * Yechhhh, because of upcoming
+ * call to ifa_ifwithaddr(), which
+ * does bcmp's over the PORTS as
+ * well. (What about flow?)
+ */
+ sin6->sin6_flowinfo = 0;
+ if ((ia = ifa_ifwithaddr((struct sockaddr *)sin6))
+ == NULL)
+ return EADDRNOTAVAIL;
+
+ /*
+ * XXX: bind to an anycast address might accidentally
+ * cause sending a packet with anycast source address.
+ * We should allow to bind to a deprecated address, since
+ * the application dare to use it.
+ */
+ if (ia &&
+ ((struct in6_ifaddr *)ia)->ia6_flags &
+ (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY|IN6_IFF_DETACHED))
+ return(EADDRNOTAVAIL);
}
#if 0 /* we don't support it */
else if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {