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

Last change on this file since 17720 was 17720, checked in by BrainSlayer, 20 months ago

should solve pptp problems with static ip's

File size: 37.8 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 * by tallest
563 * =====================================================================================
564 */
565
566int get_int_len(int num)
567{
568        char buf[80];
569
570        snprintf(buf, sizeof(buf), "%d", num);
571
572        return strlen(buf);
573}
574
575#define READ_BUF_SIZE 254
576/*
577 * from busybox find_pid_by_name.c
578 */
579pid_t *find_pid_by_name(char *pidName)
580{
581        DIR *dir;
582        struct dirent *next;
583        pid_t *pidList = NULL;
584        int i = 0;
585
586        dir = opendir("/proc");
587
588        while ((next = readdir(dir)) != NULL) {
589                FILE *status;
590                char filename[READ_BUF_SIZE];
591                char buffer[READ_BUF_SIZE];
592                char name[READ_BUF_SIZE];
593
594                /*
595                 * Must skip ".." since that is outside /proc
596                 */
597                if (strcmp(next->d_name, "..") == 0)
598                        continue;
599
600                /*
601                 * If it isn't a number, we don't want it
602                 */
603                if (!isdigit(*next->d_name))
604                        continue;
605
606                sprintf(filename, "/proc/%s/status", next->d_name);
607                if (!(status = fopen(filename, "r"))) {
608                        continue;
609                }
610                if (fgets(buffer, READ_BUF_SIZE - 1, status) == NULL) {
611                        fclose(status);
612                        continue;
613                }
614                fclose(status);
615
616                /*
617                 * Buffer should contain a string like "Name: binary_name"
618                 */
619                sscanf(buffer, "%*s %s", name);
620                // printf("buffer=[%s] name=[%s]\n",buffer,name);
621                if (strcmp(name, pidName) == 0) {
622                        pidList = realloc(pidList, sizeof(pid_t) * (i + 2));
623                        pidList[i++] = strtol(next->d_name, NULL, 0);
624                }
625        }
626
627        if (pidList)
628                pidList[i] = 0;
629        else {
630                pidList = realloc(pidList, sizeof(pid_t));
631                pidList[0] = -1;
632        }
633        return pidList;
634
635}
636
637/*
638 * Find first process pid with same name from ps command
639 */
640int find_pid_by_ps(char *pidName)
641{
642        FILE *fp;
643        int pid = -1;
644        char line[254];
645
646        if ((fp = popen("ps", "r"))) {
647                while (fgets(line, sizeof(line), fp) != NULL) {
648                        if (strstr(line, pidName)) {
649                                sscanf(line, "%d", &pid);
650                                printf("%s pid is %d\n", pidName, pid);
651                                break;
652                        }
653                }
654                pclose(fp);
655        }
656
657        return pid;
658}
659
660/*
661 * Find all process pid with same name from ps command
662 */
663int *find_all_pid_by_ps(char *pidName)
664{
665        FILE *fp;
666        int pid = -1;
667        char line[254];
668        int *pidList = NULL;
669        int i = 0;
670
671        cprintf("Search for %s\n", pidName);
672        if ((fp = popen("ps", "r"))) {
673                while (fgets(line, sizeof(line), fp) != NULL) {
674                        if (strstr(line, pidName)) {
675                                sscanf(line, "%d", &pid);
676                                cprintf("%s pid is %d\n", pidName, pid);
677                                pidList =
678                                    realloc(pidList, sizeof(int) * (i + 2));
679                                pidList[i++] = pid;
680                        }
681                }
682                pclose(fp);
683        }
684        if (pidList)
685                pidList[i] = 0;
686        else {
687                pidList = realloc(pidList, sizeof(int));
688                pidList[0] = -1;
689        }
690        cprintf("Search done...\n");
691
692        return pidList;
693}
694
695void encode(char *buf, int len)
696{
697        int i;
698        char ch;
699
700        for (i = 0; i < len; i++) {
701                ch = (buf[i] & 0x03) << 6;
702                buf[i] = (buf[i] >> 2);
703                buf[i] &= 0x3f;
704                buf[i] |= ch;
705                buf[i] = ~buf[i];
706        }
707}
708
709void decode(char *buf, int len)
710{
711        int i;
712        char ch;
713
714        for (i = 0; i < len; i++) {
715                ch = (buf[i] & 0xC0) >> 6;
716                buf[i] = (buf[i] << 2) | ch;
717                buf[i] = ~buf[i];
718        }
719}
720
721/*
722 * v1.41.7 => 014107 v1.2 => 0102
723 */
724long convert_ver(char *ver)
725{
726        char buf[10];
727        int v[3];
728        int ret;
729
730        ret = sscanf(ver, "v%d.%d.%d", &v[0], &v[1], &v[2]);
731
732        if (ret == 2) {
733                snprintf(buf, sizeof(buf), "%02d%02d", v[0], v[1]);
734                return atol(buf);
735        } else if (ret == 3) {
736                snprintf(buf, sizeof(buf), "%02d%02d%02d", v[0], v[1], v[2]);
737                return atol(buf);
738        } else
739                return -1;
740}
741
742/*
743 * To avoid user to download old image that is not support intel flash to new
744 * hardware with intel flash.
745 */
746int check_flash(void)
747{
748        // The V2 image can support intel flash completely, so we don't want to
749        // check.
750        if (check_hw_type() == BCM4712_CHIP)
751                return FALSE;
752
753        // The V1.X some images cann't support intel flash, so we want to avoid
754        // user to downgrade.
755        if (nvram_match("skip_amd_check", "1")) {
756                if (strstr(nvram_safe_get("flash_type"), "Intel")
757                    && nvram_invmatch("skip_intel_check", "1"))
758                        return TRUE;
759                else
760                        return FALSE;
761        } else                  // Cann't downgrade to old firmware version,
762                // no matter AMD or Intel flash
763                return TRUE;
764}
765
766int check_now_boot(void)
767{
768        char *ver = nvram_safe_get("pmon_ver");
769        char *cfe = nvram_safe_get("CFEver");
770
771        // for 4712
772        // The boot_ver value is lower v2.0 (no included)
773        if (!strncmp(ver, "PMON", 4)) {
774                cprintf("The boot is PMON\n");
775                return PMON_BOOT;
776        }
777        // for 4712
778        // The boot_ver value is higher v2.0 (included)
779        else if (!strncmp(ver, "CFE", 3)) {
780                cprintf("The boot is CFE\n");
781                return CFE_BOOT;
782        } else if (!strncmp(ver, "2", 1)) {
783                cprintf("The boot is CFE %s\n", ver);
784                return CFE_BOOT;
785        } else if (!strncmp(cfe, "MotoWR", 6)) {
786                cprintf("The boot is Motorola CFE\n");
787                return CFE_BOOT;
788        } else {
789                cprintf("The boot is UNKNOWN\n");
790                return UNKNOWN_BOOT;
791        }
792}
793
794int check_hw_type(void)
795{
796
797        char *boardtype = nvram_safe_get("boardtype");
798        uint boardflags = strtoul(nvram_safe_get("boardflags"), NULL, 0);
799        uint btype = strtoul(boardtype, NULL, 0);
800        char *vlan0 = nvram_safe_get("vlan0ports");
801        char *vlan1 = nvram_safe_get("vlan1ports");
802
803        if (!strncmp(boardtype, "bcm94710", 8))
804                return BCM4702_CHIP;
805        else if (btype == 0x0708 && !(boardflags & BFL_ENETADM))
806                return BCM5325E_CHIP;
807        else if (btype == 0x456 && getRouterBrand() == ROUTER_BELKIN_F5D7231)   // stupid
808                // Belkin!
809                return BCM5352E_CHIP;
810        else if (btype == 0x456)
811                return BCM5350_CHIP;
812        else if (!strncmp(boardtype, "bcm95365", 8))
813                return BCM5365_CHIP;
814        else if (btype == 0x048e)
815                return BCM5354G_CHIP;
816        else if (btype == 0x042f && !(boardflags & BFL_ENETADM))
817                return BCM4704_BCM5325F_CHIP;
818        else if (btype == 0x478 && strstr(vlan0, "5*")) /* WRT300NV1.1 */
819                return BCM4705L_BCM5325E_EWC_CHIP;
820        else if ((btype == 0x478 && (strstr(vlan0, "8*") || strstr(vlan1, "8*"))) || nvram_match("boot_hw_model", "WRT350N") || nvram_match("boot_hw_model", "WRT610N"))        /* WRT350N
821                                                                                                                                                                                 */
822                return BCM4705_BCM5397_EWC_CHIP;
823        else if (btype == 0x489 || nvram_match("boot_hw_model", "WRT310N"))     /* WRT310N,
824                                                                                 * temporal
825                                                                                 * boardtype
826                                                                                 * 0x478,
827                                                                                 * wait
828                                                                                 * for
829                                                                                 * braodcom's
830                                                                                 * txt
831                                                                                 * file
832                                                                                 */
833                return BCM4705G_BCM5395S_EWC_CHIP;
834        else if (btype == 0x0467)
835                return BCM5352E_CHIP;
836        else if (btype == 0x0101 && !(boardflags & BFL_ENETADM))
837                return BCM4712_BCM5325E_CHIP;
838        else if ((btype == 0x0101 || btype == 0x0446) && (boardflags & BFL_ENETADM))    // 0x446
839                // is
840                // wap54g
841                // v2
842                return BCM4712_CHIP;
843        else if (btype == 0x0472 && !(boardflags & BFL_ENETADM))
844                return BCM4704_BCM5325F_EWC_CHIP;
845        else
846                return NO_DEFINE_CHIP;
847}
848
849int ct_openlog(const char *ident, int option, int facility, char *log_name)
850{
851        int level = atoi(nvram_safe_get(log_name));
852
853        switch (level) {
854        case CONSOLE_ONLY:
855                break;
856        }
857        return level;
858}
859
860void ct_syslog(int level, int enable, const char *fmt, ...)
861{
862        char buf[1000];
863        va_list args;
864
865        va_start(args, fmt);
866        vsnprintf(buf, sizeof(buf), fmt, args);
867        va_end(args);
868
869        switch (enable) {
870        case CONSOLE_ONLY:
871                cprintf("[%d] %s\n", getpid(), buf);    // print to console
872                break;
873        }
874}
875
876void ct_logger(int level, const char *fmt, ...)
877{
878}
879
880static char *device_name[] = {
881        "eth0", "qos0"
882};
883
884char *get_device_name(void)
885{
886        int i;
887
888        switch (check_hw_type()) {
889        case BCM5325E_CHIP:
890        case BCM5350_CHIP:
891        case BCM5365_CHIP:
892        case BCM4704_BCM5325F_CHIP:
893        case BCM4704_BCM5325F_EWC_CHIP:
894        case BCM5352E_CHIP:
895        case BCM5354G_CHIP:
896        case BCM4712_BCM5325E_CHIP:
897        case BCM4705L_BCM5325E_EWC_CHIP:
898                i = 0;
899                break;
900        case BCM4702_CHIP:
901        case BCM4712_CHIP:
902        default:
903                i = 1;
904                break;
905        }
906
907        return device_name[i];
908}
909
910char *strncpyz(char *dest, char const *src, size_t size)
911{
912        if (!size--)
913                return dest;
914        strncpy(dest, src, size);
915        dest[size] = 0;         /* Make sure the string is null terminated */
916        return dest;
917}
918
919static int sockets_open(int domain, int type, int protocol)
920{
921        int fd = socket(domain, type, protocol);
922
923        if (fd < 0)
924                cprintf("sockets_open: no usable address was found.\n");
925        return fd;
926}
927
928int
929sys_netdev_ioctl(int family, int socket, char *if_name, int cmd,
930                 struct ifreq *ifr)
931{
932        int rc, s;
933
934        if ((s = socket) < 0) {
935                if ((s =
936                     sockets_open(family,
937                                  family ==
938                                  AF_PACKET ? SOCK_PACKET : SOCK_DGRAM,
939                                  family == AF_PACKET ? htons(ETH_P_ALL) : 0)) <
940                    0) {
941                        cprintf("sys_netdev_ioctl: failed\n");
942                        return -1;
943                }
944        }
945        strncpyz(ifr->ifr_name, if_name, IFNAMSIZ);
946        rc = ioctl(s, cmd, ifr);
947        if (socket < 0)
948                close(s);
949        return rc;
950}
951
952int set_register_value(unsigned short port_addr, unsigned short option_content)
953{
954        struct ifreq ifr;
955        struct mii_ioctl_data stats;
956
957        stats.phy_id = port_addr;
958        stats.val_in = option_content;
959
960        ifr.ifr_data = (void *)&stats;
961
962        if (sys_netdev_ioctl
963            (AF_INET, -1, get_device_name(), SIOCSMIIREG, &ifr) < 0)
964                return -1;
965
966        return 0;
967}
968
969unsigned long get_register_value(unsigned short id, unsigned short num)
970{
971        struct ifreq ifr;
972        struct mii_ioctl_data stats;
973
974        stats.phy_id = id;
975        stats.reg_num = num;
976        stats.val_in = 0;
977        stats.val_out = 0;
978
979        ifr.ifr_data = (void *)&stats;
980
981        sys_netdev_ioctl(AF_INET, -1, get_device_name(), SIOCGMIIREG, &ifr);
982
983        return ((stats.val_in << 16) | stats.val_out);
984}
985
986struct wl_assoc_mac *get_wl_assoc_mac(int instance, int *c)
987{
988        FILE *fp;
989        struct wl_assoc_mac *wlmac = NULL;
990        int count;
991        char line[80];
992        char list[2][20];
993        char checkif[12];
994        char assoccmd[32];
995
996        wlmac = NULL;
997        count = *c = 0;
998
999        int ifcnt = 4;
1000        int i;
1001        int gotit = 0;
1002
1003        // fprintf(stderr,"assoclist\n");
1004
1005        for (i = 0; i < ifcnt; i++) {
1006                if (i == 0)
1007                        strcpy(checkif, get_wl_instance_name(instance));
1008                else
1009                        sprintf(checkif, "wl%d.%d", instance, i);
1010                if (!ifexists(checkif))
1011                        break;
1012
1013                sprintf(assoccmd, "wl -i %s assoclist", checkif);
1014
1015                if ((fp = popen(assoccmd, "r"))) {
1016                        gotit = 1;
1017                        while (fgets(line, sizeof(line), fp) != NULL) {
1018                                strcpy(list[0], "");
1019                                strcpy(list[1], "");
1020
1021                                if (sscanf(line, "%s %s", list[0], list[1]) != 2)       // assoclist
1022                                        // 00:11:22:33:44:55
1023                                        continue;
1024                                if (strcmp(list[0], "assoclist"))
1025                                        continue;
1026
1027                                wlmac =
1028                                    realloc(wlmac,
1029                                            sizeof(struct wl_assoc_mac) *
1030                                            (count + 1));
1031
1032                                memset(&wlmac[count], 0,
1033                                       sizeof(struct wl_assoc_mac));
1034                                strncpy(wlmac[count].mac, list[1],
1035                                        sizeof(wlmac[0].mac));
1036                                count++;
1037                        }
1038
1039                        pclose(fp);
1040                }
1041        }
1042
1043        if (gotit) {
1044                // cprintf("Count of wl assoclist mac is %d\n", count);
1045                *c = count;
1046                return wlmac;
1047        } else
1048                return NULL;
1049}
1050
1051struct mtu_lists mtu_list[] = {
1052#ifdef BUFFALO_JP
1053        {
1054         "pppoe", "576", "1454"},
1055#else
1056        {
1057         "pppoe", "576", "1492"},
1058#endif
1059        {
1060         "pppoa", "576", "10000"},
1061        {
1062         "pptp", "576", "1460"},
1063        {
1064         "l2tp", "576", "1460"},
1065        {
1066         "dhcp", "576", "10000"},
1067        {
1068         "static", "576", "10000"},
1069        {
1070         "heartbeat", "576", "1500"},
1071        {
1072         "3g", "576", "1500"},
1073        {
1074         "default", "576", "10000"},    // The value must be at last
1075};
1076
1077struct mtu_lists *get_mtu(char *proto)
1078{
1079        struct mtu_lists *v = NULL;
1080
1081        for (v = mtu_list; v < &mtu_list[STRUCT_LEN(mtu_list)]; v++) {
1082                if (!strcmp(proto, v->proto))
1083                        return v;
1084        }
1085        return v;               // Use default settings
1086}
1087
1088void set_host_domain_name(void)
1089{
1090        char *wan_hostname = nvram_safe_get("wan_hostname");
1091        char *wan_domain = nvram_safe_get("wan_domain");
1092
1093        /*
1094         * Allow you to use gethostname to get Host Name
1095         */
1096        /*
1097         * If wan_hostname is blank then we do nothing, we leave to what it was
1098         * set at boot
1099         */
1100        if (strlen(wan_hostname) > 0)
1101                sethostname(wan_hostname, strlen(wan_hostname));
1102
1103        /*
1104         * Allow you to use getdomainname to get Domain Name
1105         */
1106        if (strlen(wan_domain) > 0 && strlen(wan_domain) <= 64) // no
1107                // more
1108                // than
1109                // 64
1110                setdomainname(wan_domain, strlen(wan_domain));
1111        else {
1112                char *wan_get_domain = nvram_safe_get("wan_get_domain");
1113
1114                setdomainname(wan_get_domain, strlen(wan_get_domain));
1115        }
1116}
1117
1118int first_time(void)
1119{
1120        struct sysinfo info;
1121
1122        sysinfo(&info);
1123        if (info.uptime < 20L)
1124                return 1;
1125        return 0;
1126}
1127
1128#ifdef CDEBUG
1129int coreleft(void)
1130{
1131        struct sysinfo info;
1132
1133        sysinfo(&info);
1134        return info.freeram;
1135}
1136
1137int mcoreleft(void)
1138{
1139        struct mallinfo minfo;
1140
1141        minfo = mallinfo();
1142        return minfo.uordblks;
1143        // int uordblks; /* total allocated space */
1144
1145}
1146#endif
1147
1148#define sin_addr(s) (((struct sockaddr_in *)(s))->sin_addr)
1149
1150// #define WDS_DEBUG 1
1151#undef WDS_DEBUG
1152#ifdef WDS_DEBUG
1153FILE *fp;
1154#endif
1155
1156int wds_dev_config(int dev, int up)
1157{
1158        char wds_var[32] = "";
1159        char wds_enable_var[32] = "";
1160        char wds_dev[32] = "";
1161        char *wds = (void *)0;
1162        char wds_gw_var[32] = "";
1163        char *gw = (void *)0;
1164        int s = -1;
1165        struct ifreq ifr;
1166
1167#ifdef WDS_DEBUG
1168        fp = fopen("/tmp/.wds_debug.log", "a");
1169#endif
1170
1171        memset(&ifr, 0, sizeof(struct ifreq));
1172
1173        snprintf(wds_var, 31, "wl_wds%d", dev);
1174        snprintf(wds_enable_var, 31, "%s_enable", wds_var);
1175
1176        if ((wds = nvram_safe_get(wds_enable_var)) == NULL ||
1177            strcmp(wds, "0") == 0)
1178                return -1;
1179        snprintf(wds_dev, 31, "wds0.%d", dev + 1);
1180        snprintf(ifr.ifr_name, IFNAMSIZ, wds_dev);
1181#ifdef WDS_DEBUG
1182        fprintf(fp, "opening kernelsocket\n");
1183#endif
1184        if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
1185                return -1;
1186
1187        if (up) {
1188                char wds_hwaddr_var[32] = "";
1189                char wds_ip_var[32] = "";
1190                char wds_netmask_var[32] = "";
1191                char *wds_list = (void *)0;
1192                char *hwaddr = (void *)0;
1193                char *ip = (void *)0;
1194                char *netmask = (void *)0;
1195
1196#ifdef WDS_DEBUG
1197                fprintf(fp, "running up\n");
1198#endif
1199
1200                wds_list = nvram_safe_get("wl0_wds");
1201                if (wds_list == (void *)0 || strlen(wds_list) <= 0)
1202                        return 0;
1203
1204                snprintf(wds_hwaddr_var, 31, "%s_hwaddr", wds_var);
1205                snprintf(wds_ip_var, 31, "%s_ipaddr", wds_var);
1206                snprintf(wds_netmask_var, 31, "%s_netmask", wds_var);
1207
1208                hwaddr = nvram_safe_get(wds_hwaddr_var);
1209                ip = nvram_safe_get(wds_ip_var);
1210                netmask = nvram_safe_get(wds_netmask_var);
1211
1212                if (!strstr(wds_list, hwaddr)) {
1213                        close(s);
1214                        return -1;
1215                }
1216#ifdef WDS_DEBUG
1217                fprintf(fp, "checking validity\n");
1218#endif
1219
1220                if (!sv_valid_hwaddr(hwaddr) || !sv_valid_ipaddr(ip)
1221                    || !sv_valid_ipaddr(netmask)) {
1222                        close(s);
1223                        return -1;
1224                }
1225#ifdef WDS_DEBUG
1226                fprintf(fp, "valid mac %s ip %s nm %s\n", hwaddr, ip, netmask);
1227#endif
1228
1229                sysprintf("ifconfig %s down", wds_dev);
1230
1231                sysprintf("ifconfig %s %s netmask %s up", wds_dev, ip, netmask);
1232
1233                snprintf(wds_gw_var, 31, "%s_gw", wds_var);
1234                gw = nvram_safe_get(wds_gw_var);
1235                if (strcmp(gw, "0.0.0.0") != 0) {
1236                        get_network(ip, netmask);
1237                        route_del(wds_dev, 0, ip, gw, netmask);
1238                        route_add(wds_dev, 0, ip, gw, netmask);
1239                }
1240
1241        } else {
1242#ifdef WDS_DEBUG
1243                fprintf(fp, "running down\n");
1244#endif
1245                sysprintf("ifconfig %s down", wds_dev);
1246
1247        }
1248
1249#ifdef WDS_DEBUG
1250        fprintf(fp, "running ioctl\n");
1251        fclose(fp);
1252#endif
1253
1254        close(s);
1255
1256        return 0;
1257}
1258
1259int sv_valid_range(char *value, int low, int high)
1260{
1261        if (!isdigit(value[0]) || atoi(value) < low || atoi(value) > high)
1262                return FALSE;
1263        else
1264                return TRUE;
1265
1266}
1267
1268int sv_valid_statics(char *value)
1269{
1270        char ip[16] = {
1271                0
1272        }, mac[18] = {
1273        0}, hostname[255] = {
1274        0}, *p = value;
1275
1276        if (NULL == value)
1277                return FALSE;
1278
1279        do {
1280                while (isspace(*p++) && p - value < strlen(value)) ;
1281
1282                if (p - value >= strlen(value))
1283                        return FALSE;
1284
1285                if (sscanf(p, "%15s%17s%254s", ip, mac, hostname) < 3)
1286                        return FALSE;
1287
1288                if (!sv_valid_ipaddr(ip) || !sv_valid_hwaddr(mac)
1289                    || strlen(hostname) <= 0)
1290                        return FALSE;
1291
1292        }
1293        while ((p = strpbrk(p, "\n\r")) && p - value < strlen(value));
1294
1295        return TRUE;
1296}
1297
1298/*
1299 * Example: legal_ipaddr("192.168.1.1"); return true;
1300 * legal_ipaddr("192.168.1.1111"); return false;
1301 */
1302int sv_valid_ipaddr(char *value)
1303{
1304        struct in_addr ipaddr;
1305        int ip[4], ret = 0;
1306
1307        ret = sscanf(value, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]);
1308
1309        if (ret != 4 || !inet_aton(value, &ipaddr))
1310                return FALSE;
1311        else
1312                return TRUE;
1313
1314}
1315
1316// note - network address returned in ipaddr
1317void get_network(char *ipaddr, char *netmask)
1318{
1319        int ip[4], mask[4];
1320
1321        if (!ipaddr || !netmask)
1322                return;
1323
1324        sscanf(ipaddr, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]);
1325        sscanf(netmask, "%d.%d.%d.%d", &mask[0], &mask[1], &mask[2], &mask[3]);
1326
1327        ip[0] &= mask[0];
1328        ip[1] &= mask[1];
1329        ip[2] &= mask[2];
1330        ip[3] &= mask[3];
1331
1332        sprintf(ipaddr, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
1333#ifdef WDS_DEBUG
1334        fprintf(fp, "get_network return %s\n", ipaddr);
1335#endif
1336
1337}
1338
1339int get_net(char *netmask)
1340{
1341        if (!netmask)
1342                return -1;
1343        unsigned int mask[4];
1344        sscanf(netmask, "%d.%d.%d.%d", &mask[0], &mask[1], &mask[2], &mask[3]);
1345        unsigned int value = 0;
1346        value |= mask[0] << 24;
1347        value |= mask[1] << 16;
1348        value |= mask[2] << 8;
1349        value |= mask[3];
1350        unsigned int base = 0;
1351        unsigned int i;
1352        for (i = 0; i < 32; i++) {
1353                if ((value & (1 << i)) == (1 << i))
1354                        base++;
1355        }
1356        return base;
1357}
1358
1359/*
1360 * note: copied from Broadcom code and put in shared via this file
1361 */
1362
1363int
1364route_manip(int cmd, char *name, int metric, char *dst, char *gateway,
1365            char *genmask)
1366{
1367        int s;
1368        struct rtentry rt;
1369
1370        // dprintf("cmd=[%d] name=[%s] ipaddr=[%s] netmask=[%s] gateway=[%s]
1371        // metric=[%d]\n",cmd,name,dst,genmask,gateway,metric);
1372
1373        /*
1374         * Open a raw socket to the kernel
1375         */
1376        if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
1377                goto err;
1378
1379        /*
1380         * Fill in rtentry
1381         */
1382        memset(&rt, 0, sizeof(rt));
1383        if (dst)
1384                inet_aton(dst, &sin_addr(&rt.rt_dst));
1385        if (gateway)
1386                inet_aton(gateway, &sin_addr(&rt.rt_gateway));
1387        if (genmask)
1388                inet_aton(genmask, &sin_addr(&rt.rt_genmask));
1389        rt.rt_metric = metric;
1390        rt.rt_flags = RTF_UP;
1391        if (sin_addr(&rt.rt_gateway).s_addr)
1392                rt.rt_flags |= RTF_GATEWAY;
1393        if (sin_addr(&rt.rt_genmask).s_addr == INADDR_BROADCAST)
1394                rt.rt_flags |= RTF_HOST;
1395        rt.rt_dev = name;
1396
1397        /*
1398         * Force address family to AF_INET
1399         */
1400        rt.rt_dst.sa_family = AF_INET;
1401        rt.rt_gateway.sa_family = AF_INET;
1402        rt.rt_genmask.sa_family = AF_INET;
1403
1404        if (ioctl(s, cmd, &rt) < 0)
1405                goto err;
1406
1407        close(s);
1408        return 0;
1409
1410      err:close(s);
1411        perror(name);
1412        return errno;
1413}
1414
1415int route_add(char *name, int metric, char *dst, char *gateway, char *genmask)
1416{
1417        if (nvram_match("console_debug", "1"))
1418                fprintf(stderr, "route_add: if:%s dst:%s gw: %s mask: %s \n",
1419                        name, dst, gateway, genmask);
1420        return route_manip(SIOCADDRT, name, metric, dst, gateway, genmask);
1421}
1422
1423int route_del(char *name, int metric, char *dst, char *gateway, char *genmask)
1424{
1425        if (nvram_match("console_debug", "1"))
1426                fprintf(stderr, "route_del: if:%s dst:%s gw: %s mask: %s \n",
1427                        name, dst, gateway, genmask);
1428        return route_manip(SIOCDELRT, name, metric, dst, gateway, genmask);
1429}
1430
1431// #endif
1432
1433void getIfLists(char *eths, int size)
1434{
1435        char eths2[256];
1436
1437        memset(eths, 0, size);
1438        memset(eths2, 0, 256);
1439#ifdef HAVE_XSCALE
1440        getIfList(eths, "ixp");
1441        getIfList(eths2, "eth");
1442        sprintf(eths, "%s %s", eths, eths2);
1443#else
1444        getIfList(eths, "eth");
1445#endif
1446        memset(eths2, 0, 256);
1447        getIfList(eths2, "vlan");
1448        sprintf(eths, "%s %s", eths, eths2);
1449#ifdef HAVE_MADWIFI
1450        memset(eths2, 0, 256);
1451        getIfList(eths2, "ath");
1452        sprintf(eths, "%s %s", eths, eths2);
1453#elif defined(HAVE_RT2880) || defined(HAVE_RT61)
1454        memset(eths2, 0, 256);
1455        getIfList(eths2, "ra");
1456        sprintf(eths, "%s %s", eths, eths2);
1457
1458        memset(eths2, 0, 256);
1459        getIfList(eths2, "apcli");
1460        sprintf(eths, "%s %s", eths, eths2);
1461
1462        memset(eths2, 0, 256);
1463        getIfList(eths2, "wds");
1464        sprintf(eths, "%s %s", eths, eths2);
1465#else
1466        memset(eths2, 0, 256);
1467        getIfList(eths2, "wl");
1468        sprintf(eths, "%s %s", eths, eths2);
1469#endif
1470        memset(eths2, 0, 256);
1471        getIfList(eths2, "br");
1472        sprintf(eths, "%s %s", eths, eths2);
1473
1474        memset(eths2, 0, 256);
1475        getIfList(eths2, "oet");
1476        sprintf(eths, "%s %s", eths, eths2);
1477#ifdef HAVE_WAVESAT
1478        memset(eths2, 0, 256);
1479        getIfList(eths2, "ofdm");
1480        sprintf(eths, "%s %s", eths, eths2);
1481#endif
1482
1483}
1484
1485int contains(const char *string, char value)
1486{
1487        if (string == NULL)
1488                return 0;
1489        int len = strlen(string);
1490        int i;
1491
1492        for (i = 0; i < len; i++) {
1493                if (string[i] == value)
1494                        return 1;
1495        }
1496        return 0;
1497}
1498
1499int haswifi(void)
1500{
1501        int count = 0;
1502#ifdef HAVE_NOWIFI
1503        return 0;
1504#elif defined(HAVE_ATH9K) || defined(HAVE_MADWIFI) || defined(HAVE_MADWIFI_MIMO)
1505        count += getdevicecount();
1506        return (count);
1507#else
1508        return 1;
1509#endif
1510}
1511
1512static uint32_t str_to_addr(const char *addr)
1513{
1514        uint32_t split[4];
1515        uint32_t ip;
1516
1517        sscanf(addr, "%d.%d.%d.%d", &split[0], &split[1], &split[2], &split[3]);
1518
1519        ip = (split[0] << 24) | (split[1] << 16) | (split[2] << 8) | (split[3]);
1520
1521        return htonl(ip);
1522}
1523
1524void getHostName(char *buf, char *ip)
1525{
1526        struct hostent *host;
1527        struct in_addr addr;
1528
1529        res_init();
1530        addr.s_addr = str_to_addr(ip);
1531        host = gethostbyaddr((char *)&addr, 4, AF_INET);
1532        if (!host || !host->h_name)
1533                strcpy(buf, "unknown");
1534        else
1535                strcpy(buf, host->h_name);
1536}
1537
1538void getinterfacelist(const char *ifprefix, char *buffer)
1539{
1540        int count = getifcount(ifprefix);
1541        int i;
1542
1543        for (i = 0; i < count; i++) {
1544                char ifname[32];
1545
1546                sprintf(ifname, "%s%d", ifprefix, i);
1547                strcat(buffer, ifname);
1548                if (i < count - 1)
1549                        strcat(buffer, " ");
1550        }
1551}
1552
1553int softkill(char *name)
1554{
1555        killall(name, SIGKILL);
1556        return 0;
1557}
1558
1559int getmask(char *nmask)
1560{
1561
1562        int loopmask = 0;
1563        int ip[4] = {
1564                0, 0, 0, 0
1565        };
1566
1567        sscanf(nmask, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]);
1568
1569        int n = 8;
1570
1571        for (--n; n >= 0; --n)  // test all 4 bytes in one pass
1572        {
1573                if (ip[0] & 1 << n)
1574                        loopmask++;
1575                if (ip[1] & 1 << n)
1576                        loopmask++;
1577                if (ip[2] & 1 << n)
1578                        loopmask++;
1579                if (ip[3] & 1 << n)
1580                        loopmask++;
1581        }
1582        return loopmask;
1583}
1584
1585int doMultiCast(void)
1586{
1587        char name[80], *next;
1588        int ifcount = 0;
1589
1590        if (nvram_match("wan_proto", "disabled"))
1591                return 0;
1592        if (nvram_match("block_multicast", "0")) {
1593                ifcount++;
1594        }
1595        char *lan_ifnames = nvram_safe_get("lan_ifnames");
1596
1597        foreach(name, lan_ifnames, next) {
1598                if (nvram_nmatch("1", "%s_multicast", name)
1599                    && nvram_nmatch("0", "%s_bridged", name)) {
1600                        ifcount++;
1601                }
1602        }
1603        return ifcount;
1604}
1605
1606static int sockaddr_to_dotted(struct sockaddr *saddr, char *buf)
1607{
1608        buf[0] = '\0';
1609        if (saddr->sa_family == AF_INET) {
1610                inet_ntop(AF_INET, &((struct sockaddr_in *)saddr)->sin_addr,
1611                          buf, 128);
1612                return 0;
1613        }
1614        if (saddr->sa_family == AF_INET6) {
1615                inet_ntop(AF_INET6, &((struct sockaddr_in6 *)saddr)->sin6_addr,
1616                          buf, 128);
1617                return 0;
1618        }
1619        return -1;
1620}
1621
1622static int sockaddr_to_dotted_n(char *sin_addr, char *buf)
1623{
1624        inet_ntop(AF_INET, sin_addr, buf, 128);
1625        return 0;
1626}
1627
1628#define DIE_ON_ERROR AI_CANONNAME
1629
1630void getIPFromName(char *name, char *ip)
1631{
1632        int count = 5;
1633        while (count--) {
1634                struct addrinfo *result = NULL;
1635                int rc;
1636                struct addrinfo hint;
1637                struct hostent *hp = gethostbyname(name);
1638                if (hp != NULL) {
1639                        sockaddr_to_dotted_n(hp->h_addr_list[0], ip);
1640                        if (strcmp(ip, "0.0.0.0"))
1641                                break;
1642                }
1643                res_init();
1644                memset(&hint, 0, sizeof(hint));
1645                hint.ai_family = AF_INET;
1646                hint.ai_socktype = SOCK_STREAM;
1647                hint.ai_flags = DIE_ON_ERROR;
1648                rc = getaddrinfo(name, NULL, &hint, &result);
1649                if (!result)    // give it a second try
1650                        rc = getaddrinfo(name, NULL, &hint, &result);
1651
1652                if (result) {
1653                        sockaddr_to_dotted(result->ai_addr, ip);
1654                        freeaddrinfo(result);
1655                } else {
1656                        struct hostent *hp = gethostbyname(name);
1657                        if (hp != NULL) {
1658                                sockaddr_to_dotted_n(hp->h_addr_list[0], ip);
1659                        } else
1660                                sprintf(ip, "0.0.0.0");
1661                }
1662                if (strcmp(ip, "0.0.0.0"))
1663                        break;
1664                sleep(1);
1665        }
1666
1667}
1668
1669/*
1670 * Example: legal_ip_netmask("192.168.1.1","255.255.255.0","192.168.1.100");
1671 * return true;
1672 * legal_ip_netmask("192.168.1.1","255.255.255.0","192.168.2.100"); return
1673 * false;
1674 */
1675int legal_ip_netmask(char *sip, char *smask, char *dip)
1676{
1677        struct in_addr ipaddr, netaddr, netmask;
1678        int tag;
1679
1680        inet_aton(nvram_safe_get(sip), &netaddr);
1681        inet_aton(nvram_safe_get(smask), &netmask);
1682        inet_aton(dip, &ipaddr);
1683
1684        netaddr.s_addr &= netmask.s_addr;
1685
1686        if (netaddr.s_addr != (ipaddr.s_addr & netmask.s_addr))
1687                tag = FALSE;
1688        else
1689                tag = TRUE;
1690
1691        return tag;
1692}
1693
1694/*
1695 * Example: ISDIGIT("", 0); return true; ISDIGIT("", 1); return false;
1696 * ISDIGIT("123", 1); return true;
1697 */
1698int ISDIGIT(char *value, int flag)
1699{
1700        int i, tag = TRUE;
1701
1702        if (!strcmp(value, "")) {
1703                if (flag)
1704                        return 0;       // null
1705                else
1706                        return 1;
1707        }
1708
1709        for (i = 0; *(value + i); i++) {
1710                if (!isdigit(*(value + i))) {
1711                        tag = FALSE;
1712                        break;
1713                }
1714        }
1715        return tag;
1716}
1717
1718void rep(char *in, char from, char to)
1719{
1720        int i;
1721        int slen = strlen(in);
1722
1723        for (i = 0; i < slen; i++)
1724                if (in[i] == from)
1725                        in[i] = to;
1726
1727}
1728
1729#include "l7protocols.h"
1730
1731char *get_filter_services(void)
1732{
1733
1734        l7filters *filters = filters_list;
1735        char temp[128] = "";
1736        char *proto[] = { "l7", "p2p", "dpi" };
1737        char *services = NULL;
1738
1739        while (filters->name)   // add l7 and p2p filters
1740        {
1741                sprintf(temp, "$NAME:%03d:%s$PROT:%03d:%s$PORT:003:0:0<&nbsp;>",
1742                        strlen(filters->name), filters->name,
1743                        filters->protocol == 0 ? 2 : 3,
1744                        proto[filters->protocol]);
1745                if (!services) {
1746                        services = malloc(strlen(temp) + 1);
1747                        services[0] = 0;
1748                } else
1749                        services =
1750                            realloc(services,
1751                                    strlen(services) + strlen(temp) + 1);
1752                strcat(services, temp);
1753                filters++;
1754        }
1755        services =
1756            realloc(services,
1757                    strlen(services) +
1758                    strlen(nvram_safe_get("filter_services")) + 1);
1759        strcat(services, nvram_safe_get("filter_services"));    // this is
1760        // user
1761        // defined
1762        // filters
1763        services =
1764            realloc(services,
1765                    strlen(services) +
1766                    strlen(nvram_safe_get("filter_services_1")) + 1);
1767        strcat(services, nvram_safe_get("filter_services_1"));
1768
1769        return services;
1770}
1771
1772int endswith(char *str, char *cmp)
1773{
1774        int cmp_len, str_len, i;
1775
1776        if (cmp == NULL)
1777                return 0;
1778        if (str == NULL)
1779                return 0;
1780        cmp_len = strlen(cmp);
1781        str_len = strlen(str);
1782        if (cmp_len > str_len)
1783                return (0);
1784        for (i = 0; i < cmp_len; i++) {
1785                if (str[(str_len - 1) - i] != cmp[(cmp_len - 1) - i])
1786                        return (0);
1787        }
1788        return (1);
1789}
1790
1791int searchfor(FILE * fp, char *str, int scansize)
1792{
1793        char *buffer = safe_malloc(scansize);
1794        int len = fread(buffer, scansize, 1, fp);
1795        int i;
1796
1797        for (i = 0; i < len - strlen(str); i++) {
1798                if (memcmp(buffer + i, str, strlen(str)) == 0) {
1799                        fseek(fp, i + strlen(str), SEEK_SET);
1800                        free(buffer);
1801                        return 0;
1802                }
1803        }
1804        free(buffer);
1805        return -1;
1806}
1807
1808void addAction(char *action)
1809{
1810        char *actionstack = "";
1811        char *next;
1812        char service[80];
1813        if (action == NULL || strlen(action) == 0)
1814                return;
1815        char *services = nvram_safe_get("action_service");
1816
1817        foreach(service, services, next) {
1818                if (!strcmp(service, action)) {
1819                        return;
1820                }
1821        }
1822        if (strlen(services) > 0) {
1823                actionstack =
1824                    safe_malloc(strlen(services) + strlen(action) + 2);
1825                memset(actionstack, 0, strlen(services) + strlen(action) + 2);
1826                strcpy(actionstack, action);
1827                strcat(actionstack, " ");
1828                strcat(actionstack, nvram_safe_get("action_service"));
1829                nvram_set("action_service", actionstack);
1830                free(actionstack);
1831        } else {
1832                nvram_set("action_service", action);
1833        }
1834
1835}
1836
1837int nvram_used(int *space)
1838{
1839        char *name, buf[NVRAM_SPACE];
1840
1841        *space = NVRAM_SPACE;
1842
1843        nvram_getall(buf, sizeof(buf));
1844
1845        name = buf;
1846
1847        while (*name) {
1848                name += strlen(name) + 1;
1849        }
1850
1851        return (sizeof(struct nvram_header) + (int)name - (int)buf);
1852
1853}
Note: See TracBrowser for help on using the repository browser.