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 <arpa/inet.h>
18 #include <cstdlib>
19 #include <cstring>
20 #include <js_native_api_types.h>
21 #include <netinet/in.h>
22 #include <sys/socket.h>
23 #include <sys/types.h>
24 #include <sys/un.h>
25 #include <unistd.h>
26 #include <securec.h>
27 
28 #define PARAM_5 5
29 #define ONEVAL 1
30 #define MINUSONE (-1)
31 #define MINUSTWO (-2)
32 #define TWOVAL 2
33 #define FIVEVAL 5
34 #define VALUE9898 9898
35 #define VALUE1234 1234
36 #define PARAM_6000 6000
37 #define PARAM_6001 6001
38 #define PARAM_6002 6002
39 #define PARAM_6003 6003
40 #define PARAM_6004 6004
41 #define PARAM_6005 6005
42 #define PARAM_8000 8000
43 
44 #define PARAM_0 0
45 #define PARAM_1 1
46 #define PARAM_2 2
47 #define PARAM_UNNORMAL (-1)
48 #define RETURN_0 0
49 #define FAILD (-1)
50 #define ERRON_0 0
51 #define SIZE_10 10
52 #define SIZE_100 100
53 #define SIZE_1024 1024
54 #define SIZE_4096 4096
55 #define SIZE_8192 8192
56 #define PORT_E 8000
57 #define PORT_X 6000
58 
59 #define MY_SOCK_PATH "/data/storage/el2/base/files"
60 
Socket(napi_env env, napi_callback_info info)61 static napi_value Socket(napi_env env, napi_callback_info info)
62 {
63     int result = socket(AF_INET, SOCK_STREAM, PARAM_0);
64     napi_value results = nullptr;
65     napi_create_int32(env, result, &results);
66     return results;
67 }
68 
Socketpair(napi_env env, napi_callback_info info)69 static napi_value Socketpair(napi_env env, napi_callback_info info)
70 {
71     int fb[2];
72     int result = socketpair(AF_INET, SOCK_STREAM, PARAM_0, fb);
73     napi_value results = nullptr;
74     napi_create_int32(env, result, &results);
75     return results;
76 }
Sendmsg(napi_env env, napi_callback_info info)77 static napi_value Sendmsg(napi_env env, napi_callback_info info)
78 {
79     napi_value result = nullptr;
80     int ret = PARAM_1;
81     if (fork() == PARAM_0) {
82         int sockfd = socket(AF_INET, SOCK_STREAM, PARAM_0);
83         if (sockfd >= PARAM_0) {
84             struct sockaddr_in local = {PARAM_0};
85             local.sin_family = AF_INET;
86             local.sin_port = htons(PARAM_6000);
87             local.sin_addr.s_addr = inet_addr("127.0.0.1");
88             bind(sockfd, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&local)), sizeof(local));
89             listen(sockfd, PARAM_5);
90             struct sockaddr_in clnAddr = {PARAM_0};
91             socklen_t clnAddrLen = sizeof(clnAddr);
92             accept(sockfd, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&clnAddr)), &clnAddrLen);
93         }
94         close(sockfd);
95         _exit(PARAM_0);
96     } else {
97         int sock = socket(AF_INET, SOCK_STREAM, PARAM_0);
98         if (sock >= PARAM_0) {
99             struct sockaddr_in server = {PARAM_0};
100             server.sin_family = AF_INET;
101             server.sin_port = htons(PARAM_6000);
102             server.sin_addr.s_addr = inet_addr("127.0.0.1");
103             int conn = PARAM_1;
104             while (conn) {
105                 conn = connect(sock, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&server)),
106                                sizeof(server));
107             }
108             struct msghdr msg = {PARAM_0};
109             ret = sendmsg(sock, &msg, PARAM_0);
110         }
111         close(sock);
112     }
113     napi_create_int32(env, ret, &result);
114     return result;
115 }
116 
Send(napi_env env, napi_callback_info info)117 static napi_value Send(napi_env env, napi_callback_info info)
118 {
119     napi_value result = nullptr;
120     int ret = PARAM_1;
121     if (fork() == PARAM_0) {
122         int sockfd = socket(AF_INET, SOCK_STREAM, PARAM_0);
123         if (sockfd >= PARAM_0) {
124             struct sockaddr_in local = {PARAM_0};
125             local.sin_family = AF_INET;
126             local.sin_port = htons(PARAM_6004);
127             local.sin_addr.s_addr = inet_addr("127.0.0.1");
128             bind(sockfd, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&local)), sizeof(local));
129             listen(sockfd, PARAM_5);
130             struct sockaddr_in clnAddr = {PARAM_0};
131             socklen_t clnAddrLen = sizeof(clnAddr);
132             accept(sockfd, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&clnAddr)), &clnAddrLen);
133         }
134         close(sockfd);
135         _exit(PARAM_0);
136     } else {
137         int sock = socket(AF_INET, SOCK_STREAM, PARAM_0);
138         if (sock >= PARAM_0) {
139             struct sockaddr_in server = {PARAM_0};
140             server.sin_family = AF_INET;
141             server.sin_port = htons(PARAM_6004);
142             server.sin_addr.s_addr = inet_addr("127.0.0.1");
143             int conn = PARAM_1;
144             while (conn) {
145                 conn = connect(sock, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&server)),
146                                sizeof(server));
147             }
148             char sendBuf[] = "x";
149             ret = send(sock, sendBuf, sizeof(sendBuf), PARAM_0);
150         }
151         close(sock);
152     }
153     napi_create_int32(env, ret, &result);
154     return result;
155 }
156 
Sendto(napi_env env, napi_callback_info info)157 static napi_value Sendto(napi_env env, napi_callback_info info)
158 {
159     napi_value result = nullptr;
160     int ret = PARAM_1;
161     if (fork() == PARAM_0) {
162         int sockfd = socket(AF_INET, SOCK_STREAM, PARAM_0);
163         if (sockfd >= PARAM_0) {
164             struct sockaddr_in local = {PARAM_0};
165             local.sin_family = AF_INET;
166             local.sin_port = htons(PARAM_6005);
167             local.sin_addr.s_addr = inet_addr("127.0.0.1");
168             bind(sockfd, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&local)), sizeof(local));
169             listen(sockfd, PARAM_5);
170             struct sockaddr_in clnAddr = {PARAM_0};
171             socklen_t clnAddrLen = sizeof(clnAddr);
172             accept(sockfd, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&clnAddr)), &clnAddrLen);
173         }
174         close(sockfd);
175         _exit(PARAM_0);
176     } else {
177         int sock = socket(AF_INET, SOCK_STREAM, PARAM_0);
178         if (sock >= PARAM_0) {
179             struct sockaddr_in server = {PARAM_0};
180             server.sin_family = AF_INET;
181             server.sin_port = htons(PARAM_6005);
182             server.sin_addr.s_addr = inet_addr("127.0.0.1");
183             int conn = PARAM_1;
184             while (conn) {
185                 conn = connect(sock, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&server)),
186                                sizeof(server));
187             }
188             char sendBuf[] = "it is a test";
189             ret = sendto(sock, sendBuf, sizeof(sendBuf), PARAM_0, nullptr, PARAM_0);
190         }
191         close(sock);
192     }
193     napi_create_int32(env, ret, &result);
194     return result;
195 }
196 
Sendmmsg(napi_env env, napi_callback_info info)197 static napi_value Sendmmsg(napi_env env, napi_callback_info info)
198 {
199     napi_value result = nullptr;
200     int ret = PARAM_1;
201     if (fork() == PARAM_0) {
202         int sockfd = socket(AF_INET, SOCK_STREAM, PARAM_0);
203         if (sockfd >= PARAM_0) {
204             struct sockaddr_in local = {PARAM_0};
205             local.sin_family = AF_INET;
206             local.sin_port = htons(PARAM_6001);
207             local.sin_addr.s_addr = inet_addr("127.0.0.1");
208             bind(sockfd, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&local)), sizeof(local));
209             listen(sockfd, PARAM_5);
210             struct sockaddr_in clnAddr = {PARAM_0};
211             socklen_t clnAddrLen = sizeof(clnAddr);
212             accept(sockfd, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&clnAddr)), &clnAddrLen);
213         }
214         close(sockfd);
215         _exit(PARAM_0);
216     } else {
217         int sock = socket(AF_INET, SOCK_STREAM, PARAM_0);
218         if (sock >= PARAM_0) {
219             struct sockaddr_in server = {PARAM_0};
220             server.sin_family = AF_INET;
221             server.sin_port = htons(PARAM_6001);
222             server.sin_addr.s_addr = inet_addr("127.0.0.1");
223             int conn = PARAM_1;
224             while (conn) {
225                 conn = connect(sock, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&server)),
226                                sizeof(server));
227             }
228             struct mmsghdr msg[2];
229             memset_s(msg, sizeof(msg), 0, sizeof(msg));
230             ret = sendmmsg(sock, msg, TWOVAL, PARAM_0);
231         }
232         close(sock);
233     }
234     napi_create_int32(env, ret, &result);
235     return result;
236 }
237 
Setsockopt(napi_env env, napi_callback_info info)238 static napi_value Setsockopt(napi_env env, napi_callback_info info)
239 {
240     int sfd = socket(AF_INET, SOCK_STREAM, PARAM_0);
241     int reuse = ONEVAL;
242     napi_value result = nullptr;
243     int setval = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
244     napi_create_int32(env, setval, &result);
245     return result;
246 }
247 
Shutdown(napi_env env, napi_callback_info info)248 static napi_value Shutdown(napi_env env, napi_callback_info info)
249 {
250     int sd = socket(AF_INET, SOCK_STREAM, PARAM_0);
251     struct sockaddr_in server_addr = {PARAM_0};
252     bzero(&server_addr, sizeof(server_addr));
253     server_addr.sin_addr.s_addr = INADDR_ANY;
254     server_addr.sin_addr.s_addr = INADDR_ANY;
255     server_addr.sin_port = htons(VALUE9898);
256     server_addr.sin_family = AF_INET;
257     bind(sd, (struct sockaddr *)(&server_addr), sizeof(server_addr));
258     listen(sd, FIVEVAL);
259     napi_value result = nullptr;
260     int shuval = shutdown(sd, PARAM_0);
261     napi_create_int32(env, shuval, &result);
262     return result;
263 }
264 
Recv(napi_env env, napi_callback_info info)265 static napi_value Recv(napi_env env, napi_callback_info info)
266 {
267     size_t argc = PARAM_1;
268     napi_value args[1] = {nullptr};
269     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
270     int param = PARAM_0;
271     napi_get_value_int32(env, args[0], &param);
272 
273     int resultValue = FAILD;
274     if (param == PARAM_UNNORMAL) {
275         size_t data_len = atoi("11");
276         char buf[SIZE_10];
277         resultValue = recv(PARAM_0, buf, data_len, PARAM_0);
278     } else {
279         char buf[SIZE_100];
280         int sockets[PARAM_2];
281         socketpair(AF_UNIX, SOCK_STREAM, PARAM_0, sockets);
282         send(sockets[PARAM_1], "x", PARAM_1, PARAM_0);
283         resultValue = recv(sockets[PARAM_0], buf, sizeof buf, PARAM_0);
284     }
285 
286     napi_value result = nullptr;
287 
288     napi_create_int32(env, resultValue, &result);
289     return result;
290 }
291 
Recvfrom(napi_env env, napi_callback_info info)292 static napi_value Recvfrom(napi_env env, napi_callback_info info)
293 {
294     size_t argc = PARAM_1;
295     napi_value args[1] = {nullptr};
296     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
297     int param = PARAM_0;
298     napi_get_value_int32(env, args[0], &param);
299 
300     int resultValue = FAILD;
301     if (param == PARAM_UNNORMAL) {
302         size_t data_len = atoi("11");
303         char buf[SIZE_10];
304         resultValue = recvfrom(PARAM_0, buf, data_len, PARAM_0, nullptr, nullptr);
305     }
306 
307     napi_value result = nullptr;
308 
309     napi_create_int32(env, resultValue, &result);
310     return result;
311 }
312 
Recvmsg(napi_env env, napi_callback_info info)313 static napi_value Recvmsg(napi_env env, napi_callback_info info)
314 {
315     size_t argc = PARAM_1;
316     napi_value args[1] = {nullptr};
317     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
318     int param = PARAM_0;
319     napi_get_value_int32(env, args[0], &param);
320 
321     int resultValue = FAILD;
322     if (param == PARAM_UNNORMAL) {
323         struct msghdr msgRev = {PARAM_0};
324         resultValue = recvmsg(PARAM_0, &msgRev, PARAM_0);
325     }
326 
327     napi_value result = nullptr;
328     napi_create_int32(env, resultValue, &result);
329 
330     return result;
331 }
332 
Recvmmsg(napi_env env, napi_callback_info info)333 static napi_value Recvmmsg(napi_env env, napi_callback_info info)
334 {
335     size_t argc = PARAM_1;
336     napi_value args[1] = {nullptr};
337     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
338     int param = PARAM_0;
339     napi_get_value_int32(env, args[0], &param);
340 
341     int resultValue = FAILD;
342     if (param == PARAM_UNNORMAL) {
343         struct mmsghdr msg[SIZE_10];
344         resultValue = recvmmsg(PARAM_0, msg, SIZE_10, PARAM_0, PARAM_0);
345     }
346 
347     napi_value result = nullptr;
348     napi_create_int32(env, resultValue, &result);
349 
350     return result;
351 }
352 
Connect(napi_env env, napi_callback_info info)353 static napi_value Connect(napi_env env, napi_callback_info info)
354 {
355     napi_value result = nullptr;
356     int ret = PARAM_1;
357     if (fork() == PARAM_0) {
358         int sockfd = socket(AF_INET, SOCK_STREAM, PARAM_0);
359         if (sockfd >= PARAM_0) {
360             struct sockaddr_in local = {PARAM_0};
361             local.sin_family = AF_INET;
362             local.sin_port = htons(PARAM_6002);
363             local.sin_addr.s_addr = inet_addr("127.0.0.1");
364             bind(sockfd, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&local)), sizeof(local));
365             listen(sockfd, PARAM_5);
366             struct sockaddr_in clnAddr = {PARAM_0};
367             socklen_t clnAddrLen = sizeof(clnAddr);
368             accept(sockfd, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&clnAddr)), &clnAddrLen);
369         }
370         close(sockfd);
371         _exit(PARAM_0);
372     } else {
373         int sock = socket(AF_INET, SOCK_STREAM, PARAM_0);
374         if (sock >= PARAM_0) {
375             struct sockaddr_in server = {PARAM_0};
376             server.sin_family = AF_INET;
377             server.sin_port = htons(PARAM_6002);
378             server.sin_addr.s_addr = inet_addr("127.0.0.1");
379             while (ret) {
380                 ret = connect(sock, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&server)),
381                               sizeof(server));
382             }
383         }
384         close(sock);
385     }
386     napi_create_int32(env, ret, &result);
387     return result;
388 }
389 
Bind(napi_env env, napi_callback_info info)390 static napi_value Bind(napi_env env, napi_callback_info info)
391 {
392     napi_value result = nullptr;
393     int sockfd = socket(AF_INET, SOCK_STREAM, PARAM_0);
394     struct sockaddr_in server = {PARAM_0};
395     server.sin_family = AF_INET;
396     server.sin_port = htons(PARAM_8000);
397     server.sin_addr.s_addr = inet_addr("127.0.0.1");
398     int ret = bind(sockfd, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&server)), sizeof(server));
399     close(sockfd);
400     napi_create_int32(env, ret, &result);
401     return result;
402 }
Listen(napi_env env, napi_callback_info info)403 static napi_value Listen(napi_env env, napi_callback_info info)
404 {
405     napi_value result = nullptr;
406     int sockfd = socket(AF_INET, SOCK_STREAM, PARAM_0);
407     struct sockaddr_in local = {PARAM_0};
408     local.sin_family = AF_INET;
409     local.sin_port = htons(PARAM_6000);
410     local.sin_addr.s_addr = inet_addr("192.168.59.65");
411     bind(sockfd, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&local)), sizeof(local));
412     int ret = listen(sockfd, PARAM_5);
413     close(sockfd);
414     napi_create_int32(env, ret, &result);
415     return result;
416 }
Getpeername(napi_env env, napi_callback_info info)417 static napi_value Getpeername(napi_env env, napi_callback_info info)
418 {
419     napi_value result = nullptr;
420     int ret = PARAM_1;
421     if (fork() == PARAM_0) {
422         int sockfd = socket(AF_INET, SOCK_STREAM, PARAM_0);
423         if (sockfd >= PARAM_0) {
424             struct sockaddr_in local = {PARAM_0};
425             local.sin_family = AF_INET;
426             local.sin_port = htons(PARAM_6003);
427             local.sin_addr.s_addr = inet_addr("127.0.0.1");
428             bind(sockfd, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&local)), sizeof(local));
429             listen(sockfd, PARAM_5);
430             struct sockaddr_in clnAddr = {PARAM_0};
431             socklen_t clnAddrLen = sizeof(clnAddr);
432             accept(sockfd, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&clnAddr)), &clnAddrLen);
433         }
434         close(sockfd);
435         _exit(PARAM_0);
436     } else {
437         int sock = socket(AF_INET, SOCK_STREAM, PARAM_0);
438         if (sock >= PARAM_0) {
439             struct sockaddr_in server = {PARAM_0};
440             server.sin_family = AF_INET;
441             server.sin_port = htons(PARAM_6003);
442             server.sin_addr.s_addr = inet_addr("127.0.0.1");
443             int conn = PARAM_1;
444             while (conn) {
445                 conn = connect(sock, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&server)),
446                                sizeof(server));
447             }
448             struct sockaddr addr = {PARAM_0};
449             socklen_t addrLen = sizeof(addr);
450             ret = getpeername(sock, &addr, &addrLen);
451         }
452         close(sock);
453     }
454     napi_create_int32(env, ret, &result);
455     return result;
456 }
457 
Getsockname(napi_env env, napi_callback_info info)458 static napi_value Getsockname(napi_env env, napi_callback_info info)
459 {
460     int sockfd = socket(AF_INET, SOCK_STREAM, PARAM_0);
461     struct sockaddr_in local = {PARAM_0};
462     struct sockaddr sa = {PARAM_0};
463     int len = sizeof(struct sockaddr_in);
464     local.sin_family = AF_INET;
465     local.sin_port = htons(PARAM_8000);
466     local.sin_addr.s_addr = inet_addr("192.168.59.65");
467     bind(sockfd, (struct sockaddr *)&local, sizeof(local));
468     socklen_t *addrlen = (socklen_t *)&len;
469     int ret = getsockname(sockfd, &sa, addrlen);
470     napi_value result = nullptr;
471     napi_create_int32(env, ret, &result);
472     return result;
473 }
Getsockopt(napi_env env, napi_callback_info info)474 static napi_value Getsockopt(napi_env env, napi_callback_info info)
475 {
476     int optval = PARAM_0;
477     int optlen = PARAM_0;
478     int sockfd = socket(AF_INET, SOCK_STREAM, PARAM_0);
479     int ret = getsockopt(sockfd, SOL_SOCKET, SO_DEBUG, &optval, (socklen_t *)(&optlen));
480     napi_value result = nullptr;
481     napi_create_int32(env, ret, &result);
482     return result;
483 }
484 
485 EXTERN_C_START
Init(napi_env env, napi_value exports)486 static napi_value Init(napi_env env, napi_value exports)
487 {
488     napi_property_descriptor desc[] = {
489         {"socket", nullptr, Socket, nullptr, nullptr, nullptr, napi_default, nullptr},
490         {"socketpair", nullptr, Socketpair, nullptr, nullptr, nullptr, napi_default, nullptr},
491         {"sendmsg", nullptr, Sendmsg, nullptr, nullptr, nullptr, napi_default, nullptr},
492         {"sendmmsg", nullptr, Sendmmsg, nullptr, nullptr, nullptr, napi_default, nullptr},
493         {"sendto", nullptr, Sendto, nullptr, nullptr, nullptr, napi_default, nullptr},
494         {"send", nullptr, Send, nullptr, nullptr, nullptr, napi_default, nullptr},
495         {"setsockopt", nullptr, Setsockopt, nullptr, nullptr, nullptr, napi_default, nullptr},
496         {"shutdown", nullptr, Shutdown, nullptr, nullptr, nullptr, napi_default, nullptr},
497         {"recv", nullptr, Recv, nullptr, nullptr, nullptr, napi_default, nullptr},
498         {"recvfrom", nullptr, Recvfrom, nullptr, nullptr, nullptr, napi_default, nullptr},
499         {"recvmsg", nullptr, Recvmsg, nullptr, nullptr, nullptr, napi_default, nullptr},
500         {"recvmmsg", nullptr, Recvmmsg, nullptr, nullptr, nullptr, napi_default, nullptr},
501         {"bind", nullptr, Bind, nullptr, nullptr, nullptr, napi_default, nullptr},
502         {"connect", nullptr, Connect, nullptr, nullptr, nullptr, napi_default, nullptr},
503         {"listen", nullptr, Listen, nullptr, nullptr, nullptr, napi_default, nullptr},
504         {"getpeername", nullptr, Getpeername, nullptr, nullptr, nullptr, napi_default, nullptr},
505         {"getsockname", nullptr, Getsockname, nullptr, nullptr, nullptr, napi_default, nullptr},
506         {"getsockopt", nullptr, Getsockopt, nullptr, nullptr, nullptr, napi_default, nullptr},
507     };
508     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
509     return exports;
510 }
511 EXTERN_C_END
512 
513 static napi_module demoModule = {
514     .nm_version = 1,
515     .nm_flags = 0,
516     .nm_filename = nullptr,
517     .nm_register_func = Init,
518     .nm_modname = "socket",
519     .nm_priv = ((void *)0),
520     .reserved = {0},
521 };
522 
RegisterModule(void)523 extern "C" __attribute__((constructor)) void RegisterModule(void) { napi_module_register(&demoModule); }
524