OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [net/] [common/] [current/] [tests/] [bridge.c] - Blame information for rev 856

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      tests/bridge.c
4
//
5
//     
6
//
7
//==========================================================================
8
// ####BSDALTCOPYRIGHTBEGIN####                                             
9
// -------------------------------------------                              
10
// Portions of this software may have been derived from FreeBSD, OpenBSD,   
11
// or other sources, and if so are covered by the appropriate copyright     
12
// and license included herein.                                             
13
// -------------------------------------------                              
14
// ####BSDALTCOPYRIGHTEND####                                               
15
//==========================================================================
16
//#####DESCRIPTIONBEGIN####
17
//
18
// Author(s):    Jason L. Wright (jason@thought.net)
19
// Contributors: andrew.lunn@ascom.ch (Andrew Lunn), hmt
20
// Date:         2000-01-10
21
// Purpose:      
22
// Description:  
23
//              
24
//
25
//####DESCRIPTIONEND####
26
//
27
//==========================================================================
28
 
29
 
30
/*      $OpenBSD: brconfig.c,v 1.6 2000/02/04 06:32:04 deraadt Exp $    */
31
 
32
/*
33
 * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
34
 * All rights reserved.
35
 *
36
 * Redistribution and use in source and binary forms, with or without
37
 * modification, are permitted provided that the following conditions
38
 * are met:
39
 * 1. Redistributions of source code must retain the above copyright
40
 *    notice, this list of conditions and the following disclaimer.
41
 * 2. Redistributions in binary form must reproduce the above copyright
42
 *    notice, this list of conditions and the following disclaimer in the
43
 *    documentation and/or other materials provided with the distribution.
44
 * 3. All advertising materials mentioning features or use of this software
45
 *    must display the following acknowledgement:
46
 *      This product includes software developed by Jason L. Wright
47
 * 4. The name of the author may not be used to endorse or promote products
48
 *    derived from this software without specific prior written permission.
49
 *
50
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
51
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
52
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
53
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
54
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
55
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
56
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
58
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
59
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
60
 * POSSIBILITY OF SUCH DAMAGE.
61
 */
62
 
63
#include <stdio.h>
64
#include <network.h>
65
#include <sys/types.h>
66
#include <stdlib.h>
67
 
68
#ifdef CYGPKG_NET_BRIDGE_HANDLER
69
#include <net/if.h>
70
#include <net/if_dl.h>
71
#include <netinet/in.h>
72
#include <netinet/if_ether.h>
73
#include <net/if_bridge.h>
74
#include <sys/errno.h>
75
#include <string.h>
76
#include <stdlib.h>
77
#include <limits.h>
78
#include <assert.h>
79
#include <ctype.h>
80
 
81
void bridge_usage __P((void));
82
int main __P((int, char **));
83
int bridge_setflag __P((int, char *, short));
84
int bridge_clrflag __P((int, char *, short));
85
int bridge_ifsetflag __P((int, char *, char *, u_int32_t));
86
int bridge_ifclrflag __P((int, char *, char *, u_int32_t));
87
int bridge_list __P((int, char *, char *));
88
int bridge_addrs __P((int, char *, char *));
89
int bridge_addaddr __P((int, char *, char *, char *));
90
int bridge_deladdr __P((int, char *, char *));
91
int bridge_maxaddr __P((int, char *, char *));
92
int bridge_timeout __P((int, char *, char *));
93
int bridge_flush __P((int, char *));
94
int bridge_flushall __P((int, char *));
95
int bridge_add __P((int, char *, char *));
96
int bridge_delete __P((int, char *, char *));
97
int bridge_status __P((int, char *));
98
int is_bridge __P((int, char *));
99
int bridge_show_all __P((int));
100
void printb __P((char *, unsigned short, char *));
101
int bridge_rule __P((int, char *, int, char **, int));
102
int bridge_rules __P((int, char *, char *, char *));
103
int bridge_flush_rule __P((int, char *, char *));
104
void bridge_badrule __P((int, char **, int));
105
void bridge_showrule __P((struct ifbrlreq *, char *));
106
int bridge_rulefile __P((int, char *, char *));
107
 
108
/* if_flags bits: borrowed from ifconfig.c */
109
#define IFFBITS \
110
"\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\
111
\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2\20MULTICAST"
112
 
113
#define IFBAFBITS       "\020\1STATIC"
114
#define IFBIFBITS       "\020\1LEARNING\2DISCOVER\3BLOCKNONIP\4BLOCKARP"
115
 
116
#define warnx(x) diag_printf(x);
117
#define warnx2(x,y) diag_printf(x,y) 
118
#define warnx3(x,y,z) diag_printf(x,y,z) 
119
#define err(x,y) assert(0);
120
extern  int cyg_kmem_print_stats(void);
121
 
122
static char * _ether_aton __P((char *, struct ether_addr *));
123
 
124
char *
125
ether_ntoa(e)
126
        struct ether_addr *e;
127
{
128
        static char a[] = "xx:xx:xx:xx:xx:xx";
129
 
130
        if (e->ether_addr_octet[0] > 0xFF || e->ether_addr_octet[1] > 0xFF ||
131
            e->ether_addr_octet[2] > 0xFF || e->ether_addr_octet[3] > 0xFF ||
132
            e->ether_addr_octet[4] > 0xFF || e->ether_addr_octet[5] > 0xFF) {
133
                errno = EINVAL;
134
                return (NULL);
135
        }
136
 
137
        (void)sprintf(a, "%02x:%02x:%02x:%02x:%02x:%02x",
138
            e->ether_addr_octet[0], e->ether_addr_octet[1],
139
            e->ether_addr_octet[2], e->ether_addr_octet[3],
140
            e->ether_addr_octet[4], e->ether_addr_octet[5]);
141
 
142
        return (a);
143
}
144
 
145
static char *
146
_ether_aton(s, e)
147
        char *s;
148
        struct ether_addr *e;
149
{
150
        int i;
151
        long l;
152
        char *pp;
153
 
154
        while (isspace(*s))
155
                s++;
156
 
157
        /* expect 6 hex octets separated by ':' or space/NUL if last octet */
158
        for (i = 0; i < 6; i++) {
159
                l = strtol(s, &pp, 16);
160
                if (pp == s || l > 0xFF || l < 0)
161
                        return (NULL);
162
                if (!(*pp == ':' || (i == 5 && (isspace(*pp) || *pp == '\0'))))
163
                        return (NULL);
164
                e->ether_addr_octet[i] = (u_char)l;
165
                s = pp + 1;
166
        }
167
 
168
        /* return character after the octets ala strtol(3) */
169
        return (pp);
170
}
171
 
172
struct ether_addr *
173
ether_aton(s)
174
        char *s;
175
{
176
        static struct ether_addr n;
177
 
178
        return (_ether_aton(s, &n) ? &n : NULL);
179
}
180
 
181
void
182
bridge_usage()
183
{
184
        diag_printf("usage: brconfig -a\n");
185
        diag_printf(
186
            "usage: brconfig interface [up] [down] [add if] [del if] ...\n");
187
}
188
 
189
 
190
int
191
bridge_ifsetflag(s, brdg, ifsname, flag)
192
        int s;
193
        char *brdg, *ifsname;
194
        u_int32_t flag;
195
{
196
        struct ifbreq req;
197
 
198
        strncpy(req.ifbr_name, brdg, sizeof(req.ifbr_name));
199
        strncpy(req.ifbr_ifsname, ifsname, sizeof(req.ifbr_ifsname));
200
        if (ioctl(s, SIOCBRDGGIFFLGS, (caddr_t)&req) < 0) {
201
                return (1);
202
        }
203
 
204
        req.ifbr_ifsflags |= flag;
205
 
206
        if (ioctl(s, SIOCBRDGSIFFLGS, (caddr_t)&req) < 0) {
207
                warnx3("%s: %s", brdg, ifsname);
208
                return (1);
209
        }
210
        return (0);
211
}
212
 
213
int
214
bridge_ifclrflag(s, brdg, ifsname, flag)
215
        int s;
216
        char *brdg, *ifsname;
217
        u_int32_t flag;
218
{
219
        struct ifbreq req;
220
 
221
        strncpy(req.ifbr_name, brdg, sizeof(req.ifbr_name));
222
        strncpy(req.ifbr_ifsname, ifsname, sizeof(req.ifbr_ifsname));
223
 
224
        if (ioctl(s, SIOCBRDGGIFFLGS, (caddr_t)&req) < 0) {
225
                warnx3("%s: %s", brdg, ifsname);
226
                return (1);
227
        }
228
 
229
        req.ifbr_ifsflags &= ~flag;
230
 
231
        if (ioctl(s, SIOCBRDGSIFFLGS, (caddr_t)&req) < 0) {
232
                warnx3("%s: %s", brdg, ifsname);
233
                return (1);
234
        }
235
        return (0);
236
}
237
 
238
int
239
bridge_show_all(s)
240
        int s;
241
{
242
        char *inbuf = NULL;
243
        struct ifconf ifc;
244
        struct ifreq *ifrp, ifreq;
245
        int len = 8192, i;
246
 
247
        while (1) {
248
                ifc.ifc_len = len;
249
                ifc.ifc_buf = inbuf = realloc(inbuf, len);
250
                if (inbuf == NULL)
251
                        err(1, "malloc");
252
                if (ioctl(s, SIOCGIFCONF, &ifc) < 0)
253
                        err(1, "ioctl(SIOCGIFCONF)");
254
                if (ifc.ifc_len + sizeof(struct ifreq) < len)
255
                        break;
256
                len *= 2;
257
        }
258
        ifrp = ifc.ifc_req;
259
        ifreq.ifr_name[0] = '\0';
260
        for (i = 0; i < ifc.ifc_len; ) {
261
                ifrp = (struct ifreq *)((caddr_t)ifc.ifc_req + i);
262
                i += sizeof(ifrp->ifr_name) +
263
                    (ifrp->ifr_addr.sa_len > sizeof(struct sockaddr) ?
264
                    ifrp->ifr_addr.sa_len : sizeof(struct sockaddr));
265
                if (ifrp->ifr_addr.sa_family != AF_LINK)
266
                        continue;
267
                if (!is_bridge(s, ifrp->ifr_name))
268
                        continue;
269
                bridge_status(s, ifrp->ifr_name);
270
        }
271
        free(ifc.ifc_buf);
272
        return (0);
273
}
274
 
275
int
276
bridge_setflag(s, brdg, f)
277
        int s;
278
        char *brdg;
279
        short f;
280
{
281
        struct ifreq ifr;
282
 
283
        strncpy(ifr.ifr_name, brdg, sizeof(ifr.ifr_name));
284
 
285
        if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
286
                warnx2("%s", brdg);
287
                if (errno == EPERM)
288
                        return (1);
289
                return (1);
290
        }
291
 
292
        ifr.ifr_flags |= f;
293
 
294
        if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) {
295
                warnx2("%s", brdg);
296
                if (errno == EPERM)
297
                        return (1);
298
                return (1);
299
        }
300
 
301
        return (0);
302
}
303
 
304
int
305
bridge_clrflag(s, brdg, f)
306
        int s;
307
        char *brdg;
308
        short f;
309
{
310
        struct ifreq ifr;
311
 
312
        strncpy(ifr.ifr_name, brdg, sizeof(ifr.ifr_name));
313
 
314
        if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
315
                warnx2("%s", brdg);
316
                if (errno == EPERM)
317
                        return (1);
318
                return (1);
319
        }
320
 
321
        ifr.ifr_flags &= ~(f);
322
 
323
        if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) {
324
                warnx2("%s", brdg);
325
                if (errno == EPERM)
326
                        return (1);
327
                return (1);
328
        }
329
 
330
        return (0);
331
}
332
 
333
int
334
bridge_flushall(s, brdg)
335
        int s;
336
        char *brdg;
337
{
338
        struct ifbreq req;
339
 
340
        strncpy(req.ifbr_name, brdg, sizeof(req.ifbr_name));
341
        req.ifbr_ifsflags = IFBF_FLUSHALL;
342
        if (ioctl(s, SIOCBRDGFLUSH, &req) < 0) {
343
                warnx2("%s", brdg);
344
                return (1);
345
        }
346
        return (0);
347
}
348
 
349
int
350
bridge_flush(s, brdg)
351
        int s;
352
        char *brdg;
353
{
354
        struct ifbreq req;
355
 
356
        strncpy(req.ifbr_name, brdg, sizeof(req.ifbr_name));
357
        req.ifbr_ifsflags = IFBF_FLUSHDYN;
358
        if (ioctl(s, SIOCBRDGFLUSH, &req) < 0) {
359
                warnx2("%s", brdg);
360
                return (1);
361
        }
362
        return (0);
363
}
364
 
365
int
366
bridge_list(s, brdg, delim)
367
        int s;
368
        char *brdg, *delim;
369
{
370
        struct ifbreq *reqp;
371
        struct ifbifconf bifc;
372
        int i, len = 8192;
373
        char buf[sizeof(reqp->ifbr_ifsname) + 1], *inbuf = NULL;
374
 
375
        while (1) {
376
                strncpy(bifc.ifbic_name, brdg, sizeof(bifc.ifbic_name));
377
                bifc.ifbic_len = len;
378
                bifc.ifbic_buf = inbuf = realloc(inbuf, len);
379
                if (inbuf == NULL)
380
                        err(1, "malloc");
381
                if (ioctl(s, SIOCBRDGIFS, &bifc) < 0)
382
                        err(1, brdg);
383
                if (bifc.ifbic_len + sizeof(*reqp) < len)
384
                        break;
385
                len *= 2;
386
        }
387
        for (i = 0; i < bifc.ifbic_len / sizeof(*reqp); i++) {
388
                reqp = bifc.ifbic_req + i;
389
                strncpy(buf, reqp->ifbr_ifsname, sizeof(buf));
390
                diag_printf("%s%s ", delim, buf);
391
                printb("flags", reqp->ifbr_ifsflags, IFBIFBITS);
392
                diag_printf("\n");
393
                bridge_rules(s, brdg, buf, delim);
394
        }
395
        free(bifc.ifbic_buf);
396
        return (0);             /* NOTREACHED */
397
}
398
 
399
int
400
bridge_add(s, brdg, ifn)
401
        int s;
402
        char *brdg, *ifn;
403
{
404
        struct ifbreq req;
405
 
406
        strncpy(req.ifbr_name, brdg, sizeof(req.ifbr_name));
407
        strncpy(req.ifbr_ifsname, ifn, sizeof(req.ifbr_ifsname));
408
        if (ioctl(s, SIOCBRDGADD, &req) < 0) {
409
                warnx3("%s: %s", brdg, ifn);
410
                if (errno == EPERM)
411
                        return (1);
412
                return (1);
413
        }
414
        return (0);
415
}
416
 
417
int
418
bridge_delete(s, brdg, ifn)
419
        int s;
420
        char *brdg, *ifn;
421
{
422
        struct ifbreq req;
423
 
424
        strncpy(req.ifbr_name, brdg, sizeof(req.ifbr_name));
425
        strncpy(req.ifbr_ifsname, ifn, sizeof(req.ifbr_ifsname));
426
        if (ioctl(s, SIOCBRDGDEL, &req) < 0) {
427
                warnx3("%s: %s", brdg, ifn);
428
                if (errno == EPERM)
429
                        return (1);
430
                return (1);
431
        }
432
        return (0);
433
}
434
 
435
int
436
bridge_timeout(s, brdg, arg)
437
        int s;
438
        char *brdg, *arg;
439
{
440
        struct ifbcachetoreq ifbct;
441
        u_int32_t newtime;
442
        char *endptr;
443
 
444
        newtime = strtoul(arg, &endptr, 0);
445
        if (arg[0] == '\0' || endptr[0] != '\0') {
446
                diag_printf("invalid arg for timeout: %s\n", arg);
447
                return (1);
448
        }
449
 
450
        strncpy(ifbct.ifbct_name, brdg, sizeof(ifbct.ifbct_name));
451
        ifbct.ifbct_time = newtime;
452
        if (ioctl(s, SIOCBRDGSTO, (caddr_t)&ifbct) < 0) {
453
                warnx2("%s", brdg);
454
                return (1);
455
        }
456
        return (0);
457
}
458
 
459
int
460
bridge_maxaddr(s, brdg, arg)
461
        int s;
462
        char *brdg, *arg;
463
{
464
        struct ifbcachereq ifbc;
465
        u_int32_t newsize;
466
        char *endptr;
467
 
468
        newsize = strtoul(arg, &endptr, 0);
469
        if (arg[0] == '\0' || endptr[0] != '\0') {
470
                diag_printf("invalid arg for maxaddr: %s\n", arg);
471
                return (1);
472
        }
473
 
474
        strncpy(ifbc.ifbc_name, brdg, sizeof(ifbc.ifbc_name));
475
        ifbc.ifbc_size = newsize;
476
        if (ioctl(s, SIOCBRDGSCACHE, (caddr_t)&ifbc) < 0) {
477
                warnx2("%s", brdg);
478
                return (1);
479
        }
480
        return (0);
481
}
482
 
483
int
484
bridge_deladdr(s, brdg, addr)
485
        int s;
486
        char *brdg, *addr;
487
{
488
        struct ifbareq ifba;
489
        struct ether_addr *ea;
490
 
491
        strncpy(ifba.ifba_name, brdg, sizeof(ifba.ifba_name));
492
        ea = ether_aton(addr);
493
        if (ea == NULL) {
494
                warnx2("Invalid address: %s", addr);
495
                return (1);
496
        }
497
        bcopy(ea, &ifba.ifba_dst, sizeof(struct ether_addr));
498
 
499
        if (ioctl(s, SIOCBRDGDADDR, &ifba) < 0) {
500
                warnx3("%s: %s", brdg, addr);
501
                return (1);
502
        }
503
 
504
        return (0);
505
}
506
 
507
int
508
bridge_addaddr(s, brdg, ifname, addr)
509
        int s;
510
        char *brdg, *ifname, *addr;
511
{
512
        struct ifbareq ifba;
513
        struct ether_addr *ea;
514
 
515
        strncpy(ifba.ifba_name, brdg, sizeof(ifba.ifba_name));
516
        strncpy(ifba.ifba_ifsname, ifname, sizeof(ifba.ifba_ifsname));
517
 
518
        ea = ether_aton(addr);
519
        if (ea == NULL) {
520
                warnx2("Invalid address: %s", addr);
521
                return (1);
522
        }
523
        bcopy(ea, &ifba.ifba_dst, sizeof(struct ether_addr));
524
        ifba.ifba_flags = IFBAF_STATIC;
525
 
526
        if (ioctl(s, SIOCBRDGSADDR, &ifba) < 0) {
527
                warnx3("%s: %s", brdg, addr);
528
                return (1);
529
        }
530
 
531
        return (0);
532
}
533
 
534
int
535
bridge_addrs(s, brdg, delim)
536
        int s;
537
        char *brdg, *delim;
538
{
539
        struct ifbaconf ifbac;
540
        struct ifbareq *ifba;
541
        char *inbuf = NULL, buf[sizeof(ifba->ifba_ifsname) + 1];
542
        int i, len = 8192;
543
 
544
        while (1) {
545
                ifbac.ifbac_len = len;
546
                ifbac.ifbac_buf = inbuf = realloc(inbuf, len);
547
                strncpy(ifbac.ifbac_name, brdg, sizeof(ifbac.ifbac_name));
548
                if (inbuf == NULL)
549
                        err(1, "malloc");
550
                if (ioctl(s, SIOCBRDGRTS, &ifbac) < 0) {
551
                        if (errno == ENETDOWN)
552
                                return (0);
553
                        err(1, brdg);
554
                }
555
                if (ifbac.ifbac_len + sizeof(*ifba) < len)
556
                        break;
557
                len *= 2;
558
        }
559
 
560
        for (i = 0; i < ifbac.ifbac_len / sizeof(*ifba); i++) {
561
                ifba = ifbac.ifbac_req + i;
562
                strncpy(buf, ifba->ifba_ifsname, sizeof(buf));
563
                diag_printf("%s%s %s %d ", delim, ether_ntoa(&ifba->ifba_dst),
564
                    buf, ifba->ifba_age);
565
                printb("flags", ifba->ifba_flags, IFBAFBITS);
566
                diag_printf("\n");
567
        }
568
        free(ifbac.ifbac_buf);
569
        return (0);
570
}
571
 
572
/*
573
 * Check to make sure 'brdg' is really a bridge interface.
574
 */
575
int
576
is_bridge(s, brdg)
577
        int s;
578
        char *brdg;
579
{
580
        struct ifreq ifr;
581
        struct ifbaconf ifbac;
582
 
583
        strncpy(ifr.ifr_name, brdg, sizeof(ifr.ifr_name));
584
 
585
        if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0)
586
                return (0);
587
 
588
        ifbac.ifbac_len = 0;
589
        strncpy(ifbac.ifbac_name, brdg, sizeof(ifbac.ifbac_name));
590
        if (ioctl(s, SIOCBRDGRTS, (caddr_t)&ifbac) < 0) {
591
                if (errno == ENETDOWN)
592
                        return (1);
593
                return (0);
594
        }
595
        return (1);
596
}
597
 
598
int
599
bridge_status(s, brdg)
600
        int s;
601
        char *brdg;
602
{
603
        struct ifreq ifr;
604
        struct ifbcachereq ifbc;
605
        struct ifbcachetoreq ifbct;
606
        int err;
607
 
608
        strncpy(ifr.ifr_name, brdg, sizeof(ifr.ifr_name));
609
        if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
610
                warnx2("%s", brdg);
611
                if (errno == EPERM)
612
                        return (1);
613
                return (1);
614
        }
615
 
616
        diag_printf("%s: ", brdg);
617
        printb("flags", ifr.ifr_flags, IFFBITS);
618
        diag_printf("\n");
619
 
620
        diag_printf("Interfaces:\n");
621
        err = bridge_list(s, brdg, "  ");
622
        if (err)
623
                return (err);
624
 
625
        strncpy(ifbc.ifbc_name, brdg, sizeof(ifbc.ifbc_name));
626
        if (ioctl(s, SIOCBRDGGCACHE, (caddr_t)&ifbc) < 0) {
627
                warnx2("%s", brdg);
628
                return (1);
629
        }
630
 
631
        strncpy(ifbct.ifbct_name, brdg, sizeof(ifbct.ifbct_name));
632
        if (ioctl(s, SIOCBRDGGTO, (caddr_t)&ifbct) < 0) {
633
                warnx2("%s", brdg);
634
                return (1);
635
        }
636
 
637
        diag_printf("Addresses (max cache: %d, timeout: %d):\n",
638
            ifbc.ifbc_size, ifbct.ifbct_time);
639
 
640
        err = bridge_addrs(s, brdg, "   ");
641
        return (err);
642
}
643
 
644
int
645
bridge_flush_rule(s, brdg, ifname)
646
        int s;
647
        char *brdg, *ifname;
648
{
649
        struct ifbrlreq req;
650
 
651
        strncpy(req.ifbr_name, brdg, sizeof(req.ifbr_name));
652
        strncpy(req.ifbr_ifsname, ifname, sizeof(req.ifbr_ifsname));
653
        if (ioctl(s, SIOCBRDGFRL, &req) < 0) {
654
                warnx3("%s: %s", brdg, ifname);
655
                return (1);
656
        }
657
        return (0);
658
}
659
 
660
int
661
bridge_rules(s, brdg, ifname, delim)
662
        int s;
663
        char *brdg, *ifname;
664
        char *delim;
665
{
666
        char *inbuf = NULL;
667
        struct ifbrlconf ifc;
668
        struct ifbrlreq *ifrp, ifreq;
669
        int len = 8192, i;
670
 
671
        while (1) {
672
                ifc.ifbrl_len = len;
673
                ifc.ifbrl_buf = inbuf = realloc(inbuf, len);
674
                strncpy(ifc.ifbrl_name, brdg, sizeof(ifc.ifbrl_name));
675
                strncpy(ifc.ifbrl_ifsname, ifname, sizeof(ifc.ifbrl_ifsname));
676
                if (inbuf == NULL)
677
                        err(1, "malloc");
678
                if (ioctl(s, SIOCBRDGGRL, &ifc) < 0)
679
                        err(1, "ioctl(SIOCBRDGGRL)");
680
                if (ifc.ifbrl_len + sizeof(ifreq) < len)
681
                        break;
682
                len *= 2;
683
        }
684
        ifrp = ifc.ifbrl_req;
685
        for (i = 0; i < ifc.ifbrl_len; i += sizeof(ifreq)) {
686
                ifrp = (struct ifbrlreq *)((caddr_t)ifc.ifbrl_req + i);
687
                bridge_showrule(ifrp, delim);
688
        }
689
        free(ifc.ifbrl_buf);
690
        return (0);
691
}
692
 
693
void
694
bridge_showrule(r, delim)
695
        struct ifbrlreq *r;
696
        char *delim;
697
{
698
        if (delim)
699
                diag_printf("%s    ", delim);
700
        else
701
                diag_printf("%s: ", r->ifbr_name);
702
 
703
        if (r->ifbr_action == BRL_ACTION_BLOCK)
704
                diag_printf("block ");
705
        else if (r->ifbr_action == BRL_ACTION_PASS)
706
                diag_printf("pass ");
707
        else
708
                diag_printf("[neither block nor pass?]\n");
709
 
710
        if ((r->ifbr_flags & (BRL_FLAG_IN | BRL_FLAG_OUT)) ==
711
            (BRL_FLAG_IN | BRL_FLAG_OUT))
712
                diag_printf("in/out ");
713
        else if (r->ifbr_flags & BRL_FLAG_IN)
714
                diag_printf("in ");
715
        else if (r->ifbr_flags & BRL_FLAG_OUT)
716
                diag_printf("out ");
717
        else
718
                diag_printf("[neither in nor out?]\n");
719
 
720
        diag_printf("on %s", r->ifbr_ifsname);
721
 
722
        if (r->ifbr_flags & BRL_FLAG_SRCVALID)
723
                diag_printf(" src %s", ether_ntoa(&r->ifbr_src));
724
        if (r->ifbr_flags & BRL_FLAG_DSTVALID)
725
                diag_printf(" dst %s", ether_ntoa(&r->ifbr_dst));
726
 
727
        diag_printf("\n");
728
}
729
 
730
/*
731
 * Parse a rule definition and send it upwards.
732
 *
733
 * Syntax:
734
 *      {block|pass} {in|out|in/out} on {ifs} [src {mac}] [dst {mac}]
735
 */
736
int
737
bridge_rule(int s, char *brdg, int targc, char **targv, int ln)
738
{
739
        char **argv = targv;
740
        int argc = targc;
741
        struct ifbrlreq rule;
742
        struct ether_addr *ea, *dea;
743
 
744
        if (argc == 0) {
745
                diag_printf( "invalid rule\n");
746
                return (1);
747
        }
748
        rule.ifbr_flags = 0;
749
        rule.ifbr_action = 0;
750
        strncpy(rule.ifbr_name, brdg, sizeof(rule.ifbr_name));
751
 
752
        if (strcmp(argv[0], "block") == 0)
753
                rule.ifbr_action = BRL_ACTION_BLOCK;
754
        else if (strcmp(argv[0], "pass") == 0)
755
                rule.ifbr_action = BRL_ACTION_PASS;
756
        else
757
                goto bad_rule;
758
        argc--; argv++;
759
 
760
        if (argc == 0) {
761
                bridge_badrule(targc, targv, ln);
762
                return (1);
763
        }
764
        if (strcmp(argv[0], "in") == 0)
765
                rule.ifbr_flags |= BRL_FLAG_IN;
766
        else if (strcmp(argv[0], "out") == 0)
767
                rule.ifbr_flags |= BRL_FLAG_OUT;
768
        else if (strcmp(argv[0], "in/out") == 0)
769
                rule.ifbr_flags |= BRL_FLAG_IN | BRL_FLAG_OUT;
770
        else
771
                goto bad_rule;
772
        argc--; argv++;
773
 
774
        if (argc == 0 || strcmp(argv[0], "on"))
775
                goto bad_rule;
776
        argc--; argv++;
777
 
778
        if (argc == 0)
779
                goto bad_rule;
780
        strncpy(rule.ifbr_ifsname, argv[0], sizeof(rule.ifbr_ifsname));
781
        argc--; argv++;
782
 
783
        while (argc) {
784
                if (strcmp(argv[0], "dst") == 0) {
785
                        if (rule.ifbr_flags & BRL_FLAG_DSTVALID)
786
                                goto bad_rule;
787
                        rule.ifbr_flags |= BRL_FLAG_DSTVALID;
788
                        dea = &rule.ifbr_dst;
789
                }
790
                else if (strcmp(argv[0], "src") == 0) {
791
                        if (rule.ifbr_flags & BRL_FLAG_SRCVALID)
792
                                goto bad_rule;
793
                        rule.ifbr_flags |= BRL_FLAG_SRCVALID;
794
                        dea = &rule.ifbr_src;
795
                }
796
                else
797
                        goto bad_rule;
798
 
799
                argc--; argv++;
800
 
801
                if (argc == 0)
802
                        goto bad_rule;
803
                ea = ether_aton(argv[0]);
804
                if (ea == NULL) {
805
                        warnx2("Invalid address: %s", argv[0]);
806
                        return (1);
807
                }
808
                bcopy(ea, dea, sizeof(*dea));
809
                argc--; argv++;
810
        }
811
 
812
        if (ioctl(s, SIOCBRDGARL, &rule) < 0) {
813
                warnx2("%s", brdg);
814
                return (1);
815
        }
816
        return (0);
817
 
818
bad_rule:
819
        bridge_badrule(targc, targv, ln);
820
        return (1);
821
}
822
 
823
#define MAXRULEWORDS 8
824
#ifdef ZAP
825
int
826
bridge_rulefile(s, brdg, fname)
827
        int s;
828
        char *brdg, *fname;
829
{
830
        FILE *f;
831
        char *str, *argv[MAXRULEWORDS], buf[1024], xbuf[1024];
832
        int ln = 1, argc = 0, err = 0, xerr;
833
 
834
        f = fopen(fname, "r");
835
        if (f == NULL) {
836
                warnx2("%s", fname);
837
                return (1);
838
        }
839
 
840
        while (1) {
841
                fgets(buf, sizeof(buf), f);
842
                if (feof(f))
843
                        break;
844
                ln++;
845
                if (buf[0] == '#')
846
                        continue;
847
 
848
                argc = 0;
849
                str = strtok(buf, "\n\r ");
850
                strncpy(xbuf, buf, sizeof(xbuf));
851
                while (str != NULL) {
852
                        argv[argc++] = str;
853
                        if (argc > MAXRULEWORDS) {
854
                                diag_printf( "invalid rule: %d: %s\n",
855
                                    ln, xbuf);
856
                                break;
857
                        }
858
                        str = strtok(NULL, "\n\r ");
859
                }
860
 
861
                if (argc > MAXRULEWORDS)
862
                        continue;
863
 
864
                xerr = bridge_rule(s, brdg, argc, argv, ln);
865
                if (xerr)
866
                        err = xerr;
867
        }
868
        fclose(f);
869
        return (err);
870
}
871
#endif
872
void
873
bridge_badrule(argc, argv, ln)
874
        int argc, ln;
875
        char **argv;
876
{
877
        int i;
878
 
879
        diag_printf( "invalid rule: ");
880
        if (ln != -1)
881
                diag_printf( "%d: ", ln);
882
        for (i = 0; i < argc; i++) {
883
                diag_printf( "%s ", argv[i]);
884
        }
885
        diag_printf( "\n");
886
}
887
 
888
/*
889
 * Print a value ala the %b format of the kernel's printf
890
 * (borrowed from ifconfig.c)
891
 */
892
void
893
printb(s, v, bits)
894
        char *s;
895
        char *bits;
896
        unsigned short v;
897
{
898
        register int i, any = 0;
899
        register char c;
900
 
901
        if (bits && *bits == 8)
902
                diag_printf("%s=%o", s, v);
903
        else
904
                diag_printf("%s=%x", s, v);
905
        bits++;
906
        if (bits) {
907
                diag_printf("<");
908
                while ((i = *bits++)) {
909
                        if (v & (1 << (i-1))) {
910
                                if (any)
911
                                        diag_printf(",");
912
                                any = 1;
913
                                for (; (c = *bits) > 32; bits++)
914
                                        diag_printf("%c",c);
915
                        } else
916
                                for (; *bits > 32; bits++)
917
                                        ;
918
                }
919
                diag_printf(">");
920
        }
921
}
922
 
923
static void
924
interface_up(const char *intf)
925
{
926
  struct ifreq ifr;
927
  int s;
928
 
929
  s = socket(AF_INET, SOCK_DGRAM, 0);
930
  if (s < 0) {
931
    perror("socket");
932
    return;
933
  }
934
 
935
  strcpy(ifr.ifr_name, intf);
936
  ifr.ifr_flags = IFF_UP | IFF_BROADCAST | IFF_RUNNING;
937
  if (ioctl(s, SIOCSIFFLAGS, &ifr)) {
938
    perror("SIOCSIFFLAGS");
939
  }
940
  close(s);
941
}
942
 
943
static void
944
main_fn(cyg_addrword_t data) {
945
 
946
  int sock;
947
  char brdg[] = "bridge0";
948
 
949
  sock = socket(AF_INET, SOCK_DGRAM, 0);
950
  assert(sock >= 0);
951
 
952
#ifdef CYGHWR_NET_DRIVER_ETH0
953
  interface_up("eth0");
954
  eth0_up = 1;
955
  bridge_add(sock,brdg,"eth0");
956
#ifdef CYGPKG_NET_BRIDGE_STP_CODE
957
  bridge_ifsetflag (sock, brdg, "eth0", IFBIF_STP);
958
#endif
959
#endif
960
#ifdef CYGHWR_NET_DRIVER_ETH1
961
  interface_up("eth1");
962
  eth1_up = 1;
963
  bridge_add(sock,brdg,"eth1");
964
#ifdef CYGPKG_NET_BRIDGE_STP_CODE
965
  bridge_ifsetflag (sock, brdg, "eth1", IFBIF_STP);
966
#endif
967
#endif
968
 
969
  bridge_status(sock,brdg);
970
  bridge_setflag(sock,brdg, IFF_UP);
971
 
972
  while(1) {
973
    cyg_kmem_print_stats();
974
    cyg_thread_delay(500);
975
  }
976
}
977
 
978
static char main_stack[8192];
979
static cyg_handle_t main_handle;
980
static cyg_thread main_thread;
981
 
982
void
983
cyg_user_start(void) {
984
  printf("cyg_user_start starting\n");
985
  cyg_thread_create(4, &main_fn, 0, "main", &main_stack, sizeof(main_stack),
986
                    &main_handle, &main_thread);
987
  cyg_thread_resume(main_handle);
988
  printf("cyg_user_start done\n");
989
}
990
 
991
#else // CYGPKG_NET_BRIDGE_HANDLER
992
 
993
void
994
cyg_user_start(void) {
995
    printf("No bridge support available\n");
996
}
997
#endif
998
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.