X-Git-Url: https://git.piment-noir.org/?p=deb_shairplay.git;a=blobdiff_plain;f=src%2Flib%2Fnetutils.c;h=3fc8838547aeb6857591eb95849f30737a5cd9c8;hp=255822bb436f9cd7f0cf35494c701370acc477cc;hb=64d59e3087f829006d091fa0d114efb50972a2bf;hpb=1b4a582b04fc39d9d4d930acb4d0803bdedfb32e diff --git a/src/lib/netutils.c b/src/lib/netutils.c index 255822b..3fc8838 100644 --- a/src/lib/netutils.c +++ b/src/lib/netutils.c @@ -1,3 +1,17 @@ +/** + * Copyright (C) 2011-2012 Juho Vähä-Herttua + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ + #include #include #include @@ -57,12 +71,19 @@ netutils_init_socket(unsigned short *port, int use_ipv6, int use_udp) memset(&saddr, 0, sizeof(saddr)); if (use_ipv6) { struct sockaddr_in6 *sin6ptr = (struct sockaddr_in6 *)&saddr; + int v6only = 1; /* Initialize sockaddr for bind */ sin6ptr->sin6_family = family; sin6ptr->sin6_addr = in6addr_any; sin6ptr->sin6_port = htons(*port); +#ifndef WIN32 + /* Make sure we only listen to IPv6 addresses */ + setsockopt(server_fd, IPPROTO_IPV6, IPV6_V6ONLY, + (char *) &v6only, sizeof(v6only)); +#endif + socklen = sizeof(*sin6ptr); ret = bind(server_fd, (struct sockaddr *)sin6ptr, socklen); if (ret == -1) { @@ -137,3 +158,39 @@ netutils_get_address(void *sockaddr, int *length) return NULL; } +int +netutils_parse_address(int family, const char *src, void *dst, int dstlen) +{ + struct addrinfo *result; + struct addrinfo *ptr; + struct addrinfo hints; + int length; + int ret; + + if (family != AF_INET && family != AF_INET6) { + return -1; + } + if (!src || !dst) { + return -1; + } + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = family; + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; + + ret = getaddrinfo(src, NULL, &hints, &result); + if (ret != 0) { + return -1; + } + + length = -1; + for (ptr=result; ptr!=NULL; ptr=ptr->ai_next) { + if (family == ptr->ai_family && (unsigned int)dstlen >= ptr->ai_addrlen) { + memcpy(dst, ptr->ai_addr, ptr->ai_addrlen); + length = ptr->ai_addrlen; + break; + } + } + freeaddrinfo(result); + return length; +}