7bcb85fc500fe2f71126bc61b2e1b7f182927477
[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 <string.h>
9 #include <ctype.h>
10 #include "lookup.h"
11
12 int __inet_aton(const char *, struct in_addr *);
13
14 int __lookup_ipliteral(struct address buf[static 1], const char *name, int family)
15 {
16         struct in_addr a4;
17         struct in6_addr a6;
18         if (family != AF_INET6 && __inet_aton(name, &a4)>0) {
19                 memcpy(&buf[0].addr, &a4, sizeof a4);
20                 buf[0].family = AF_INET;
21                 buf[0].scopeid = 0;
22                 return 1;
23         }
24         if (family != AF_INET) {
25                 char tmp[64];
26                 char *p = strchr(name, '%'), *z;
27                 unsigned long long scopeid;
28                 if (p && p-name < 64) {
29                         memcpy(tmp, name, p-name);
30                         tmp[p-name] = 0;
31                         name = tmp;
32                 }
33                 if (inet_pton(AF_INET6, name, &a6)<=0) return 0;
34                 memcpy(&buf[0].addr, &a6, sizeof a6);
35                 buf[0].family = AF_INET6;
36                 if (p) {
37                         if (isdigit(*++p)) scopeid = strtoull(p, &z, 10);
38                         else z = p-1;
39                         if (*z) {
40                                 if (!IN6_IS_ADDR_LINKLOCAL(&a6) &&
41                                     !IN6_IS_ADDR_MC_LINKLOCAL(&a6))
42                                         return EAI_NONAME;
43                                 scopeid = if_nametoindex(p);
44                                 if (!scopeid) return EAI_NONAME;
45                         }
46                         if (scopeid > UINT_MAX) return EAI_NONAME;
47                         buf[0].scopeid = scopeid;
48                 }
49                 return 1;
50         }
51         return 0;
52 }