/* $NetBSD: brconfig.c,v 1.7 2003/09/19 08:39:09 itojun Exp $ */ /* * Copyright 2001 Wasabi Systems, Inc. * All rights reserved. * * Written by Jason R. Thorpe for Wasabi Systems, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed for the NetBSD Project by * Wasabi Systems, Inc. * 4. The name of Wasabi Systems, Inc. may not be used to endorse * or promote products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * brconfig(8) -- * * Configuration utility for the bridge(4) driver. */ #include #ifndef lint __RCSID("$NetBSD: brconfig.c,v 1.7 2003/09/19 08:39:09 itojun Exp $"); #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include struct command { const char *cmd_keyword; int cmd_argcnt; int cmd_flags; void (*cmd_func)(const struct command *, int, const char *, char **); }; #define CMD_INVERT 0x01 /* "invert" the sense of the command */ void cmd_add(const struct command *, int, const char *, char **); void cmd_delete(const struct command *, int, const char *, char **); void cmd_up(const struct command *, int, const char *, char **); void cmd_down(const struct command *, int, const char *, char **); void cmd_discover(const struct command *, int, const char *, char **); void cmd_learn(const struct command *, int, const char *, char **); void cmd_flush(const struct command *, int, const char *, char **); void cmd_flushall(const struct command *, int, const char *, char **); void cmd_static(const struct command *, int, const char *, char **); void cmd_deladdr(const struct command *, int, const char *, char **); void cmd_addr(const struct command *, int, const char *, char **); void cmd_maxaddr(const struct command *, int, const char *, char **); void cmd_hellotime(const struct command *, int, const char *, char **); void cmd_fwddelay(const struct command *, int, const char *, char **); void cmd_maxage(const struct command *, int, const char *, char **); void cmd_priority(const struct command *, int, const char *, char **); void cmd_ifpriority(const struct command *, int, const char *, char **); void cmd_ifpathcost(const struct command *, int, const char *, char **); void cmd_timeout(const struct command *, int, const char *, char **); void cmd_stp(const struct command *, int, const char *, char **); void cmd_ipf(const struct command *, int, const char *, char **); const struct command command_table[] = { { "add", 1, 0, cmd_add }, { "delete", 1, 0, cmd_delete }, { "up", 0, 0, cmd_up }, { "down", 0, 0, cmd_down }, { "discover", 1, 0, cmd_discover }, { "-discover", 1, CMD_INVERT, cmd_discover }, { "learn", 1, 0, cmd_learn }, { "-learn", 1, CMD_INVERT, cmd_learn }, { "flush", 0, 0, cmd_flush }, { "flushall", 0, 0, cmd_flushall }, { "static", 2, 0, cmd_static }, { "deladdr", 1, 0, cmd_deladdr }, { "addr", 0, 0, cmd_addr }, { "maxaddr", 1, 0, cmd_maxaddr }, { "hellotime", 1, 0, cmd_hellotime }, { "fwddelay", 1, 0, cmd_fwddelay }, { "maxage", 1, 0, cmd_maxage }, { "priority", 1, 0, cmd_priority }, { "ifpriority", 2, 0, cmd_ifpriority }, { "ifpathcost", 2, 0, cmd_ifpathcost }, { "timeout", 1, 0, cmd_timeout }, { "stp", 1, 0, cmd_stp }, { "-stp", 1, CMD_INVERT, cmd_stp }, { "ipf", 0, 0, cmd_ipf }, { "-ipf", 0, CMD_INVERT, cmd_ipf }, { NULL, 0, 0, NULL }, }; void printall(int); void status(int, const char *); int is_bridge(const char *); void show_config(int, const char *, const char *); void show_interfaces(int, const char *, const char *); void show_addresses(int, const char *, const char *); int get_val(const char *, u_long *); int do_cmd(int, const char *, u_long, void *, size_t, int); void do_ifflag(int, const char *, int, int); void do_bridgeflag(int, const char *, const char *, int, int); void printb(const char *, u_int, const char *); int main(int, char *[]); void usage(void); int aflag; struct ifreq g_ifr; int g_ifr_updated; #define IFFBITS \ "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\ \11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2\20MULTICAST" int main(int argc, char *argv[]) { const struct command *cmd; char *bridge; int sock, ch; if (argc < 2) usage(); sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) err(1, "socket"); while ((ch = getopt(argc, argv, "a")) != -1) { switch (ch) { case 'a': aflag = 1; break; default: usage(); } } argc -= optind; argv += optind; if (aflag) { if (argc != 0) usage(); printall(sock); exit(0); } if (argc == 0) usage(); bridge = argv[0]; if (is_bridge(bridge) == 0) errx(1, "%s is not a bridge", bridge); /* Get a copy of the interface flags. */ strlcpy(g_ifr.ifr_name, bridge, sizeof(g_ifr.ifr_name)); if (ioctl(sock, SIOCGIFFLAGS, &g_ifr) < 0) err(1, "unable to get interface flags"); argc--; argv++; if (argc == 0) { status(sock, bridge); exit(0); } while (argc != 0) { for (cmd = command_table; cmd->cmd_keyword != NULL; cmd++) { if (strcmp(cmd->cmd_keyword, argv[0]) == 0) break; } if (cmd->cmd_keyword == NULL) errx(1, "unknown command: %s", argv[0]); argc--; argv++; if (argc < cmd->cmd_argcnt) errx(1, "command %s requires %d argument%s", cmd->cmd_keyword, cmd->cmd_argcnt, cmd->cmd_argcnt == 1 ? "" : "s"); (*cmd->cmd_func)(cmd, sock, bridge, argv); argc -= cmd->cmd_argcnt; argv += cmd->cmd_argcnt; } /* If the flags changed, update them. */ if (g_ifr_updated && ioctl(sock, SIOCSIFFLAGS, &g_ifr) < 0) err(1, "unable to set interface flags"); exit (0); } void usage(void) { static const char *usage_strings[] = { "-a", "", " up|down", " addr", " add ", " delete ", " maxaddr ", " timeout