1 /*
2  * Copyright (c) 2019 Linaro Limited
3  * Copyright (c) 2024, Friedt Professional Engineering Services, Inc
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <ctype.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 
12 #include <zephyr/net/net_if.h>
13 #include <zephyr/posix/arpa/inet.h>
14 #include <zephyr/posix/netinet/in.h>
15 #include <zephyr/posix/net/if.h>
16 #include <zephyr/posix/sys/socket.h>
17 
18 /* From arpa/inet.h */
19 
inet_addr(const char * cp)20 in_addr_t inet_addr(const char *cp)
21 {
22 	int val = 0;
23 	int len = 0;
24 	int dots = 0;
25 	int digits = 0;
26 
27 	/* error checking */
28 	if (cp == NULL) {
29 		return -1;
30 	}
31 
32 	for (int i = 0, subdigits = 0; i <= INET_ADDRSTRLEN; ++i, ++len) {
33 		if (subdigits > 3) {
34 			return -1;
35 		}
36 		if (cp[i] == '\0') {
37 			break;
38 		} else if (cp[i] == '.') {
39 			if (subdigits == 0) {
40 				return -1;
41 			}
42 			++dots;
43 			subdigits = 0;
44 			continue;
45 		} else if (isdigit((int)cp[i])) {
46 			++digits;
47 			++subdigits;
48 			continue;
49 		} else if (isspace((int)cp[i])) {
50 			break;
51 		}
52 
53 		return -1;
54 	}
55 
56 	if (dots != 3 || digits < 4) {
57 		return -1;
58 	}
59 
60 	/* conversion */
61 	for (int i = 0, tmp = 0; i < len; ++i, ++cp) {
62 		if (*cp != '.') {
63 			tmp *= 10;
64 			tmp += *cp - '0';
65 		}
66 
67 		if (*cp == '.' || i == len - 1) {
68 			val <<= 8;
69 			val |= tmp;
70 			tmp = 0;
71 		}
72 	}
73 
74 	return htonl(val);
75 }
76 
inet_ntoa(struct in_addr in)77 char *inet_ntoa(struct in_addr in)
78 {
79 	static char buf[INET_ADDRSTRLEN];
80 	unsigned char *bytes = (unsigned char *)&in.s_addr;
81 
82 	snprintf(buf, sizeof(buf), "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]);
83 
84 	return buf;
85 }
86 
inet_ntop(sa_family_t family,const void * src,char * dst,size_t size)87 char *inet_ntop(sa_family_t family, const void *src, char *dst, size_t size)
88 {
89 	return zsock_inet_ntop(family, src, dst, size);
90 }
91 
inet_pton(sa_family_t family,const char * src,void * dst)92 int inet_pton(sa_family_t family, const char *src, void *dst)
93 {
94 	return zsock_inet_pton(family, src, dst);
95 }
96 
97 /* From net/if.h */
98 
if_indextoname(unsigned int ifindex,char * ifname)99 char *if_indextoname(unsigned int ifindex, char *ifname)
100 {
101 	int ret;
102 
103 	ret = net_if_get_name(net_if_get_by_index(ifindex), ifname, IF_NAMESIZE);
104 	if (ret < 0) {
105 		errno = ENXIO;
106 		return NULL;
107 	}
108 
109 	return ifname;
110 }
111 
if_freenameindex(struct if_nameindex * ptr)112 void if_freenameindex(struct if_nameindex *ptr)
113 {
114 	size_t n;
115 
116 	if (ptr == NULL) {
117 		return;
118 	}
119 
120 	NET_IFACE_COUNT(&n);
121 
122 	for (size_t i = 0; i < n; ++i) {
123 		if (ptr[i].if_name != NULL) {
124 			free(ptr[i].if_name);
125 		}
126 	}
127 
128 	free(ptr);
129 }
130 
if_nameindex(void)131 struct if_nameindex *if_nameindex(void)
132 {
133 	size_t n;
134 	char *name;
135 	struct if_nameindex *ni;
136 
137 	/* FIXME: would be nice to use this without malloc */
138 	NET_IFACE_COUNT(&n);
139 	ni = malloc((n + 1) * sizeof(*ni));
140 	if (ni == NULL) {
141 		goto return_err;
142 	}
143 
144 	for (size_t i = 0; i < n; ++i) {
145 		ni[i].if_index = i + 1;
146 
147 		ni[i].if_name = malloc(IF_NAMESIZE);
148 		if (ni[i].if_name == NULL) {
149 			goto return_err;
150 		}
151 
152 		name = if_indextoname(i + 1, ni[i].if_name);
153 		__ASSERT_NO_MSG(name != NULL);
154 	}
155 
156 	ni[n].if_index = 0;
157 	ni[n].if_name = NULL;
158 
159 	return ni;
160 
161 return_err:
162 	if_freenameindex(ni);
163 	errno = ENOBUFS;
164 
165 	return NULL;
166 }
167 
if_nametoindex(const char * ifname)168 unsigned int if_nametoindex(const char *ifname)
169 {
170 	int ret;
171 
172 	ret = net_if_get_by_name(ifname);
173 	if (ret < 0) {
174 		return 0;
175 	}
176 
177 	return ret;
178 }
179 
180 /* From netdb.h */
181 
endhostent(void)182 void endhostent(void)
183 {
184 }
185 
endnetent(void)186 void endnetent(void)
187 {
188 }
189 
endprotoent(void)190 void endprotoent(void)
191 {
192 }
193 
endservent(void)194 void endservent(void)
195 {
196 }
197 
freeaddrinfo(struct zsock_addrinfo * ai)198 void freeaddrinfo(struct zsock_addrinfo *ai)
199 {
200 	zsock_freeaddrinfo(ai);
201 }
202 
gai_strerror(int errcode)203 const char *gai_strerror(int errcode)
204 {
205 	return zsock_gai_strerror(errcode);
206 }
207 
getaddrinfo(const char * host,const char * service,const struct zsock_addrinfo * hints,struct zsock_addrinfo ** res)208 int getaddrinfo(const char *host, const char *service, const struct zsock_addrinfo *hints,
209 		struct zsock_addrinfo **res)
210 {
211 	return zsock_getaddrinfo(host, service, hints, res);
212 }
213 
gethostent(void)214 struct hostent *gethostent(void)
215 {
216 	return NULL;
217 }
218 
getnameinfo(const struct sockaddr * addr,socklen_t addrlen,char * host,socklen_t hostlen,char * serv,socklen_t servlen,int flags)219 int getnameinfo(const struct sockaddr *addr, socklen_t addrlen, char *host, socklen_t hostlen,
220 		char *serv, socklen_t servlen, int flags)
221 {
222 	return zsock_getnameinfo(addr, addrlen, host, hostlen, serv, servlen, flags);
223 }
224 
getnetbyaddr(uint32_t net,int type)225 struct netent *getnetbyaddr(uint32_t net, int type)
226 {
227 	ARG_UNUSED(net);
228 	ARG_UNUSED(type);
229 
230 	return NULL;
231 }
232 
getnetbyname(const char * name)233 struct netent *getnetbyname(const char *name)
234 {
235 	ARG_UNUSED(name);
236 
237 	return NULL;
238 }
239 
getnetent(void)240 struct netent *getnetent(void)
241 {
242 	return NULL;
243 }
244 
getpeername(int sock,struct sockaddr * addr,socklen_t * addrlen)245 int getpeername(int sock, struct sockaddr *addr, socklen_t *addrlen)
246 {
247 	return zsock_getpeername(sock, addr, addrlen);
248 }
249 
getprotobyname(const char * name)250 struct protoent *getprotobyname(const char *name)
251 {
252 	ARG_UNUSED(name);
253 
254 	return NULL;
255 }
256 
getprotobynumber(int proto)257 struct protoent *getprotobynumber(int proto)
258 {
259 	ARG_UNUSED(proto);
260 
261 	return NULL;
262 }
263 
getprotoent(void)264 struct protoent *getprotoent(void)
265 {
266 	return NULL;
267 }
268 
getservbyname(const char * name,const char * proto)269 struct servent *getservbyname(const char *name, const char *proto)
270 {
271 	ARG_UNUSED(name);
272 	ARG_UNUSED(proto);
273 
274 	return NULL;
275 }
276 
getservbyport(int port,const char * proto)277 struct servent *getservbyport(int port, const char *proto)
278 {
279 	ARG_UNUSED(port);
280 	ARG_UNUSED(proto);
281 
282 	return NULL;
283 }
284 
getservent(void)285 struct servent *getservent(void)
286 {
287 	return NULL;
288 }
289 
sethostent(int stayopen)290 void sethostent(int stayopen)
291 {
292 	ARG_UNUSED(stayopen);
293 }
294 
setnetent(int stayopen)295 void setnetent(int stayopen)
296 {
297 	ARG_UNUSED(stayopen);
298 }
299 
setprotoent(int stayopen)300 void setprotoent(int stayopen)
301 {
302 	ARG_UNUSED(stayopen);
303 }
304 
setservent(int stayopen)305 void setservent(int stayopen)
306 {
307 	ARG_UNUSED(stayopen);
308 }
309 
310 /* From sys/socket.h */
311 
accept(int sock,struct sockaddr * addr,socklen_t * addrlen)312 int accept(int sock, struct sockaddr *addr, socklen_t *addrlen)
313 {
314 	return zsock_accept(sock, addr, addrlen);
315 }
316 
bind(int sock,const struct sockaddr * addr,socklen_t addrlen)317 int bind(int sock, const struct sockaddr *addr, socklen_t addrlen)
318 {
319 	return zsock_bind(sock, addr, addrlen);
320 }
321 
connect(int sock,const struct sockaddr * addr,socklen_t addrlen)322 int connect(int sock, const struct sockaddr *addr, socklen_t addrlen)
323 {
324 	return zsock_connect(sock, addr, addrlen);
325 }
326 
getsockname(int sock,struct sockaddr * addr,socklen_t * addrlen)327 int getsockname(int sock, struct sockaddr *addr, socklen_t *addrlen)
328 {
329 	return zsock_getsockname(sock, addr, addrlen);
330 }
331 
getsockopt(int sock,int level,int optname,void * optval,socklen_t * optlen)332 int getsockopt(int sock, int level, int optname, void *optval, socklen_t *optlen)
333 {
334 	return zsock_getsockopt(sock, level, optname, optval, optlen);
335 }
336 
listen(int sock,int backlog)337 int listen(int sock, int backlog)
338 {
339 	return zsock_listen(sock, backlog);
340 }
341 
recv(int sock,void * buf,size_t max_len,int flags)342 ssize_t recv(int sock, void *buf, size_t max_len, int flags)
343 {
344 	return zsock_recv(sock, buf, max_len, flags);
345 }
346 
recvfrom(int sock,void * buf,size_t max_len,int flags,struct sockaddr * src_addr,socklen_t * addrlen)347 ssize_t recvfrom(int sock, void *buf, size_t max_len, int flags, struct sockaddr *src_addr,
348 		 socklen_t *addrlen)
349 {
350 	return zsock_recvfrom(sock, buf, max_len, flags, src_addr, addrlen);
351 }
352 
recvmsg(int sock,struct msghdr * msg,int flags)353 ssize_t recvmsg(int sock, struct msghdr *msg, int flags)
354 {
355 	return zsock_recvmsg(sock, msg, flags);
356 }
357 
send(int sock,const void * buf,size_t len,int flags)358 ssize_t send(int sock, const void *buf, size_t len, int flags)
359 {
360 	return zsock_send(sock, buf, len, flags);
361 }
362 
sendmsg(int sock,const struct msghdr * message,int flags)363 ssize_t sendmsg(int sock, const struct msghdr *message, int flags)
364 {
365 	return zsock_sendmsg(sock, message, flags);
366 }
367 
sendto(int sock,const void * buf,size_t len,int flags,const struct sockaddr * dest_addr,socklen_t addrlen)368 ssize_t sendto(int sock, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr,
369 	       socklen_t addrlen)
370 {
371 	return zsock_sendto(sock, buf, len, flags, dest_addr, addrlen);
372 }
373 
setsockopt(int sock,int level,int optname,const void * optval,socklen_t optlen)374 int setsockopt(int sock, int level, int optname, const void *optval, socklen_t optlen)
375 {
376 	return zsock_setsockopt(sock, level, optname, optval, optlen);
377 }
378 
shutdown(int sock,int how)379 int shutdown(int sock, int how)
380 {
381 	return zsock_shutdown(sock, how);
382 }
383 
sockatmark(int s)384 int sockatmark(int s)
385 {
386 	ARG_UNUSED(s);
387 
388 	errno = ENOSYS;
389 	return -1;
390 }
391 
socket(int family,int type,int proto)392 int socket(int family, int type, int proto)
393 {
394 	return zsock_socket(family, type, proto);
395 }
396 
socketpair(int family,int type,int proto,int sv[2])397 int socketpair(int family, int type, int proto, int sv[2])
398 {
399 	return zsock_socketpair(family, type, proto, sv);
400 }
401