return NULL;
}
+#if 0 /* FIXME */
+static bool check_addr_port_in_use(const struct sockaddr *sa, socklen_t len)
+{
+ struct socket_info *s;
+
+ /* first catch invalid input */
+ switch (sa->sa_family) {
+ case AF_INET:
+ if (len < sizeof(struct sockaddr_in)) {
+ return false;
+ }
+ break;
+#if HAVE_IPV6
+ case AF_INET6:
+ if (len < sizeof(struct sockaddr_in6)) {
+ return false;
+ }
+ break;
+#endif
+ default:
+ return false;
+ break;
+ }
+
+ for (s = sockets; s != NULL; s = s->next) {
+ if (s->myname == NULL) {
+ continue;
+ }
+ if (s->myname->sa_family != sa->sa_family) {
+ continue;
+ }
+ switch (s->myname->sa_family) {
+ case AF_INET: {
+ struct sockaddr_in *sin1, *sin2;
+
+ sin1 = (struct sockaddr_in *)s->myname;
+ sin2 = (struct sockaddr_in *)sa;
+
+ if (sin1->sin_addr.s_addr == htonl(INADDR_ANY)) {
+ continue;
+ }
+ if (sin1->sin_port != sin2->sin_port) {
+ continue;
+ }
+ if (sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) {
+ continue;
+ }
+
+ /* found */
+ return true;
+ break;
+ }
+#if HAVE_IPV6
+ case AF_INET6: {
+ struct sockaddr_in6 *sin1, *sin2;
+
+ sin1 = (struct sockaddr_in6 *)s->myname;
+ sin2 = (struct sockaddr_in6 *)sa;
+
+ if (sin1->sin6_port != sin2->sin6_port) {
+ continue;
+ }
+ if (!IN6_ARE_ADDR_EQUAL(&sin1->sin6_addr,
+ &sin2->sin6_addr))
+ {
+ continue;
+ }
+
+ /* found */
+ return true;
+ break;
+ }
+#endif
+ default:
+ continue;
+ break;
+
+ }
+ }
+
+ return false;
+}
+#endif
+
static void swrap_remove_stale(int fd)
{
struct socket_info *si = find_socket_info(fd);
switch (in_addr->sa_family) {
case AF_UNSPEC: {
- struct sockaddr_in *sin;
+ const struct sockaddr_in *sin;
if (si->family != AF_INET) {
break;
}
if (in_len < sizeof(struct sockaddr_in)) {
break;
}
- sin = (struct sockaddr_in *)in_addr;
+ sin = (const struct sockaddr_in *)in_addr;
if(sin->sin_addr.s_addr != htonl(INADDR_ANY)) {
break;
}
struct sockaddr_un un_addr;
struct socket_info *si = find_socket_info(s);
int bind_error = 0;
+#if 0 /* FIXME */
+ bool in_use;
+#endif
if (!si) {
return libc_bind(s, myaddr, addrlen);
break;
}
- sin = (struct sockaddr_in *)myaddr;
+ sin = (const struct sockaddr_in *)myaddr;
if (sin->sin_family != AF_INET) {
bind_error = EAFNOSUPPORT;
break;
}
- sin6 = (struct sockaddr_in6 *)myaddr;
+ sin6 = (const struct sockaddr_in6 *)myaddr;
if (sin6->sin6_family != AF_INET6) {
bind_error = EAFNOSUPPORT;
return -1;
}
+#if 0 /* FIXME */
+ in_use = check_addr_port_in_use(myaddr, addrlen);
+ if (in_use) {
+ errno = EADDRINUSE;
+ return -1;
+ }
+#endif
+
free(si->myname);
si->myname_len = addrlen;
si->myname = sockaddr_dup(myaddr, addrlen);
*(int *)optval = si->family;
return 0;
#endif /* SO_DOMAIN */
+
+#ifdef SO_PROTOCOL
case SO_PROTOCOL:
if (optval == NULL || optlen == NULL ||
*optlen < (socklen_t)sizeof(int)) {
*optlen = sizeof(int);
*(int *)optval = si->protocol;
return 0;
+#endif /* SO_PROTOCOL */
case SO_TYPE:
if (optval == NULL || optlen == NULL ||
*optlen < (socklen_t)sizeof(int)) {
{
/* Add packet info */
switch (si->pktinfo) {
-#if defined(IP_PKTINFO)
-/* && (defined(HAVE_STRUCT_IN_PKTINFO) || defined(IP_RECVDSTADDR)) */
+#if defined(IP_PKTINFO) && (defined(HAVE_STRUCT_IN_PKTINFO) || defined(IP_RECVDSTADDR))
case AF_INET: {
struct sockaddr_in *sin;
#if defined(HAVE_STRUCT_IN_PKTINFO)