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