implement dn_skipname (legacy resolver function)
[musl] / src / network / getnameinfo.c
1 #include <netdb.h>
2 #include <limits.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <stdio.h>
6 #include <sys/socket.h>
7 #include <netinet/in.h>
8 #include <arpa/inet.h>
9 #include "__dns.h"
10
11 int getnameinfo(const struct sockaddr *restrict sa, socklen_t sl,
12         char *restrict node, socklen_t nodelen,
13         char *restrict serv, socklen_t servlen,
14         int flags)
15 {
16         char buf[256];
17         unsigned char reply[512];
18         int af = sa->sa_family;
19         unsigned char *a;
20
21         switch (af) {
22         case AF_INET:
23                 a = (void *)&((struct sockaddr_in *)sa)->sin_addr;
24                 if (sl != sizeof(struct sockaddr_in)) return EAI_FAMILY;
25                 break;
26         case AF_INET6:
27                 a = (void *)&((struct sockaddr_in6 *)sa)->sin6_addr;
28                 if (sl != sizeof(struct sockaddr_in6)) return EAI_FAMILY;
29                 break;
30         default:
31                 return EAI_FAMILY;
32         }
33
34         if (node && nodelen) {
35                 if ((flags & NI_NUMERICHOST)
36                         || __dns_query(reply, a, af, 1) <= 0
37                         || __dns_get_rr(buf, 0, 256, 1, reply, RR_PTR, 1) <= 0)
38                 {
39                         if (flags & NI_NAMEREQD) return EAI_NONAME;
40                         inet_ntop(af, a, buf, sizeof buf);
41                 }
42                 if (strlen(buf) >= nodelen) return EAI_OVERFLOW;
43                 strcpy(node, buf);
44         }
45
46         if (serv && servlen) {
47                 if (snprintf(buf, sizeof buf, "%d",
48                         ntohs(((struct sockaddr_in *)sa)->sin_port))>=servlen)
49                         return EAI_OVERFLOW;
50                 strcpy(serv, buf);
51         }
52
53         return 0;
54 }