📄 bridge.c
字号:
if (ioctl(s, SIOCBRDGDADDR, &ifba) < 0) { warnx3("%s: %s", brdg, addr); return (1); } return (0);}intbridge_addaddr(s, brdg, ifname, addr) int s; char *brdg, *ifname, *addr;{ struct ifbareq ifba; struct ether_addr *ea; strncpy(ifba.ifba_name, brdg, sizeof(ifba.ifba_name)); strncpy(ifba.ifba_ifsname, ifname, sizeof(ifba.ifba_ifsname)); ea = ether_aton(addr); if (ea == NULL) { warnx2("Invalid address: %s", addr); return (1); } bcopy(ea, &ifba.ifba_dst, sizeof(struct ether_addr)); ifba.ifba_flags = IFBAF_STATIC; if (ioctl(s, SIOCBRDGSADDR, &ifba) < 0) { warnx3("%s: %s", brdg, addr); return (1); } return (0);}intbridge_addrs(s, brdg, delim) int s; char *brdg, *delim;{ struct ifbaconf ifbac; struct ifbareq *ifba; char *inbuf = NULL, buf[sizeof(ifba->ifba_ifsname) + 1]; int i, len = 8192; while (1) { ifbac.ifbac_len = len; ifbac.ifbac_buf = inbuf = realloc(inbuf, len); strncpy(ifbac.ifbac_name, brdg, sizeof(ifbac.ifbac_name)); if (inbuf == NULL) err(1, "malloc"); if (ioctl(s, SIOCBRDGRTS, &ifbac) < 0) { if (errno == ENETDOWN) return (0); err(1, brdg); } if (ifbac.ifbac_len + sizeof(*ifba) < len) break; len *= 2; } for (i = 0; i < ifbac.ifbac_len / sizeof(*ifba); i++) { ifba = ifbac.ifbac_req + i; strncpy(buf, ifba->ifba_ifsname, sizeof(buf)); diag_printf("%s%s %s %d ", delim, ether_ntoa(&ifba->ifba_dst), buf, ifba->ifba_age); printb("flags", ifba->ifba_flags, IFBAFBITS); diag_printf("\n"); } free(ifbac.ifbac_buf); return (0);}/* * Check to make sure 'brdg' is really a bridge interface. */intis_bridge(s, brdg) int s; char *brdg;{ struct ifreq ifr; struct ifbaconf ifbac; strncpy(ifr.ifr_name, brdg, sizeof(ifr.ifr_name)); if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) return (0); ifbac.ifbac_len = 0; strncpy(ifbac.ifbac_name, brdg, sizeof(ifbac.ifbac_name)); if (ioctl(s, SIOCBRDGRTS, (caddr_t)&ifbac) < 0) { if (errno == ENETDOWN) return (1); return (0); } return (1);}intbridge_status(s, brdg) int s; char *brdg;{ struct ifreq ifr; struct ifbcachereq ifbc; struct ifbcachetoreq ifbct; int err; strncpy(ifr.ifr_name, brdg, sizeof(ifr.ifr_name)); if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) { warnx2("%s", brdg); if (errno == EPERM) return (1); return (1); } diag_printf("%s: ", brdg); printb("flags", ifr.ifr_flags, IFFBITS); diag_printf("\n"); diag_printf("Interfaces:\n"); err = bridge_list(s, brdg, " "); if (err) return (err); strncpy(ifbc.ifbc_name, brdg, sizeof(ifbc.ifbc_name)); if (ioctl(s, SIOCBRDGGCACHE, (caddr_t)&ifbc) < 0) { warnx2("%s", brdg); return (1); } strncpy(ifbct.ifbct_name, brdg, sizeof(ifbct.ifbct_name)); if (ioctl(s, SIOCBRDGGTO, (caddr_t)&ifbct) < 0) { warnx2("%s", brdg); return (1); } diag_printf("Addresses (max cache: %d, timeout: %d):\n", ifbc.ifbc_size, ifbct.ifbct_time); err = bridge_addrs(s, brdg, " "); return (err);}intbridge_flush_rule(s, brdg, ifname) int s; char *brdg, *ifname;{ struct ifbrlreq req; strncpy(req.ifbr_name, brdg, sizeof(req.ifbr_name)); strncpy(req.ifbr_ifsname, ifname, sizeof(req.ifbr_ifsname)); if (ioctl(s, SIOCBRDGFRL, &req) < 0) { warnx3("%s: %s", brdg, ifname); return (1); } return (0);}intbridge_rules(s, brdg, ifname, delim) int s; char *brdg, *ifname; char *delim;{ char *inbuf = NULL; struct ifbrlconf ifc; struct ifbrlreq *ifrp, ifreq; int len = 8192, i; while (1) { ifc.ifbrl_len = len; ifc.ifbrl_buf = inbuf = realloc(inbuf, len); strncpy(ifc.ifbrl_name, brdg, sizeof(ifc.ifbrl_name)); strncpy(ifc.ifbrl_ifsname, ifname, sizeof(ifc.ifbrl_ifsname)); if (inbuf == NULL) err(1, "malloc"); if (ioctl(s, SIOCBRDGGRL, &ifc) < 0) err(1, "ioctl(SIOCBRDGGRL)"); if (ifc.ifbrl_len + sizeof(ifreq) < len) break; len *= 2; } ifrp = ifc.ifbrl_req; for (i = 0; i < ifc.ifbrl_len; i += sizeof(ifreq)) { ifrp = (struct ifbrlreq *)((caddr_t)ifc.ifbrl_req + i); bridge_showrule(ifrp, delim); } free(ifc.ifbrl_buf); return (0);}voidbridge_showrule(r, delim) struct ifbrlreq *r; char *delim;{ if (delim) diag_printf("%s ", delim); else diag_printf("%s: ", r->ifbr_name); if (r->ifbr_action == BRL_ACTION_BLOCK) diag_printf("block "); else if (r->ifbr_action == BRL_ACTION_PASS) diag_printf("pass "); else diag_printf("[neither block nor pass?]\n"); if ((r->ifbr_flags & (BRL_FLAG_IN | BRL_FLAG_OUT)) == (BRL_FLAG_IN | BRL_FLAG_OUT)) diag_printf("in/out "); else if (r->ifbr_flags & BRL_FLAG_IN) diag_printf("in "); else if (r->ifbr_flags & BRL_FLAG_OUT) diag_printf("out "); else diag_printf("[neither in nor out?]\n"); diag_printf("on %s", r->ifbr_ifsname); if (r->ifbr_flags & BRL_FLAG_SRCVALID) diag_printf(" src %s", ether_ntoa(&r->ifbr_src)); if (r->ifbr_flags & BRL_FLAG_DSTVALID) diag_printf(" dst %s", ether_ntoa(&r->ifbr_dst)); diag_printf("\n");}/* * Parse a rule definition and send it upwards. * * Syntax: * {block|pass} {in|out|in/out} on {ifs} [src {mac}] [dst {mac}] */intbridge_rule(int s, char *brdg, int targc, char **targv, int ln){ char **argv = targv; int argc = targc; struct ifbrlreq rule; struct ether_addr *ea, *dea; if (argc == 0) { diag_printf( "invalid rule\n"); return (1); } rule.ifbr_flags = 0; rule.ifbr_action = 0; strncpy(rule.ifbr_name, brdg, sizeof(rule.ifbr_name)); if (strcmp(argv[0], "block") == 0) rule.ifbr_action = BRL_ACTION_BLOCK; else if (strcmp(argv[0], "pass") == 0) rule.ifbr_action = BRL_ACTION_PASS; else goto bad_rule; argc--; argv++; if (argc == 0) { bridge_badrule(targc, targv, ln); return (1); } if (strcmp(argv[0], "in") == 0) rule.ifbr_flags |= BRL_FLAG_IN; else if (strcmp(argv[0], "out") == 0) rule.ifbr_flags |= BRL_FLAG_OUT; else if (strcmp(argv[0], "in/out") == 0) rule.ifbr_flags |= BRL_FLAG_IN | BRL_FLAG_OUT; else goto bad_rule; argc--; argv++; if (argc == 0 || strcmp(argv[0], "on")) goto bad_rule; argc--; argv++; if (argc == 0) goto bad_rule; strncpy(rule.ifbr_ifsname, argv[0], sizeof(rule.ifbr_ifsname)); argc--; argv++; while (argc) { if (strcmp(argv[0], "dst") == 0) { if (rule.ifbr_flags & BRL_FLAG_DSTVALID) goto bad_rule; rule.ifbr_flags |= BRL_FLAG_DSTVALID; dea = &rule.ifbr_dst; } else if (strcmp(argv[0], "src") == 0) { if (rule.ifbr_flags & BRL_FLAG_SRCVALID) goto bad_rule; rule.ifbr_flags |= BRL_FLAG_SRCVALID; dea = &rule.ifbr_src; } else goto bad_rule; argc--; argv++; if (argc == 0) goto bad_rule; ea = ether_aton(argv[0]); if (ea == NULL) { warnx2("Invalid address: %s", argv[0]); return (1); } bcopy(ea, dea, sizeof(*dea)); argc--; argv++; } if (ioctl(s, SIOCBRDGARL, &rule) < 0) { warnx2("%s", brdg); return (1); } return (0);bad_rule: bridge_badrule(targc, targv, ln); return (1);}#define MAXRULEWORDS 8#ifdef ZAPintbridge_rulefile(s, brdg, fname) int s; char *brdg, *fname;{ FILE *f; char *str, *argv[MAXRULEWORDS], buf[1024], xbuf[1024]; int ln = 1, argc = 0, err = 0, xerr; f = fopen(fname, "r"); if (f == NULL) { warnx2("%s", fname); return (1); } while (1) { fgets(buf, sizeof(buf), f); if (feof(f)) break; ln++; if (buf[0] == '#') continue; argc = 0; str = strtok(buf, "\n\r "); strncpy(xbuf, buf, sizeof(xbuf)); while (str != NULL) { argv[argc++] = str; if (argc > MAXRULEWORDS) { diag_printf( "invalid rule: %d: %s\n", ln, xbuf); break; } str = strtok(NULL, "\n\r "); } if (argc > MAXRULEWORDS) continue; xerr = bridge_rule(s, brdg, argc, argv, ln); if (xerr) err = xerr; } fclose(f); return (err);}#endifvoidbridge_badrule(argc, argv, ln) int argc, ln; char **argv;{ int i; diag_printf( "invalid rule: "); if (ln != -1) diag_printf( "%d: ", ln); for (i = 0; i < argc; i++) { diag_printf( "%s ", argv[i]); } diag_printf( "\n");}/* * Print a value ala the %b format of the kernel's printf * (borrowed from ifconfig.c) */voidprintb(s, v, bits) char *s; char *bits; unsigned short v;{ register int i, any = 0; register char c; if (bits && *bits == 8) diag_printf("%s=%o", s, v); else diag_printf("%s=%x", s, v); bits++; if (bits) { diag_printf("<"); while ((i = *bits++)) { if (v & (1 << (i-1))) { if (any) diag_printf(","); any = 1; for (; (c = *bits) > 32; bits++) diag_printf("%c",c); } else for (; *bits > 32; bits++) ; } diag_printf(">"); }}static void interface_up(const char *intf){ struct ifreq ifr; int s; s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { perror("socket"); return; } strcpy(ifr.ifr_name, intf); ifr.ifr_flags = IFF_UP | IFF_BROADCAST | IFF_RUNNING; if (ioctl(s, SIOCSIFFLAGS, &ifr)) { perror("SIOCSIFFLAGS"); } close(s);}static voidmain_fn(cyg_addrword_t data) { int sock; char brdg[] = "bridge0"; sock = socket(AF_INET, SOCK_DGRAM, 0); assert(sock >= 0);#ifdef CYGHWR_NET_DRIVER_ETH0 interface_up("eth0"); eth0_up = 1; bridge_add(sock,brdg,"eth0");#ifdef CYGPKG_NET_BRIDGE_STP_CODE bridge_ifsetflag (sock, brdg, "eth0", IFBIF_STP);#endif#endif#ifdef CYGHWR_NET_DRIVER_ETH1 interface_up("eth1"); eth1_up = 1; bridge_add(sock,brdg,"eth1");#ifdef CYGPKG_NET_BRIDGE_STP_CODE bridge_ifsetflag (sock, brdg, "eth1", IFBIF_STP);#endif#endif bridge_status(sock,brdg); bridge_setflag(sock,brdg, IFF_UP); while(1) { cyg_kmem_print_stats(); cyg_thread_delay(500); }}static char main_stack[8192];static cyg_handle_t main_handle;static cyg_thread main_thread;voidcyg_user_start(void) { printf("cyg_user_start starting\n"); cyg_thread_create(4, &main_fn, 0, "main", &main_stack, sizeof(main_stack), &main_handle, &main_thread); cyg_thread_resume(main_handle); printf("cyg_user_start done\n");}#else // CYGPKG_NET_BRIDGE_HANDLERvoidcyg_user_start(void) { printf("No bridge support available\n");}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -