wsutil: fix compilation on freebsd.
[metze/wireshark/wip.git] / wsutil / inet_addr.c
1 /* inet_addr.c
2  *
3  * Wireshark - Network traffic analyzer
4  * By Gerald Combs <gerald@wireshark.org>
5  * Copyright 1998 Gerald Combs
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  */
9
10 #include "config.h"
11 #include "inet_addr.h"
12
13 #include <errno.h>
14 #include <string.h>
15
16 #ifdef HAVE_ARPA_INET_H
17 #include <arpa/inet.h>
18 #endif
19
20 #ifdef HAVE_NETINET_IN_H
21 #include <netinet/in.h>
22 #endif
23
24 #include <sys/types.h>
25
26 #ifdef HAVE_SYS_SOCKET_H
27 #include <sys/socket.h>         /* needed to define AF_ values on UNIX */
28 #endif
29
30 #ifdef _WIN32
31 #include <Ws2tcpip.h>   /* indirectly defines AF_ values on Windows */
32 #define _NTOP_SRC_CAST_ (PVOID)
33 #else
34 #define _NTOP_SRC_CAST_
35 #endif
36
37 /*
38  * We assume and require an inet_pton/inet_ntop that supports AF_INET
39  * and AF_INET6.
40  */
41
42 static inline gboolean
43 _inet_pton(int af, const gchar *src, gpointer dst)
44 {
45     gint ret = inet_pton(af, src, dst);
46     if (G_UNLIKELY(ret < 0)) {
47         /* EAFNOSUPPORT */
48         if (af == AF_INET) {
49             memset(dst, 0, sizeof(struct in_addr));
50             g_critical("ws_inet_pton4: EAFNOSUPPORT");
51         }
52         else if (af == AF_INET6) {
53             memset(dst, 0, sizeof(struct in6_addr));
54             g_critical("ws_inet_pton6: EAFNOSUPPORT");
55         }
56         else {
57             g_assert(0);
58         }
59         errno = EAFNOSUPPORT;
60     }
61     return ret == 1;
62 }
63
64 static inline const gchar *
65 _inet_ntop(int af, gconstpointer src, gchar *dst, guint dst_size)
66 {
67     const gchar *ret = inet_ntop(af, _NTOP_SRC_CAST_ src, dst, dst_size);
68     if (G_UNLIKELY(ret == NULL)) {
69         int saved_errno = errno;
70         gchar *errmsg = "<<ERROR>>";
71         switch (errno) {
72             case EAFNOSUPPORT:
73                 errmsg = "<<EAFNOSUPPORT>>";
74                 g_critical("ws_inet_ntop: EAFNOSUPPORT");
75                 break;
76             case ENOSPC:
77                 errmsg = "<<ENOSPC>>";
78                 break;
79             default:
80                 break;
81         }
82         /* set result to something that can't be confused with a valid conversion */
83         g_strlcpy(dst, errmsg, dst_size);
84         /* set errno for caller */
85         errno = saved_errno;
86     }
87     return dst;
88 }
89
90 const gchar *
91 ws_inet_ntop4(gconstpointer src, gchar *dst, guint dst_size)
92 {
93     return _inet_ntop(AF_INET, src, dst, dst_size);
94 }
95
96 gboolean
97 ws_inet_pton4(const gchar *src, guint32 *dst)
98 {
99     return _inet_pton(AF_INET, src, dst);
100 }
101
102 const gchar *
103 ws_inet_ntop6(gconstpointer src, gchar *dst, guint dst_size)
104 {
105     return _inet_ntop(AF_INET6, src, dst, dst_size);
106 }
107
108 gboolean
109 ws_inet_pton6(const gchar *src, ws_in6_addr *dst)
110 {
111     return _inet_pton(AF_INET6, src, dst);
112 }