• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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