blob: c1d73ce178788e0876dd32a1028b46c1a9bbae2d [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;
323 case RXBYTE:
324 if ((field = getField(semiColon, " ", 0))) {
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 slog(MISC_PRINT, SLOG_DEBUG, "[getIfStatistic]RXBYTE field:%s, result_data:%llu\n", field, *result_data);
335 return 0;
336 }
337 break;
338 case RXPACKET:
339 if ((field = getField(semiColon, " ", 1))) {
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;
352 }
353 return -1;
354}
355
356void *safe_malloc(int size, BOOL is_assert)
357{
358 void *ret = malloc(size);
359
360 if (ret == NULL) {
361 if (is_assert == TRUE) {
362 assert(ret);
363 } else {
364 printf("[%s][%s] ----can not get memory", __FILE__, __FUNCTION__);
365 }
366 } else {
367 memset(ret, 0, size);
368 }
369
370 return ret;
371}
372
373//ÊäÈësize±ØÐëÊÇdestµÄ³¤¶È
374void safe_strcpy(char *dest, char *source, int size)
375{
376 if (dest == NULL || source == NULL || size < 1) {
377 return;
378 }
379
380 strncpy(dest, source, size - 1);
381 dest[size - 1] = '\0';
382}
383
384int get_dev_list(struct pc_node* mypc_node)
385{
386 int ret = 0;
387
388 ret = netioctl_handle(NIOCGPCINFO, mypc_node);
389 if (-1 == ret) {
390 slog(NET_PRINT, SLOG_ERR, "NIOCGPCINFO err");
391 return -1;
392 }
393 return 0;
394}
395
396int zte_get_mac_list_from_lease(struct list_head *dhcp_list_info)
397{
398 FILE *leaseFile = NULL;
399 int64_t leaseFirst = 0;
400 char buf[32];
401
402 DHCPOFFERADDRNET dhcpInfo = {0};
403
404 char path_conf[50] = {0};
405 char path_file[100] = {0};
406
407 if (!list_empty(dhcp_list_info))
408 return -1;
409
410 sc_cfg_get("path_conf", path_conf, sizeof(path_conf));
411 sprintf(path_file, "%s/udhcpd.leases", path_conf);
412
413 leaseFile = fopen(path_file, "r");
414 if (leaseFile == NULL) {
415 fprintf(stderr, "can not open file udhcpd.leases.");
416 return -1 ;
417 }
418
419 if (fread(&leaseFirst, 1, sizeof(leaseFirst), leaseFile) != sizeof(leaseFirst)) {
420 fprintf(stderr, "read the first part of udhcpd.leases fail!");
421 fclose(leaseFile);
422 return -1 ;
423 }
424
425 memset(buf, 0x00, sizeof(buf));
426 sc_cfg_get("dhcpEnabled", buf, sizeof(buf));
427 if (strcmp(buf, "0") == 0) {
428 fclose(leaseFile);
429 return -1 ;
430 }
431
432 while ((fread(&dhcpInfo, 1, sizeof(dhcpInfo), leaseFile) == sizeof(dhcpInfo))) {
433 DHCPOFFERADDR_LIST_t *dhcpInfo_ptr = (DHCPOFFERADDR_LIST_t *)safe_malloc(sizeof(DHCPOFFERADDR_LIST_t), TRUE);
434 if (!dhcpInfo_ptr) {
435 slog(NET_PRINT, SLOG_ERR, "get_lan_info_list safe_malloc dhcpInfo_ptr fail \n");
436 return -1;
437 }
438 memcpy(&(dhcpInfo_ptr->dhcp_info), &dhcpInfo, sizeof(DHCPOFFERADDRNET));
439 list_add_tail(&dhcpInfo_ptr->list, dhcp_list_info);
440 }
441
442 fclose(leaseFile);
443 return 0;
444}
445
446void flash_file(char *file, char *file_num)
447{
448 char newFile[128] = {0};
449 char oldFile[128] = {0};
450 int i = 0;//klocwork
451 int i_file_num = atoi(file_num);
452
453 if(i_file_num < 0 || i_file_num > INT_MAX-1)
454 {
455 return ;
456 }
457
458 for (i = i_file_num - 2; i > 0 && i < 1000; i--) {
459 sprintf(newFile, "%s_bk%d", file, i);
460 sprintf(oldFile, "%s_bk%d", file, i + 1);
461 if ((access(newFile, F_OK)) == 0) {
462 if(rename(newFile, oldFile) < 0){
463 // cov M
464 }
465 }
466 }
467 sprintf(newFile, "%s_bk1", file);
468
469 if(rename(file, newFile) < 0)
470 {
471 // cov M
472 }
473}
474
475void file_write(char *filename, char *info)
476{
477 FILE *fp;
478 char logpath[128] = {0};
479 char logname[128] = {0};
480 char filesize[32] = {0};
481 char temp[64] = {0};
482 int flag = 0;
483 time_t now;
484 struct tm *timenow;
485
486 time(&now);
487 timenow = localtime(&now);
488 if (!timenow) {//klocwork
489 printf("localtime get err.\n");
490 return;
491 }
492
493 if (!filename || 0 == strcmp(filename, "")) {
494 printf("filename is err.\n");
495 return;
496 }
497
498 //Ö¸¶¨logÎļþ´óС£¬Èç¹ûδָ¶¨¾ÍÓÃĬÈÏcomm_logsize
499 sprintf(temp, "%s_logsize", filename);
500 sc_cfg_get(temp, filesize, sizeof(filesize));
501 if (0 == strcmp(filesize, "0")) {
502 return ;
503 } else if (0 == strcmp(filesize, "")) {
504 sc_cfg_get("comm_logsize", filesize, sizeof(filesize));
505 if (0 == strcmp(filesize, "0") || 0 == strcmp(filesize, "")) {
506 printf("filesize is not set.\n");
507 return;
508 }
509 }
510
511 sc_cfg_get("path_log", logpath, sizeof(logpath));
512 snprintf(logname, sizeof(logname), "%s%s.log", logpath, filename);
513
514 fp = fopen(logname, "a");
515 if (!fp) {
516 printf("fopen %s failed \n", logname);
517 return;
518 }
519 //flock»úÖÆ²¢²»ÄÜÕæµÄÆðµ½lock×÷Ó㬷µ»Ø»áÔì³Éunlock²»µô
520 /*
521 else if (flock(fileno(fp), LOCK_EX) != 0)
522 {
523 perror("flock");
524 fclose(fp);
525 return;
526 }*/
527
528 fprintf(fp, "%s:%s\n", str_ctime(timenow), info);
529 //fprintf(fp, "%s %s %s[%d]: %s", ctime(timenow), asctime(timenow), filename, getpid(), info);
530 fflush(fp);
531 fseek(fp, 0L, SEEK_END);
532
533 if (ftell(fp) > atoi(filesize))
534 flag = 1;
535
536 //flock(fileno(fp), LOCK_UN);
537 fclose(fp);
538
539 if (flag == 1) {
540 flash_file(logname, "2");
541 }
542}
543
544int echo_file(char *filename, char*info)
545{
546 int len;
547 int ret;
548 int fd;
549 if (!filename || 0 == strcmp(filename, "") || !info) {
550 printf("echo filename is err.\n");
551 return -1;
552 }
553 fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, 777);
554 if (fd < 0) {
555 printf("%s open failed!\n", filename);
556 return -1;
557 }
558 len = strlen(info);
559 ret = write(fd, info, len);
560
561 close(fd);
562
563 return ret;
564}
565
566void save_file(char *filename, char* info)
567{
568 FILE* fp;
569 char filepath[128] = {0};
570 char filesize[32] = {0};
571 char filenum[32] = {0};
572 char temp[64] = {0};
573 int flag = 0;
574 time_t now;
575 struct tm *timenow;
576 time(&now);
577 timenow = localtime(&now);
578 if (!timenow) {//klocwork
579 printf("localtime get err.\n");
580 return;
581 }
582
583 if (!filename || 0 == strcmp(filename, "")) {
584 printf("filename is err.\n");
585 return;
586 }
587 sprintf(temp, "%sfile", filename);
588 sc_cfg_get(temp, filepath, sizeof(filepath));
589 sprintf(temp, "%sfileSize", filename);
590 sc_cfg_get(temp, filesize, sizeof(filesize));
591 if (0 == strcmp(filesize, "0") || 0 == strcmp(filesize, "")) {
592 printf("filesize is not set.\n");
593 return;
594 }
595
596 sprintf(temp, "%sNum", filename);
597 sc_cfg_get(temp, filenum, sizeof(filenum));
598 fp = fopen(filepath, "a");
599 if (!fp) {
600 printf("fopen %s failed \n", filepath);
601 return;
602 } else if (flock(fileno(fp), LOCK_EX) != 0) {
603 perror("flock");
604 fclose(fp);
605 return;
606 }
607
608 fprintf(fp, "%s %s\n", str_ctime(timenow), info);
609 fflush(fp);
610 fseek(fp, 0L, SEEK_END);
611 if (ftell(fp) > atoi(filesize))
612 flag = 1;
613
614 flock(fileno(fp), LOCK_UN);
615 fclose(fp);
616
617 if (flag == 1) {
618 flash_file(filepath, "2");
619 }
620}
621
622struct timeval timeget(void)
623{
624 struct timeval now;
625 unsigned char timestr[60] = {0};
626 unsigned char uptimestr[30] = {0};
627 unsigned char * dotaddr = NULL;
628 unsigned long second;
629 char error = 0;
630 FILE * timefile = NULL;
631 int read_len = 0;
632
633 timefile = fopen("/proc/uptime", "r");
634 if (!timefile) {
635 printf("[%s:line:%d] error opening '/proc/uptime'", __FILE__, __LINE__);
636 error = 1;
637 goto out;
638 }
639 //klocwork cov M
640 read_len = fread(timestr, sizeof(char), sizeof(timestr)-1, timefile);
641 if (read_len == 0 ) {
642 printf("[%s:line:%d] read '/proc/uptime' error", __FILE__, __LINE__);
643 error = 1;
644 goto out;
645 }
646 timestr[sizeof(timestr)-1] = '\0';//cov
647 dotaddr = strchr(timestr, '.');
648 if (dotaddr != NULL && (dotaddr - timestr) < (30 - 2))//cov
649 memcpy(uptimestr, timestr, dotaddr - timestr + 2);
650 else {
651 printf("[%s:line:%d] uptime string is too long", __FILE__, __LINE__);
652 error = 1;
653 goto out;
654 }
655 uptimestr[dotaddr - timestr + 2] = '\0';
656
657out:
658 if (error) {
659 now.tv_sec = 0;
660 now.tv_usec = 0;
661 } else {
662 now.tv_sec = atol(uptimestr);
663 now.tv_usec = 0;
664 }
665 if (timefile) {//klocwork
666 fclose(timefile);
667 }
668 return now;
669}
670
671unsigned long time_sec()
672{
673 struct timeval uptime;
674
675 uptime = timeget();
676 //printf("uptime = %lu \n",(unsigned long)uptime.tv_sec);
677 return uptime.tv_sec;
678}
679
680int get_lan_info_list(struct list_head *file_list_info)
681{
682 FILE *lanFile = NULL;
683 char buf[32];
684
685 LAN_INFO_t lanInfo = {0};
686 char path_conf[50] = {0};
687 char path_file[100] = {0};
688
689 if (!list_empty(file_list_info)) {
690 return -1;
691 }
692
693 sc_cfg_get("path_conf", path_conf, sizeof(path_conf));
694 sprintf(path_file, "%s/laninfo.tmp", path_conf);
695
696 lanFile = fopen(path_file, "r");
697 if (lanFile == NULL) {
698 slog(NET_PRINT, SLOG_ERR, "fopen laninfo.tmp fail \n");
699 return 0;
700 }
701
702 while (fread(&lanInfo, sizeof(LAN_INFO_t), 1, lanFile) == 1) {
703 LAN_INFO_LIST_t *lanInfo_ptr = (LAN_INFO_LIST_t *)safe_malloc(sizeof(LAN_INFO_LIST_t), TRUE);
704 if (!lanInfo_ptr) {
705 slog(NET_PRINT, SLOG_ERR, "get_lan_info_list safe_malloc lanInfo_ptr fail \n");
706 return -1;
707 }
708 memcpy(&(lanInfo_ptr->lan_info), &lanInfo, sizeof(LAN_INFO_t));
709 list_add_tail(&lanInfo_ptr->list, file_list_info);
710 }
711
712 fclose(lanFile);
713 return 0;
714
715}
716
717/* ÉèÖó¬Ê±Ëø£¬ ³¬Ê±0±íʾÓÀ¾ÃËø - Ôݲ»¶ÔÍ⣬ÐèÒªms¼¶±ðʱ¿ª·Å */
718int set_wake_lock_timeout_ms(const char *lockid, unsigned long interval_ms)
719{
720 char *p = NULL;
721 int ret = -1;
722
723 if ((lockid == NULL) || (*lockid == '\0'))
724 return -1;
725
726 if (interval_ms == 0) {
727 ret = asprintf(&p, "%s", lockid);
728 } else {
729 ret = asprintf(&p, "%s %lu000000", lockid, interval_ms);
730 }
731 if (ret < 0) {
732 ret = -1;
733 goto out;
734 }
735 ret = write_to_file(WAKE_LOCK_PATH, p, strlen(p));
736
737out:
738 safe_free(p);
739 return ret;
740}
741
742/* »ñÈ¡wakelockËø */
743int set_wake_lock(const char *lockId)
744{
745 return set_wake_lock_timeout_ms(lockId, 0);
746}
747
748/* ÉèÖó¬Ê±Ëø */
749int set_wake_lock_timeout(const char *lockId, unsigned long seconds)
750{
751 return set_wake_lock_timeout_ms(lockId, seconds * 1000);
752}
753
754/* ÊÍ·ÅwakelockËø */
755int set_wake_unlock(const char *lockId)
756{
757 if ((lockId == NULL) || (*lockId == '\0'))
758 return -1;
759
760 return write_to_file(WAKE_UNLOCK_PATH, lockId, strlen(lockId));
761}
762
763int readNlSock(int sockFd, char *bufPtr, int seqNum, int pId)
764{
765 struct nlmsghdr *nlHdr;
766 int readLen = 0, msgLen = 0;
767 do {
768 //ÊÕµ½Äں˵ÄÓ¦´ð
769 if ((readLen = recv(sockFd, bufPtr, BUFSIZE - msgLen, 0)) < 0) {
770 perror("SOCK READ: ");
771 return -1;
772 }
773
774
775 nlHdr = (struct nlmsghdr *)bufPtr;
776 //¼ì²éheaderÊÇ·ñÓÐЧ
777 if ((NLMSG_OK(nlHdr, readLen) == 0) || (nlHdr->nlmsg_type == NLMSG_ERROR)) {
778 perror("Error in recieved packet");
779 return -1;
780 }
781
782
783
784
785 if (nlHdr->nlmsg_type == NLMSG_DONE) {
786 break;
787 } else {
788 bufPtr += readLen;
789 msgLen += readLen;
790 }
791
792 if ((nlHdr->nlmsg_flags & NLM_F_MULTI) == 0) {
793 break;
794 }
795 } while ((nlHdr->nlmsg_seq != seqNum) || (nlHdr->nlmsg_pid != pId));
796 return msgLen;
797}
798
799//coverity
800static int net_RTA_OK(struct rtattr *rta, unsigned int len)
801{
802 return RTA_OK(rta, len);
803}
804
805//·ÖÎö·µ»ØµÄ·ÓÉÐÅÏ¢
806void parseRoutes(struct nlmsghdr *nlHdr, struct route_info *rtInfo)
807{
808 struct rtmsg *rtMsg;
809 struct rtattr *rtAttr;
810 int rtLen, dstLen;
811 //char *tempBuf = NULL;
812 struct in_addr dst;
813 struct in_addr gate;
814 char cmd[128];
815 char dstaddr[32], srcaddr[32];
816
817
818 //tempBuf = (char *)malloc(100);
819 rtMsg = (struct rtmsg *)NLMSG_DATA(nlHdr);
820 // If the route is not for AF_INET or does not belong to main routing table
821 //then return.
822 if ((rtMsg->rtm_family != AF_INET) || (rtMsg->rtm_table != RT_TABLE_MAIN))
823 return;
824 //printf("rtmsg srclen:%d,dstlen:%d\n",rtMsg->rtm_src_len,rtMsg->rtm_dst_len);
825 dstLen = rtMsg->rtm_dst_len; //·ÓɱíÖÐÄ¿µÄµØÖ·µÄÑÚÂ볤¶È
826
827
828 rtAttr = (struct rtattr *)RTM_RTA(rtMsg);
829 rtLen = RTM_PAYLOAD(nlHdr);
830 for (; net_RTA_OK(rtAttr, rtLen); rtAttr = RTA_NEXT(rtAttr, rtLen)) {
831 switch (rtAttr->rta_type) {
832 case RTA_OIF:
833 if_indextoname(*(int *)RTA_DATA(rtAttr), rtInfo->ifName); //Íø¿¨Ãû³Æ
834 break;
835 case RTA_GATEWAY:
836 rtInfo->gateWay = *(u_int *)RTA_DATA(rtAttr); //´ËÌõ·ÓÉÏîµÄÍø¹Ø
837 break;
838 case RTA_PREFSRC:
839 rtInfo->srcAddr = *(u_int *)RTA_DATA(rtAttr); //·ÓÉÏîµÄÔ´µØÖ·
840 break;
841 case RTA_DST:
842 rtInfo->dstAddr = *(u_int *)RTA_DATA(rtAttr); //·ÓÉÏîÖеÄÄ¿µÄµØÖ·
843 break;
844 }
845 }
846 dst.s_addr = rtInfo->dstAddr;
847
848 printf("oif:%s\t", rtInfo->ifName);
849 gate.s_addr = rtInfo->gateWay;
850 printf("%s\n", (char *)inet_ntoa(gate));
851
852 printf("src:%s\n", (char *)inet_ntoa(gate));
853 snprintf(srcaddr, sizeof(srcaddr), "%s", (char *)inet_ntoa(gate));//klocwork
854 gate.s_addr = rtInfo->dstAddr;
855 printf("dst:%s\n", (char *)inet_ntoa(gate));
856
857 //free(tempBuf);
858 return;
859}
860
861/****************************************/
862//½Ó¿Ú¹¦ÄÜ£º ¼ì²âÊÇ·ñÅäÖÃÁËȱʡ·ÓÉ£¬ÐèÒªÁ¬ÍâÍøµÄÓ¦ÓÿÉÒÔµ÷Óñ¾½Ó¿ÚÅжÏÍøÂçÊÇ·ñ¾ÍÐ÷
863//return:
864// -1: error;
865// 0: ÍøÂçδ¾ÍÐ÷
866// 1: ÍøÂçÒѾÍÐ÷
867/****************************************/
868int default_route_check()
869{
870 struct nlmsghdr *nlMsg;
871 struct rtmsg *rtMsg;
872 struct route_info *rtInfo;
873 char *msgBuf = malloc(BUFSIZE);
874
875
876 int sock, len, msgSeq = 0;
877
878 if(NULL == msgBuf) {
879 softap_assert("");
880 return -1;//klocwork
881 }
882
883 if ((sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0) {
884 perror("Socket Creation: ");
885 free(msgBuf);
886 return -1;
887 }
888
889 memset(msgBuf, 0, BUFSIZE);
890
891 nlMsg = (struct nlmsghdr *)msgBuf;
892 rtMsg = (struct rtmsg *)NLMSG_DATA(nlMsg);
893 nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); // Length of message.
894 nlMsg->nlmsg_type = RTM_GETROUTE; // Get the routes from kernel routing table .
895 nlMsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST; // The message is a request for dump.
896 nlMsg->nlmsg_seq = msgSeq++; // Sequence of the message packet.
897 nlMsg->nlmsg_pid = getpid(); // PID of process sending the request.
898
899 if (send(sock, nlMsg, nlMsg->nlmsg_len, 0) < 0) {
900 printf("Write To Socket Failed¡­\n");
901 free(msgBuf);
902 close(sock);
903 return -1;
904 }
905
906 if ((len = readNlSock(sock, msgBuf, msgSeq, getpid())) < 0) {
907 printf("Read From Socket Failed¡­\n");
908 free(msgBuf);
909 close(sock);
910 return -1;
911 }
912
913
914 rtInfo = (struct route_info *)malloc(sizeof(struct route_info));
915 if (NULL == rtInfo) { //klocwork
916 printf("Malloc route_info Failed¡­\n");
917 free(msgBuf);
918 close(sock);
919 return -1;
920 }
921 for (; NLMSG_OK(nlMsg, len); nlMsg = NLMSG_NEXT(nlMsg, len)) {
922 memset(rtInfo, 0, sizeof(struct route_info));
923 parseRoutes(nlMsg, rtInfo);
924 if (rtInfo->dstAddr == 0 && strlen(rtInfo->ifName)) {
925 printf("default wan :%s \n", rtInfo->ifName);
926 free(rtInfo);
927 close(sock);
928 free(msgBuf);
929 return 1;
930 }
931 }
932 free(rtInfo);
933 close(sock);
934 free(msgBuf);
935 return 0;
936}
937
938
939
940/**************************************/
941//½Ó¿Ú¹¦ÄÜ: ¼ì²âflashÊÇ·ñ±»ÆäËûºËÕ¼ÓÃ
942//return:
943// 0 ----- flashûÓб»Õ¼ÓÃ
944// 1 ----- flashÕý±»ÆäËûºËÕ¼ÓÃ
945// -1 ----- open½Úµãʧ°Ü
946// -2 ----- ioctlʧ°Ü
947/**************************************/
948
949int flash_mutex_check()
950{
951 int fd, ret;
952 char arg = 3;
953 fd = open("/dev/softspinlock", O_RDWR);
954 //printf("fd = %d \n",fd);
955 if (fd < 0)
956 return -1;
957
958 ret = ioctl(fd, SPINLOCK_GET_STATUS, &arg);
959 //printf("ret = %d arg = %d \n",ret,arg);
960 if (ret < 0) {
961 close(fd);
962 return -2;
963 }
964 close(fd);
965 return arg;
966
967}
968
969//»ñȡָ¶¨Ïß³ÌÃûµÄpidºÅ£¬×¢Ò⣺µ÷Óøú¯Êý»ñÈ¡·µ»ØÖµ£¬Ê¹ÓúóÒ»¶¨ÒªÊͷŸÃÄÚ´æ¿Õ¼ä
970pid_t* find_pid_by_name(char *pidName)
971{
972 DIR *dir;
973 struct dirent *next;
974 pid_t* pidList = NULL;
975 pid_t* tmpList = NULL;
976 int i = 0;
977
978 //procÖаüÀ¨µ±Ç°µÄ½ø³ÌÐÅÏ¢£¬¶ÁÈ¡¸ÃĿ¼
979 dir = opendir("/proc");
980 if(!dir)
981 {
982 perror("Cannot open /proc");
983 return pidList;
984 }
985 //±éÀú/procÏÂĿ¼
986 while((next = readdir(dir)) != NULL)
987 {
988 FILE *status;
989 char filename[READ_BUF_SIZE] = {0};//klocwork
990 char filename1[READ_BUF_SIZE] = {0};//klocwork
991 char name[READ_BUF_SIZE] = {0};
992 //skip ".." since that is outside /proc
993 if(0 == strcmp(next->d_name,".."))
994 continue;
995 //if it isn't a number,we skip it
996 if(!isdigit(*next->d_name))
997 continue;
998
999 snprintf(filename,sizeof(filename),"/proc/%s/status",next->d_name);
1000
1001 if(!(status = fopen(filename,"r")))
1002 {
1003 continue;
1004 }
1005 if(NULL == fgets(filename1,READ_BUF_SIZE-1,status))
1006 {
1007 fclose(status);
1008 continue;
1009 }
1010 fclose(status);
1011
1012 //»ñÈ¡½ø³Ìpid£¬Í¬Ê±Ò²»áÓжà¸öÏàͬ½ø³ÌÃûµÄÇé¿ö
1013 sscanf(filename1, "%*s %s", name);
1014 if(0 == strcmp(name,pidName))
1015 {
1016 //pidList = realloc(pidList,sizeof(pid_t)*(i+2));
1017 //klocwork
1018 tmpList = realloc(pidList,sizeof(pid_t)*(i+2));
1019 if (NULL == tmpList) {
1020 continue;
1021 }
1022 pidList = tmpList;
1023 errno = 0;
1024 pidList[i++] = strtol(next->d_name,NULL,0);
1025 if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
1026 {
1027 printf("strtol errno %d: %s\n", errno, strerror(errno));
1028 }
1029 }
1030 }
1031 if(pidList)
1032 {
1033 pidList[i] = 0;
1034 }
1035 closedir(dir);
1036 return pidList;
1037}
1038
1039void handle_quit(int signo)
1040{
1041 pthread_exit(NULL);
1042}
1043
1044/* gethostbyname¹¦ÄÜÖж¨Ê±Æ÷³¬Ê±´¦Àíº¯Êý */
1045void gethostbyname_timeout(int msg_id)
1046{
1047 slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_timeout begin,msg_id=%d\n",msg_id);
1048 if(ipc_send_message(msg_id, msg_id, MSG_GET_HOST_BY_NAME_TIMEOUT,0, 0, 0) < 0)
1049 {
1050 // todo: for cov M
1051 }
1052}
1053
1054/**
1055* gethostbyname¹¦ÄÜÖд´½¨¶¨Ê±Æ÷
1056* second_time: ³¬Ê±Ê±³¤
1057* msg_id: Ïß³Ìid
1058*/
1059void gethostbyname_creattimer(int second_time, int msg_id)
1060{
1061 slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_creattimer begin\n");
1062 sc_timer_delete(TIMER_GETHOSTBYNAME_ID);
1063 sc_timer_create(TIMER_GETHOSTBYNAME_ID, TIMER_FLAG_ONCE, second_time*1000, gethostbyname_timeout, (void *)msg_id);
1064}
1065
1066/* gethostbyname¹¦ÄÜÖÐɾ³ý¶¨Ê±Æ÷ */
1067void gethostbyname_deletetimer()
1068{
1069 slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_deletetimer begin\n");
1070 sc_timer_delete(TIMER_GETHOSTBYNAME_ID);
1071}
1072
1073void *gethostbyname_timer(void *arg)
1074{
1075 int time = 0;
1076 char *name = NULL;
1077 int msg_id;
1078 struct hostent* hptr = NULL;
1079
1080 time =((struct gethostbyname_info *)arg)->time;
1081 name = ((struct gethostbyname_info *)arg)->name;
1082 msg_id = ((struct gethostbyname_info *)arg)->msg_id;
1083
1084 slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_timer time=%d,name=%s,msg_id=%d\n", time, name, msg_id);
1085
1086 signal(SIGQUIT, handle_quit);
1087
1088 gethostbyname_creattimer(time, msg_id); //Æð¶¨Ê±Æ÷
1089
1090 hptr = gethostbyname(name);
1091 if(NULL != hptr) //»ñÈ¡µ½hostÐÅÏ¢
1092 {
1093 slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_timer get info\n");
1094 gethostbyname_deletetimer(); //ɾ³ý¶¨Ê±Æ÷
1095 slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_timer result hostname=%s\n",hptr->h_name);
1096 //¸øÖ÷½ø³Ì·¢ÏûÏ¢
1097 if(ipc_send_message(msg_id, msg_id, MSG_GET_HOST_BY_NAME_SUCCESS, sizeof(void *), (UCHAR *)&hptr, 0) < 0)
1098 {
1099 // todo: for cov M
1100 }
1101 pthread_exit(NULL);
1102 }
1103 return NULL;
1104}
1105
1106//·â×°gethostbynameº¯Êý£¬Ôö¼ÓÒ»¸ö³¬Ê±Ê±¼äµÄÈë²Î£¬timeµ¥Î»ÎªÃë
1107//Èç¹û³¬¹ý³¬Ê±Ê±¼äÈÔÈ»»ñÈ¡²»µ½hostÐÅÏ¢£¬Ôòº¯Êý·µ»Ø²»¼ÌÐø×èÈû
1108//¶¨Ê±Æ÷IDÏß³ÌÄÚ¹²Ïí£¬Ò»¸ö½ø³Ì²»ÒªÍ¬Ê±µ÷ÓøýӿÚ
1109struct hostent *gethostbyname_t(const char *name, int time)
1110{
1111 slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_t begin\n");
1112 pthread_t pthread;
1113 int my_handle = 0;
1114 int module_id = MODULE_ID_AP_GETHOSTBYNAME_BASE;
1115 int ret = 0;
1116 int msg_ret = 0;
1117 struct hostent* hostresultinfo = NULL;
1118 struct gethostbyname_info myhostinfo = {0};
1119 MSG_BUF rsp_msg = {0};
1120 LONG msgSize = sizeof(MSG_BUF) - sizeof(LONG);
1121 if(0 == time)
1122 {
1123 slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_t time =0\n");
1124 return gethostbyname(name);
1125 }
1126 else
1127 {
1128 slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_t time = %d\n",time);
1129
1130 //¶¯Ì¬´´½¨ÁÙʱµÄÏûÏ¢¶ÓÁйܵÀ
1131 //msggetʹÓòÎÊýIPC_CREAT | IPC_EXCL| 0600£¬Åжϵ±Ç°module_idµÄÏûÏ¢¶ÓÁÐÊÇ·ñ
1132 //´æÔÚ£¬Èç¹û²»´æÔÚ£¬Ö±½Ó´´½¨ÐµÄÏûÏ¢¶ÓÁУ»Èç¹û´æÔÚ£¬·µ»ØÖµÎ´-1£¬È»ºómodule_id
1133 //Öµ¼Ó1£¬²»¶ÏÑ­»·Ö±µ½ÕÒµ½Ã»ÓÐʹÓõÄmodule_idÖµ
1134 while((my_handle = msgget(module_id,IPC_CREAT | IPC_EXCL| 0600)) == -1)
1135 {
1136 module_id++;
1137 //µ±module_id´óÓÚMODULE_ID_ATDYNAMIC_ENDֵʱ£¬Ö÷¶¯¶ÏÑÔ
1138 if (module_id > MODULE_ID_AP_GETHOSTBYNAME_END)
1139 {
1140 softap_assert("MODULE_ID_AP_GETHOSTBYNAME_END!!!!!!!!!!!\n");
1141 }
1142 }
1143 myhostinfo.time = time;
1144 strncpy(myhostinfo.name, name, sizeof(myhostinfo.name)-1);
1145 myhostinfo.msg_id = module_id;
1146 //Æð×ÓỊ̈߳¬ÔÚ×ÓÏß³ÌÀï´´½¨¶¨Ê±Æ÷
1147 ret = pthread_create(&pthread, NULL, (void *)gethostbyname_timer, (void *)&myhostinfo);
1148 if (ret < 0 || pthread == NULL) {
1149 slog(NET_PRINT, SLOG_DEBUG, "creat thread fail\n");
1150 return NULL;
1151 }
1152 while(1)
1153 {
1154 msg_ret = 0;
1155 memset(&rsp_msg, 0x00, sizeof(MSG_BUF));
1156 msg_ret = msgrcv(my_handle, &rsp_msg, msgSize, 0, 0);
1157 if (msg_ret < 0)
1158 {
1159 continue;
1160 }
1161
1162 if(rsp_msg.usMsgCmd == MSG_GET_HOST_BY_NAME_SUCCESS)
1163 {
1164 slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_t success\n");
1165 hostresultinfo = (struct hostent*)(*(int *)rsp_msg.aucDataBuf);
1166 slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_t result:name=%s\n",hostresultinfo->h_name);
1167 return hostresultinfo;
1168 }
1169 else if(rsp_msg.usMsgCmd == MSG_GET_HOST_BY_NAME_TIMEOUT)
1170 {
1171 slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_t fail\n");
1172 pthread_kill(pthread, SIGQUIT);
1173 return NULL;
1174 }
1175 else
1176 {
1177 slog(NET_PRINT, SLOG_ERR, "gethostbyname_t fail\n");
1178 }
1179 }
1180 }
1181}
1182
1183/******************************************************************************/
1184
1185#define DNS_SERVER_NUM 2
1186
1187#define T_A 1 //Ipv4 address
1188#define T_NS 2 //Nameserver
1189#define T_CNAME 5 // canonical name
1190#define T_SOA 6 /* start of authority zone */
1191#define T_PTR 12 /* domain name pointer */
1192#define T_MX 15 //Mail server
1193
1194
1195
1196//DNS header structure
1197struct DNS_HEADER {
1198 unsigned short id; // identification number
1199
1200 unsigned char rd :1; // recursion desired
1201 unsigned char tc :1; // truncated message
1202 unsigned char aa :1; // authoritive answer
1203 unsigned char opcode :4; // purpose of message
1204 unsigned char qr :1; // query/response flag
1205
1206 unsigned char rcode :4; // response code
1207 unsigned char cd :1; // checking disabled
1208 unsigned char ad :1; // authenticated data
1209 unsigned char z :1; // its z! reserved
1210 unsigned char ra :1; // recursion available
1211
1212 unsigned short q_count; // number of question entries
1213 unsigned short ans_count; // number of answer entries
1214 unsigned short auth_count; // number of authority entries
1215 unsigned short add_count; // number of resource entries
1216};
1217
1218//Constant sized fields of query structure
1219struct QUESTION {
1220 unsigned short qtype;
1221 unsigned short qclass;
1222};
1223
1224//Constant sized fields of the resource record structure
1225#pragma pack(push, 1)
1226struct R_DATA {
1227 unsigned short type;
1228 unsigned short _class;
1229 unsigned int ttl;
1230 unsigned short data_len;
1231};
1232#pragma pack(pop)
1233
1234//Pointers to resource record contents
1235struct RES_RECORD {
1236 unsigned char *name;
1237 struct R_DATA *resource;
1238 unsigned char *rdata;
1239};
1240
1241//Structure of a Query
1242typedef struct {
1243 unsigned char *name;
1244 struct QUESTION *ques;
1245} QUERY;
1246
1247
1248void ChangetoDnsNameFormat(unsigned char* dns, unsigned char* host) {
1249 int lock = 0, i;
1250 strcat((char*) host, ".");
1251
1252 for (i = 0; i < strlen((char*) host); i++) {
1253 if (host[i] == '.') {
1254 *dns++ = i - lock;
1255 for (; lock < i; lock++) {
1256 *dns++ = host[lock];
1257 }
1258 lock++; //or lock=i+1;
1259 }
1260 }
1261 *dns++ = '\0';
1262}
1263
1264u_char* ReadName(unsigned char* reader, unsigned char* buffer, int* count) {
1265 unsigned char *name;
1266 unsigned int p = 0, jumped = 0, offset;
1267 int i, j;
1268
1269 *count = 1;
1270 name = (unsigned char*) malloc(256);
1271 if (!name)
1272 return NULL;//klocwork
1273
1274 name[0] = '\0';
1275
1276 //read the names in 3www6google3com format
1277 while (*reader != 0) {
1278 if (*reader >= 192) {
1279 offset = (*reader) * 256 + *(reader + 1) - 49152; //49152 = 11000000 00000000 ;)
1280 reader = buffer + offset - 1;
1281 jumped = 1; //we have jumped to another location so counting wont go up!
1282 } else {
1283 name[p++] = *reader;
1284 }
1285
1286 reader = reader + 1;
1287
1288 if (jumped == 0) {
1289 *count = *count + 1; //if we havent jumped to another location then we can count up
1290 }
1291 }
1292
1293 name[p] = '\0'; //string complete
1294 if (jumped == 1) {
1295 *count = *count + 1; //number of steps we actually moved forward in the packet
1296 }
1297
1298 //now convert 3www6google3com0 to www.google.com
1299 for (i = 0; i < (int) strlen((const char*) name); i++) {
1300 p = name[i];
1301 for (j = 0; j < (int) p; j++) {
1302 name[i] = name[i + 1];
1303 i = i + 1;
1304 }
1305 name[i] = '.';
1306 }
1307 name[i - 1] = '\0'; //remove the last dot
1308 return name;
1309}
1310
1311unsigned long my_gethostbyname(unsigned char *host, char *dev_name,char* dns_server, int query_type) {
1312 unsigned char buf[1025], *qname, *reader;
1313 int i, j, stop, s, ans_max;
1314 struct timeval tv;
1315 unsigned long ret = 0;
1316 struct ifreq ifr;
1317
1318 struct sockaddr_in a;
1319
1320 struct RES_RECORD answers[20], auth[20], addit[20]; //the replies from the DNS server
1321 struct sockaddr_in dest;
1322
1323 struct DNS_HEADER *dns = NULL;
1324 struct QUESTION *qinfo = NULL;
1325
1326 printf("Resolving %s", host);
1327
1328 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //UDP packet for DNS queries
1329 if(s < 0)
1330 {
1331 printf("socket return fail \n");
1332 return ret;
1333 }
1334
1335 memset(&ifr,0,sizeof(ifr));
1336 strncpy(ifr.ifr_name, dev_name, sizeof(ifr.ifr_name)-1);
1337 if(setsockopt(s,SOL_SOCKET,SO_BINDTODEVICE,(char*)&ifr,sizeof(ifr)) < 0){
1338 printf("SO_BINDTODEVICE fail \n");
1339 goto out;
1340 }
1341 tv.tv_sec = 5;
1342 tv.tv_usec = 0;
1343 if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
1344 printf("socket option SO_RCVTIMEO not support\n");
1345 goto out;
1346 }
1347 dest.sin_family = AF_INET;
1348 dest.sin_port = htons(53);
1349 dest.sin_addr.s_addr = inet_addr(dns_server); //dns servers
1350
1351 //Set the DNS structure to standard queries
1352 dns = (struct DNS_HEADER *) &buf;
1353
1354 dns->id = (unsigned short) htons(getpid());
1355 dns->qr = 0; //This is a query
1356 dns->opcode = 0; //This is a standard query
1357 dns->aa = 0; //Not Authoritative
1358 dns->tc = 0; //This message is not truncated
1359 dns->rd = 1; //Recursion Desired
1360 dns->ra = 0; //Recursion not available! hey we dont have it (lol)
1361 dns->z = 0;
1362 dns->ad = 0;
1363 dns->cd = 0;
1364 dns->rcode = 0;
1365 dns->q_count = htons(1); //we have only 1 question
1366 dns->ans_count = 0;
1367 dns->auth_count = 0;
1368 dns->add_count = 0;
1369
1370 //point to the query portion
1371 qname = (unsigned char*) &buf[sizeof(struct DNS_HEADER)];
1372
1373 ChangetoDnsNameFormat(qname, host);
1374 qinfo = (struct QUESTION*) &buf[sizeof(struct DNS_HEADER)
1375 + (strlen((const char*) qname) + 1)]; //fill it
1376
1377 qinfo->qtype = htons(query_type); //type of the query , A , MX , CNAME , NS etc
1378 qinfo->qclass = htons(1); //its internet (lol)
1379
1380 printf("\nSending Packet...");
1381 if (sendto(s, (char*) buf,
1382 sizeof(struct DNS_HEADER) + (strlen((const char*) qname) + 1)
1383 + sizeof(struct QUESTION), 0, (struct sockaddr*) &dest,
1384 sizeof(dest)) < 0) {
1385 perror("sendto failed");
1386 }
1387 printf("Done");
1388
1389 //Receive the answer
1390 i = sizeof dest;
1391 printf("\nReceiving answer...");
1392 if (recvfrom(s, (char*) buf, sizeof(buf)-1, 0, (struct sockaddr*) &dest,
1393 (socklen_t*) &i) < 0) {
1394 perror("recvfrom failed");
1395 }
1396 *(buf+sizeof(buf)-1) = 0;
1397 printf("Done");
1398
1399 dns = (struct DNS_HEADER*) buf;
1400 if((sizeof(struct DNS_HEADER) +
1401 (strlen((const char*) qname) + 1)+
1402 sizeof(struct QUESTION)) >= sizeof(buf))
1403 {
1404 perror("my_gethostbyname error");
1405 goto out;
1406 }
1407
1408 //move ahead of the dns header and the query field
1409 reader = &buf[sizeof(struct DNS_HEADER) + (strlen((const char*) qname) + 1)
1410 + sizeof(struct QUESTION)];
1411
1412 //printf("\nThe response contains : ");
1413 //printf("\n %d Questions.", ntohs(dns->q_count));
1414 //printf("\n %d Answers.", ntohs(dns->ans_count));
1415 //printf("\n %d Authoritative Servers.", ntohs(dns->auth_count));
1416 //printf("\n %d Additional records.\n\n", ntohs(dns->add_count));
1417
1418 //Start reading answers
1419 stop = 0;
1420 //klocwork
1421 //ans_max = ((ntohs(dns->ans_count) <= (sizeof(answers)/sizeof(answers[0]))) ? ntohs(dns->ans_count) : (sizeof(answers)/sizeof(answers[0])));
1422 ans_max = ntohs(dns->ans_count);
1423 if (ans_max > (sizeof(answers)/sizeof(answers[0])))
1424 ans_max = (sizeof(answers)/sizeof(answers[0]));
1425 for (i = 0; i < ans_max; i++)
1426 {
1427 answers[i].name = ReadName(reader, buf, &stop);
1428 reader = reader + stop;
1429
1430 answers[i].resource = (struct R_DATA*) (reader);
1431 reader = reader + sizeof(struct R_DATA);
1432
1433 if (ntohs(answers[i].resource->type) == 1) //if its an ipv4 address
1434 {
1435 answers[i].rdata = (unsigned char*) malloc(
1436 ntohs(answers[i].resource->data_len));
1437
1438 for (j = 0; j < ntohs(answers[i].resource->data_len); j++) {
1439 answers[i].rdata[j] = reader[j];
1440 }
1441
1442 answers[i].rdata[ntohs(answers[i].resource->data_len)] = '\0';
1443
1444 reader = reader + ntohs(answers[i].resource->data_len);
1445 } else {
1446 answers[i].rdata = ReadName(reader, buf, &stop);
1447 reader = reader + stop;
1448 }
1449 }
1450
1451 //print answers
1452 printf("\nAnswer Records : %d \n", ntohs(dns->ans_count));
1453 for (i = 0; i < ans_max; i++) {
1454 printf("Name : %s ", answers[i].name);
1455
1456 if (ntohs(answers[i].resource->type) == T_A) //IPv4 address
1457 {
1458 long *p;
1459 p = (long*) answers[i].rdata;
1460 a.sin_addr.s_addr = (*p); //working without ntohl
1461#if 1 // cov M
1462 char * s_addr = inet_ntoa(a.sin_addr);
1463 printf("has IPv4 address : %s", s_addr);
1464#else
1465 printf("has IPv4 address : %s", inet_ntoa(a.sin_addr));
1466#endif
1467 ret = (unsigned long)a.sin_addr.s_addr;
1468 }
1469
1470 if (ntohs(answers[i].resource->type) == 5) {
1471 //Canonical name for an alias
1472 printf("has alias name : %s", answers[i].rdata);
1473 }
1474
1475 printf("\n");
1476 }
1477out:
1478 close(s);
1479 return ret;
1480}
1481
1482
1483unsigned long gethostbyname_l(char *hostname,char* dev_name)
1484{
1485 int i = 0;
1486 unsigned long ret = 0;
1487 char dns_servers[DNS_SERVER_NUM][32] = {0};
1488
1489 //Get the DNS servers from the resolv.conf file
1490 char nv_dns[32] = {0};
1491 char ip_dns[32] = {0};
1492
1493 sprintf(nv_dns, "%s_pridns", dev_name);
1494 sc_cfg_get(nv_dns, ip_dns, sizeof(ip_dns));
1495 strcpy(dns_servers[0], ip_dns);
1496
1497 memset(nv_dns,0,sizeof(nv_dns));
1498 memset(ip_dns,0,sizeof(ip_dns));
1499 sprintf(nv_dns, "%s_secdns", dev_name);
1500 sc_cfg_get(nv_dns, ip_dns, sizeof(ip_dns));
1501 strcpy(dns_servers[1], ip_dns);
1502
1503
1504 //Now get the ip of this hostname , A record
1505 for(i=0;i<DNS_SERVER_NUM;i++)
1506 {
1507 ret = my_gethostbyname(hostname, dev_name , dns_servers[i], T_A);
1508 if(ret > 0)
1509 break;
1510 }
1511
1512 return ret;
1513}
1514
1515
1516
1517
1518/******************************************************************************/
1519
1520