1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "napi/native_api.h"
17 #include <cerrno>
18 #include <cstring>
19 #include <ifaddrs.h>
20 #include <js_native_api_types.h>
21 #include <net/if.h>
22 #include <netdb.h>
23 #include <sys/inotify.h>
24 #include <uv.h>
25
26 #define PARAM_0 0
27 #define PARAM_1 1
28 #define PARAM_2 2
29 #define PARAM_8192 8192
30 #define PARAM_UNNORMAL (-1)
31 #define ERRON_0 0
32 #define ONEVAL 1
33 #define MINUSONE (-1)
34 #define MINUSTWO (-2)
35 #define MINUSTHR (-3)
36 #define MAX_NAMBER 1024
37 #define PARAM_4 4
38 #define NO_ERR 0
39 #define SUCCESS 1
40 #define FAIL (-1)
41 #define TRUE 1
42 #define LENGTH 64
43 #define EIGHTY 80
44 #define BUFLEN 256
45 #define FLAG 127
46
GetProtoEnt(napi_env env, napi_callback_info info)47 static napi_value GetProtoEnt(napi_env env, napi_callback_info info)
48 {
49 struct protoent *getInfo = nullptr;
50 getInfo = getprotoent();
51 int ret = FAIL;
52 if (getInfo != nullptr) {
53 ret = SUCCESS;
54 }
55 napi_value result = nullptr;
56 napi_create_int32(env, ret, &result);
57 return result;
58 }
GetProtoByName(napi_env env, napi_callback_info info)59 static napi_value GetProtoByName(napi_env env, napi_callback_info info)
60 {
61 size_t argc = PARAM_1;
62 napi_value args[1] = {nullptr};
63 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
64
65 size_t length = LENGTH, strResult = PARAM_0;
66 char proto_name[LENGTH] = {0};
67
68 napi_get_value_string_utf8(env, args[0], proto_name, length, &strResult);
69 struct protoent *getInfo = nullptr;
70 getInfo = getprotobyname(proto_name);
71 napi_value result = nullptr;
72 if (getInfo != nullptr) {
73 napi_create_string_utf8(env, getInfo->p_name, NAPI_AUTO_LENGTH, &result);
74 } else {
75 napi_create_string_utf8(env, "null", NAPI_AUTO_LENGTH, &result);
76 }
77 return result;
78 }
Hstrerror(napi_env env, napi_callback_info info)79 static napi_value Hstrerror(napi_env env, napi_callback_info info)
80 {
81 const char *ret = hstrerror(PARAM_1);
82 napi_value result;
83 if (strcmp(ret, "Unknown error nnn")) {
84 napi_create_int32(env, PARAM_0, &result);
85 } else {
86 napi_create_int32(env, PARAM_UNNORMAL, &result);
87 }
88 return result;
89 }
90
Herror(napi_env env, napi_callback_info info)91 static napi_value Herror(napi_env env, napi_callback_info info)
92 {
93 errno = ERRON_0;
94 herror("herror");
95 napi_value result;
96 if (errno == ERRON_0) {
97 napi_create_int32(env, PARAM_0, &result);
98 } else {
99 napi_create_int32(env, PARAM_UNNORMAL, &result);
100 }
101 return result;
102 }
103
GetProtoByNumber(napi_env env, napi_callback_info info)104 static napi_value GetProtoByNumber(napi_env env, napi_callback_info info)
105 {
106 size_t argc = PARAM_1;
107 napi_value args[1] = {nullptr};
108 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
109
110 int valueZero = PARAM_0;
111 napi_get_value_int32(env, args[0], &valueZero);
112 struct protoent *getInfo = nullptr;
113 getInfo = getprotobynumber(valueZero);
114 napi_value result = nullptr;
115 if (getInfo != nullptr) {
116 napi_create_string_utf8(env, getInfo->p_name, NAPI_AUTO_LENGTH, &result);
117 } else {
118 napi_create_string_utf8(env, "null", NAPI_AUTO_LENGTH, &result);
119 }
120 return result;
121 }
GetNameInfo(napi_env env, napi_callback_info info)122 static napi_value GetNameInfo(napi_env env, napi_callback_info info)
123 {
124 char hostname[128] = {PARAM_0};
125 char serverName[128] = {PARAM_0};
126 sockaddr_in addR_dst = {PARAM_0};
127 memset(&addR_dst, PARAM_0, sizeof(addR_dst));
128 addR_dst.sin_family = AF_INET;
129 inet_pton(AF_INET, "127.0.0.1", &addR_dst.sin_addr.s_addr);
130 int getInfo = getnameinfo((sockaddr *)&addR_dst, sizeof(addR_dst), hostname, sizeof(hostname), serverName,
131 sizeof(serverName), PARAM_0);
132 napi_value result = nullptr;
133 napi_create_int32(env, getInfo, &result);
134 return result;
135 }
GetHostEnt(napi_env env, napi_callback_info info)136 static napi_value GetHostEnt(napi_env env, napi_callback_info info)
137 {
138 hostent *getInfo = nullptr;
139 sethostent(TRUE);
140 getInfo = gethostent();
141 int ret = FAIL;
142 if (getInfo == nullptr) {
143 ret = SUCCESS;
144 }
145 endhostent();
146 napi_value result = nullptr;
147 napi_create_int32(env, ret, &result);
148 return result;
149 }
GetServEnt(napi_env env, napi_callback_info info)150 static napi_value GetServEnt(napi_env env, napi_callback_info info)
151 {
152 errno = NO_ERR;
153 setservent(TRUE);
154 int ret = FAIL;
155 getservent();
156 if (errno == NO_ERR) {
157 ret = SUCCESS;
158 }
159 napi_value result = nullptr;
160 napi_create_int32(env, ret, &result);
161 return result;
162 }
GetNetEnt(napi_env env, napi_callback_info info)163 static napi_value GetNetEnt(napi_env env, napi_callback_info info)
164 {
165 netent *getInfo = nullptr;
166 getInfo = getnetent();
167 int ret = FAIL;
168 if (getInfo == nullptr) {
169 ret = SUCCESS;
170 }
171 napi_value result = nullptr;
172 napi_create_int32(env, ret, &result);
173 return result;
174 }
GetNetByAddr(napi_env env, napi_callback_info info)175 static napi_value GetNetByAddr(napi_env env, napi_callback_info info)
176 {
177 netent *getInfo = nullptr;
178 errno = NO_ERR;
179 getInfo = getnetbyaddr(FLAG, AF_INET);
180 int ret = FAIL;
181 if (getInfo != nullptr) {
182 ret = SUCCESS;
183 }
184 napi_value result = nullptr;
185 napi_create_int32(env, ret, &result);
186 return result;
187 }
GetNetByName(napi_env env, napi_callback_info info)188 static napi_value GetNetByName(napi_env env, napi_callback_info info)
189 {
190 netent *getInfo = nullptr;
191 errno = NO_ERR;
192 getInfo = getnetbyname("loopback");
193 int ret = FAIL;
194 if (getInfo != nullptr) {
195 ret = SUCCESS;
196 }
197 napi_value result = nullptr;
198 napi_create_int32(env, ret, &result);
199 return result;
200 }
GetServByName(napi_env env, napi_callback_info info)201 static napi_value GetServByName(napi_env env, napi_callback_info info)
202 {
203 servent *getInfo = nullptr;
204 errno = NO_ERR;
205 getInfo = getservbyname("http", "tcp");
206 int ret = FAIL;
207 if (getInfo != nullptr) {
208 ret = SUCCESS;
209 }
210 napi_value result = nullptr;
211 napi_create_int32(env, ret, &result);
212 return result;
213 }
GetServByPort(napi_env env, napi_callback_info info)214 static napi_value GetServByPort(napi_env env, napi_callback_info info)
215 {
216 servent *getInfo = nullptr;
217 errno = NO_ERR;
218 getInfo = getservbyport(htons(EIGHTY), "tcp");
219 int ret = FAIL;
220 if (getInfo != nullptr) {
221 ret = SUCCESS;
222 }
223 napi_value result = nullptr;
224 napi_create_int32(env, ret, &result);
225 return result;
226 }
GetHostByName(napi_env env, napi_callback_info info)227 static napi_value GetHostByName(napi_env env, napi_callback_info info)
228 {
229 hostent *getInfo = nullptr;
230 errno = NO_ERR;
231 getInfo = gethostbyname("127.0.0.1");
232 int ret = FAIL;
233 if (getInfo != nullptr) {
234 ret = SUCCESS;
235 }
236 napi_value result = nullptr;
237 napi_create_int32(env, ret, &result);
238 return result;
239 }
GetHostByAddr(napi_env env, napi_callback_info info)240 static napi_value GetHostByAddr(napi_env env, napi_callback_info info)
241 {
242 hostent *getInfo = nullptr;
243 errno = NO_ERR;
244 const char *add = "127.0.0.1";
245 in_addr addr = {PARAM_0};
246 inet_pton(AF_INET, add, &addr);
247 getInfo = gethostbyaddr((const char *)&addr, sizeof(addr), AF_INET);
248 int ret = FAIL;
249 if (getInfo != nullptr) {
250 ret = SUCCESS;
251 }
252 napi_value result = nullptr;
253 napi_create_int32(env, ret, &result);
254 return result;
255 }
GetHostByNameR(napi_env env, napi_callback_info info)256 static napi_value GetHostByNameR(napi_env env, napi_callback_info info)
257 {
258 int getInfo;
259 errno = NO_ERR;
260 char buf[1024] = "\0";
261 hostent hostInfo;
262 hostent *pHost = nullptr;
263 int type;
264 getInfo = gethostbyname_r("127.0.0.1", &hostInfo, buf, sizeof(buf), &pHost, &type);
265 napi_value result = nullptr;
266 napi_create_int32(env, getInfo, &result);
267 return result;
268 }
GetHostByAddrR(napi_env env, napi_callback_info info)269 static napi_value GetHostByAddrR(napi_env env, napi_callback_info info)
270 {
271 int getInfo;
272 errno = NO_ERR;
273 in_addr_t address = inet_addr("127.0.0.1");
274 hostent hostBuf;
275 hostent *hostResult = nullptr;
276 char buffer[2048];
277 int errNum = PARAM_0;
278 getInfo = gethostbyaddr_r(&address, PARAM_4, AF_INET, &hostBuf, buffer, sizeof(buffer), &hostResult, &errNum);
279 napi_value result = nullptr;
280 napi_create_int32(env, getInfo, &result);
281 return result;
282 }
GetHostByName2(napi_env env, napi_callback_info info)283 static napi_value GetHostByName2(napi_env env, napi_callback_info info)
284 {
285 hostent *getInfo = nullptr;
286 errno = NO_ERR;
287 getInfo = gethostbyname2("127.0.0.1", AF_INET);
288 int ret = FAIL;
289 if (getInfo != nullptr) {
290 ret = SUCCESS;
291 }
292 napi_value result = nullptr;
293 napi_create_int32(env, ret, &result);
294 return result;
295 }
296
GetHostByName2R(napi_env env, napi_callback_info info)297 static napi_value GetHostByName2R(napi_env env, napi_callback_info info)
298 {
299 int getInfo;
300 errno = NO_ERR;
301 int err;
302 int buf_len = PARAM_8192;
303 hostent hBuf;
304 hostent *ret = nullptr;
305 char buf[buf_len];
306 memset(buf, PARAM_0, buf_len);
307 getInfo = gethostbyname2_r("127.0.0.1", AF_INET, &hBuf, buf, buf_len, &ret, &err);
308 napi_value result = nullptr;
309 napi_create_int32(env, getInfo, &result);
310 return result;
311 }
Sethostent(napi_env env, napi_callback_info info)312 static napi_value Sethostent(napi_env env, napi_callback_info info)
313 {
314 errno = ERRON_0;
315 sethostent(ONEVAL);
316 gethostent();
317 endhostent();
318 napi_value result;
319 napi_create_int32(env, errno, &result);
320 return result;
321 }
322
Setnetent(napi_env env, napi_callback_info info)323 static napi_value Setnetent(napi_env env, napi_callback_info info)
324 {
325 errno = ERRON_0;
326 const char *netname = nullptr;
327 napi_value result = nullptr;
328 netent *ne = nullptr;
329 setnetent(ONEVAL);
330 while (ONEVAL) {
331 ne = getnetent();
332 if (!ne)
333 break;
334 if (strcmp(ne->n_name, netname) == PARAM_0) {
335 setnetent(PARAM_0);
336 endnetent();
337 napi_create_int32(env, ONEVAL, &result);
338 return result;
339 }
340 }
341 setnetent(PARAM_0);
342 endnetent();
343 napi_create_int32(env, errno, &result);
344 return result;
345 }
346
Setprotoent(napi_env env, napi_callback_info info)347 static napi_value Setprotoent(napi_env env, napi_callback_info info)
348 {
349 errno = ERRON_0;
350 endprotoent();
351 napi_value result = nullptr;
352 protoent *getval = getprotoent();
353 if (getval == nullptr) {
354 napi_create_int32(env, MINUSONE, &result);
355 }
356 char buf[MAX_NAMBER] = {PARAM_0};
357 strcpy(buf, getval->p_name);
358 setprotoent(PARAM_0);
359 getval = getprotoent();
360 if (getval == nullptr) {
361 napi_create_int32(env, MINUSTWO, &result);
362 }
363 if (strcmp(getval->p_name, buf)) {
364 napi_create_int32(env, MINUSTHR, &result);
365 } else {
366 napi_create_int32(env, errno, &result);
367 }
368 return result;
369 }
370
Setservent(napi_env env, napi_callback_info info)371 static napi_value Setservent(napi_env env, napi_callback_info info)
372 {
373 errno = ERRON_0;
374 char **p = nullptr;
375 struct servent *serv = nullptr;
376 napi_value result;
377 setservent(ONEVAL);
378 while ((serv = getservent()) != nullptr) {
379 for (p = serv->s_aliases; *p != nullptr; p++)
380 ;
381 }
382 endservent();
383 if (errno == PARAM_0) {
384 napi_create_int32(env, errno, &result);
385 } else {
386 napi_create_int32(env, MINUSONE, &result);
387 }
388 return result;
389 }
390
EndServEnt(napi_env env, napi_callback_info info)391 static napi_value EndServEnt(napi_env env, napi_callback_info info)
392 {
393 errno = NO_ERR;
394 endservent();
395 napi_value result = nullptr;
396 napi_create_int32(env, errno, &result);
397 return result;
398 }
399
EndProToEnt(napi_env env, napi_callback_info info)400 static napi_value EndProToEnt(napi_env env, napi_callback_info info)
401 {
402 errno = NO_ERR;
403 endprotoent();
404 napi_value result = nullptr;
405 napi_create_int32(env, errno, &result);
406 return result;
407 }
408
EndNetEnt(napi_env env, napi_callback_info info)409 static napi_value EndNetEnt(napi_env env, napi_callback_info info)
410 {
411 errno = NO_ERR;
412 endnetent();
413 napi_value result = nullptr;
414 napi_create_int32(env, errno, &result);
415 return result;
416 }
417
EndHostEnt(napi_env env, napi_callback_info info)418 static napi_value EndHostEnt(napi_env env, napi_callback_info info)
419 {
420 errno = NO_ERR;
421 endhostent();
422 napi_value result = nullptr;
423 napi_create_int32(env, errno, &result);
424 return result;
425 }
426
GaiStrerror(napi_env env, napi_callback_info info)427 napi_value GaiStrerror(napi_env env, napi_callback_info info)
428 {
429 const char *value = gai_strerror(EAI_BADFLAGS);
430 int ret = FAIL;
431 if (value != nullptr) {
432 ret = SUCCESS;
433 }
434 napi_value result = nullptr;
435 napi_create_int32(env, ret, &result);
436 return result;
437 }
Freeaddrinfo(napi_env env, napi_callback_info info)438 napi_value Freeaddrinfo(napi_env env, napi_callback_info info)
439 {
440 struct addrinfo *ai, hint;
441 hint.ai_flags = AI_PASSIVE;
442 hint.ai_family = AF_UNSPEC;
443 getaddrinfo("127.0.0.1", nullptr, &hint, &ai);
444 errno = NO_ERR;
445 try{
446 freeaddrinfo(ai);
447 }
448 catch(...)
449 {
450 errno = FAIL;
451 }
452 napi_value result = nullptr;
453 napi_create_int32(env, errno, &result);
454 return result;
455 }
456
Getaddrinfo(napi_env env, napi_callback_info info)457 napi_value Getaddrinfo(napi_env env, napi_callback_info info)
458 {
459 struct addrinfo hint, *ai;
460 hint.ai_flags = AI_PASSIVE;
461 hint.ai_family = AF_UNSPEC;
462 int ret = getaddrinfo("127.0.0.1", nullptr, &hint, &ai);
463 freeaddrinfo(ai);
464 napi_value result = nullptr;
465 napi_create_int32(env, ret, &result);
466 return result;
467 }
468 EXTERN_C_START
Init(napi_env env, napi_value exports)469 static napi_value Init(napi_env env, napi_value exports)
470 {
471 napi_property_descriptor desc[] = {
472 {"hstrerror", nullptr, Hstrerror, nullptr, nullptr, nullptr, napi_default, nullptr},
473 {"herror", nullptr, Herror, nullptr, nullptr, nullptr, napi_default, nullptr},
474 {"getProtoEnt", nullptr, GetProtoEnt, nullptr, nullptr, nullptr, napi_default, nullptr},
475 {"getProtoByName", nullptr, GetProtoByName, nullptr, nullptr, nullptr, napi_default, nullptr},
476 {"getProtoByNumber", nullptr, GetProtoByNumber, nullptr, nullptr, nullptr, napi_default, nullptr},
477 {"getNameInfo", nullptr, GetNameInfo, nullptr, nullptr, nullptr, napi_default, nullptr},
478 {"getHostEnt", nullptr, GetHostEnt, nullptr, nullptr, nullptr, napi_default, nullptr},
479 {"getServEnt", nullptr, GetServEnt, nullptr, nullptr, nullptr, napi_default, nullptr},
480 {"getNetEnt", nullptr, GetNetEnt, nullptr, nullptr, nullptr, napi_default, nullptr},
481 {"getNetByAddr", nullptr, GetNetByAddr, nullptr, nullptr, nullptr, napi_default, nullptr},
482 {"getNetByName", nullptr, GetNetByName, nullptr, nullptr, nullptr, napi_default, nullptr},
483 {"getServByName", nullptr, GetServByName, nullptr, nullptr, nullptr, napi_default, nullptr},
484 {"getServByPort", nullptr, GetServByPort, nullptr, nullptr, nullptr, napi_default, nullptr},
485 {"getHostByName", nullptr, GetHostByName, nullptr, nullptr, nullptr, napi_default, nullptr},
486 {"getHostByAddr", nullptr, GetHostByAddr, nullptr, nullptr, nullptr, napi_default, nullptr},
487 {"getHostByNameR", nullptr, GetHostByNameR, nullptr, nullptr, nullptr, napi_default, nullptr},
488 {"getHostByAddrR", nullptr, GetHostByAddrR, nullptr, nullptr, nullptr, napi_default, nullptr},
489 {"getHostByName2", nullptr, GetHostByName2, nullptr, nullptr, nullptr, napi_default, nullptr},
490 {"getHostByName2R", nullptr, GetHostByName2R, nullptr, nullptr, nullptr, napi_default, nullptr},
491 {"sethostent", nullptr, Sethostent, nullptr, nullptr, nullptr, napi_default, nullptr},
492 {"setnetent", nullptr, Setnetent, nullptr, nullptr, nullptr, napi_default, nullptr},
493 {"setprotoent", nullptr, Setprotoent, nullptr, nullptr, nullptr, napi_default, nullptr},
494 {"setservent", nullptr, Setservent, nullptr, nullptr, nullptr, napi_default, nullptr},
495 {"endservent", nullptr, EndServEnt, nullptr, nullptr, nullptr, napi_default, nullptr},
496 {"endprotoent", nullptr, EndProToEnt, nullptr, nullptr, nullptr, napi_default, nullptr},
497 {"endnetent", nullptr, EndNetEnt, nullptr, nullptr, nullptr, napi_default, nullptr},
498 {"endhostent", nullptr, EndHostEnt, nullptr, nullptr, nullptr, napi_default, nullptr},
499 {"gaiStrerror", nullptr, GaiStrerror, nullptr, nullptr, nullptr, napi_default, nullptr},
500 {"freeaddrinfo", nullptr, Freeaddrinfo, nullptr, nullptr, nullptr, napi_default, nullptr},
501 {"getaddrinfo", nullptr, Getaddrinfo, nullptr, nullptr, nullptr, napi_default, nullptr}};
502 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
503 return exports;
504 }
505 EXTERN_C_END
506
507 static napi_module demoModule = {
508 .nm_version = 1,
509 .nm_flags = 0,
510 .nm_filename = nullptr,
511 .nm_register_func = Init,
512 .nm_modname = "netdb",
513 .nm_priv = ((void *)0),
514 .reserved = {0},
515 };
516
RegisterModule(void)517 extern "C" __attribute__((constructor)) void RegisterModule(void) { napi_module_register(&demoModule); }
518