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 errno = NO_ERR;
140 sethostent(TRUE);
141 getInfo = gethostent();
142 int ret = FAIL;
143 if (getInfo != nullptr) {
144 ret = SUCCESS;
145 }
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 errno = NO_ERR;
167 setnetent(TRUE);
168 getInfo = getnetent();
169 int ret = FAIL;
170 if (getInfo != nullptr) {
171 ret = SUCCESS;
172 }
173 napi_value result = nullptr;
174 napi_create_int32(env, ret, &result);
175 return result;
176 }
GetNetByAddr(napi_env env,napi_callback_info info)177 static napi_value GetNetByAddr(napi_env env, napi_callback_info info)
178 {
179 netent *getInfo = nullptr;
180 errno = NO_ERR;
181 getInfo = getnetbyaddr(FLAG, AF_INET);
182 int ret = FAIL;
183 if (getInfo != nullptr) {
184 ret = SUCCESS;
185 }
186 napi_value result = nullptr;
187 napi_create_int32(env, ret, &result);
188 return result;
189 }
GetNetByName(napi_env env,napi_callback_info info)190 static napi_value GetNetByName(napi_env env, napi_callback_info info)
191 {
192 netent *getInfo = nullptr;
193 errno = NO_ERR;
194 getInfo = getnetbyname("loopback");
195 int ret = FAIL;
196 if (getInfo != nullptr) {
197 ret = SUCCESS;
198 }
199 napi_value result = nullptr;
200 napi_create_int32(env, ret, &result);
201 return result;
202 }
GetServByName(napi_env env,napi_callback_info info)203 static napi_value GetServByName(napi_env env, napi_callback_info info)
204 {
205 servent *getInfo = nullptr;
206 errno = NO_ERR;
207 getInfo = getservbyname("http", "tcp");
208 int ret = FAIL;
209 if (getInfo != nullptr) {
210 ret = SUCCESS;
211 }
212 napi_value result = nullptr;
213 napi_create_int32(env, ret, &result);
214 return result;
215 }
GetServByPort(napi_env env,napi_callback_info info)216 static napi_value GetServByPort(napi_env env, napi_callback_info info)
217 {
218 servent *getInfo = nullptr;
219 errno = NO_ERR;
220 getInfo = getservbyport(htons(EIGHTY), "tcp");
221 int ret = FAIL;
222 if (getInfo != nullptr) {
223 ret = SUCCESS;
224 }
225 napi_value result = nullptr;
226 napi_create_int32(env, ret, &result);
227 return result;
228 }
GetHostByName(napi_env env,napi_callback_info info)229 static napi_value GetHostByName(napi_env env, napi_callback_info info)
230 {
231 hostent *getInfo = nullptr;
232 errno = NO_ERR;
233 getInfo = gethostbyname("www.baidu.com");
234 int ret = FAIL;
235 if (getInfo != nullptr) {
236 ret = SUCCESS;
237 }
238 napi_value result = nullptr;
239 napi_create_int32(env, ret, &result);
240 return result;
241 }
GetHostByAddr(napi_env env,napi_callback_info info)242 static napi_value GetHostByAddr(napi_env env, napi_callback_info info)
243 {
244 hostent *getInfo = nullptr;
245 errno = NO_ERR;
246 const char *add = "127.0.0.1";
247 in_addr addr = {PARAM_0};
248 inet_pton(AF_INET, add, &addr);
249 getInfo = gethostbyaddr((const char *)&addr, sizeof(addr), AF_INET);
250 int ret = FAIL;
251 if (getInfo != nullptr) {
252 ret = SUCCESS;
253 }
254 napi_value result = nullptr;
255 napi_create_int32(env, ret, &result);
256 return result;
257 }
GetHostByNameR(napi_env env,napi_callback_info info)258 static napi_value GetHostByNameR(napi_env env, napi_callback_info info)
259 {
260 int getInfo;
261 errno = NO_ERR;
262 char buf[1024];
263 hostent hostInfo;
264 hostent *pHost = nullptr;
265 int type;
266 getInfo = gethostbyname_r("www.baidu.com", &hostInfo, buf, sizeof(buf), &pHost, &type);
267 napi_value result = nullptr;
268 napi_create_int32(env, getInfo, &result);
269 return result;
270 }
GetHostByAddrR(napi_env env,napi_callback_info info)271 static napi_value GetHostByAddrR(napi_env env, napi_callback_info info)
272 {
273 int getInfo;
274 errno = NO_ERR;
275 in_addr_t address = inet_addr("127.0.0.1");
276 hostent hostBuf;
277 hostent *hostResult = nullptr;
278 char buffer[2048];
279 int errNum = PARAM_0;
280 getInfo = gethostbyaddr_r(&address, PARAM_4, AF_INET, &hostBuf, buffer, sizeof(buffer), &hostResult, &errNum);
281 napi_value result = nullptr;
282 napi_create_int32(env, getInfo, &result);
283 return result;
284 }
GetHostByName2(napi_env env,napi_callback_info info)285 static napi_value GetHostByName2(napi_env env, napi_callback_info info)
286 {
287 hostent *getInfo = nullptr;
288 errno = NO_ERR;
289 getInfo = gethostbyname2("127.0.0.1", AF_INET);
290 int ret = FAIL;
291 if (getInfo != nullptr) {
292 ret = SUCCESS;
293 }
294 napi_value result = nullptr;
295 napi_create_int32(env, ret, &result);
296 return result;
297 }
298
GetHostByName2R(napi_env env,napi_callback_info info)299 static napi_value GetHostByName2R(napi_env env, napi_callback_info info)
300 {
301 int getInfo;
302 errno = NO_ERR;
303 int err;
304 int buf_len = PARAM_8192;
305 hostent hBuf;
306 hostent *ret = nullptr;
307 char buf[buf_len];
308 memset(buf, PARAM_0, buf_len);
309 getInfo = gethostbyname2_r("127.0.0.1", AF_INET, &hBuf, buf, buf_len, &ret, &err);
310 napi_value result = nullptr;
311 napi_create_int32(env, getInfo, &result);
312 return result;
313 }
Sethostent(napi_env env,napi_callback_info info)314 static napi_value Sethostent(napi_env env, napi_callback_info info)
315 {
316 errno = ERRON_0;
317 sethostent(ONEVAL);
318 gethostent();
319 endhostent();
320 napi_value result;
321 napi_create_int32(env, errno, &result);
322 return result;
323 }
324
Setnetent(napi_env env,napi_callback_info info)325 static napi_value Setnetent(napi_env env, napi_callback_info info)
326 {
327 errno = ERRON_0;
328 const char *netname = nullptr;
329 napi_value result = nullptr;
330 netent *ne = nullptr;
331 setnetent(ONEVAL);
332 while (ONEVAL) {
333 ne = getnetent();
334 if (!ne)
335 break;
336 if (strcmp(ne->n_name, netname) == PARAM_0) {
337 setnetent(PARAM_0);
338 endnetent();
339 napi_create_int32(env, ONEVAL, &result);
340 return result;
341 }
342 }
343 setnetent(PARAM_0);
344 endnetent();
345 napi_create_int32(env, errno, &result);
346 return result;
347 }
348
Setprotoent(napi_env env,napi_callback_info info)349 static napi_value Setprotoent(napi_env env, napi_callback_info info)
350 {
351 errno = ERRON_0;
352 endprotoent();
353 napi_value result = nullptr;
354 protoent *getval = getprotoent();
355 if (getval == nullptr) {
356 napi_create_int32(env, MINUSONE, &result);
357 }
358 char buf[MAX_NAMBER] = {PARAM_0};
359 strcpy(buf, getval->p_name);
360 setprotoent(PARAM_0);
361 getval = getprotoent();
362 if (getval == nullptr) {
363 napi_create_int32(env, MINUSTWO, &result);
364 }
365 if (strcmp(getval->p_name, buf)) {
366 napi_create_int32(env, MINUSTHR, &result);
367 } else {
368 napi_create_int32(env, errno, &result);
369 }
370 return result;
371 }
372
Setservent(napi_env env,napi_callback_info info)373 static napi_value Setservent(napi_env env, napi_callback_info info)
374 {
375 errno = ERRON_0;
376 char **p = nullptr;
377 struct servent *serv = nullptr;
378 napi_value result;
379 setservent(ONEVAL);
380 while ((serv = getservent()) != nullptr) {
381 for (p = serv->s_aliases; *p != nullptr; p++)
382 ;
383 }
384 endservent();
385 if (errno == PARAM_0) {
386 napi_create_int32(env, errno, &result);
387 } else {
388 napi_create_int32(env, MINUSONE, &result);
389 }
390 return result;
391 }
392
EndServEnt(napi_env env,napi_callback_info info)393 static napi_value EndServEnt(napi_env env, napi_callback_info info)
394 {
395 errno = NO_ERR;
396 endservent();
397 napi_value result = nullptr;
398 napi_create_int32(env, errno, &result);
399 return result;
400 }
401
EndProToEnt(napi_env env,napi_callback_info info)402 static napi_value EndProToEnt(napi_env env, napi_callback_info info)
403 {
404 errno = NO_ERR;
405 endprotoent();
406 napi_value result = nullptr;
407 napi_create_int32(env, errno, &result);
408 return result;
409 }
410
EndNetEnt(napi_env env,napi_callback_info info)411 static napi_value EndNetEnt(napi_env env, napi_callback_info info)
412 {
413 errno = NO_ERR;
414 endnetent();
415 napi_value result = nullptr;
416 napi_create_int32(env, errno, &result);
417 return result;
418 }
419
EndHostEnt(napi_env env,napi_callback_info info)420 static napi_value EndHostEnt(napi_env env, napi_callback_info info)
421 {
422 errno = NO_ERR;
423 endhostent();
424 napi_value result = nullptr;
425 napi_create_int32(env, errno, &result);
426 return result;
427 }
428
GaiStrerror(napi_env env,napi_callback_info info)429 napi_value GaiStrerror(napi_env env, napi_callback_info info)
430 {
431 const char *value = gai_strerror(EAI_BADFLAGS);
432 int ret = FAIL;
433 if (value != nullptr) {
434 ret = SUCCESS;
435 }
436 napi_value result = nullptr;
437 napi_create_int32(env, ret, &result);
438 return result;
439 }
Freeaddrinfo(napi_env env,napi_callback_info info)440 napi_value Freeaddrinfo(napi_env env, napi_callback_info info)
441 {
442 struct addrinfo *ai, hint;
443 hint.ai_flags = AI_PASSIVE;
444 hint.ai_family = AF_UNSPEC;
445 if (getaddrinfo("127.0.0.1", nullptr, &hint, &ai) != NO_ERR) {
446 freeaddrinfo(ai);
447 }
448 napi_value result = nullptr;
449 napi_create_int32(env, errno, &result);
450 return result;
451 }
452
Getaddrinfo(napi_env env,napi_callback_info info)453 napi_value Getaddrinfo(napi_env env, napi_callback_info info)
454 {
455 struct addrinfo hint, *ai;
456 hint.ai_flags = AI_PASSIVE;
457 hint.ai_family = AF_UNSPEC;
458 int ret = getaddrinfo("127.0.0.1", nullptr, &hint, &ai);
459 freeaddrinfo(ai);
460 napi_value result = nullptr;
461 napi_create_int32(env, ret, &result);
462 return result;
463 }
464 EXTERN_C_START
Init(napi_env env,napi_value exports)465 static napi_value Init(napi_env env, napi_value exports)
466 {
467 napi_property_descriptor desc[] = {
468 {"hstrerror", nullptr, Hstrerror, nullptr, nullptr, nullptr, napi_default, nullptr},
469 {"herror", nullptr, Herror, nullptr, nullptr, nullptr, napi_default, nullptr},
470 {"getProtoEnt", nullptr, GetProtoEnt, nullptr, nullptr, nullptr, napi_default, nullptr},
471 {"getProtoByName", nullptr, GetProtoByName, nullptr, nullptr, nullptr, napi_default, nullptr},
472 {"getProtoByNumber", nullptr, GetProtoByNumber, nullptr, nullptr, nullptr, napi_default, nullptr},
473 {"getNameInfo", nullptr, GetNameInfo, nullptr, nullptr, nullptr, napi_default, nullptr},
474 {"getHostEnt", nullptr, GetHostEnt, nullptr, nullptr, nullptr, napi_default, nullptr},
475 {"getServEnt", nullptr, GetServEnt, nullptr, nullptr, nullptr, napi_default, nullptr},
476 {"getNetEnt", nullptr, GetNetEnt, nullptr, nullptr, nullptr, napi_default, nullptr},
477 {"getNetByAddr", nullptr, GetNetByAddr, nullptr, nullptr, nullptr, napi_default, nullptr},
478 {"getNetByName", nullptr, GetNetByName, nullptr, nullptr, nullptr, napi_default, nullptr},
479 {"getServByName", nullptr, GetServByName, nullptr, nullptr, nullptr, napi_default, nullptr},
480 {"getServByPort", nullptr, GetServByPort, nullptr, nullptr, nullptr, napi_default, nullptr},
481 {"getHostByName", nullptr, GetHostByName, nullptr, nullptr, nullptr, napi_default, nullptr},
482 {"getHostByAddr", nullptr, GetHostByAddr, nullptr, nullptr, nullptr, napi_default, nullptr},
483 {"getHostByNameR", nullptr, GetHostByNameR, nullptr, nullptr, nullptr, napi_default, nullptr},
484 {"getHostByAddrR", nullptr, GetHostByAddrR, nullptr, nullptr, nullptr, napi_default, nullptr},
485 {"getHostByName2", nullptr, GetHostByName2, nullptr, nullptr, nullptr, napi_default, nullptr},
486 {"getHostByName2R", nullptr, GetHostByName2R, nullptr, nullptr, nullptr, napi_default, nullptr},
487 {"sethostent", nullptr, Sethostent, nullptr, nullptr, nullptr, napi_default, nullptr},
488 {"setnetent", nullptr, Setnetent, nullptr, nullptr, nullptr, napi_default, nullptr},
489 {"setprotoent", nullptr, Setprotoent, nullptr, nullptr, nullptr, napi_default, nullptr},
490 {"setservent", nullptr, Setservent, nullptr, nullptr, nullptr, napi_default, nullptr},
491 {"endservent", nullptr, EndServEnt, nullptr, nullptr, nullptr, napi_default, nullptr},
492 {"endprotoent", nullptr, EndProToEnt, nullptr, nullptr, nullptr, napi_default, nullptr},
493 {"endnetent", nullptr, EndNetEnt, nullptr, nullptr, nullptr, napi_default, nullptr},
494 {"endhostent", nullptr, EndHostEnt, nullptr, nullptr, nullptr, napi_default, nullptr},
495 {"gaiStrerror", nullptr, GaiStrerror, nullptr, nullptr, nullptr, napi_default, nullptr},
496 {"freeaddrinfo", nullptr, Freeaddrinfo, nullptr, nullptr, nullptr, napi_default, nullptr},
497 {"getaddrinfo", nullptr, Getaddrinfo, nullptr, nullptr, nullptr, napi_default, nullptr}};
498 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
499 return exports;
500 }
501 EXTERN_C_END
502
503 static napi_module demoModule = {
504 .nm_version = 1,
505 .nm_flags = 0,
506 .nm_filename = nullptr,
507 .nm_register_func = Init,
508 .nm_modname = "netdb",
509 .nm_priv = ((void *)0),
510 .reserved = {0},
511 };
512
RegisterModule(void)513 extern "C" __attribute__((constructor)) void RegisterModule(void) { napi_module_register(&demoModule); }
514