1 #include <sys/socket.h>
2 #include <netinet/in.h>
3 #include <netdb.h>
4 #include <ctype.h>
5 #include <string.h>
6 #include <stdlib.h>
7 #include <fcntl.h>
8 #include <errno.h>
9 #include "lookup.h"
10 #include "stdio_impl.h"
11 #include "network_conf_function.h"
12
__lookup_serv(struct service buf[static MAXSERVS],const char * name,int proto,int socktype,int flags)13 int __lookup_serv(struct service buf[static MAXSERVS], const char *name, int proto, int socktype, int flags)
14 {
15 char line[128];
16 int cnt = 0;
17 char *p, *z = "";
18 unsigned long port = 0;
19
20 switch (socktype) {
21 case SOCK_STREAM:
22 switch (proto) {
23 case 0:
24 proto = IPPROTO_TCP;
25 case IPPROTO_TCP:
26 break;
27 default:
28 #ifndef __LITEOS__
29 MUSL_LOGE("%{public}s: %{public}d: socktype mismatch IPPROTO_TCP: %{public}d", __func__, __LINE__, proto);
30 #endif
31 return EAI_SERVICE;
32 }
33 break;
34 case SOCK_DGRAM:
35 switch (proto) {
36 case 0:
37 proto = IPPROTO_UDP;
38 case IPPROTO_UDP:
39 break;
40 default:
41 #ifndef __LITEOS__
42 MUSL_LOGE("%{public}s: %{public}d: socktype mismatch IPPROTO_UDP: %{public}d", __func__, __LINE__, proto);
43 #endif
44 return EAI_SERVICE;
45 }
46 case 0:
47 break;
48 default:
49 if (name) {
50 #ifndef __LITEOS__
51 MUSL_LOGE("%{public}s: %{public}d: socktype mismatch name: %{public}d", __func__, __LINE__, EAI_SERVICE);
52 #endif
53 return EAI_SERVICE;
54 }
55 buf[0].port = 0;
56 buf[0].proto = proto;
57 buf[0].socktype = socktype;
58 return 1;
59 }
60
61 if (name) {
62 if (!*name) {
63 #ifndef __LITEOS__
64 MUSL_LOGE("%{public}s: %{public}d: invaild server name: %{public}d", __func__, __LINE__, EAI_SERVICE);
65 #endif
66 return EAI_SERVICE;
67 }
68 port = strtoul(name, &z, 10);
69 }
70 if (!*z) {
71 if (port > 65535) {
72 #ifndef __LITEOS__
73 MUSL_LOGE("%{public}s: %{public}d: port is larger than 65535: %{public}d", __func__, __LINE__, EAI_SERVICE);
74 #endif
75 return EAI_SERVICE;
76 }
77 if (proto != IPPROTO_UDP) {
78 buf[cnt].port = port;
79 buf[cnt].socktype = SOCK_STREAM;
80 buf[cnt++].proto = IPPROTO_TCP;
81 }
82 if (proto != IPPROTO_TCP) {
83 buf[cnt].port = port;
84 buf[cnt].socktype = SOCK_DGRAM;
85 buf[cnt++].proto = IPPROTO_UDP;
86 }
87 return cnt;
88 }
89
90 if (flags & AI_NUMERICSERV) {
91 #ifndef __LITEOS__
92 MUSL_LOGE("%{public}s: %{public}d: flags is AI_NUMERICSERV: %{public}d", __func__, __LINE__, EAI_NONAME);
93 #endif
94 return EAI_NONAME;
95 }
96
97 size_t l = strlen(name);
98
99 unsigned char _buf[1032];
100 FILE _f, *f = __fopen_rb_ca("/etc/services", &_f, _buf, sizeof _buf);
101 int indexPtr = 0;
102 while (get_services_str(line, f, &indexPtr)) {
103 if ((p=strchr(line, '#'))) *p++='\n', *p=0;
104
105 /* Find service name */
106 for(p=line; (p=strstr(p, name)); p++) {
107 if (p>line && !isspace(p[-1])) continue;
108 if (p[l] && !isspace(p[l])) continue;
109 break;
110 }
111 if (!p) continue;
112
113 /* Skip past canonical name at beginning of line */
114 for (p=line; *p && !isspace(*p); p++);
115
116 port = strtoul(p, &z, 10);
117 if (port > 65535 || z==p) continue;
118 if (!strncmp(z, "/udp", 4)) {
119 if (proto == IPPROTO_TCP) continue;
120 buf[cnt].port = port;
121 buf[cnt].socktype = SOCK_DGRAM;
122 buf[cnt++].proto = IPPROTO_UDP;
123 }
124 if (!strncmp(z, "/tcp", 4)) {
125 if (proto == IPPROTO_UDP) continue;
126 buf[cnt].port = port;
127 buf[cnt].socktype = SOCK_STREAM;
128 buf[cnt++].proto = IPPROTO_TCP;
129 }
130 }
131 if (f) {
132 __fclose_ca(f);
133 }
134 if (cnt > 0) {
135 return cnt;
136 } else {
137 #ifndef __LITEOS__
138 MUSL_LOGE("%{public}s: %{public}d: wrong server count: %{public}d", __func__, __LINE__, cnt);
139 #endif
140 return EAI_SERVICE;
141 }
142 }
143