add support for reverse name lookups from hosts file to getnameinfo
[musl] / src / network / lookup_ipliteral.c
1 #include <sys/socket.h>
2 #include <netinet/in.h>
3 #include <netdb.h>
4 #include <net/if.h>
5 #include <arpa/inet.h>
6 #include <limits.h>
7 #include <stdlib.h>
8 #include <ctype.h>
9 #include "lookup.h"
10
11 int __inet_aton(const char *, struct in_addr *);
12
13 int __lookup_ipliteral(struct address buf[static 1], const char *name, int family)
14 {
15         struct in_addr a4;
16         struct in6_addr a6;
17         if (family != AF_INET6 && __inet_aton(name, &a4)>0) {
18                 memcpy(&buf[0].addr, &a4, sizeof a4);
19                 buf[0].family = AF_INET;
20                 buf[0].scopeid = 0;
21                 return 1;
22         }
23         if (family != AF_INET) {
24                 char tmp[64];
25                 char *p = strchr(name, '%'), *z;
26                 unsigned long long scopeid;
27                 if (p && p-name < 64) {
28                         memcpy(tmp, name, p-name);
29                         tmp[p-name] = 0;
30                         name = tmp;
31                 }
32                 if (inet_pton(AF_INET6, name, &a6)<=0) return 0;
33                 memcpy(&buf[0].addr, &a6, sizeof a6);
34                 buf[0].family = AF_INET6;
35                 if (p) {
36                         if (isdigit(*++p)) scopeid = strtoull(p, &z, 10);
37                         else z = p-1;
38                         if (*z) {
39                                 if (!IN6_IS_ADDR_LINKLOCAL(&a6) &&
40                                     !IN6_IS_ADDR_MC_LINKLOCAL(&a6))
41                                         return EAI_NONAME;
42                                 scopeid = if_nametoindex(p);
43                                 if (!scopeid) return EAI_NONAME;
44                         }
45                         if (scopeid > UINT_MAX) return EAI_NONAME;
46                         buf[0].scopeid = scopeid;
47                 }
48                 return 1;
49         }
50         return 0;
51 }