Commit 5ceabdd8 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Rewrite inet_pton() and inet_ntop() into compat

This should correct error handling cases.
parent 1a357f6f
/*****************************************************************************
* inet_pton.c: POSIX/IETF inet_pton() and inet_ntop() replacements
*****************************************************************************
* Copyright © 2011 Rémi Denis-Courmont
*
* This program 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 program 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.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#ifndef WIN32
# include <sys/socket.h>
#else
# include <winsock2.h>
# define EAFNOSUPPORT WSAEAFNOSUPPORT
#endif
int inet_pton (int af, const char *src, void *dst)
{
unsigned char *b = dst;
switch (af)
{
case AF_INET:
return sscanf (src, "%hhu.%hhu.%hhu.%hhu",
b + 0, b + 1, b + 2, b + 3) == 4;
}
errno = EAFNOSUPPORT;
return -1;
}
const char *inet_ntop (int af, const void *src, char *dst, int len)
{
const unsigned char *b = src;
switch (af)
{
case AF_INET:
if (snprintf (dst, len, "%hhu.%hhu.%hhu.%hhu",
b[0], b[1], b[2], b[3]) <= len)
{
errno = ENOSPC;
return NULL;
}
return dst;
}
errno = EAFNOSUPPORT;
return NULL;
}
...@@ -559,7 +559,7 @@ need_libc=false ...@@ -559,7 +559,7 @@ need_libc=false
dnl Check for usual libc functions dnl Check for usual libc functions
AC_CHECK_DECLS([nanosleep],,,[#include <time.h>]) AC_CHECK_DECLS([nanosleep],,,[#include <time.h>])
AC_CHECK_FUNCS([daemon fcntl fstatvfs fork getenv getpwuid_r if_nameindex if_nametoindex isatty lstat memalign mmap openat pread posix_fadvise posix_madvise setlocale stricmp strnicmp uselocale]) AC_CHECK_FUNCS([daemon fcntl fstatvfs fork getenv getpwuid_r if_nameindex if_nametoindex isatty lstat memalign mmap openat pread posix_fadvise posix_madvise setlocale stricmp strnicmp uselocale])
AC_REPLACE_FUNCS([asprintf atof atoll dirfd fdopendir flockfile fsync getdelim getpid gmtime_r lldiv localtime_r nrand48 rewind setenv strcasecmp strcasestr strdup strlcpy strncasecmp strndup strnlen strsep strtof strtok_r strtoll swab tdestroy vasprintf]) AC_REPLACE_FUNCS([asprintf atof atoll dirfd fdopendir flockfile fsync getdelim getpid gmtime_r inet_pton lldiv localtime_r nrand48 rewind setenv strcasecmp strcasestr strdup strlcpy strncasecmp strndup strnlen strsep strtof strtok_r strtoll swab tdestroy vasprintf])
AC_CHECK_FUNCS(fdatasync,, AC_CHECK_FUNCS(fdatasync,,
[AC_DEFINE(fdatasync, fsync, [Alias fdatasync() to fsync() if missing.]) [AC_DEFINE(fdatasync, fsync, [Alias fdatasync() to fsync() if missing.])
]) ])
...@@ -1645,22 +1645,6 @@ AS_IF([test "${enable_vlm}" != "no"], [ ...@@ -1645,22 +1645,6 @@ AS_IF([test "${enable_vlm}" != "no"], [
AM_CONDITIONAL([ENABLE_VLM], [test "${enable_vlm}" != "no"]) AM_CONDITIONAL([ENABLE_VLM], [test "${enable_vlm}" != "no"])
dnl
dnl ipv6 support
dnl
have_ipv6=no
AC_CHECK_FUNCS(inet_pton,[have_ipv6=yes],[
AC_CHECK_LIB(nsl,inet_pton, [have_ipv6=yes])
])
AS_IF([test "${have_ipv6}" = "yes"], [
AC_DEFINE(HAVE_INET_PTON, 1, [Define to 1 if you have inet_pton().])])
AC_CHECK_FUNCS(inet_ntop,[
AC_DEFINE(HAVE_INET_NTOP, 1, [Define to 1 if you have inet_ntop().])])
dnl dnl
dnl Input plugins dnl Input plugins
dnl dnl
......
...@@ -250,11 +250,8 @@ void swab (const void *, void *, ssize_t); ...@@ -250,11 +250,8 @@ void swab (const void *, void *, ssize_t);
/* Socket stuff */ /* Socket stuff */
#ifndef HAVE_INET_PTON #ifndef HAVE_INET_PTON
# define inet_pton vlc_inet_pton int inet_pton(int, const char *, void *);
#endif const char *inet_ntop(int, const void *, char *, int);
#ifndef HAVE_INET_NTOP
# define inet_ntop vlc_inet_ntop
#endif #endif
#ifndef HAVE_STRUCT_POLLFD #ifndef HAVE_STRUCT_POLLFD
......
...@@ -163,9 +163,6 @@ VLC_API ssize_t net_Printf( vlc_object_t *p_this, int fd, const v_socket_t *, co ...@@ -163,9 +163,6 @@ VLC_API ssize_t net_Printf( vlc_object_t *p_this, int fd, const v_socket_t *, co
VLC_API ssize_t net_vaPrintf( vlc_object_t *p_this, int fd, const v_socket_t *, const char *psz_fmt, va_list args ); VLC_API ssize_t net_vaPrintf( vlc_object_t *p_this, int fd, const v_socket_t *, const char *psz_fmt, va_list args );
#define net_vaPrintf(a,b,c,d,e) net_vaPrintf(VLC_OBJECT(a),b,c,d,e) #define net_vaPrintf(a,b,c,d,e) net_vaPrintf(VLC_OBJECT(a),b,c,d,e)
VLC_API int vlc_inet_pton(int af, const char *src, void *dst);
VLC_API const char *vlc_inet_ntop(int af, const void *src,
char *dst, socklen_t cnt);
struct pollfd; struct pollfd;
VLC_API int vlc_poll(struct pollfd *fds, unsigned nfds, int timeout); VLC_API int vlc_poll(struct pollfd *fds, unsigned nfds, int timeout);
......
...@@ -549,8 +549,6 @@ vlc_hold ...@@ -549,8 +549,6 @@ vlc_hold
vlc_iconv vlc_iconv
vlc_iconv_close vlc_iconv_close
vlc_iconv_open vlc_iconv_open
vlc_inet_ntop
vlc_inet_pton
vlc_join vlc_join
vlc_list_children vlc_list_children
vlc_list_release vlc_list_release
......
...@@ -189,88 +189,3 @@ out: ...@@ -189,88 +189,3 @@ out:
LocaleFree (node); LocaleFree (node);
return ret; return ret;
} }
/**
* inet_pton() replacement
*/
int vlc_inet_pton (int af, const char *src, void *dst)
{
#ifndef HAVE_INET_PTON
/* Windows Vista has inet_pton(), but not XP. */
/* We have a pretty good example of abstraction inversion here... */
struct addrinfo hints = {
.ai_family = af,
.ai_socktype = SOCK_DGRAM, /* make sure we have... */
.ai_protocol = IPPROTO_UDP, /* ...only one response */
.ai_flags = AI_NUMERICHOST,
}, *res;
if (getaddrinfo (src, NULL, &hints, &res))
return 0;
const void *data;
size_t len;
switch (af)
{
case AF_INET:
data = &((const struct sockaddr_in *)res->ai_addr)->sin_addr;
len = sizeof (struct in_addr);
break;
#ifdef AF_INET6
case AF_INET6:
data = &((const struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
len = sizeof (struct in6_addr);
break;
#endif
default:
freeaddrinfo (res);
return -1;
}
memcpy (dst, data, len);
freeaddrinfo (res);
return 1;
#else /* HAVE_INET_PTON */
return inet_pton( af, src, dst );
#endif /* HAVE_INET_PTON */
}
/**
* inet_ntop() replacement
*/
const char *vlc_inet_ntop (int af, const void *src, char *dst, socklen_t cnt)
{
#ifndef HAVE_INET_NTOP
int ret = EAI_FAMILY;
switch (af)
{
#ifdef AF_INET6
case AF_INET6:
{
struct sockaddr_in6 addr;
memset (&addr, 0, sizeof(addr));
addr.sin6_family = AF_INET6;
addr.sin6_addr = *(struct in6_addr *)src;
ret = getnameinfo ((struct sockaddr *)&addr, sizeof (addr),
dst, cnt, NULL, 0, NI_NUMERICHOST);
}
#endif
case AF_INET:
{
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr = *(struct in_addr *)src;
ret = getnameinfo ((struct sockaddr *)&addr, sizeof (addr),
dst, cnt, NULL, 0, NI_NUMERICHOST);
}
}
return (ret == 0) ? dst : NULL;
#else /* HAVE_INET_NTOP */
return inet_ntop( af, src, dst, cnt );
#endif /* HAVE_INET_NTOP */
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment