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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [net/] [common/] [v2_0/] [tests/] [bridge.c] - Blame information for rev 27

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

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

powered by: WebSVN 2.1.0

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