blob: 4fb37f5eb62934fe0309643b6d1ba759f9553676 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/**
2* @file netotherapi.c
3* @brief Public APIs of Sanechips
4*
5* Copyright (C) 2017 Sanechips Technology Co., Ltd.
6* @author Linxu Gebin
7* @defgroup si_id Sanechips
8*
9* This program is free software; you can redistribute it and/or modify
10* it under the terms of the GNU General Public License version 2 as
11* published by the Free Software Foundation.
12*************************************************************************
13*/
14
15/*******************************************************************************
16 * Include header files *
17 ******************************************************************************/
18
19#include <stdio.h>
20#include <unistd.h>
21#include <sys/types.h>
22#include <fcntl.h>
23#include <string.h>
24#include <stdlib.h>
25#include <assert.h>
26#include <syslog.h>
27#include <sys/klog.h>
28#include <sys/msg.h>
29#include "message.h"
30#include <sys/time.h>
31#include <asm/types.h>
32#include <netinet/ether.h>
33#include <netinet/in.h>
34#include <net/if.h>
35#include <netdb.h>
36#include <sys/socket.h>
37#include <signal.h>
38#include <sys/ioctl.h>
39#include <linux/netlink.h>
40#include <linux/rtnetlink.h>
41#include <sys/types.h>
42#include <pthread.h>
43#include "softap_api.h"
44#include <netotherapi.h>
45#include <dirent.h>
46#include <limits.h>
47
48/*******************************************************************************
49 * Type definitions *
50 ******************************************************************************/
51/**
52* @brief route information
53* @param dstAddr destination address
54* @param srcAddr source address
55* @param gateWay gateWay
56* @param ifName NIC name
57*/
58struct route_info {
59 u_int dstAddr;
60 u_int srcAddr;
61 u_int gateWay;
62 char ifName[IF_NAMESIZE];
63};
64
65#define BUFSIZE 8192
66
67#define SPINLOCK_IOC_MAGIC 'S'
68
69#define SPINLOCK_GET_STATUS _IOWR(SPINLOCK_IOC_MAGIC,1,char *)
70
71#define READ_BUF_SIZE 56
72/*******************************************************************************
73 * Inline function implementations *
74 ******************************************************************************/
75inline char *strip_space(char *str)
76{
77 while (*str == ' ')
78 str++;
79 return str;
80}
81/*******************************************************************************
82 * Local function implementations *
83 ******************************************************************************/
84/* дÎļþ²Ù×÷º¯Êý */
85int write_file(const char *filepath, int flags, const char *buf, int size)
86{
87 int fd = 0;
88 int ret = 0;
89
90 fd = open(filepath, flags, 0644);
91 if (fd < 0) {
92 slog(MISC_PRINT, SLOG_ERR, "write_to_file open %s fail, error:%s! \n", filepath, strerror(errno));
93 ret = -1;
94 goto out;
95 }
96
97 ret = TEMP_FAILURE_RETRY(write(fd, buf, size));
98 if (ret != size) {
99 slog(MISC_PRINT, SLOG_ERR, "write_to_file write %s fail, error:%s! \n", filepath, strerror(errno));
100 ret = -1;
101 goto out;
102 }
103 if(fsync(fd) < 0)
104 {
105 // todo: cov m
106 }
107
108 ret = 0;
109
110out:
111 if (fd >= 0)
112 close(fd);
113 return ret;
114}
115
116/* дÎļþ: ¸²¸Çд */
117int write_to_file(const char *filepath, const char *buf, int size)
118{
119 return write_file(filepath, O_WRONLY | O_CREAT | O_TRUNC, buf, size);
120}
121
122/* дÎļþ: β²¿×·¼Óд */
123int append_to_file(const char *filepath, const char *buf, int size)
124{
125 return write_file(filepath, O_WRONLY | O_APPEND | O_CREAT, buf, size);
126}
127
128//¿â½Ó¿Úctime¡¢asctime»á»»ÐУ¬Ôì³ÉÿÌõlog±»·ÖÐÐÏÔʾ£¬²»·½±ã¿´£¬ËùÒÔ½«ctimeÔ´ÂëÉÔ΢¸ÄÔìÏÂ
129static char *str_ctime(const struct tm *timeptr)
130{
131 /*static const char wday_name[][4] = {
132 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
133 };*/
134
135 static const char mon_name[][4] = {
136 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
137 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
138 };
139
140 static char result[26];
141
142 /*sprintf(result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d",
143 wday_name[timeptr->tm_wday],
144 mon_name[timeptr->tm_mon],
145 timeptr->tm_mday, timeptr->tm_hour,
146 timeptr->tm_min, timeptr->tm_sec,
147 1900 + timeptr->tm_year);*/
148 snprintf(result, sizeof(result), "%.3s%3d %.2d:%.2d:%.2d %d",
149 mon_name[timeptr->tm_mon],
150 timeptr->tm_mday, timeptr->tm_hour,
151 timeptr->tm_min, timeptr->tm_sec,
152 1900 + timeptr->tm_year);
153 return result;
154}
155
156/*******************************************************************************
157 * Global function implementations *
158 ******************************************************************************/
159
160/****************************************/
161//input: nv_str:nvÄÚÈÝÖ¸Õë * nv_param ½âÎöºó²ÎÊýµÄÖ¸Õë
162//output: param_num nv_param
163//ʾÀý:
164// int num;
165// char** nv_param;
166// num = nv_analyze(nv_str,&nv_param)
167// strcmp(nv_param[0],"aaa") ...
168// strcmp(nv_param[1],"bbb") ...
169// ...
170// free(nv_param);
171//
172/****************************************/
173
174int nv_analyze(char* nv_str, char*** nv_param)
175{
176 int param_num = 1;
177 int i = 0;
178 char* str_ptr;
179 char** mem_ptr;
180 char* tmp_ptr;
181 for (str_ptr = nv_str; *str_ptr != '\0'; str_ptr++) {
182 if (*str_ptr == '+')
183 param_num++;
184 }
185 mem_ptr = (char**)malloc((1 + sizeof(char*)) * param_num + strlen(nv_str));
186 if (mem_ptr == NULL) {//klocwork
187 return -1;
188 }
189 memset(mem_ptr, 0, (1 + sizeof(char*)) * param_num + strlen(nv_str));
190 * nv_param = mem_ptr;
191 str_ptr = strtok(nv_str, "+");
192 tmp_ptr = (char*)(mem_ptr + param_num);
193 while (str_ptr != NULL) {
194 memcpy((mem_ptr + i), &tmp_ptr, sizeof(char*));
195 strcpy(tmp_ptr, str_ptr);
196 tmp_ptr = (char*)((long)tmp_ptr + strlen(str_ptr) + 1);
197 i ++;
198 str_ptr = strtok(NULL, "+");
199 }
200 return param_num;
201}
202
203
204char* getField(char *a_line, char *delim, int count)
205{
206 int i = 0;
207 char *tok = NULL;
208 char *save = NULL;
209 tok = strtok_r(a_line, delim, &save);
210 while (tok) {
211 if (i == count)
212 break;
213 i++;
214 tok = strtok_r(NULL, delim, &save);
215 }
216 if (tok)
217 return tok;
218
219 return NULL;
220}
221
222void free_dhcp_list(struct list_head *dhcp_info_list)
223{
224 DHCPOFFERADDR_LIST_t *dhcp_info_temp = NULL;
225 DHCPOFFERADDR_LIST_t *dhcp_info_temp1 = NULL;
226
227 list_for_each_entry_safe(dhcp_info_temp, dhcp_info_temp1, dhcp_info_list, list) {
228 list_del(&dhcp_info_temp->list);
229 free(dhcp_info_temp);
230 }
231}
232
233void free_laninfo_list(struct list_head *file_info_list)
234{
235 LAN_INFO_LIST_t *lan_info_list_tmp = NULL;
236 LAN_INFO_LIST_t *lan_info_list_tmp1 = NULL;
237
238 list_for_each_entry_safe(lan_info_list_tmp, lan_info_list_tmp1, file_info_list, list) {
239 list_del(&lan_info_list_tmp->list);
240 free(lan_info_list_tmp);
241 }
242
243}
244
245/**************************************************************************
246* º¯ÊýÃû³Æ£º getIfStatistic
247* ¹¦ÄÜÃèÊö£º »ñÈ¡ÍøÂçÉ豸µ±Ç°Á÷Á¿
248* ²ÎÊý˵Ã÷£º interface: Íø¿ÚÉ豸Ãû³Æ
249* type: Á÷Á¿ÀàÐÍ£¬ÉÏÐС¢ÏÂÐбÈÌØ»ò°ü¸öÊý
250* result_data: ±£´æÁ÷Á¿Öµ
251* ·µ »Ø Öµ£º ʧ°Ü·µ»Ø-1£¬³É¹¦·µ»Ø0
252**************************************************************************/
253int getIfStatistic(char *interface, int type, unsigned long long *result_data)
254{
255 int found_flag = 0;
256 int skip_line = 2;
257 char temp_rcv[64] = {0};
258 char buf[1024], *field, *semiColon = NULL;
259 long long result_data_num = 0;
260 FILE *fp = fopen(PROC_IF_STATISTIC, "r");
261 if (!fp) {
262 slog(MISC_PRINT, SLOG_ERR, "no proc?\n");
263 return -1;
264 }
265
266 while (fgets(buf, 1024, fp)) {
267 char *ifname;
268 if (skip_line != 0) {
269 skip_line--;
270 continue;
271 }
272 if (!(semiColon = strchr(buf, ':')))
273 continue;
274 *semiColon = '\0';
275 ifname = buf;
276 ifname = strip_space(ifname);
277
278 if (!strcmp(ifname, interface)) {
279 found_flag = 1;
280 break;
281 }
282 }
283 fclose(fp);
284
285 if (found_flag == 0) {
286 slog(MISC_PRINT, SLOG_DEBUG, "[fluxstat]getIfStatistic no found data======\n");
287 return -1;
288 }
289
290 semiColon++;
291
292 switch (type) {
293 case TXBYTE:
294 if ((field = getField(semiColon, " ", 8))) {
295 errno = 0;
296 result_data_num = strtoull(field, NULL, 10);
297 if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
298 {
299 printf("strtoull errno %d: %s\n", errno, strerror(errno));
300 }
301 if (result_data_num < 0 || result_data_num > LLONG_MAX-1)
302 result_data_num = 0;
303 *result_data = result_data_num;
304
305 slog(MISC_PRINT, SLOG_DEBUG, "[getIfStatistic]TXBYTE field:%s, result_data:%llu\n", field, *result_data);
306 return 0; //kw 3
307 }
308 break;
309 case TXPACKET:
310 if ((field = getField(semiColon, " ", 9))) {
311 errno = 0;
312 result_data_num = strtoull(field, NULL, 10);
313 if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
314 {
315 printf("strtoull errno %d: %s\n", errno, strerror(errno));
316 }
317 if (result_data_num < 0 || result_data_num > LLONG_MAX-1)
318 result_data_num = 0;
319 *result_data = result_data_num;
320 return 0;
321 }
322 break;
xf.li742dd022023-06-08 01:43:32 -0700323 case TXERR:
324 if ((field = getField(semiColon, " ", 10))) {
325 errno = 0;
326 result_data_num = strtoull(field, NULL, 10);
327 if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
328 {
329 printf("strtoull errno %d: %s\n", errno, strerror(errno));
330 }
331 if (result_data_num < 0 || result_data_num > LLONG_MAX-1)
332 result_data_num = 0;
333 *result_data = result_data_num;
334
335 return 0; //kw 3
336 }
337 break;
338 case TXDROP:
339 if ((field = getField(semiColon, " ", 11))) {
340 errno = 0;
341 result_data_num = strtoull(field, NULL, 10);
342 if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
343 {
344 printf("strtoull errno %d: %s\n", errno, strerror(errno));
345 }
346 if (result_data_num < 0 || result_data_num > LLONG_MAX-1)
347 result_data_num = 0;
348 *result_data = result_data_num;
349 return 0;
350 }
351 break;
lh9ed821d2023-04-07 01:36:19 -0700352 case RXBYTE:
353 if ((field = getField(semiColon, " ", 0))) {
354 errno = 0;
355 result_data_num = strtoull(field, NULL, 10);
356 if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
357 {
358 printf("strtoull errno %d: %s\n", errno, strerror(errno));
359 }
360 if (result_data_num < 0 || result_data_num > LLONG_MAX-1)
361 result_data_num = 0;
362 *result_data = result_data_num;
363 slog(MISC_PRINT, SLOG_DEBUG, "[getIfStatistic]RXBYTE field:%s, result_data:%llu\n", field, *result_data);
364 return 0;
365 }
366 break;
367 case RXPACKET:
368 if ((field = getField(semiColon, " ", 1))) {
369 errno = 0;
370 result_data_num = strtoull(field, NULL, 10);
371 if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
372 {
373 printf("strtoull errno %d: %s\n", errno, strerror(errno));
374 }
375 if (result_data_num < 0 || result_data_num > LLONG_MAX-1)
376 result_data_num = 0;
377 *result_data = result_data_num;
378 return 0;
379 }
380 break;
xf.li742dd022023-06-08 01:43:32 -0700381 case RXERR:
382 if ((field = getField(semiColon, " ", 2))) {
383 errno = 0;
384 result_data_num = strtoull(field, NULL, 10);
385 if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
386 {
387 printf("strtoull errno %d: %s\n", errno, strerror(errno));
388 }
389 if (result_data_num < 0 || result_data_num > LLONG_MAX-1)
390 result_data_num = 0;
391 *result_data = result_data_num;
392 return 0;
393 }
394 break;
395 case RXDROP:
396 if ((field = getField(semiColon, " ", 3))) {
397 errno = 0;
398 result_data_num = strtoull(field, NULL, 10);
399 if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
400 {
401 printf("strtoull errno %d: %s\n", errno, strerror(errno));
402 }
403 if (result_data_num < 0 || result_data_num > LLONG_MAX-1)
404 result_data_num = 0;
405 *result_data = result_data_num;
406 return 0;
407 }
408 break;
lh9ed821d2023-04-07 01:36:19 -0700409 }
410 return -1;
411}
412
413void *safe_malloc(int size, BOOL is_assert)
414{
415 void *ret = malloc(size);
416
417 if (ret == NULL) {
418 if (is_assert == TRUE) {
419 assert(ret);
420 } else {
421 printf("[%s][%s] ----can not get memory", __FILE__, __FUNCTION__);
422 }
423 } else {
424 memset(ret, 0, size);
425 }
426
427 return ret;
428}
429
430//ÊäÈësize±ØÐëÊÇdestµÄ³¤¶È
431void safe_strcpy(char *dest, char *source, int size)
432{
433 if (dest == NULL || source == NULL || size < 1) {
434 return;
435 }
436
437 strncpy(dest, source, size - 1);
438 dest[size - 1] = '\0';
439}
440
441int get_dev_list(struct pc_node* mypc_node)
442{
443 int ret = 0;
444
445 ret = netioctl_handle(NIOCGPCINFO, mypc_node);
446 if (-1 == ret) {
447 slog(NET_PRINT, SLOG_ERR, "NIOCGPCINFO err");
448 return -1;
449 }
450 return 0;
451}
452
453int zte_get_mac_list_from_lease(struct list_head *dhcp_list_info)
454{
455 FILE *leaseFile = NULL;
456 int64_t leaseFirst = 0;
457 char buf[32];
458
459 DHCPOFFERADDRNET dhcpInfo = {0};
460
461 char path_conf[50] = {0};
462 char path_file[100] = {0};
463
464 if (!list_empty(dhcp_list_info))
465 return -1;
466
467 sc_cfg_get("path_conf", path_conf, sizeof(path_conf));
468 sprintf(path_file, "%s/udhcpd.leases", path_conf);
469
470 leaseFile = fopen(path_file, "r");
471 if (leaseFile == NULL) {
472 fprintf(stderr, "can not open file udhcpd.leases.");
473 return -1 ;
474 }
475
476 if (fread(&leaseFirst, 1, sizeof(leaseFirst), leaseFile) != sizeof(leaseFirst)) {
477 fprintf(stderr, "read the first part of udhcpd.leases fail!");
478 fclose(leaseFile);
479 return -1 ;
480 }
481
482 memset(buf, 0x00, sizeof(buf));
483 sc_cfg_get("dhcpEnabled", buf, sizeof(buf));
484 if (strcmp(buf, "0") == 0) {
485 fclose(leaseFile);
486 return -1 ;
487 }
488
489 while ((fread(&dhcpInfo, 1, sizeof(dhcpInfo), leaseFile) == sizeof(dhcpInfo))) {
490 DHCPOFFERADDR_LIST_t *dhcpInfo_ptr = (DHCPOFFERADDR_LIST_t *)safe_malloc(sizeof(DHCPOFFERADDR_LIST_t), TRUE);
491 if (!dhcpInfo_ptr) {
492 slog(NET_PRINT, SLOG_ERR, "get_lan_info_list safe_malloc dhcpInfo_ptr fail \n");
493 return -1;
494 }
495 memcpy(&(dhcpInfo_ptr->dhcp_info), &dhcpInfo, sizeof(DHCPOFFERADDRNET));
496 list_add_tail(&dhcpInfo_ptr->list, dhcp_list_info);
497 }
498
499 fclose(leaseFile);
500 return 0;
501}
502
503void flash_file(char *file, char *file_num)
504{
505 char newFile[128] = {0};
506 char oldFile[128] = {0};
507 int i = 0;//klocwork
508 int i_file_num = atoi(file_num);
509
510 if(i_file_num < 0 || i_file_num > INT_MAX-1)
511 {
512 return ;
513 }
514
515 for (i = i_file_num - 2; i > 0 && i < 1000; i--) {
516 sprintf(newFile, "%s_bk%d", file, i);
517 sprintf(oldFile, "%s_bk%d", file, i + 1);
518 if ((access(newFile, F_OK)) == 0) {
519 if(rename(newFile, oldFile) < 0){
520 // cov M
521 }
522 }
523 }
524 sprintf(newFile, "%s_bk1", file);
525
526 if(rename(file, newFile) < 0)
527 {
528 // cov M
529 }
530}
531
532void file_write(char *filename, char *info)
533{
534 FILE *fp;
535 char logpath[128] = {0};
536 char logname[128] = {0};
537 char filesize[32] = {0};
538 char temp[64] = {0};
539 int flag = 0;
540 time_t now;
541 struct tm *timenow;
542
543 time(&now);
544 timenow = localtime(&now);
545 if (!timenow) {//klocwork
546 printf("localtime get err.\n");
547 return;
548 }
549
550 if (!filename || 0 == strcmp(filename, "")) {
551 printf("filename is err.\n");
552 return;
553 }
554
555 //Ö¸¶¨logÎļþ´óС£¬Èç¹ûδָ¶¨¾ÍÓÃĬÈÏcomm_logsize
556 sprintf(temp, "%s_logsize", filename);
557 sc_cfg_get(temp, filesize, sizeof(filesize));
558 if (0 == strcmp(filesize, "0")) {
559 return ;
560 } else if (0 == strcmp(filesize, "")) {
561 sc_cfg_get("comm_logsize", filesize, sizeof(filesize));
562 if (0 == strcmp(filesize, "0") || 0 == strcmp(filesize, "")) {
563 printf("filesize is not set.\n");
564 return;
565 }
566 }
567
568 sc_cfg_get("path_log", logpath, sizeof(logpath));
569 snprintf(logname, sizeof(logname), "%s%s.log", logpath, filename);
570
571 fp = fopen(logname, "a");
572 if (!fp) {
573 printf("fopen %s failed \n", logname);
574 return;
575 }
576 //flock»úÖÆ²¢²»ÄÜÕæµÄÆðµ½lock×÷Ó㬷µ»Ø»áÔì³Éunlock²»µô
577 /*
578 else if (flock(fileno(fp), LOCK_EX) != 0)
579 {
580 perror("flock");
581 fclose(fp);
582 return;
583 }*/
584
585 fprintf(fp, "%s:%s\n", str_ctime(timenow), info);
586 //fprintf(fp, "%s %s %s[%d]: %s", ctime(timenow), asctime(timenow), filename, getpid(), info);
587 fflush(fp);
588 fseek(fp, 0L, SEEK_END);
589
590 if (ftell(fp) > atoi(filesize))
591 flag = 1;
592
593 //flock(fileno(fp), LOCK_UN);
594 fclose(fp);
595
596 if (flag == 1) {
597 flash_file(logname, "2");
598 }
599}
600
601int echo_file(char *filename, char*info)
602{
603 int len;
604 int ret;
605 int fd;
606 if (!filename || 0 == strcmp(filename, "") || !info) {
607 printf("echo filename is err.\n");
608 return -1;
609 }
610 fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, 777);
611 if (fd < 0) {
612 printf("%s open failed!\n", filename);
613 return -1;
614 }
615 len = strlen(info);
616 ret = write(fd, info, len);
617
618 close(fd);
619
620 return ret;
621}
622
623void save_file(char *filename, char* info)
624{
625 FILE* fp;
626 char filepath[128] = {0};
627 char filesize[32] = {0};
628 char filenum[32] = {0};
629 char temp[64] = {0};
630 int flag = 0;
631 time_t now;
632 struct tm *timenow;
633 time(&now);
634 timenow = localtime(&now);
635 if (!timenow) {//klocwork
636 printf("localtime get err.\n");
637 return;
638 }
639
640 if (!filename || 0 == strcmp(filename, "")) {
641 printf("filename is err.\n");
642 return;
643 }
644 sprintf(temp, "%sfile", filename);
645 sc_cfg_get(temp, filepath, sizeof(filepath));
646 sprintf(temp, "%sfileSize", filename);
647 sc_cfg_get(temp, filesize, sizeof(filesize));
648 if (0 == strcmp(filesize, "0") || 0 == strcmp(filesize, "")) {
649 printf("filesize is not set.\n");
650 return;
651 }
652
653 sprintf(temp, "%sNum", filename);
654 sc_cfg_get(temp, filenum, sizeof(filenum));
655 fp = fopen(filepath, "a");
656 if (!fp) {
657 printf("fopen %s failed \n", filepath);
658 return;
659 } else if (flock(fileno(fp), LOCK_EX) != 0) {
660 perror("flock");
661 fclose(fp);
662 return;
663 }
664
665 fprintf(fp, "%s %s\n", str_ctime(timenow), info);
666 fflush(fp);
667 fseek(fp, 0L, SEEK_END);
668 if (ftell(fp) > atoi(filesize))
669 flag = 1;
670
671 flock(fileno(fp), LOCK_UN);
672 fclose(fp);
673
674 if (flag == 1) {
675 flash_file(filepath, "2");
676 }
677}
678
679struct timeval timeget(void)
680{
681 struct timeval now;
682 unsigned char timestr[60] = {0};
683 unsigned char uptimestr[30] = {0};
684 unsigned char * dotaddr = NULL;
685 unsigned long second;
686 char error = 0;
687 FILE * timefile = NULL;
688 int read_len = 0;
689
690 timefile = fopen("/proc/uptime", "r");
691 if (!timefile) {
692 printf("[%s:line:%d] error opening '/proc/uptime'", __FILE__, __LINE__);
693 error = 1;
694 goto out;
695 }
696 //klocwork cov M
697 read_len = fread(timestr, sizeof(char), sizeof(timestr)-1, timefile);
698 if (read_len == 0 ) {
699 printf("[%s:line:%d] read '/proc/uptime' error", __FILE__, __LINE__);
700 error = 1;
701 goto out;
702 }
703 timestr[sizeof(timestr)-1] = '\0';//cov
704 dotaddr = strchr(timestr, '.');
705 if (dotaddr != NULL && (dotaddr - timestr) < (30 - 2))//cov
706 memcpy(uptimestr, timestr, dotaddr - timestr + 2);
707 else {
708 printf("[%s:line:%d] uptime string is too long", __FILE__, __LINE__);
709 error = 1;
710 goto out;
711 }
712 uptimestr[dotaddr - timestr + 2] = '\0';
713
714out:
715 if (error) {
716 now.tv_sec = 0;
717 now.tv_usec = 0;
718 } else {
719 now.tv_sec = atol(uptimestr);
720 now.tv_usec = 0;
721 }
722 if (timefile) {//klocwork
723 fclose(timefile);
724 }
725 return now;
726}
727
728unsigned long time_sec()
729{
730 struct timeval uptime;
731
732 uptime = timeget();
733 //printf("uptime = %lu \n",(unsigned long)uptime.tv_sec);
734 return uptime.tv_sec;
735}
736
737int get_lan_info_list(struct list_head *file_list_info)
738{
739 FILE *lanFile = NULL;
740 char buf[32];
741
742 LAN_INFO_t lanInfo = {0};
743 char path_conf[50] = {0};
744 char path_file[100] = {0};
745
746 if (!list_empty(file_list_info)) {
747 return -1;
748 }
749
750 sc_cfg_get("path_conf", path_conf, sizeof(path_conf));
751 sprintf(path_file, "%s/laninfo.tmp", path_conf);
752
753 lanFile = fopen(path_file, "r");
754 if (lanFile == NULL) {
755 slog(NET_PRINT, SLOG_ERR, "fopen laninfo.tmp fail \n");
756 return 0;
757 }
758
759 while (fread(&lanInfo, sizeof(LAN_INFO_t), 1, lanFile) == 1) {
760 LAN_INFO_LIST_t *lanInfo_ptr = (LAN_INFO_LIST_t *)safe_malloc(sizeof(LAN_INFO_LIST_t), TRUE);
761 if (!lanInfo_ptr) {
762 slog(NET_PRINT, SLOG_ERR, "get_lan_info_list safe_malloc lanInfo_ptr fail \n");
763 return -1;
764 }
765 memcpy(&(lanInfo_ptr->lan_info), &lanInfo, sizeof(LAN_INFO_t));
766 list_add_tail(&lanInfo_ptr->list, file_list_info);
767 }
768
769 fclose(lanFile);
770 return 0;
771
772}
773
774/* ÉèÖó¬Ê±Ëø£¬ ³¬Ê±0±íʾÓÀ¾ÃËø - Ôݲ»¶ÔÍ⣬ÐèÒªms¼¶±ðʱ¿ª·Å */
775int set_wake_lock_timeout_ms(const char *lockid, unsigned long interval_ms)
776{
777 char *p = NULL;
778 int ret = -1;
779
780 if ((lockid == NULL) || (*lockid == '\0'))
781 return -1;
782
783 if (interval_ms == 0) {
784 ret = asprintf(&p, "%s", lockid);
785 } else {
786 ret = asprintf(&p, "%s %lu000000", lockid, interval_ms);
787 }
788 if (ret < 0) {
789 ret = -1;
790 goto out;
791 }
792 ret = write_to_file(WAKE_LOCK_PATH, p, strlen(p));
793
794out:
795 safe_free(p);
796 return ret;
797}
798
799/* »ñÈ¡wakelockËø */
800int set_wake_lock(const char *lockId)
801{
802 return set_wake_lock_timeout_ms(lockId, 0);
803}
804
805/* ÉèÖó¬Ê±Ëø */
806int set_wake_lock_timeout(const char *lockId, unsigned long seconds)
807{
808 return set_wake_lock_timeout_ms(lockId, seconds * 1000);
809}
810
811/* ÊÍ·ÅwakelockËø */
812int set_wake_unlock(const char *lockId)
813{
814 if ((lockId == NULL) || (*lockId == '\0'))
815 return -1;
816
817 return write_to_file(WAKE_UNLOCK_PATH, lockId, strlen(lockId));
818}
819
820int readNlSock(int sockFd, char *bufPtr, int seqNum, int pId)
821{
822 struct nlmsghdr *nlHdr;
823 int readLen = 0, msgLen = 0;
824 do {
825 //ÊÕµ½Äں˵ÄÓ¦´ð
826 if ((readLen = recv(sockFd, bufPtr, BUFSIZE - msgLen, 0)) < 0) {
827 perror("SOCK READ: ");
828 return -1;
829 }
830
831
832 nlHdr = (struct nlmsghdr *)bufPtr;
833 //¼ì²éheaderÊÇ·ñÓÐЧ
834 if ((NLMSG_OK(nlHdr, readLen) == 0) || (nlHdr->nlmsg_type == NLMSG_ERROR)) {
835 perror("Error in recieved packet");
836 return -1;
837 }
838
839
840
841
842 if (nlHdr->nlmsg_type == NLMSG_DONE) {
843 break;
844 } else {
845 bufPtr += readLen;
846 msgLen += readLen;
847 }
848
849 if ((nlHdr->nlmsg_flags & NLM_F_MULTI) == 0) {
850 break;
851 }
852 } while ((nlHdr->nlmsg_seq != seqNum) || (nlHdr->nlmsg_pid != pId));
853 return msgLen;
854}
855
856//coverity
857static int net_RTA_OK(struct rtattr *rta, unsigned int len)
858{
859 return RTA_OK(rta, len);
860}
861
862//·ÖÎö·µ»ØµÄ·ÓÉÐÅÏ¢
863void parseRoutes(struct nlmsghdr *nlHdr, struct route_info *rtInfo)
864{
865 struct rtmsg *rtMsg;
866 struct rtattr *rtAttr;
867 int rtLen, dstLen;
868 //char *tempBuf = NULL;
869 struct in_addr dst;
870 struct in_addr gate;
871 char cmd[128];
872 char dstaddr[32], srcaddr[32];
873
874
875 //tempBuf = (char *)malloc(100);
876 rtMsg = (struct rtmsg *)NLMSG_DATA(nlHdr);
877 // If the route is not for AF_INET or does not belong to main routing table
878 //then return.
879 if ((rtMsg->rtm_family != AF_INET) || (rtMsg->rtm_table != RT_TABLE_MAIN))
880 return;
881 //printf("rtmsg srclen:%d,dstlen:%d\n",rtMsg->rtm_src_len,rtMsg->rtm_dst_len);
882 dstLen = rtMsg->rtm_dst_len; //·ÓɱíÖÐÄ¿µÄµØÖ·µÄÑÚÂ볤¶È
883
884
885 rtAttr = (struct rtattr *)RTM_RTA(rtMsg);
886 rtLen = RTM_PAYLOAD(nlHdr);
887 for (; net_RTA_OK(rtAttr, rtLen); rtAttr = RTA_NEXT(rtAttr, rtLen)) {
888 switch (rtAttr->rta_type) {
889 case RTA_OIF:
890 if_indextoname(*(int *)RTA_DATA(rtAttr), rtInfo->ifName); //Íø¿¨Ãû³Æ
891 break;
892 case RTA_GATEWAY:
893 rtInfo->gateWay = *(u_int *)RTA_DATA(rtAttr); //´ËÌõ·ÓÉÏîµÄÍø¹Ø
894 break;
895 case RTA_PREFSRC:
896 rtInfo->srcAddr = *(u_int *)RTA_DATA(rtAttr); //·ÓÉÏîµÄÔ´µØÖ·
897 break;
898 case RTA_DST:
899 rtInfo->dstAddr = *(u_int *)RTA_DATA(rtAttr); //·ÓÉÏîÖеÄÄ¿µÄµØÖ·
900 break;
901 }
902 }
903 dst.s_addr = rtInfo->dstAddr;
904
905 printf("oif:%s\t", rtInfo->ifName);
906 gate.s_addr = rtInfo->gateWay;
907 printf("%s\n", (char *)inet_ntoa(gate));
908
909 printf("src:%s\n", (char *)inet_ntoa(gate));
910 snprintf(srcaddr, sizeof(srcaddr), "%s", (char *)inet_ntoa(gate));//klocwork
911 gate.s_addr = rtInfo->dstAddr;
912 printf("dst:%s\n", (char *)inet_ntoa(gate));
913
914 //free(tempBuf);
915 return;
916}
917
918/****************************************/
919//½Ó¿Ú¹¦ÄÜ£º ¼ì²âÊÇ·ñÅäÖÃÁËȱʡ·ÓÉ£¬ÐèÒªÁ¬ÍâÍøµÄÓ¦ÓÿÉÒÔµ÷Óñ¾½Ó¿ÚÅжÏÍøÂçÊÇ·ñ¾ÍÐ÷
920//return:
921// -1: error;
922// 0: ÍøÂçδ¾ÍÐ÷
923// 1: ÍøÂçÒѾÍÐ÷
924/****************************************/
925int default_route_check()
926{
927 struct nlmsghdr *nlMsg;
928 struct rtmsg *rtMsg;
929 struct route_info *rtInfo;
930 char *msgBuf = malloc(BUFSIZE);
931
932
933 int sock, len, msgSeq = 0;
934
935 if(NULL == msgBuf) {
936 softap_assert("");
937 return -1;//klocwork
938 }
939
940 if ((sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0) {
941 perror("Socket Creation: ");
942 free(msgBuf);
943 return -1;
944 }
945
946 memset(msgBuf, 0, BUFSIZE);
947
948 nlMsg = (struct nlmsghdr *)msgBuf;
949 rtMsg = (struct rtmsg *)NLMSG_DATA(nlMsg);
950 nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); // Length of message.
951 nlMsg->nlmsg_type = RTM_GETROUTE; // Get the routes from kernel routing table .
952 nlMsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST; // The message is a request for dump.
953 nlMsg->nlmsg_seq = msgSeq++; // Sequence of the message packet.
954 nlMsg->nlmsg_pid = getpid(); // PID of process sending the request.
955
956 if (send(sock, nlMsg, nlMsg->nlmsg_len, 0) < 0) {
957 printf("Write To Socket Failed¡­\n");
958 free(msgBuf);
959 close(sock);
960 return -1;
961 }
962
963 if ((len = readNlSock(sock, msgBuf, msgSeq, getpid())) < 0) {
964 printf("Read From Socket Failed¡­\n");
965 free(msgBuf);
966 close(sock);
967 return -1;
968 }
969
970
971 rtInfo = (struct route_info *)malloc(sizeof(struct route_info));
972 if (NULL == rtInfo) { //klocwork
973 printf("Malloc route_info Failed¡­\n");
974 free(msgBuf);
975 close(sock);
976 return -1;
977 }
978 for (; NLMSG_OK(nlMsg, len); nlMsg = NLMSG_NEXT(nlMsg, len)) {
979 memset(rtInfo, 0, sizeof(struct route_info));
980 parseRoutes(nlMsg, rtInfo);
981 if (rtInfo->dstAddr == 0 && strlen(rtInfo->ifName)) {
982 printf("default wan :%s \n", rtInfo->ifName);
983 free(rtInfo);
984 close(sock);
985 free(msgBuf);
986 return 1;
987 }
988 }
989 free(rtInfo);
990 close(sock);
991 free(msgBuf);
992 return 0;
993}
994
995
996
997/**************************************/
998//½Ó¿Ú¹¦ÄÜ: ¼ì²âflashÊÇ·ñ±»ÆäËûºËÕ¼ÓÃ
999//return:
1000// 0 ----- flashûÓб»Õ¼ÓÃ
1001// 1 ----- flashÕý±»ÆäËûºËÕ¼ÓÃ
1002// -1 ----- open½Úµãʧ°Ü
1003// -2 ----- ioctlʧ°Ü
1004/**************************************/
1005
1006int flash_mutex_check()
1007{
1008 int fd, ret;
1009 char arg = 3;
1010 fd = open("/dev/softspinlock", O_RDWR);
1011 //printf("fd = %d \n",fd);
1012 if (fd < 0)
1013 return -1;
1014
1015 ret = ioctl(fd, SPINLOCK_GET_STATUS, &arg);
1016 //printf("ret = %d arg = %d \n",ret,arg);
1017 if (ret < 0) {
1018 close(fd);
1019 return -2;
1020 }
1021 close(fd);
1022 return arg;
1023
1024}
1025
1026//»ñȡָ¶¨Ïß³ÌÃûµÄpidºÅ£¬×¢Ò⣺µ÷Óøú¯Êý»ñÈ¡·µ»ØÖµ£¬Ê¹ÓúóÒ»¶¨ÒªÊͷŸÃÄÚ´æ¿Õ¼ä
1027pid_t* find_pid_by_name(char *pidName)
1028{
1029 DIR *dir;
1030 struct dirent *next;
1031 pid_t* pidList = NULL;
1032 pid_t* tmpList = NULL;
1033 int i = 0;
1034
1035 //procÖаüÀ¨µ±Ç°µÄ½ø³ÌÐÅÏ¢£¬¶ÁÈ¡¸ÃĿ¼
1036 dir = opendir("/proc");
1037 if(!dir)
1038 {
1039 perror("Cannot open /proc");
1040 return pidList;
1041 }
1042 //±éÀú/procÏÂĿ¼
1043 while((next = readdir(dir)) != NULL)
1044 {
1045 FILE *status;
1046 char filename[READ_BUF_SIZE] = {0};//klocwork
1047 char filename1[READ_BUF_SIZE] = {0};//klocwork
1048 char name[READ_BUF_SIZE] = {0};
1049 //skip ".." since that is outside /proc
1050 if(0 == strcmp(next->d_name,".."))
1051 continue;
1052 //if it isn't a number,we skip it
1053 if(!isdigit(*next->d_name))
1054 continue;
1055
1056 snprintf(filename,sizeof(filename),"/proc/%s/status",next->d_name);
1057
1058 if(!(status = fopen(filename,"r")))
1059 {
1060 continue;
1061 }
1062 if(NULL == fgets(filename1,READ_BUF_SIZE-1,status))
1063 {
1064 fclose(status);
1065 continue;
1066 }
1067 fclose(status);
1068
1069 //»ñÈ¡½ø³Ìpid£¬Í¬Ê±Ò²»áÓжà¸öÏàͬ½ø³ÌÃûµÄÇé¿ö
1070 sscanf(filename1, "%*s %s", name);
1071 if(0 == strcmp(name,pidName))
1072 {
1073 //pidList = realloc(pidList,sizeof(pid_t)*(i+2));
1074 //klocwork
1075 tmpList = realloc(pidList,sizeof(pid_t)*(i+2));
1076 if (NULL == tmpList) {
1077 continue;
1078 }
1079 pidList = tmpList;
1080 errno = 0;
1081 pidList[i++] = strtol(next->d_name,NULL,0);
1082 if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
1083 {
1084 printf("strtol errno %d: %s\n", errno, strerror(errno));
1085 }
1086 }
1087 }
1088 if(pidList)
1089 {
1090 pidList[i] = 0;
1091 }
1092 closedir(dir);
1093 return pidList;
1094}
1095
1096void handle_quit(int signo)
1097{
1098 pthread_exit(NULL);
1099}
1100
1101/* gethostbyname¹¦ÄÜÖж¨Ê±Æ÷³¬Ê±´¦Àíº¯Êý */
1102void gethostbyname_timeout(int msg_id)
1103{
1104 slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_timeout begin,msg_id=%d\n",msg_id);
1105 if(ipc_send_message(msg_id, msg_id, MSG_GET_HOST_BY_NAME_TIMEOUT,0, 0, 0) < 0)
1106 {
1107 // todo: for cov M
1108 }
1109}
1110
1111/**
1112* gethostbyname¹¦ÄÜÖд´½¨¶¨Ê±Æ÷
1113* second_time: ³¬Ê±Ê±³¤
1114* msg_id: Ïß³Ìid
1115*/
1116void gethostbyname_creattimer(int second_time, int msg_id)
1117{
1118 slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_creattimer begin\n");
1119 sc_timer_delete(TIMER_GETHOSTBYNAME_ID);
1120 sc_timer_create(TIMER_GETHOSTBYNAME_ID, TIMER_FLAG_ONCE, second_time*1000, gethostbyname_timeout, (void *)msg_id);
1121}
1122
1123/* gethostbyname¹¦ÄÜÖÐɾ³ý¶¨Ê±Æ÷ */
1124void gethostbyname_deletetimer()
1125{
1126 slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_deletetimer begin\n");
1127 sc_timer_delete(TIMER_GETHOSTBYNAME_ID);
1128}
1129
1130void *gethostbyname_timer(void *arg)
1131{
1132 int time = 0;
1133 char *name = NULL;
1134 int msg_id;
1135 struct hostent* hptr = NULL;
1136
1137 time =((struct gethostbyname_info *)arg)->time;
1138 name = ((struct gethostbyname_info *)arg)->name;
1139 msg_id = ((struct gethostbyname_info *)arg)->msg_id;
1140
1141 slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_timer time=%d,name=%s,msg_id=%d\n", time, name, msg_id);
1142
1143 signal(SIGQUIT, handle_quit);
1144
1145 gethostbyname_creattimer(time, msg_id); //Æð¶¨Ê±Æ÷
1146
1147 hptr = gethostbyname(name);
1148 if(NULL != hptr) //»ñÈ¡µ½hostÐÅÏ¢
1149 {
1150 slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_timer get info\n");
1151 gethostbyname_deletetimer(); //ɾ³ý¶¨Ê±Æ÷
1152 slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_timer result hostname=%s\n",hptr->h_name);
1153 //¸øÖ÷½ø³Ì·¢ÏûÏ¢
1154 if(ipc_send_message(msg_id, msg_id, MSG_GET_HOST_BY_NAME_SUCCESS, sizeof(void *), (UCHAR *)&hptr, 0) < 0)
1155 {
1156 // todo: for cov M
1157 }
1158 pthread_exit(NULL);
1159 }
1160 return NULL;
1161}
1162
1163//·â×°gethostbynameº¯Êý£¬Ôö¼ÓÒ»¸ö³¬Ê±Ê±¼äµÄÈë²Î£¬timeµ¥Î»ÎªÃë
1164//Èç¹û³¬¹ý³¬Ê±Ê±¼äÈÔÈ»»ñÈ¡²»µ½hostÐÅÏ¢£¬Ôòº¯Êý·µ»Ø²»¼ÌÐø×èÈû
1165//¶¨Ê±Æ÷IDÏß³ÌÄÚ¹²Ïí£¬Ò»¸ö½ø³Ì²»ÒªÍ¬Ê±µ÷ÓøýӿÚ
1166struct hostent *gethostbyname_t(const char *name, int time)
1167{
1168 slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_t begin\n");
1169 pthread_t pthread;
1170 int my_handle = 0;
1171 int module_id = MODULE_ID_AP_GETHOSTBYNAME_BASE;
1172 int ret = 0;
1173 int msg_ret = 0;
1174 struct hostent* hostresultinfo = NULL;
1175 struct gethostbyname_info myhostinfo = {0};
1176 MSG_BUF rsp_msg = {0};
1177 LONG msgSize = sizeof(MSG_BUF) - sizeof(LONG);
1178 if(0 == time)
1179 {
1180 slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_t time =0\n");
1181 return gethostbyname(name);
1182 }
1183 else
1184 {
1185 slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_t time = %d\n",time);
1186
1187 //¶¯Ì¬´´½¨ÁÙʱµÄÏûÏ¢¶ÓÁйܵÀ
1188 //msggetʹÓòÎÊýIPC_CREAT | IPC_EXCL| 0600£¬Åжϵ±Ç°module_idµÄÏûÏ¢¶ÓÁÐÊÇ·ñ
1189 //´æÔÚ£¬Èç¹û²»´æÔÚ£¬Ö±½Ó´´½¨ÐµÄÏûÏ¢¶ÓÁУ»Èç¹û´æÔÚ£¬·µ»ØÖµÎ´-1£¬È»ºómodule_id
1190 //Öµ¼Ó1£¬²»¶ÏÑ­»·Ö±µ½ÕÒµ½Ã»ÓÐʹÓõÄmodule_idÖµ
1191 while((my_handle = msgget(module_id,IPC_CREAT | IPC_EXCL| 0600)) == -1)
1192 {
1193 module_id++;
1194 //µ±module_id´óÓÚMODULE_ID_ATDYNAMIC_ENDֵʱ£¬Ö÷¶¯¶ÏÑÔ
1195 if (module_id > MODULE_ID_AP_GETHOSTBYNAME_END)
1196 {
1197 softap_assert("MODULE_ID_AP_GETHOSTBYNAME_END!!!!!!!!!!!\n");
1198 }
1199 }
1200 myhostinfo.time = time;
1201 strncpy(myhostinfo.name, name, sizeof(myhostinfo.name)-1);
1202 myhostinfo.msg_id = module_id;
1203 //Æð×ÓỊ̈߳¬ÔÚ×ÓÏß³ÌÀï´´½¨¶¨Ê±Æ÷
1204 ret = pthread_create(&pthread, NULL, (void *)gethostbyname_timer, (void *)&myhostinfo);
1205 if (ret < 0 || pthread == NULL) {
1206 slog(NET_PRINT, SLOG_DEBUG, "creat thread fail\n");
1207 return NULL;
1208 }
1209 while(1)
1210 {
1211 msg_ret = 0;
1212 memset(&rsp_msg, 0x00, sizeof(MSG_BUF));
1213 msg_ret = msgrcv(my_handle, &rsp_msg, msgSize, 0, 0);
1214 if (msg_ret < 0)
1215 {
1216 continue;
1217 }
1218
1219 if(rsp_msg.usMsgCmd == MSG_GET_HOST_BY_NAME_SUCCESS)
1220 {
1221 slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_t success\n");
1222 hostresultinfo = (struct hostent*)(*(int *)rsp_msg.aucDataBuf);
1223 slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_t result:name=%s\n",hostresultinfo->h_name);
1224 return hostresultinfo;
1225 }
1226 else if(rsp_msg.usMsgCmd == MSG_GET_HOST_BY_NAME_TIMEOUT)
1227 {
1228 slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_t fail\n");
1229 pthread_kill(pthread, SIGQUIT);
1230 return NULL;
1231 }
1232 else
1233 {
1234 slog(NET_PRINT, SLOG_ERR, "gethostbyname_t fail\n");
1235 }
1236 }
1237 }
1238}
1239
1240/******************************************************************************/
1241
1242#define DNS_SERVER_NUM 2
1243
1244#define T_A 1 //Ipv4 address
xf.liaa4d92f2023-09-13 00:18:58 -07001245#define T_AAAA 28 //Ipv6 address
lh9ed821d2023-04-07 01:36:19 -07001246#define T_NS 2 //Nameserver
1247#define T_CNAME 5 // canonical name
1248#define T_SOA 6 /* start of authority zone */
1249#define T_PTR 12 /* domain name pointer */
1250#define T_MX 15 //Mail server
1251
1252
1253
1254//DNS header structure
1255struct DNS_HEADER {
1256 unsigned short id; // identification number
1257
1258 unsigned char rd :1; // recursion desired
1259 unsigned char tc :1; // truncated message
1260 unsigned char aa :1; // authoritive answer
1261 unsigned char opcode :4; // purpose of message
1262 unsigned char qr :1; // query/response flag
1263
1264 unsigned char rcode :4; // response code
1265 unsigned char cd :1; // checking disabled
1266 unsigned char ad :1; // authenticated data
1267 unsigned char z :1; // its z! reserved
1268 unsigned char ra :1; // recursion available
1269
1270 unsigned short q_count; // number of question entries
1271 unsigned short ans_count; // number of answer entries
1272 unsigned short auth_count; // number of authority entries
1273 unsigned short add_count; // number of resource entries
1274};
1275
1276//Constant sized fields of query structure
1277struct QUESTION {
1278 unsigned short qtype;
1279 unsigned short qclass;
1280};
1281
1282//Constant sized fields of the resource record structure
1283#pragma pack(push, 1)
1284struct R_DATA {
1285 unsigned short type;
1286 unsigned short _class;
1287 unsigned int ttl;
1288 unsigned short data_len;
1289};
1290#pragma pack(pop)
1291
1292//Pointers to resource record contents
1293struct RES_RECORD {
1294 unsigned char *name;
1295 struct R_DATA *resource;
1296 unsigned char *rdata;
1297};
1298
1299//Structure of a Query
1300typedef struct {
1301 unsigned char *name;
1302 struct QUESTION *ques;
1303} QUERY;
1304
1305
1306void ChangetoDnsNameFormat(unsigned char* dns, unsigned char* host) {
1307 int lock = 0, i;
1308 strcat((char*) host, ".");
1309
1310 for (i = 0; i < strlen((char*) host); i++) {
1311 if (host[i] == '.') {
1312 *dns++ = i - lock;
1313 for (; lock < i; lock++) {
1314 *dns++ = host[lock];
1315 }
1316 lock++; //or lock=i+1;
1317 }
1318 }
1319 *dns++ = '\0';
1320}
1321
1322u_char* ReadName(unsigned char* reader, unsigned char* buffer, int* count) {
1323 unsigned char *name;
1324 unsigned int p = 0, jumped = 0, offset;
1325 int i, j;
1326
1327 *count = 1;
1328 name = (unsigned char*) malloc(256);
1329 if (!name)
1330 return NULL;//klocwork
1331
1332 name[0] = '\0';
1333
1334 //read the names in 3www6google3com format
1335 while (*reader != 0) {
1336 if (*reader >= 192) {
1337 offset = (*reader) * 256 + *(reader + 1) - 49152; //49152 = 11000000 00000000 ;)
1338 reader = buffer + offset - 1;
1339 jumped = 1; //we have jumped to another location so counting wont go up!
1340 } else {
1341 name[p++] = *reader;
1342 }
1343
1344 reader = reader + 1;
1345
1346 if (jumped == 0) {
1347 *count = *count + 1; //if we havent jumped to another location then we can count up
1348 }
1349 }
1350
1351 name[p] = '\0'; //string complete
1352 if (jumped == 1) {
1353 *count = *count + 1; //number of steps we actually moved forward in the packet
1354 }
1355
1356 //now convert 3www6google3com0 to www.google.com
1357 for (i = 0; i < (int) strlen((const char*) name); i++) {
1358 p = name[i];
1359 for (j = 0; j < (int) p; j++) {
1360 name[i] = name[i + 1];
1361 i = i + 1;
1362 }
1363 name[i] = '.';
1364 }
1365 name[i - 1] = '\0'; //remove the last dot
1366 return name;
1367}
1368
1369unsigned long my_gethostbyname(unsigned char *host, char *dev_name,char* dns_server, int query_type) {
1370 unsigned char buf[1025], *qname, *reader;
1371 int i, j, stop, s, ans_max;
1372 struct timeval tv;
1373 unsigned long ret = 0;
1374 struct ifreq ifr;
1375
1376 struct sockaddr_in a;
1377
xf.liaa4d92f2023-09-13 00:18:58 -07001378 struct RES_RECORD answers[20]; //the replies from the DNS server
lh9ed821d2023-04-07 01:36:19 -07001379 struct sockaddr_in dest;
1380
1381 struct DNS_HEADER *dns = NULL;
1382 struct QUESTION *qinfo = NULL;
1383
1384 printf("Resolving %s", host);
1385
1386 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //UDP packet for DNS queries
1387 if(s < 0)
1388 {
1389 printf("socket return fail \n");
1390 return ret;
1391 }
1392
1393 memset(&ifr,0,sizeof(ifr));
1394 strncpy(ifr.ifr_name, dev_name, sizeof(ifr.ifr_name)-1);
1395 if(setsockopt(s,SOL_SOCKET,SO_BINDTODEVICE,(char*)&ifr,sizeof(ifr)) < 0){
1396 printf("SO_BINDTODEVICE fail \n");
1397 goto out;
1398 }
1399 tv.tv_sec = 5;
1400 tv.tv_usec = 0;
1401 if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
1402 printf("socket option SO_RCVTIMEO not support\n");
1403 goto out;
1404 }
1405 dest.sin_family = AF_INET;
1406 dest.sin_port = htons(53);
1407 dest.sin_addr.s_addr = inet_addr(dns_server); //dns servers
1408
1409 //Set the DNS structure to standard queries
1410 dns = (struct DNS_HEADER *) &buf;
1411
1412 dns->id = (unsigned short) htons(getpid());
1413 dns->qr = 0; //This is a query
1414 dns->opcode = 0; //This is a standard query
1415 dns->aa = 0; //Not Authoritative
1416 dns->tc = 0; //This message is not truncated
1417 dns->rd = 1; //Recursion Desired
1418 dns->ra = 0; //Recursion not available! hey we dont have it (lol)
1419 dns->z = 0;
1420 dns->ad = 0;
1421 dns->cd = 0;
1422 dns->rcode = 0;
1423 dns->q_count = htons(1); //we have only 1 question
1424 dns->ans_count = 0;
1425 dns->auth_count = 0;
1426 dns->add_count = 0;
1427
1428 //point to the query portion
1429 qname = (unsigned char*) &buf[sizeof(struct DNS_HEADER)];
1430
1431 ChangetoDnsNameFormat(qname, host);
1432 qinfo = (struct QUESTION*) &buf[sizeof(struct DNS_HEADER)
1433 + (strlen((const char*) qname) + 1)]; //fill it
1434
1435 qinfo->qtype = htons(query_type); //type of the query , A , MX , CNAME , NS etc
1436 qinfo->qclass = htons(1); //its internet (lol)
1437
xf.liaa4d92f2023-09-13 00:18:58 -07001438 printf("\nSending Packet to %s...", dns_server);
lh9ed821d2023-04-07 01:36:19 -07001439 if (sendto(s, (char*) buf,
1440 sizeof(struct DNS_HEADER) + (strlen((const char*) qname) + 1)
1441 + sizeof(struct QUESTION), 0, (struct sockaddr*) &dest,
1442 sizeof(dest)) < 0) {
1443 perror("sendto failed");
1444 }
1445 printf("Done");
1446
1447 //Receive the answer
1448 i = sizeof dest;
1449 printf("\nReceiving answer...");
1450 if (recvfrom(s, (char*) buf, sizeof(buf)-1, 0, (struct sockaddr*) &dest,
1451 (socklen_t*) &i) < 0) {
1452 perror("recvfrom failed");
1453 }
1454 *(buf+sizeof(buf)-1) = 0;
1455 printf("Done");
1456
1457 dns = (struct DNS_HEADER*) buf;
1458 if((sizeof(struct DNS_HEADER) +
1459 (strlen((const char*) qname) + 1)+
1460 sizeof(struct QUESTION)) >= sizeof(buf))
1461 {
1462 perror("my_gethostbyname error");
1463 goto out;
1464 }
1465
1466 //move ahead of the dns header and the query field
1467 reader = &buf[sizeof(struct DNS_HEADER) + (strlen((const char*) qname) + 1)
1468 + sizeof(struct QUESTION)];
1469
1470 //printf("\nThe response contains : ");
1471 //printf("\n %d Questions.", ntohs(dns->q_count));
1472 //printf("\n %d Answers.", ntohs(dns->ans_count));
1473 //printf("\n %d Authoritative Servers.", ntohs(dns->auth_count));
1474 //printf("\n %d Additional records.\n\n", ntohs(dns->add_count));
1475
1476 //Start reading answers
1477 stop = 0;
1478 //klocwork
1479 //ans_max = ((ntohs(dns->ans_count) <= (sizeof(answers)/sizeof(answers[0]))) ? ntohs(dns->ans_count) : (sizeof(answers)/sizeof(answers[0])));
1480 ans_max = ntohs(dns->ans_count);
1481 if (ans_max > (sizeof(answers)/sizeof(answers[0])))
1482 ans_max = (sizeof(answers)/sizeof(answers[0]));
1483 for (i = 0; i < ans_max; i++)
1484 {
1485 answers[i].name = ReadName(reader, buf, &stop);
1486 reader = reader + stop;
1487
1488 answers[i].resource = (struct R_DATA*) (reader);
1489 reader = reader + sizeof(struct R_DATA);
1490
xf.liaa4d92f2023-09-13 00:18:58 -07001491 if (ntohs(answers[i].resource->type) == T_A) //if its an ipv4 address
lh9ed821d2023-04-07 01:36:19 -07001492 {
1493 answers[i].rdata = (unsigned char*) malloc(
1494 ntohs(answers[i].resource->data_len));
1495
1496 for (j = 0; j < ntohs(answers[i].resource->data_len); j++) {
1497 answers[i].rdata[j] = reader[j];
1498 }
1499
1500 answers[i].rdata[ntohs(answers[i].resource->data_len)] = '\0';
1501
1502 reader = reader + ntohs(answers[i].resource->data_len);
1503 } else {
1504 answers[i].rdata = ReadName(reader, buf, &stop);
1505 reader = reader + stop;
1506 }
1507 }
1508
1509 //print answers
1510 printf("\nAnswer Records : %d \n", ntohs(dns->ans_count));
1511 for (i = 0; i < ans_max; i++) {
1512 printf("Name : %s ", answers[i].name);
1513
1514 if (ntohs(answers[i].resource->type) == T_A) //IPv4 address
1515 {
1516 long *p;
1517 p = (long*) answers[i].rdata;
1518 a.sin_addr.s_addr = (*p); //working without ntohl
1519#if 1 // cov M
1520 char * s_addr = inet_ntoa(a.sin_addr);
1521 printf("has IPv4 address : %s", s_addr);
1522#else
1523 printf("has IPv4 address : %s", inet_ntoa(a.sin_addr));
1524#endif
1525 ret = (unsigned long)a.sin_addr.s_addr;
1526 }
1527
1528 if (ntohs(answers[i].resource->type) == 5) {
1529 //Canonical name for an alias
1530 printf("has alias name : %s", answers[i].rdata);
1531 }
lh9ed821d2023-04-07 01:36:19 -07001532 printf("\n");
xf.liaa4d92f2023-09-13 00:18:58 -07001533 free(answers[i].name);
1534 free(answers[i].rdata);
lh9ed821d2023-04-07 01:36:19 -07001535 }
1536out:
1537 close(s);
1538 return ret;
1539}
1540
lh9ed821d2023-04-07 01:36:19 -07001541unsigned long gethostbyname_l(char *hostname,char* dev_name)
1542{
1543 int i = 0;
1544 unsigned long ret = 0;
1545 char dns_servers[DNS_SERVER_NUM][32] = {0};
1546
1547 //Get the DNS servers from the resolv.conf file
1548 char nv_dns[32] = {0};
1549 char ip_dns[32] = {0};
1550
xf.liaa4d92f2023-09-13 00:18:58 -07001551 snprintf(nv_dns, sizeof(nv_dns), "%s_pridns", dev_name);
lh9ed821d2023-04-07 01:36:19 -07001552 sc_cfg_get(nv_dns, ip_dns, sizeof(ip_dns));
1553 strcpy(dns_servers[0], ip_dns);
1554
1555 memset(nv_dns,0,sizeof(nv_dns));
1556 memset(ip_dns,0,sizeof(ip_dns));
xf.liaa4d92f2023-09-13 00:18:58 -07001557 snprintf(nv_dns, sizeof(nv_dns), "%s_secdns", dev_name);
lh9ed821d2023-04-07 01:36:19 -07001558 sc_cfg_get(nv_dns, ip_dns, sizeof(ip_dns));
1559 strcpy(dns_servers[1], ip_dns);
1560
1561
1562 //Now get the ip of this hostname , A record
1563 for(i=0;i<DNS_SERVER_NUM;i++)
1564 {
1565 ret = my_gethostbyname(hostname, dev_name , dns_servers[i], T_A);
1566 if(ret > 0)
1567 break;
1568 }
1569
1570 return ret;
1571}
1572
xf.liaa4d92f2023-09-13 00:18:58 -07001573int my_gethostbyname6(unsigned char *host, char *dev_name, char* dns_server, int query_type, struct in6_addr* ip6)
1574{
1575 unsigned char buf[1025], *qname, *reader;
1576 int i, j, stop, s, ans_max, ret = 0;
1577 struct timeval tv;
1578 struct ifreq ifr = {0};
1579 struct RES_RECORD answers[20]; //the replies from the DNS server
1580 struct sockaddr_in6 dest = {0};
1581 struct in6_addr a = {0};
1582 struct DNS_HEADER *dns = NULL;
1583 struct QUESTION *qinfo = NULL;
1584 char nv_cmd[64] = {0};
1585 char ip_src[64] = {0};
1586 struct sockaddr_in6 src = {0};
lh9ed821d2023-04-07 01:36:19 -07001587
xf.liaa4d92f2023-09-13 00:18:58 -07001588 printf("Resolving %s", host);
1589
1590 s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); //UDP packet for DNS queries
1591 if(s < 0)
1592 {
1593 printf("socket return fail \n");
1594 return ret;
1595 }
1596
1597 memset(&ifr,0,sizeof(ifr));
1598 strncpy(ifr.ifr_name, dev_name, sizeof(ifr.ifr_name)-1);
1599 if(setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, (char*)&ifr, sizeof(ifr)) < 0){
1600 printf("SO_BINDTODEVICE fail \n");
1601 goto out;
1602 }
1603 tv.tv_sec = 5;
1604 tv.tv_usec = 0;
1605 if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
1606 printf("socket option SO_RCVTIMEO not support\n");
1607 goto out;
1608 }
1609 snprintf(nv_cmd, sizeof(nv_cmd), "%s_ipv6_ip", dev_name);
1610 sc_cfg_get(nv_cmd, ip_src, sizeof(ip_src));
1611 src.sin6_family = AF_INET6;
1612 if(inet_pton(AF_INET6, ip_src, &src.sin6_addr) <= 0){
1613 printf("inet_pton fail1 \n");
1614 goto out;
1615 }
1616 if (bind(s, (struct sockaddr*)&src, sizeof(src)) < 0) {
1617 printf("bind fail \n");
1618 goto out;
1619 }
1620 dest.sin6_family = AF_INET6;
1621 dest.sin6_port = htons(53);
1622 if(inet_pton(AF_INET6, dns_server, &dest.sin6_addr) <= 0){
1623 printf("inet_pton fail2 \n");
1624 goto out;
1625 }
1626 //Set the DNS structure to standard queries
1627 dns = (struct DNS_HEADER *) &buf;
1628
1629 dns->id = (unsigned short) htons(getpid());
1630 dns->qr = 0; //This is a query
1631 dns->opcode = 0; //This is a standard query
1632 dns->aa = 0; //Not Authoritative
1633 dns->tc = 0; //This message is not truncated
1634 dns->rd = 1; //Recursion Desired
1635 dns->ra = 0; //Recursion not available! hey we dont have it (lol)
1636 dns->z = 0;
1637 dns->ad = 0;
1638 dns->cd = 0;
1639 dns->rcode = 0;
1640 dns->q_count = htons(1); //we have only 1 question
1641 dns->ans_count = 0;
1642 dns->auth_count = 0;
1643 dns->add_count = 0;
1644
1645 //point to the query portion
1646 qname = (unsigned char*) &buf[sizeof(struct DNS_HEADER)];
1647
1648 ChangetoDnsNameFormat(qname, host);
1649 qinfo = (struct QUESTION*) &buf[sizeof(struct DNS_HEADER)
1650 + (strlen((const char*) qname) + 1)]; //fill it
1651
1652 qinfo->qtype = htons(query_type); //type of the query , A , MX , CNAME , NS etc
1653 qinfo->qclass = htons(1); //its internet (lol)
1654
1655 printf("\nSending Packet to %s...", dns_server);
1656 if (sendto(s, (char*) buf,
1657 sizeof(struct DNS_HEADER) + (strlen((const char*) qname) + 1)
1658 + sizeof(struct QUESTION), 0, (struct sockaddr*) &dest,
1659 sizeof(dest)) < 0) {
1660 perror("sendto failed");
1661 }
1662 printf("Done");
1663
1664 //Receive the answer
1665 i = sizeof dest;
1666 printf("\nReceiving answer...");
1667 if (recvfrom(s, (char*) buf, sizeof(buf)-1, 0, (struct sockaddr*) &dest,
1668 (socklen_t*) &i) < 0) {
1669 perror("recvfrom failed");
1670 }
1671 *(buf+sizeof(buf)-1) = 0;
1672 printf("Done");
1673
1674 dns = (struct DNS_HEADER*) buf;
1675 if((sizeof(struct DNS_HEADER) +
1676 (strlen((const char*) qname) + 1)+
1677 sizeof(struct QUESTION)) >= sizeof(buf))
1678 {
1679 perror("my_gethostbyname error");
1680 goto out;
1681 }
1682
1683 //move ahead of the dns header and the query field
1684 reader = &buf[sizeof(struct DNS_HEADER) + (strlen((const char*) qname) + 1)
1685 + sizeof(struct QUESTION)];
1686
1687 //printf("\nThe response contains : ");
1688 //printf("\n %d Questions.", ntohs(dns->q_count));
1689 //printf("\n %d Answers.", ntohs(dns->ans_count));
1690 //printf("\n %d Authoritative Servers.", ntohs(dns->auth_count));
1691 //printf("\n %d Additional records.\n\n", ntohs(dns->add_count));
1692
1693 //Start reading answers
1694 stop = 0;
1695 ans_max = ntohs(dns->ans_count);
1696 if (ans_max > (sizeof(answers)/sizeof(answers[0])))
1697 ans_max = (sizeof(answers)/sizeof(answers[0]));
1698 for (i = 0; i < ans_max; i++)
1699 {
1700 answers[i].name = ReadName(reader, buf, &stop);
1701 reader = reader + stop;
1702
1703 answers[i].resource = (struct R_DATA*) (reader);
1704 reader = reader + sizeof(struct R_DATA);
1705
1706 if (ntohs(answers[i].resource->type) == T_AAAA) //if its an ipv6 address
1707 {
1708 answers[i].rdata = (unsigned char*) malloc(
1709 ntohs(answers[i].resource->data_len));
1710
1711 for (j = 0; j < ntohs(answers[i].resource->data_len); j++) {
1712 answers[i].rdata[j] = reader[j];
1713 }
1714
1715 answers[i].rdata[ntohs(answers[i].resource->data_len)] = '\0';
1716
1717 reader = reader + ntohs(answers[i].resource->data_len);
1718 } else {
1719 answers[i].rdata = ReadName(reader, buf, &stop);
1720 reader = reader + stop;
1721 }
1722 }
1723
1724 //print answers
1725 printf("\nAnswer Records : %d \n", ntohs(dns->ans_count));
1726 for (i = 0; i < ans_max; i++) {
1727 printf("Name : %s ", answers[i].name);
1728
1729 if (ntohs(answers[i].resource->type) == T_AAAA) //IPv6 address
1730 {
1731 char ip6_addr[IPV6ADDLEN_MAX] = {0};
1732 memcpy(&a, answers[i].rdata, sizeof(struct in6_addr));
1733 if(inet_ntop(AF_INET6, &a, ip6_addr, sizeof(ip6_addr))){
1734 if(ip6)
1735 memcpy(ip6, &a, sizeof(struct in6_addr));
1736 printf("%p has IPv6 address : %s", ip6, ip6_addr);
1737 ret = 1;
1738 }else
1739 printf("nohas IPv6 address len:%d", answers[i].resource->data_len);
1740 }
1741
1742 if (ntohs(answers[i].resource->type) == 5) {
1743 //Canonical name for an alias
1744 printf("has alias name : %s", answers[i].rdata);
1745 }
1746 printf("\n");
1747 free(answers[i].name);
1748 free(answers[i].rdata);
1749 }
1750out:
1751 close(s);
1752 return ret;
1753}
1754
1755int gethostbyname6_l(char *hostname,char* dev_name, struct in6_addr* ip6)
1756{
1757 int i = 0;
1758 unsigned long ret = 0;
1759 char dns_servers[DNS_SERVER_NUM][64] = {0};
1760
1761 //Get the DNS servers from the resolv.conf file
1762 char nv_dns[64] = {0};
1763 char ip_dns[64] = {0};
1764
1765 sprintf(nv_dns, "%s_ipv6_pridns_auto", dev_name);
1766 sc_cfg_get(nv_dns, ip_dns, sizeof(ip_dns));
1767 strcpy(dns_servers[0], ip_dns);
1768
1769 memset(nv_dns,0,sizeof(nv_dns));
1770 memset(ip_dns,0,sizeof(ip_dns));
1771 sprintf(nv_dns, "%s_ipv6_secdns_auto", dev_name);
1772 sc_cfg_get(nv_dns, ip_dns, sizeof(ip_dns));
1773 strcpy(dns_servers[1], ip_dns);
1774
1775
1776 //Now get the ip of this hostname , A record
1777 for(i=0;i<DNS_SERVER_NUM;i++)
1778 {
1779 if(my_gethostbyname6(hostname, dev_name , dns_servers[i], T_AAAA, ip6))
1780 return 0;
1781 }
1782 return -1;
1783}
lh9ed821d2023-04-07 01:36:19 -07001784
1785
1786/******************************************************************************/
1787
1788