3 #include "inet_ntop_cache.h"
6 #include "sys-socket.h"
12 unsigned short sock_addr_get_port (const sock_addr
*addr
)
14 switch (addr
->plain
.sa_family
) {
16 return ntohs(addr
->ipv4
.sin_port
);
19 return ntohs(addr
->ipv6
.sin6_port
);
21 default: /* case AF_UNIX: */
27 int sock_addr_inet_pton(sock_addr
*addr
, const char *str
,
28 int family
, unsigned short port
)
30 if (AF_INET
== family
) {
31 memset(&addr
->ipv4
, 0, sizeof(struct sockaddr_in
));
32 addr
->ipv4
.sin_family
= AF_INET
;
33 addr
->ipv4
.sin_port
= htons(port
);
34 #if defined(HAVE_INET_ATON) /*(Windows does not provide inet_aton())*/
35 return (0 != inet_aton(str
, &addr
->ipv4
.sin_addr
));
37 return ((addr
->ipv4
.sin_addr
.s_addr
= inet_addr(str
)) != INADDR_NONE
);
41 else if (AF_INET6
== family
) {
42 memset(&addr
->ipv6
, 0, sizeof(struct sockaddr_in6
));
43 addr
->ipv6
.sin6_family
= AF_INET6
;
44 addr
->ipv6
.sin6_port
= htons(port
);
45 return inet_pton(AF_INET6
, str
, &addr
->ipv6
.sin6_addr
);
55 const char * sock_addr_inet_ntop(const sock_addr
*addr
, char *buf
, socklen_t sz
)
57 if (addr
->plain
.sa_family
== AF_INET
) {
58 #if defined(HAVE_INET_PTON) /*(expect inet_ntop if inet_pton)*/
59 return inet_ntop(AF_INET
,(const void *)&addr
->ipv4
.sin_addr
,buf
,sz
);
60 #else /*(inet_ntoa() not thread-safe)*/
61 return inet_ntoa(addr
->ipv4
.sin_addr
);
65 else if (addr
->plain
.sa_family
== AF_INET6
) {
66 return inet_ntop(AF_INET6
,(const void *)&addr
->ipv6
.sin6_addr
,buf
,sz
);
70 else if (addr
->plain
.sa_family
== AF_UNIX
) {
71 return addr
->un
.sun_path
;
81 int sock_addr_inet_ntop_copy_buffer(buffer
*b
, const sock_addr
*addr
)
83 /*(incur cost of extra copy to avoid potential extra memory allocation)*/
84 char buf
[UNIX_PATH_MAX
];
85 const char *s
= sock_addr_inet_ntop(addr
, buf
, sizeof(buf
));
86 if (NULL
== s
) return -1; /*(buffer not modified if any error occurs)*/
87 buffer_copy_string(b
, s
);
92 int sock_addr_inet_ntop_append_buffer(buffer
*b
, const sock_addr
*addr
)
94 /*(incur cost of extra copy to avoid potential extra memory allocation)*/
95 char buf
[UNIX_PATH_MAX
];
96 const char *s
= sock_addr_inet_ntop(addr
, buf
, sizeof(buf
));
97 if (NULL
== s
) return -1; /*(buffer not modified if any error occurs)*/
98 buffer_append_string(b
, s
);
103 const char * inet_ntop_cache_get_ip(server
*srv
, sock_addr
*addr
) {
108 struct in6_addr ipv6
;
111 char b2
[INET6_ADDRSTRLEN
+ 1];
112 } inet_ntop_cache_type
;
113 #define INET_NTOP_CACHE_MAX 4
114 static inet_ntop_cache_type inet_ntop_cache
[INET_NTOP_CACHE_MAX
];
119 for (i
= 0; i
< INET_NTOP_CACHE_MAX
; i
++) {
120 if (inet_ntop_cache
[i
].family
== addr
->plain
.sa_family
) {
121 if (inet_ntop_cache
[i
].family
== AF_INET6
&&
122 0 == memcmp(inet_ntop_cache
[i
].addr
.ipv6
.s6_addr
, addr
->ipv6
.sin6_addr
.s6_addr
, 16)) {
123 /* IPv6 found in cache */
125 } else if (inet_ntop_cache
[i
].family
== AF_INET
&&
126 inet_ntop_cache
[i
].addr
.ipv4
.s_addr
== addr
->ipv4
.sin_addr
.s_addr
) {
127 /* IPv4 found in cache */
134 if (i
== INET_NTOP_CACHE_MAX
) {
135 /* not found in cache */
139 if (++ndx
>= INET_NTOP_CACHE_MAX
) ndx
= 0;
141 inet_ntop(addr
->plain
.sa_family
,
142 addr
->plain
.sa_family
== AF_INET6
?
143 (const void *) &(addr
->ipv6
.sin6_addr
) :
144 (const void *) &(addr
->ipv4
.sin_addr
),
145 inet_ntop_cache
[i
].b2
, INET6_ADDRSTRLEN
);
146 if (NULL
== s
) return "";
148 inet_ntop_cache
[i
].family
= addr
->plain
.sa_family
;
150 if (inet_ntop_cache
[i
].family
== AF_INET
) {
151 inet_ntop_cache
[i
].addr
.ipv4
.s_addr
= addr
->ipv4
.sin_addr
.s_addr
;
152 } else if (inet_ntop_cache
[i
].family
== AF_INET6
) {
153 memcpy(inet_ntop_cache
[i
].addr
.ipv6
.s6_addr
, addr
->ipv6
.sin6_addr
.s6_addr
, 16);
157 return inet_ntop_cache
[i
].b2
;
160 return inet_ntoa(addr
->ipv4
.sin_addr
);