source: src/router/libutils/bcmutils.c @ 17681

Last change on this file since 17681 was 17681, checked in by eko, 20 months ago

fix nvram free / size

File size: 37.5 KB
Line 
1// #define CDEBUG
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6#include <errno.h>
7#include <net/if.h>
8#include <dirent.h>
9#include <unistd.h>
10#include <ctype.h>
11#include <syslog.h>
12#include <sys/socket.h>
13#include <sys/stat.h>
14#include <fcntl.h>
15#include <netinet/in.h>
16#include <stdarg.h>
17#include <sys/ioctl.h>
18#include <sys/sysinfo.h>
19#include <arpa/inet.h>
20#include <netdb.h>
21#include <resolv.h>
22#include <signal.h>
23
24#include <utils.h>
25#include <wlutils.h>
26#include <bcmnvram.h>
27#include <shutils.h>
28#include <cy_conf.h>
29#include <code_pattern.h>
30#include <bcmdevs.h>
31#include <net/route.h>
32#include <cy_conf.h>
33#include <linux/if_ether.h>
34// #include <linux/mii.h>
35#include <linux/sockios.h>
36#include <cymac.h>
37#include <broadcom.h>
38#include <md5.h>
39
40#define SIOCGMIIREG     0x8948  /* Read MII PHY register.  */
41#define SIOCSMIIREG     0x8949  /* Write MII PHY register.  */
42
43struct mii_ioctl_data {
44        unsigned short phy_id;
45        unsigned short reg_num;
46        unsigned short val_in;
47        unsigned short val_out;
48};
49
50int getcpurev(void)
51{
52        FILE *fp = fopen("/proc/cpuinfo", "rb");
53
54        if (fp == NULL) {
55                return -1;
56        }
57        int cnt = 0;
58        int b = 0;
59
60        while (b != EOF) {
61                b = getc(fp);
62                if (b == ':')
63                        cnt++;
64                if (cnt == 3) {
65                        getc(fp);
66                        char cpurev[32];
67                        int i = 0;
68
69                        for (i = 0; i < 32; i++) {
70                                cpurev[i] = getc(fp);
71                                if (cpurev[i] == '\n')
72                                        break;
73                        }
74                        cpurev[i] = 0;
75                        fclose(fp);
76                        if (strstr(cpurev, "BCM4710 V0.0"))     // BCM4702, BCM4710
77                                // (old 125 MHz)
78                                return 0;
79                        if (strstr(cpurev, "BCM3302 V0.6"))     // BCM4704
80                                return 6;
81                        if (strstr(cpurev, "BCM3302 V0.7"))     // BCM4712, BCM5365
82                                return 7;
83                        if (strstr(cpurev, "BCM3302 V0.8"))     // BCM5350, BCM5352
84                                return 8;
85                        if (strstr(cpurev, "BCM3302 V2.9"))     // BCM5354
86                                return 29;
87                        if (strstr(cpurev, "BCM3302 V1.10"))    // BCM4785 (BCM3302 V1.10)
88                                return 110;
89                        if (strstr(cpurev, "MIPS 74K V4.0"))    // BCM4718 (Broadcom BCM4716 chip rev 1)
90                                return 40;
91                        if (strstr(cpurev, "MIPS 74K V4.9"))    // BCM4716B0 (Broadcom BCMB83A chip rev 0)
92                                return 49;      // BCM5356B0 (Broadcom BCM5356 chip rev 1)
93                        return -1;
94                }
95        }
96        fclose(fp);
97        return -1;
98}
99
100int cpu_plltype(void)
101{
102#if defined(HAVE_BUFFALO) || defined(BUFFALO_JP)
103        if (nvram_match("DD_BOARD", "Buffalo WHR-G54S") ||      //
104            nvram_match("DD_BOARD", "Buffalo WHR-HP-G54") ||    //
105            nvram_match("DD_BOARD", "Buffalo AS-A100") ||       //
106            nvram_match("DD_BOARD", "Buffalo WHR-HP-G54DD"))    //
107                return 0;
108#endif
109
110        int cpurev = getcpurev();
111        int cputype = check_hw_type();
112
113        if (cpurev == 0)        // BCM4702, BCM4710 (old 125 MHz)
114                return 0;
115        if (cpurev == 6)        // BCM4704
116                return 0;
117        if (cpurev == 7 && cputype == BCM5365_CHIP)     // BCM5365 only
118                // supports fixed 200
119                // MHz
120                return 0;
121        if (cpurev == 7 && cputype != BCM5365_CHIP)     // BCM4712
122                return 4;
123        if (cpurev == 8 && cputype == BCM5350_CHIP)     // BCM5350
124                return 3;
125        if (cpurev == 8 && cputype != BCM5350_CHIP)     // BCM5352
126                return 7;
127        if (cpurev == 29)       // BCM5354, only supports fixed 240 MHz
128                return 0;
129        if (cpurev == 110)      // BCM4705
130                return 2;
131
132        return 0;
133}
134
135/* In the space-separated/null-terminated list(haystack), try to
136 * locate the string "needle"
137 */
138char *find_in_list(const char *haystack, const char *needle)
139{
140        const char *ptr = haystack;
141        int needle_len = 0;
142        int haystack_len = 0;
143        int len = 0;
144
145        if (!haystack || !needle || !*haystack || !*needle)
146                return NULL;
147
148        needle_len = strlen(needle);
149        haystack_len = strlen(haystack);
150
151        while (*ptr != 0 && ptr < &haystack[haystack_len]) {
152                /* consume leading spaces */
153                ptr += strspn(ptr, " ");
154
155                /* what's the length of the next word */
156                len = strcspn(ptr, " ");
157
158                if ((needle_len == len) && (!strncmp(needle, ptr, len)))
159                        return (char *)ptr;
160
161                ptr += len;
162        }
163        return NULL;
164}
165
166/**
167 *      remove_from_list
168 *      Remove the specified word from the list.
169
170 *      @param name word to be removed from the list
171 *      @param list Space separated list to modify
172 *      @param listsize Max size the list can occupy
173
174 *      @return error code
175 */
176int remove_from_list(const char *name, char *list, int listsize)
177{
178        int listlen = 0;
179        int namelen = 0;
180        char *occurrence = list;
181
182        if (!list || !name || (listsize <= 0))
183                return EINVAL;
184
185        listlen = strlen(list);
186        namelen = strlen(name);
187
188        occurrence = find_in_list(occurrence, name);
189
190        if (!occurrence)
191                return EINVAL;
192
193        /* last item in list? */
194        if (occurrence[namelen] == 0) {
195                /* only item in list? */
196                if (occurrence != list)
197                        occurrence--;
198                occurrence[0] = 0;
199        } else if (occurrence[namelen] == ' ') {
200                strncpy(occurrence, &occurrence[namelen + 1 /* space */ ],
201                        strlen(&occurrence[namelen + 1 /* space */ ]) +
202                        1 /* terminate */ );
203        }
204
205        return 0;
206}
207
208/**
209 *              add_to_list
210 *      Add the specified interface(string) to the list as long as
211 *      it will fit in the space left in the list.
212
213 *      NOTE: If item is already in list, it won't be added again.
214
215 *      @param name Name of interface to be added to the list
216 *      @param list List to modify
217 *      @param listsize Max size the list can occupy
218
219 *      @return error code
220 */
221int add_to_list(const char *name, char *list, int listsize)
222{
223        int listlen = 0;
224        int namelen = 0;
225
226        if (!list || !name || (listsize <= 0))
227                return EINVAL;
228
229        listlen = strlen(list);
230        namelen = strlen(name);
231
232        /* is the item already in the list? */
233        if (find_in_list(list, name))
234                return 0;
235
236        if (listsize <= listlen + namelen + 1 /* space */  + 1 /* NULL */ )
237                return EMSGSIZE;
238
239        /* add a space if the list isn't empty and it doesn't already have space */
240        if (list[0] != 0 && list[listlen - 1] != ' ') {
241                list[listlen++] = 0x20;
242        }
243
244        strncpy(&list[listlen], name, namelen + 1 /* terminate */ );
245
246        return 0;
247}
248
249int count_occurences(char *source, int cmp)
250{
251        int i, cnt = 0;
252        int len = strlen(source);
253
254        for (i = 0; i < len; i++) {
255                if (source[i] == cmp)
256                        cnt++;
257        }
258        return cnt;
259}
260
261int pos_nthoccurence(char *source, int cmp, int which)
262{
263        int i, cnt = 0;
264        int len = strlen(source);
265
266        for (i = 0; i < len; i++) {
267                if (source[i] == cmp)
268                        cnt++;
269                if (cnt == which)
270                        return i;
271        }
272        return -1;
273}
274
275char *substring(int start, int stop, const char *src, char *dst)
276{
277        sprintf(dst, "%.*s", stop - start, src + start);
278
279        return dst;
280}
281
282/*
283 * given month, day, year, returns day of week, eg. Monday = 0 etc. 
284 */
285int weekday(int month, int day, int year)
286{
287        int ix, tx, vx = 0;
288
289        switch (month) {
290        case 2:
291        case 6:
292                vx = 0;
293                break;
294        case 8:
295                vx = 4;
296                break;
297        case 10:
298                vx = 8;
299                break;
300        case 9:
301        case 12:
302                vx = 12;
303                break;
304        case 3:
305        case 11:
306                vx = 16;
307                break;
308        case 1:
309        case 5:
310                vx = 20;
311                break;
312        case 4:
313        case 7:
314                vx = 24;
315                break;
316        }
317
318        if (year > 1900)        // 1900 was not a leap year
319                year -= 1900;
320        ix = ((year - 21) % 28) + vx + (month > 2);     // take care of
321        // February
322        tx = (ix + (ix / 4)) % 7 + day; // take care of leap year
323
324        return (tx % 7);
325
326}
327
328#if defined(HAVE_RT2880) || defined(HAVE_RT61)
329
330int has_mimo(char *prefix)
331{
332        return 1;
333}
334#else
335
336int has_mimo(char *prefix)
337{
338        char mimo[32];
339        sprintf(mimo, "%s_phytypes", prefix);
340        char *phy = nvram_safe_get(mimo);
341        if (contains(phy, 'n') || contains(phy, 'h') || contains(phy, 's'))
342                return 1;
343        else
344                return 0;
345}
346#endif
347
348char *get_mac_from_ip(char *ip)
349{
350        FILE *fp;
351        char line[100];
352        char ipa[50];           // ip address
353        char hwa[50];           // HW address / MAC
354        char mask[50];          // ntemask
355        char dev[50];           // interface
356        int type;               // HW type
357        int flags;              // flags
358        static char mac[20];
359
360        if ((fp = fopen("/proc/net/arp", "r")) == NULL)
361                return NULL;
362
363        // Bypass header -- read until newline
364        if (fgets(line, sizeof(line), fp) != (char *)NULL) {
365                // Read the ARP cache entries.
366                // IP address HW type Flags HW address Mask Device
367                // 192.168.1.1 0x1 0x2 00:90:4C:21:00:2A * eth0
368                for (; fgets(line, sizeof(line), fp);) {
369                        if (sscanf
370                            (line, "%s 0x%x 0x%x %100s %100s %100s\n", ipa,
371                             &type, &flags, hwa, mask, dev) != 6)
372                                continue;
373                        // cprintf("ip1=[%s] ip2=[%s] mac=[%s] (flags & ATF_COM)=%d\n",
374                        // ip, ipa, hwa, (flags & ATF_COM));
375                        if (strcmp(ip, ipa))
376                                continue;
377                        // if (!(flags & ATF_COM)) { //ATF_COM = 0x02 completed entry (ha
378                        // valid)
379                        strcpy(mac, hwa);
380                        fclose(fp);
381                        return mac;
382                        // }
383                }
384        }
385
386        fclose(fp);
387        return "";
388}
389
390struct dns_lists *get_dns_list(void)
391{
392        char list[254];
393        char *next, word[254];
394        struct dns_lists *dns_list = NULL;
395        int i, match = 0, altdns_index = 1;
396
397        dns_list = (struct dns_lists *)malloc(sizeof(struct dns_lists));
398        memset(dns_list, 0, sizeof(struct dns_lists));
399
400        dns_list->num_servers = 0;
401
402        // nvram_safe_get("wan_dns") ==> Set by user
403        // nvram_safe_get("wan_get_dns") ==> Get from DHCP, PPPoE or PPTP
404        // The nvram_safe_get("wan_dns") priority is higher than
405        // nvram_safe_get("wan_get_dns")
406        snprintf(list, sizeof(list), "%s %s %s",
407                 nvram_safe_get("sv_localdns"), nvram_safe_get("wan_dns"),
408                 nvram_safe_get("wan_get_dns"));
409        foreach(word, list, next) {
410                if (strcmp(word, "0.0.0.0") && strcmp(word, "")) {
411                        match = 0;
412                        for (i = 0; i < dns_list->num_servers; i++) {   // Skip same DNS
413                                if (!strcmp(dns_list->dns_server[i], word))
414                                        match = 1;
415                        }
416                        if (!match) {
417                                snprintf(dns_list->dns_server
418                                         [dns_list->num_servers],
419                                         sizeof(dns_list->dns_server
420                                                [dns_list->num_servers]), "%s",
421                                         word);
422                                dns_list->num_servers++;
423                        }
424                }
425                if (dns_list->num_servers == 3)
426                        break;  // We only need 3 DNS entries
427        }
428
429        /*
430         * if < 3 DNS servers found, try to insert alternates
431         */
432        while (dns_list->num_servers < 3 && altdns_index <= 3) {
433                char altdnsvar[32] = {
434                        0
435                };
436
437                snprintf(altdnsvar, 31, "altdns%d", altdns_index);
438
439                if (strlen(nvram_safe_get(altdnsvar)) > 0) {
440                        snprintf(dns_list->dns_server[dns_list->num_servers],
441                                 sizeof(dns_list->dns_server
442                                        [dns_list->num_servers]), "%s",
443                                 nvram_safe_get(altdnsvar));
444                        dns_list->num_servers++;
445                }
446                altdns_index++;
447        }
448        return dns_list;
449}
450
451int dns_to_resolv(void)
452{
453        FILE *fp_w;
454        struct dns_lists *dns_list = NULL;
455        int i = 0;
456
457        /*
458         * Save DNS to resolv.conf
459         */
460        if (!(fp_w = fopen(RESOLV_FILE, "w"))) {
461                perror(RESOLV_FILE);
462                return errno;
463        }
464        if (nvram_invmatch("wan_get_domain", "")) {
465                fprintf(fp_w, "search %s\n", nvram_safe_get("wan_get_domain"));
466        } else if (nvram_invmatch("wan_domain", "")) {
467                fprintf(fp_w, "search %s\n", nvram_safe_get("wan_domain"));
468        }
469        if (nvram_invmatch("lan_domain", "")) {
470                fprintf(fp_w, "search %s\n", nvram_safe_get("lan_domain"));
471        }
472        if (nvram_match("dnsmasq_enable", "1")) {
473                fprintf(fp_w, "nameserver %s\n", nvram_get("lan_ipaddr"));
474                fclose(fp_w);
475                if (!(fp_w = fopen(RESOLV_FORW, "w"))) {
476                        perror(RESOLV_FORW);
477                        return errno;
478                }
479        }
480
481        dns_list = get_dns_list();
482
483        for (i = 0; i < dns_list->num_servers; i++)
484                fprintf(fp_w, "nameserver %s\n", dns_list->dns_server[i]);
485
486        /*
487         * Put a pseudo DNS IP to trigger Connect On Demand
488         */
489        if (dns_list->num_servers == 0 && (nvram_match("wan_proto", "pppoe")
490                                           || nvram_match("wan_proto", "pptp")
491#ifdef HAVE_PPPOATM
492                                           || nvram_match("wan_proto", "pppoa")
493#endif
494#ifdef HAVE_L2TP
495                                           || nvram_match("wan_proto", "l2tp")
496#endif
497#ifdef HAVE_3G
498                                           || nvram_match("wan_proto", "3g")
499#endif
500            ) && nvram_match("ppp_demand", "1"))
501                fprintf(fp_w, "nameserver 1.1.1.1\n");
502
503        fclose(fp_w);
504        if (dns_list)
505                free(dns_list);
506
507        eval("touch", "/tmp/hosts");
508
509        return 1;
510}
511
512/*
513 * Example: lan_ipaddr = 192.168.1.1 get_dns_ip("lan_ipaddr", 1); produces
514 * "168"
515 */
516int get_single_ip(char *ipaddr, int which)
517{
518        int ip[4] = {
519                0, 0, 0, 0
520        };
521        int ret;
522
523        ret = sscanf(ipaddr, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]);
524        return ip[which];
525}
526
527char *get_complete_ip(char *from, char *to)
528{
529        static char ipaddr[20];
530
531        int i[4];
532
533        if (!from || !to)
534                return "0.0.0.0";
535
536        if (sscanf(from, "%d.%d.%d.%d", &i[0], &i[1], &i[2], &i[3]) != 4)
537                return "0.0.0.0";
538
539        snprintf(ipaddr, sizeof(ipaddr), "%d.%d.%d.%s", i[0], i[1], i[2], to);
540
541        return ipaddr;
542}
543
544char *get_complete_lan_ip(char *ip)
545{
546        static char ipaddr[20];
547
548        int i[4];
549
550        if (sscanf
551            (nvram_safe_get("lan_ipaddr"), "%d.%d.%d.%d", &i[0], &i[1], &i[2],
552             &i[3]) != 4)
553                return "0.0.0.0";
554
555        snprintf(ipaddr, sizeof(ipaddr), "%d.%d.%d.%s", i[0], i[1], i[2], ip);
556
557        return ipaddr;
558}
559
560
561/*
562 * =====================================================================================
563 * by tallest
564 * =====================================================================================
565 */
566
567int get_int_len(int num)
568{
569        char buf[80];
570
571        snprintf(buf, sizeof(buf), "%d", num);
572
573        return strlen(buf);
574}
575
576#define READ_BUF_SIZE 254
577/*
578 * from busybox find_pid_by_name.c
579 */
580pid_t *find_pid_by_name(char *pidName)
581{
582        DIR *dir;
583        struct dirent *next;
584        pid_t *pidList = NULL;
585        int i = 0;
586
587        dir = opendir("/proc");
588
589        while ((next = readdir(dir)) != NULL) {
590                FILE *status;
591                char filename[READ_BUF_SIZE];
592                char buffer[READ_BUF_SIZE];
593                char name[READ_BUF_SIZE];
594
595                /*
596                 * Must skip ".." since that is outside /proc
597                 */
598                if (strcmp(next->d_name, "..") == 0)
599                        continue;
600
601                /*
602                 * If it isn't a number, we don't want it
603                 */
604                if (!isdigit(*next->d_name))
605                        continue;
606
607                sprintf(filename, "/proc/%s/status", next->d_name);
608                if (!(status = fopen(filename, "r"))) {
609                        continue;
610                }
611                if (fgets(buffer, READ_BUF_SIZE - 1, status) == NULL) {
612                        fclose(status);
613                        continue;
614                }
615                fclose(status);
616
617                /*
618                 * Buffer should contain a string like "Name: binary_name"
619                 */
620                sscanf(buffer, "%*s %s", name);
621                // printf("buffer=[%s] name=[%s]\n",buffer,name);
622                if (strcmp(name, pidName) == 0) {
623                        pidList = realloc(pidList, sizeof(pid_t) * (i + 2));
624                        pidList[i++] = strtol(next->d_name, NULL, 0);
625                }
626        }
627
628        if (pidList)
629                pidList[i] = 0;
630        else {
631                pidList = realloc(pidList, sizeof(pid_t));
632                pidList[0] = -1;
633        }
634        return pidList;
635
636}
637
638/*
639 * Find first process pid with same name from ps command
640 */
641int find_pid_by_ps(char *pidName)
642{
643        FILE *fp;
644        int pid = -1;
645        char line[254];
646
647        if ((fp = popen("ps", "r"))) {
648                while (fgets(line, sizeof(line), fp) != NULL) {
649                        if (strstr(line, pidName)) {
650                                sscanf(line, "%d", &pid);
651                                printf("%s pid is %d\n", pidName, pid);
652                                break;
653                        }
654                }
655                pclose(fp);
656        }
657
658        return pid;
659}
660
661/*
662 * Find all process pid with same name from ps command
663 */
664int *find_all_pid_by_ps(char *pidName)
665{
666        FILE *fp;
667        int pid = -1;
668        char line[254];
669        int *pidList = NULL;
670        int i = 0;
671
672        cprintf("Search for %s\n", pidName);
673        if ((fp = popen("ps", "r"))) {
674                while (fgets(line, sizeof(line), fp) != NULL) {
675                        if (strstr(line, pidName)) {
676                                sscanf(line, "%d", &pid);
677                                cprintf("%s pid is %d\n", pidName, pid);
678                                pidList =
679                                    realloc(pidList, sizeof(int) * (i + 2));
680                                pidList[i++] = pid;
681                        }
682                }
683                pclose(fp);
684        }
685        if (pidList)
686                pidList[i] = 0;
687        else {
688                pidList = realloc(pidList, sizeof(int));
689                pidList[0] = -1;
690        }
691        cprintf("Search done...\n");
692
693        return pidList;
694}
695
696void encode(char *buf, int len)
697{
698        int i;
699        char ch;
700
701        for (i = 0; i < len; i++) {
702                ch = (buf[i] & 0x03) << 6;
703                buf[i] = (buf[i] >> 2);
704                buf[i] &= 0x3f;
705                buf[i] |= ch;
706                buf[i] = ~buf[i];
707        }
708}
709
710void decode(char *buf, int len)
711{
712        int i;
713        char ch;
714
715        for (i = 0; i < len; i++) {
716                ch = (buf[i] & 0xC0) >> 6;
717                buf[i] = (buf[i] << 2) | ch;
718                buf[i] = ~buf[i];
719        }
720}
721
722/*
723 * v1.41.7 => 014107 v1.2 => 0102
724 */
725long convert_ver(char *ver)
726{
727        char buf[10];
728        int v[3];
729        int ret;
730
731        ret = sscanf(ver, "v%d.%d.%d", &v[0], &v[1], &v[2]);
732
733        if (ret == 2) {
734                snprintf(buf, sizeof(buf), "%02d%02d", v[0], v[1]);
735                return atol(buf);
736        } else if (ret == 3) {
737                snprintf(buf, sizeof(buf), "%02d%02d%02d", v[0], v[1], v[2]);
738                return atol(buf);
739        } else
740                return -1;
741}
742
743/*
744 * To avoid user to download old image that is not support intel flash to new
745 * hardware with intel flash.
746 */
747int check_flash(void)
748{
749        // The V2 image can support intel flash completely, so we don't want to
750        // check.
751        if (check_hw_type() == BCM4712_CHIP)
752                return FALSE;
753
754        // The V1.X some images cann't support intel flash, so we want to avoid
755        // user to downgrade.
756        if (nvram_match("skip_amd_check", "1")) {
757                if (strstr(nvram_safe_get("flash_type"), "Intel")
758                    && nvram_invmatch("skip_intel_check", "1"))
759                        return TRUE;
760                else
761                        return FALSE;
762        } else                  // Cann't downgrade to old firmware version,
763                // no matter AMD or Intel flash
764                return TRUE;
765}
766
767int check_now_boot(void)
768{
769        char *ver = nvram_safe_get("pmon_ver");
770        char *cfe = nvram_safe_get("CFEver");
771
772        // for 4712
773        // The boot_ver value is lower v2.0 (no included)
774        if (!strncmp(ver, "PMON", 4)) {
775                cprintf("The boot is PMON\n");
776                return PMON_BOOT;
777        }
778        // for 4712
779        // The boot_ver value is higher v2.0 (included)
780        else if (!strncmp(ver, "CFE", 3)) {
781                cprintf("The boot is CFE\n");
782                return CFE_BOOT;
783        } else if (!strncmp(ver, "2", 1)) {
784                cprintf("The boot is CFE %s\n", ver);
785                return CFE_BOOT;
786        } else if (!strncmp(cfe, "MotoWR", 6)) {
787                cprintf("The boot is Motorola CFE\n");
788                return CFE_BOOT;
789        } else {
790                cprintf("The boot is UNKNOWN\n");
791                return UNKNOWN_BOOT;
792        }
793}
794
795int check_hw_type(void)
796{
797
798        char *boardtype = nvram_safe_get("boardtype");
799        uint boardflags = strtoul(nvram_safe_get("boardflags"), NULL, 0);
800        uint btype = strtoul(boardtype, NULL, 0);
801        char *vlan0 = nvram_safe_get("vlan0ports");
802        char *vlan1 = nvram_safe_get("vlan1ports");
803
804        if (!strncmp(boardtype, "bcm94710", 8))
805                return BCM4702_CHIP;
806        else if (btype == 0x0708 && !(boardflags & BFL_ENETADM))
807                return BCM5325E_CHIP;
808        else if (btype == 0x456 && getRouterBrand() == ROUTER_BELKIN_F5D7231)   // stupid
809                // Belkin!
810                return BCM5352E_CHIP;
811        else if (btype == 0x456)
812                return BCM5350_CHIP;
813        else if (!strncmp(boardtype, "bcm95365", 8))
814                return BCM5365_CHIP;
815        else if (btype == 0x048e)
816                return BCM5354G_CHIP;
817        else if (btype == 0x042f && !(boardflags & BFL_ENETADM))
818                return BCM4704_BCM5325F_CHIP;
819        else if (btype == 0x478 && strstr(vlan0, "5*")) /* WRT300NV1.1 */
820                return BCM4705L_BCM5325E_EWC_CHIP;
821        else if ((btype == 0x478 && (strstr(vlan0, "8*") || strstr(vlan1, "8*"))) || nvram_match("boot_hw_model", "WRT350N") || nvram_match("boot_hw_model", "WRT610N"))        /* WRT350N
822                                                                                                                                                                                 */
823                return BCM4705_BCM5397_EWC_CHIP;
824        else if (btype == 0x489 || nvram_match("boot_hw_model", "WRT310N"))     /* WRT310N,
825                                                                                 * temporal
826                                                                                 * boardtype
827                                                                                 * 0x478,
828                                                                                 * wait
829                                                                                 * for
830                                                                                 * braodcom's
831                                                                                 * txt
832                                                                                 * file
833                                                                                 */
834                return BCM4705G_BCM5395S_EWC_CHIP;
835        else if (btype == 0x0467)
836                return BCM5352E_CHIP;
837        else if (btype == 0x0101 && !(boardflags & BFL_ENETADM))
838                return BCM4712_BCM5325E_CHIP;
839        else if ((btype == 0x0101 || btype == 0x0446) && (boardflags & BFL_ENETADM))    // 0x446
840                // is
841                // wap54g
842                // v2
843                return BCM4712_CHIP;
844        else if (btype == 0x0472 && !(boardflags & BFL_ENETADM))
845                return BCM4704_BCM5325F_EWC_CHIP;
846        else
847                return NO_DEFINE_CHIP;
848}
849
850int ct_openlog(const char *ident, int option, int facility, char *log_name)
851{
852        int level = atoi(nvram_safe_get(log_name));
853
854        switch (level) {
855        case CONSOLE_ONLY:
856                break;
857        }
858        return level;
859}
860
861void ct_syslog(int level, int enable, const char *fmt, ...)
862{
863        char buf[1000];
864        va_list args;
865
866        va_start(args, fmt);
867        vsnprintf(buf, sizeof(buf), fmt, args);
868        va_end(args);
869
870        switch (enable) {
871        case CONSOLE_ONLY:
872                cprintf("[%d] %s\n", getpid(), buf);    // print to console
873                break;
874        }
875}
876
877void ct_logger(int level, const char *fmt, ...)
878{
879}
880
881static char *device_name[] = {
882        "eth0", "qos0"
883};
884
885char *get_device_name(void)
886{
887        int i;
888
889        switch (check_hw_type()) {
890        case BCM5325E_CHIP:
891        case BCM5350_CHIP:
892        case BCM5365_CHIP:
893        case BCM4704_BCM5325F_CHIP:
894        case BCM4704_BCM5325F_EWC_CHIP:
895        case BCM5352E_CHIP:
896        case BCM5354G_CHIP:
897        case BCM4712_BCM5325E_CHIP:
898        case BCM4705L_BCM5325E_EWC_CHIP:
899                i = 0;
900                break;
901        case BCM4702_CHIP:
902        case BCM4712_CHIP:
903        default:
904                i = 1;
905                break;
906        }
907
908        return device_name[i];
909}
910
911char *strncpyz(char *dest, char const *src, size_t size)
912{
913        if (!size--)
914                return dest;
915        strncpy(dest, src, size);
916        dest[size] = 0;         /* Make sure the string is null terminated */
917        return dest;
918}
919
920static int sockets_open(int domain, int type, int protocol)
921{
922        int fd = socket(domain, type, protocol);
923
924        if (fd < 0)
925                cprintf("sockets_open: no usable address was found.\n");
926        return fd;
927}
928
929int
930sys_netdev_ioctl(int family, int socket, char *if_name, int cmd,
931                 struct ifreq *ifr)
932{
933        int rc, s;
934
935        if ((s = socket) < 0) {
936                if ((s =
937                     sockets_open(family,
938                                  family ==
939                                  AF_PACKET ? SOCK_PACKET : SOCK_DGRAM,
940                                  family == AF_PACKET ? htons(ETH_P_ALL) : 0)) <
941                    0) {
942                        cprintf("sys_netdev_ioctl: failed\n");
943                        return -1;
944                }
945        }
946        strncpyz(ifr->ifr_name, if_name, IFNAMSIZ);
947        rc = ioctl(s, cmd, ifr);
948        if (socket < 0)
949                close(s);
950        return rc;
951}
952
953int set_register_value(unsigned short port_addr, unsigned short option_content)
954{
955        struct ifreq ifr;
956        struct mii_ioctl_data stats;
957
958        stats.phy_id = port_addr;
959        stats.val_in = option_content;
960
961        ifr.ifr_data = (void *)&stats;
962
963        if (sys_netdev_ioctl
964            (AF_INET, -1, get_device_name(), SIOCSMIIREG, &ifr) < 0)
965                return -1;
966
967        return 0;
968}
969
970unsigned long get_register_value(unsigned short id, unsigned short num)
971{
972        struct ifreq ifr;
973        struct mii_ioctl_data stats;
974
975        stats.phy_id = id;
976        stats.reg_num = num;
977        stats.val_in = 0;
978        stats.val_out = 0;
979
980        ifr.ifr_data = (void *)&stats;
981
982        sys_netdev_ioctl(AF_INET, -1, get_device_name(), SIOCGMIIREG, &ifr);
983
984        return ((stats.val_in << 16) | stats.val_out);
985}
986
987struct wl_assoc_mac *get_wl_assoc_mac(int instance, int *c)
988{
989        FILE *fp;
990        struct wl_assoc_mac *wlmac = NULL;
991        int count;
992        char line[80];
993        char list[2][20];
994        char checkif[12];
995        char assoccmd[32];
996
997        wlmac = NULL;
998        count = *c = 0;
999
1000        int ifcnt = 4;
1001        int i;
1002        int gotit = 0;
1003
1004        // fprintf(stderr,"assoclist\n");
1005
1006        for (i = 0; i < ifcnt; i++) {
1007                if (i == 0)
1008                        strcpy(checkif, get_wl_instance_name(instance));
1009                else
1010                        sprintf(checkif, "wl%d.%d", instance, i);
1011                if (!ifexists(checkif))
1012                        break;
1013
1014                sprintf(assoccmd, "wl -i %s assoclist", checkif);
1015
1016                if ((fp = popen(assoccmd, "r"))) {
1017                        gotit = 1;
1018                        while (fgets(line, sizeof(line), fp) != NULL) {
1019                                strcpy(list[0], "");
1020                                strcpy(list[1], "");
1021
1022                                if (sscanf(line, "%s %s", list[0], list[1]) != 2)       // assoclist
1023                                        // 00:11:22:33:44:55
1024                                        continue;
1025                                if (strcmp(list[0], "assoclist"))
1026                                        continue;
1027
1028                                wlmac =
1029                                    realloc(wlmac,
1030                                            sizeof(struct wl_assoc_mac) *
1031                                            (count + 1));
1032
1033                                memset(&wlmac[count], 0,
1034                                       sizeof(struct wl_assoc_mac));
1035                                strncpy(wlmac[count].mac, list[1],
1036                                        sizeof(wlmac[0].mac));
1037                                count++;
1038                        }
1039
1040                        pclose(fp);
1041                }
1042        }
1043
1044        if (gotit) {
1045                // cprintf("Count of wl assoclist mac is %d\n", count);
1046                *c = count;
1047                return wlmac;
1048        } else
1049                return NULL;
1050}
1051
1052struct mtu_lists mtu_list[] = {
1053#ifdef BUFFALO_JP
1054        {
1055         "pppoe", "576", "1454"},
1056#else
1057        {
1058         "pppoe", "576", "1492"},
1059#endif
1060        {
1061         "pppoa", "576", "10000"},
1062        {
1063         "pptp", "576", "1460"},
1064        {
1065         "l2tp", "576", "1460"},
1066        {
1067         "dhcp", "576", "10000"},
1068        {
1069         "static", "576", "10000"},
1070        {
1071         "heartbeat", "576", "1500"},
1072        {
1073         "3g", "576", "1500"},
1074        {
1075         "default", "576", "10000"},    // The value must be at last
1076};
1077
1078struct mtu_lists *get_mtu(char *proto)
1079{
1080        struct mtu_lists *v = NULL;
1081
1082        for (v = mtu_list; v < &mtu_list[STRUCT_LEN(mtu_list)]; v++) {
1083                if (!strcmp(proto, v->proto))
1084                        return v;
1085        }
1086        return v;               // Use default settings
1087}
1088
1089void set_host_domain_name(void)
1090{
1091        char *wan_hostname = nvram_safe_get("wan_hostname");
1092        char *wan_domain = nvram_safe_get("wan_domain");
1093
1094        /*
1095         * Allow you to use gethostname to get Host Name
1096         */
1097        /*
1098         * If wan_hostname is blank then we do nothing, we leave to what it was
1099         * set at boot
1100         */
1101        if (strlen(wan_hostname) > 0)
1102                sethostname(wan_hostname, strlen(wan_hostname));
1103
1104        /*
1105         * Allow you to use getdomainname to get Domain Name
1106         */
1107        if (strlen(wan_domain) > 0 && strlen(wan_domain) <= 64) // no
1108                // more
1109                // than
1110                // 64
1111                setdomainname(wan_domain, strlen(wan_domain));
1112        else {
1113                char *wan_get_domain = nvram_safe_get("wan_get_domain");
1114
1115                setdomainname(wan_get_domain, strlen(wan_get_domain));
1116        }
1117}
1118
1119int first_time(void)
1120{
1121        struct sysinfo info;
1122
1123        sysinfo(&info);
1124        if (info.uptime < 20L)
1125                return 1;
1126        return 0;
1127}
1128
1129#ifdef CDEBUG
1130int coreleft(void)
1131{
1132        struct sysinfo info;
1133
1134        sysinfo(&info);
1135        return info.freeram;
1136}
1137
1138int mcoreleft(void)
1139{
1140        struct mallinfo minfo;
1141
1142        minfo = mallinfo();
1143        return minfo.uordblks;
1144        // int uordblks; /* total allocated space */
1145
1146}
1147#endif
1148
1149#define sin_addr(s) (((struct sockaddr_in *)(s))->sin_addr)
1150
1151// #define WDS_DEBUG 1
1152#undef WDS_DEBUG
1153#ifdef WDS_DEBUG
1154FILE *fp;
1155#endif
1156
1157int wds_dev_config(int dev, int up)
1158{
1159        char wds_var[32] = "";
1160        char wds_enable_var[32] = "";
1161        char wds_dev[32] = "";
1162        char *wds = (void *)0;
1163        char wds_gw_var[32] = "";
1164        char *gw = (void *)0;
1165        int s = -1;
1166        struct ifreq ifr;
1167
1168#ifdef WDS_DEBUG
1169        fp = fopen("/tmp/.wds_debug.log", "a");
1170#endif
1171
1172        memset(&ifr, 0, sizeof(struct ifreq));
1173
1174        snprintf(wds_var, 31, "wl_wds%d", dev);
1175        snprintf(wds_enable_var, 31, "%s_enable", wds_var);
1176
1177        if ((wds = nvram_safe_get(wds_enable_var)) == NULL ||
1178            strcmp(wds, "0") == 0)
1179                return -1;
1180        snprintf(wds_dev, 31, "wds0.%d", dev + 1);
1181        snprintf(ifr.ifr_name, IFNAMSIZ, wds_dev);
1182#ifdef WDS_DEBUG
1183        fprintf(fp, "opening kernelsocket\n");
1184#endif
1185        if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
1186                return -1;
1187
1188        if (up) {
1189                char wds_hwaddr_var[32] = "";
1190                char wds_ip_var[32] = "";
1191                char wds_netmask_var[32] = "";
1192                char *wds_list = (void *)0;
1193                char *hwaddr = (void *)0;
1194                char *ip = (void *)0;
1195                char *netmask = (void *)0;
1196
1197#ifdef WDS_DEBUG
1198                fprintf(fp, "running up\n");
1199#endif
1200
1201                wds_list = nvram_safe_get("wl0_wds");
1202                if (wds_list == (void *)0 || strlen(wds_list) <= 0)
1203                        return 0;
1204
1205                snprintf(wds_hwaddr_var, 31, "%s_hwaddr", wds_var);
1206                snprintf(wds_ip_var, 31, "%s_ipaddr", wds_var);
1207                snprintf(wds_netmask_var, 31, "%s_netmask", wds_var);
1208
1209                hwaddr = nvram_safe_get(wds_hwaddr_var);
1210                ip = nvram_safe_get(wds_ip_var);
1211                netmask = nvram_safe_get(wds_netmask_var);
1212
1213                if (!strstr(wds_list, hwaddr)) {
1214                        close(s);
1215                        return -1;
1216                }
1217#ifdef WDS_DEBUG
1218                fprintf(fp, "checking validity\n");
1219#endif
1220
1221                if (!sv_valid_hwaddr(hwaddr) || !sv_valid_ipaddr(ip)
1222                    || !sv_valid_ipaddr(netmask)) {
1223                        close(s);
1224                        return -1;
1225                }
1226#ifdef WDS_DEBUG
1227                fprintf(fp, "valid mac %s ip %s nm %s\n", hwaddr, ip, netmask);
1228#endif
1229
1230                sysprintf("ifconfig %s down", wds_dev);
1231
1232                sysprintf("ifconfig %s %s netmask %s up", wds_dev, ip, netmask);
1233
1234                snprintf(wds_gw_var, 31, "%s_gw", wds_var);
1235                gw = nvram_safe_get(wds_gw_var);
1236                if (strcmp(gw, "0.0.0.0") != 0) {
1237                        get_network(ip, netmask);
1238                        route_del(wds_dev, 0, ip, gw, netmask);
1239                        route_add(wds_dev, 0, ip, gw, netmask);
1240                }
1241
1242        } else {
1243#ifdef WDS_DEBUG
1244                fprintf(fp, "running down\n");
1245#endif
1246                sysprintf("ifconfig %s down", wds_dev);
1247
1248        }
1249
1250#ifdef WDS_DEBUG
1251        fprintf(fp, "running ioctl\n");
1252        fclose(fp);
1253#endif
1254
1255        close(s);
1256
1257        return 0;
1258}
1259
1260int sv_valid_range(char *value, int low, int high)
1261{
1262        if (!isdigit(value[0]) || atoi(value) < low || atoi(value) > high)
1263                return FALSE;
1264        else
1265                return TRUE;
1266
1267}
1268
1269int sv_valid_statics(char *value)
1270{
1271        char ip[16] = {
1272                0
1273        }, mac[18] = {
1274        0}, hostname[255] = {
1275        0}, *p = value;
1276
1277        if (NULL == value)
1278                return FALSE;
1279
1280        do {
1281                while (isspace(*p++) && p - value < strlen(value)) ;
1282
1283                if (p - value >= strlen(value))
1284                        return FALSE;
1285
1286                if (sscanf(p, "%15s%17s%254s", ip, mac, hostname) < 3)
1287                        return FALSE;
1288
1289                if (!sv_valid_ipaddr(ip) || !sv_valid_hwaddr(mac)
1290                    || strlen(hostname) <= 0)
1291                        return FALSE;
1292
1293        }
1294        while ((p = strpbrk(p, "\n\r")) && p - value < strlen(value));
1295
1296        return TRUE;
1297}
1298
1299/*
1300 * Example: legal_ipaddr("192.168.1.1"); return true;
1301 * legal_ipaddr("192.168.1.1111"); return false;
1302 */
1303int sv_valid_ipaddr(char *value)
1304{
1305        struct in_addr ipaddr;
1306        int ip[4], ret = 0;
1307
1308        ret = sscanf(value, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]);
1309
1310        if (ret != 4 || !inet_aton(value, &ipaddr))
1311                return FALSE;
1312        else
1313                return TRUE;
1314
1315}
1316
1317// note - network address returned in ipaddr
1318void get_network(char *ipaddr, char *netmask)
1319{
1320        int ip[4], mask[4];
1321
1322        if (!ipaddr || !netmask)
1323                return;
1324
1325        sscanf(ipaddr, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]);
1326        sscanf(netmask, "%d.%d.%d.%d", &mask[0], &mask[1], &mask[2], &mask[3]);
1327
1328        ip[0] &= mask[0];
1329        ip[1] &= mask[1];
1330        ip[2] &= mask[2];
1331        ip[3] &= mask[3];
1332
1333        sprintf(ipaddr, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
1334#ifdef WDS_DEBUG
1335        fprintf(fp, "get_network return %s\n", ipaddr);
1336#endif
1337
1338}
1339
1340int get_net(char *netmask)
1341{
1342        if (!netmask)
1343                return -1;
1344        unsigned int mask[4];
1345        sscanf(netmask, "%d.%d.%d.%d", &mask[0], &mask[1], &mask[2], &mask[3]);
1346        unsigned int value = 0;
1347        value |= mask[0] << 24;
1348        value |= mask[1] << 16;
1349        value |= mask[2] << 8;
1350        value |= mask[3];
1351        unsigned int base = 0;
1352        unsigned int i;
1353        for (i = 0; i < 32; i++) {
1354                if ((value & (1 << i)) == (1 << i))
1355                        base++;
1356        }
1357        return base;
1358}
1359
1360/*
1361 * note: copied from Broadcom code and put in shared via this file
1362 */
1363
1364int
1365route_manip(int cmd, char *name, int metric, char *dst, char *gateway,
1366            char *genmask)
1367{
1368        int s;
1369        struct rtentry rt;
1370
1371        // dprintf("cmd=[%d] name=[%s] ipaddr=[%s] netmask=[%s] gateway=[%s]
1372        // metric=[%d]\n",cmd,name,dst,genmask,gateway,metric);
1373
1374        /*
1375         * Open a raw socket to the kernel
1376         */
1377        if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
1378                goto err;
1379
1380        /*
1381         * Fill in rtentry
1382         */
1383        memset(&rt, 0, sizeof(rt));
1384        if (dst)
1385                inet_aton(dst, &sin_addr(&rt.rt_dst));
1386        if (gateway)
1387                inet_aton(gateway, &sin_addr(&rt.rt_gateway));
1388        if (genmask)
1389                inet_aton(genmask, &sin_addr(&rt.rt_genmask));
1390        rt.rt_metric = metric;
1391        rt.rt_flags = RTF_UP;
1392        if (sin_addr(&rt.rt_gateway).s_addr)
1393                rt.rt_flags |= RTF_GATEWAY;
1394        if (sin_addr(&rt.rt_genmask).s_addr == INADDR_BROADCAST)
1395                rt.rt_flags |= RTF_HOST;
1396        rt.rt_dev = name;
1397
1398        /*
1399         * Force address family to AF_INET
1400         */
1401        rt.rt_dst.sa_family = AF_INET;
1402        rt.rt_gateway.sa_family = AF_INET;
1403        rt.rt_genmask.sa_family = AF_INET;
1404
1405        if (ioctl(s, cmd, &rt) < 0)
1406                goto err;
1407
1408        close(s);
1409        return 0;
1410
1411      err:close(s);
1412        perror(name);
1413        return errno;
1414}
1415
1416int route_add(char *name, int metric, char *dst, char *gateway, char *genmask)
1417{
1418        return route_manip(SIOCADDRT, name, metric, dst, gateway, genmask);
1419}
1420
1421int route_del(char *name, int metric, char *dst, char *gateway, char *genmask)
1422{
1423        return route_manip(SIOCDELRT, name, metric, dst, gateway, genmask);
1424}
1425
1426// #endif
1427
1428void getIfLists(char *eths, int size)
1429{
1430        char eths2[256];
1431
1432        memset(eths, 0, size);
1433        memset(eths2, 0, 256);
1434#ifdef HAVE_XSCALE
1435        getIfList(eths, "ixp");
1436        getIfList(eths2, "eth");
1437        sprintf(eths, "%s %s", eths, eths2);
1438#else
1439        getIfList(eths, "eth");
1440#endif
1441        memset(eths2, 0, 256);
1442        getIfList(eths2, "vlan");
1443        sprintf(eths, "%s %s", eths, eths2);
1444#ifdef HAVE_MADWIFI
1445        memset(eths2, 0, 256);
1446        getIfList(eths2, "ath");
1447        sprintf(eths, "%s %s", eths, eths2);
1448#elif defined(HAVE_RT2880) || defined(HAVE_RT61)
1449        memset(eths2, 0, 256);
1450        getIfList(eths2, "ra");
1451        sprintf(eths, "%s %s", eths, eths2);
1452
1453        memset(eths2, 0, 256);
1454        getIfList(eths2, "apcli");
1455        sprintf(eths, "%s %s", eths, eths2);
1456
1457        memset(eths2, 0, 256);
1458        getIfList(eths2, "wds");
1459        sprintf(eths, "%s %s", eths, eths2);
1460#else
1461        memset(eths2, 0, 256);
1462        getIfList(eths2, "wl");
1463        sprintf(eths, "%s %s", eths, eths2);
1464#endif
1465        memset(eths2, 0, 256);
1466        getIfList(eths2, "br");
1467        sprintf(eths, "%s %s", eths, eths2);
1468
1469        memset(eths2, 0, 256);
1470        getIfList(eths2, "oet");
1471        sprintf(eths, "%s %s", eths, eths2);
1472#ifdef HAVE_WAVESAT
1473        memset(eths2, 0, 256);
1474        getIfList(eths2, "ofdm");
1475        sprintf(eths, "%s %s", eths, eths2);
1476#endif
1477
1478}
1479
1480int contains(const char *string, char value)
1481{
1482        if (string == NULL)
1483                return 0;
1484        int len = strlen(string);
1485        int i;
1486
1487        for (i = 0; i < len; i++) {
1488                if (string[i] == value)
1489                        return 1;
1490        }
1491        return 0;
1492}
1493
1494int haswifi(void)
1495{
1496        int count=0;
1497#ifdef HAVE_NOWIFI
1498        return 0;
1499#elif defined(HAVE_ATH9K) || defined(HAVE_MADWIFI) || defined(HAVE_MADWIFI_MIMO)
1500        count+=getdevicecount();
1501        return(count);
1502#else
1503        return 1;
1504#endif
1505}
1506
1507static uint32_t str_to_addr(const char *addr)
1508{
1509        uint32_t split[4];
1510        uint32_t ip;
1511
1512        sscanf(addr, "%d.%d.%d.%d", &split[0], &split[1], &split[2], &split[3]);
1513
1514        ip = (split[0] << 24) | (split[1] << 16) | (split[2] << 8) | (split[3]);
1515
1516        return htonl(ip);
1517}
1518
1519void getHostName(char *buf, char *ip)
1520{
1521        struct hostent *host;
1522        struct in_addr addr;
1523
1524        res_init();
1525        addr.s_addr = str_to_addr(ip);
1526        host = gethostbyaddr((char *)&addr, 4, AF_INET);
1527        if (!host || !host->h_name)
1528                strcpy(buf, "unknown");
1529        else
1530                strcpy(buf, host->h_name);
1531}
1532
1533void getinterfacelist(const char *ifprefix, char *buffer)
1534{
1535        int count = getifcount(ifprefix);
1536        int i;
1537
1538        for (i = 0; i < count; i++) {
1539                char ifname[32];
1540
1541                sprintf(ifname, "%s%d", ifprefix, i);
1542                strcat(buffer, ifname);
1543                if (i < count - 1)
1544                        strcat(buffer, " ");
1545        }
1546}
1547
1548int softkill(char *name)
1549{
1550        killall(name, SIGKILL);
1551        return 0;
1552}
1553
1554
1555int getmask(char *nmask)
1556{
1557
1558        int loopmask = 0;
1559        int ip[4] = {
1560                0, 0, 0, 0
1561        };
1562
1563        sscanf(nmask, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]);
1564
1565        int n = 8;
1566
1567        for (--n; n >= 0; --n)  // test all 4 bytes in one pass
1568        {
1569                if (ip[0] & 1 << n)
1570                        loopmask++;
1571                if (ip[1] & 1 << n)
1572                        loopmask++;
1573                if (ip[2] & 1 << n)
1574                        loopmask++;
1575                if (ip[3] & 1 << n)
1576                        loopmask++;
1577        }
1578        return loopmask;
1579}
1580
1581int doMultiCast(void)
1582{
1583        char name[80], *next;
1584        int ifcount = 0;
1585
1586        if (nvram_match("wan_proto", "disabled"))
1587                return 0;
1588        if (nvram_match("block_multicast", "0")) {
1589                ifcount++;
1590        }
1591        char *lan_ifnames = nvram_safe_get("lan_ifnames");
1592
1593        foreach(name, lan_ifnames, next) {
1594                if (nvram_nmatch("1", "%s_multicast", name)
1595                    && nvram_nmatch("0", "%s_bridged", name)) {
1596                        ifcount++;
1597                }
1598        }
1599        return ifcount;
1600}
1601
1602static int sockaddr_to_dotted(struct sockaddr *saddr, char *buf)
1603{
1604        buf[0] = '\0';
1605        if (saddr->sa_family == AF_INET) {
1606                inet_ntop(AF_INET, &((struct sockaddr_in *)saddr)->sin_addr,
1607                          buf, 128);
1608                return 0;
1609        }
1610        if (saddr->sa_family == AF_INET6) {
1611                inet_ntop(AF_INET6, &((struct sockaddr_in6 *)saddr)->sin6_addr,
1612                          buf, 128);
1613                return 0;
1614        }
1615        return -1;
1616}
1617
1618static int sockaddr_to_dotted_n(char *sin_addr, char *buf)
1619{
1620        inet_ntop(AF_INET, sin_addr, buf, 128);
1621        return 0;
1622}
1623
1624#define DIE_ON_ERROR AI_CANONNAME
1625
1626void getIPFromName(char *name, char *ip)
1627{
1628        int count = 5;
1629        while (count--) {
1630                struct addrinfo *result = NULL;
1631                int rc;
1632                struct addrinfo hint;
1633                struct hostent *hp = gethostbyname(name);
1634                if (hp != NULL) {
1635                        sockaddr_to_dotted_n(hp->h_addr_list[0], ip);
1636                        if (strcmp(ip, "0.0.0.0"))
1637                                break;
1638                }
1639                res_init();
1640                memset(&hint, 0, sizeof(hint));
1641                hint.ai_family = AF_INET;
1642                hint.ai_socktype = SOCK_STREAM;
1643                hint.ai_flags = DIE_ON_ERROR;
1644                rc = getaddrinfo(name, NULL, &hint, &result);
1645                if (!result)    // give it a second try
1646                        rc = getaddrinfo(name, NULL, &hint, &result);
1647
1648                if (result) {
1649                        sockaddr_to_dotted(result->ai_addr, ip);
1650                        freeaddrinfo(result);
1651                } else {
1652                        struct hostent *hp = gethostbyname(name);
1653                        if (hp != NULL) {
1654                                sockaddr_to_dotted_n(hp->h_addr_list[0], ip);
1655                        } else
1656                                sprintf(ip, "0.0.0.0");
1657                }
1658                if (strcmp(ip, "0.0.0.0"))
1659                        break;
1660                sleep(1);
1661        }
1662
1663}
1664
1665/*
1666 * Example: legal_ip_netmask("192.168.1.1","255.255.255.0","192.168.1.100");
1667 * return true;
1668 * legal_ip_netmask("192.168.1.1","255.255.255.0","192.168.2.100"); return
1669 * false;
1670 */
1671int legal_ip_netmask(char *sip, char *smask, char *dip)
1672{
1673        struct in_addr ipaddr, netaddr, netmask;
1674        int tag;
1675
1676        inet_aton(nvram_safe_get(sip), &netaddr);
1677        inet_aton(nvram_safe_get(smask), &netmask);
1678        inet_aton(dip, &ipaddr);
1679
1680        netaddr.s_addr &= netmask.s_addr;
1681
1682        if (netaddr.s_addr != (ipaddr.s_addr & netmask.s_addr))
1683                tag = FALSE;
1684        else
1685                tag = TRUE;
1686
1687        return tag;
1688}
1689
1690/*
1691 * Example: ISDIGIT("", 0); return true; ISDIGIT("", 1); return false;
1692 * ISDIGIT("123", 1); return true;
1693 */
1694int ISDIGIT(char *value, int flag)
1695{
1696        int i, tag = TRUE;
1697
1698        if (!strcmp(value, "")) {
1699                if (flag)
1700                        return 0;       // null
1701                else
1702                        return 1;
1703        }
1704
1705        for (i = 0; *(value + i); i++) {
1706                if (!isdigit(*(value + i))) {
1707                        tag = FALSE;
1708                        break;
1709                }
1710        }
1711        return tag;
1712}
1713
1714void rep(char *in, char from, char to)
1715{
1716        int i;
1717        int slen = strlen(in);
1718
1719        for (i = 0; i < slen; i++)
1720                if (in[i] == from)
1721                        in[i] = to;
1722
1723}
1724
1725#include "l7protocols.h"
1726
1727char *get_filter_services(void)
1728{
1729
1730        l7filters *filters = filters_list;
1731        char temp[128] = "";
1732        char *proto[]= {"l7","p2p","dpi"};
1733        char *services=NULL;
1734
1735        while (filters->name)   // add l7 and p2p filters
1736        {
1737                sprintf(temp, "$NAME:%03d:%s$PROT:%03d:%s$PORT:003:0:0<&nbsp;>",
1738                        strlen(filters->name), filters->name,
1739                            filters->protocol == 0 ? 2 : 3,proto[filters->protocol]);
1740                if (!services)
1741                {
1742                    services = malloc(strlen(temp)+1);
1743                    services[0]=0;
1744                }else
1745                    services = realloc(services,strlen(services)+strlen(temp)+1);
1746                strcat(services, temp);
1747                filters++;
1748        }
1749        services = realloc(services, strlen(services)+strlen(nvram_safe_get("filter_services"))+1);
1750        strcat(services, nvram_safe_get("filter_services"));    // this is
1751        // user
1752        // defined
1753        // filters
1754        services = realloc(services, strlen(services)+strlen(nvram_safe_get("filter_services_1"))+1);
1755        strcat(services, nvram_safe_get("filter_services_1"));
1756
1757        return services;
1758}
1759
1760int endswith(char *str, char *cmp)
1761{
1762        int cmp_len, str_len, i;
1763
1764        if (cmp == NULL)
1765                return 0;
1766        if (str == NULL)
1767                return 0;
1768        cmp_len = strlen(cmp);
1769        str_len = strlen(str);
1770        if (cmp_len > str_len)
1771                return (0);
1772        for (i = 0; i < cmp_len; i++) {
1773                if (str[(str_len - 1) - i] != cmp[(cmp_len - 1) - i])
1774                        return (0);
1775        }
1776        return (1);
1777}
1778
1779int searchfor(FILE * fp, char *str, int scansize)
1780{
1781        char *buffer = safe_malloc(scansize);
1782        int len = fread(buffer, scansize, 1, fp);
1783        int i;
1784
1785        for (i = 0; i < len - strlen(str); i++) {
1786                if (memcmp(buffer + i, str, strlen(str)) == 0) {
1787                        fseek(fp, i + strlen(str), SEEK_SET);
1788                        free(buffer);
1789                        return 0;
1790                }
1791        }
1792        free(buffer);
1793        return -1;
1794}
1795
1796void addAction(char *action)
1797{
1798        char *actionstack = "";
1799        char *next;
1800        char service[80];
1801        if (action == NULL || strlen(action) == 0)
1802                return;
1803        char *services = nvram_safe_get("action_service");
1804
1805        foreach(service, services, next) {
1806                if (!strcmp(service, action)) {
1807                        return;
1808                }
1809        }
1810        if (strlen(services) > 0) {
1811                actionstack = safe_malloc(strlen(services) + strlen(action) + 2);
1812                memset(actionstack, 0, strlen(services) + strlen(action) + 2);
1813                strcpy(actionstack, action);
1814                strcat(actionstack, " ");
1815                strcat(actionstack, nvram_safe_get("action_service"));
1816                nvram_set("action_service", actionstack);
1817                free(actionstack);
1818        } else {
1819                nvram_set("action_service", action);
1820        }
1821
1822}
1823
1824int nvram_used(int *space)
1825{
1826        char *name, buf[NVRAM_SPACE];
1827       
1828        *space = NVRAM_SPACE;
1829
1830        nvram_getall(buf, sizeof(buf));
1831       
1832        name = buf;
1833       
1834        while (*name)
1835        {
1836                name += strlen(name) + 1;
1837        }
1838
1839        return (sizeof(struct nvram_header) + (int)name - (int)buf);
1840       
1841}
1842
1843
Note: See TracBrowser for help on using the repository browser.