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