$NetBSD: patch-af,v 1.1 2002/01/10 16:43:28 skrll Exp $ --- qw_common/net_udp.c.orig Thu Jan 13 04:01:30 2000 +++ qw_common/net_udp.c @@ -73,11 +73,9 @@ #else typedef struct sockaddr_in6 sockaddress_t; #ifdef __sun__ -#define s6_addr32 _S6_un._S6_u32 +#define ss_family __ss_family +#define ss_len __ss_len #endif __sun__ -#ifdef __FreeBSD__ -#define s6_addr32 __u6_addr.__u6_addr32 -#endif __FreeBSD__ #endif AF_INET6 @@ -108,11 +106,8 @@ memset (s, 0, sizeof(*s)); // s->sin6_family = a->family; - s->sin6_family = AF_UNSPEC; - s->sin6_addr.s6_addr32[0] = a->ip[0]; - s->sin6_addr.s6_addr32[1] = a->ip[1]; - s->sin6_addr.s6_addr32[2] = a->ip[2]; - s->sin6_addr.s6_addr32[3] = a->ip[3]; + s->sin6_family = AF_INET6; + memcpy(&s->sin6_addr, a->ip, sizeof(s->sin6_addr)); s->sin6_port = a->port; s->sin6_len = sizeof(struct sockaddr_in6); #endif @@ -124,10 +119,7 @@ *(int *)&a->ip = *(int *)&s->sin_addr; a->port = s->sin_port; #else - a->ip[0] = s->sin6_addr.s6_addr32[0]; - a->ip[1] = s->sin6_addr.s6_addr32[1]; - a->ip[2] = s->sin6_addr.s6_addr32[2]; - a->ip[3] = s->sin6_addr.s6_addr32[3]; + memcpy(a->ip, &s->sin6_addr, sizeof(s->sin6_addr)); a->port = s->sin6_port; a->family = s->sin6_family; #endif @@ -182,11 +174,21 @@ static char s[BUFSIZ]; struct sockaddr_storage ss; - ss.__ss_len = sizeof(ss); - ss.__ss_family = AF_UNSPEC; - memcpy(ss.__ss_pad1, &(a.ip), sizeof(a.ip)); - if (getnameinfo((struct sockaddr *) &ss,sizeof(ss),s,sizeof(s),NULL,0,NI_NUMERICHOST)) { - strcpy(s,""); + memset(&ss, 0, sizeof(ss)); + if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)a.ip)) { + ss.ss_len = sizeof(struct sockaddr_in); + ss.ss_family = AF_INET; + memcpy(&((struct sockaddr_in *)&ss)->sin_addr, + &((struct in6_addr *)a.ip)->s6_addr[12], sizeof(struct in_addr)); + } else { + ss.ss_len = sizeof(struct sockaddr_in6); + ss.ss_family = AF_INET6; + memcpy(&((struct sockaddr_in6 *)&ss)->sin6_addr, + a.ip, sizeof(struct in6_addr)); + } + if (getnameinfo((struct sockaddr *)&ss, ss.ss_len, s, sizeof(s), + NULL, 0, NI_NUMERICHOST)) { + strcpy(s, ""); } return s; } @@ -282,10 +284,9 @@ ss6=(struct sockaddr_in6 *) &ss; ss4=(struct sockaddr_in *) resultp->ai_addr; ss6->sin6_family=AF_INET6; - ss6->sin6_addr.s6_addr32[0]=0; - ss6->sin6_addr.s6_addr32[1]=0; - ss6->sin6_addr.s6_addr32[2]=htonl(0xffff); - ss6->sin6_addr.s6_addr32[3]=ss4->sin_addr.s_addr; + memset(&ss6->sin6_addr, 0, sizeof(ss6->sin6_addr)); + ss6->sin6_addr.s6_addr[10] = ss6->sin6_addr.s6_addr[11] = 0xff; + memcpy(&ss6->sin6_addr.s6_addr[12], &ss4->sin_addr, sizeof(ss4->sin_addr)); break; case AF_INET6: memcpy(&ss,resultp->ai_addr,sizeof(struct sockaddr_in6)); @@ -305,10 +306,10 @@ // the IP is NOT one of our interfaces. qboolean NET_IsClientLegal(netadr_t *adr) { +#if 0 sockaddress_t sadr; int newsocket; -#if 0 if (adr->ip[0] == 127) return false; // no local connections period @@ -416,6 +417,7 @@ int Error; char Buf[BUFSIZ], *Service, *Host; qboolean _true = true; + const int false = 0; int i; memset(&hints, 0, sizeof(hints)); @@ -438,13 +440,21 @@ Service = Buf; } - if(Error = getaddrinfo(Host, Service, &hints, &res)) + Error = getaddrinfo(Host, Service, &hints, &res); + if (Error) Sys_Error ("UDP_OpenSocket: getaddrinfo: %s", gai_strerror(Error)); if ((newsocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) Sys_Error ("UDP_OpenSocket: socket:", strerror(errno)); if (ioctl (newsocket, FIONBIO, (char *)&_true) == -1) Sys_Error ("UDP_OpenSocket: ioctl FIONBIO:", strerror(errno)); + +#ifdef IPV6_BINDV6ONLY + if (setsockopt(newsocket, IPPROTO_IPV6, IPV6_BINDV6ONLY, &false, + sizeof(false)) < 0) { + /* I don't care */ + } +#endif if (bind(newsocket, res->ai_addr, res->ai_addrlen) < 0) Sys_Error ("UDP_OpenSocket: bind: %s", strerror(errno));