leafnode  1.12.0
About: Leafnode is a store & forward NNTP proxy for small (dialup) sites.
  Fossies Dox: leafnode-1.12.0.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

masock_sa2name.c
Go to the documentation of this file.
1/** \file masock_sa2name.c
2 * (C) Copyright 2001 - 2021 by Matthias Andree
3 * \author Matthias Andree
4 * \year 2001,2021
5 */
6
7#ifndef _GNU_SOURCE
8#define _GNU_SOURCE /* to expose nonstandard members in in.h structures to
9 * fix compilation in strict conformance mode on Linux
10 */
11#endif
12
13#include "masock.h"
14#include "critmem.h"
15#include "config.h"
16
17#include <sys/types.h>
18#include <sys/socket.h>
19#include <netinet/in.h>
20#ifndef __LCLINT__
21#include <arpa/inet.h>
22#endif /* not __LCLINT__ */
23#include <netdb.h>
24
25#include <string.h>
26
27#ifdef WITH_DMALLOC
28#include <dmalloc.h>
29#endif
30
31#include <errno.h>
32
33/** Look up the host name belonging to the socket address. If compiled
34 * with IPv6 support, use IPv6 lookup unless the address is actually an
35 * IPv6-mapped IPv4 address.
36 *
37 * \return strdup'ed string containing the host name or NULL in case of
38 * trouble.
39 *
40 * \bug Linux [e]glibc has broken IN6_IS_ADDR_* macros that do not cast to
41 * const and that do not work in strict conformance mode because they
42 * access nonstandard members.
43 */
44char *
45masock_sa2name(const struct sockaddr *sa
46 /** socket address to convert */ ,
47 /*@out@*/ int *h_e
48 /** variable to place h_errno into */ )
49{
50 struct hostent *he;
51 char *ret;
52
53 switch (sa->sa_family) {
54#ifdef HAVE_IPV6
55 case AF_INET6:
56 /* any warnings issued here are the fault of broken system
57 includes */
58 if (IN6_IS_ADDR_V4MAPPED(&((const struct sockaddr_in6 *)sa)->sin6_addr)) {
59 /* do IPv4 lookup on mapped addresses */
60 /* see RFC-2553 section 6.2 for "12" */
61 he = gethostbyaddr(12 + (const char *)
62 &((const struct sockaddr_in6 *)sa)
63 ->sin6_addr, sizeof(struct in_addr), AF_INET);
64 } else {
65 /* real IPv6 */
66 he = gethostbyaddr((const char *)
67 &((const struct sockaddr_in6 *)sa)
68 ->sin6_addr,
69 sizeof(struct in6_addr), sa->sa_family);
70 }
71 if (!he)
72 errno = 0, *h_e = h_errno;
73 break;
74#endif
75 case AF_INET:
76 he = gethostbyaddr((const char *)
77 &((const struct sockaddr_in *)sa)
78 ->sin_addr.s_addr,
79 sizeof(struct in_addr), sa->sa_family);
80 if (!he)
81 errno = 0, *h_e = h_errno;
82 break;
83 default:
84 errno = EAFNOSUPPORT;
85 *h_e = 0;
86 he = 0;
87 break;
88 }
89
90 ret = he && he->h_name ? critstrdup(he->h_name, "masock_sa2name") : 0;
91 endhostent();
92 return ret;
93}
char * critstrdup(const char *source, const char *message)
Definition: critmem.c:92
char * masock_sa2name(const struct sockaddr *sa, int *h_e)