diff options
author | buytenh <buytenh> | 2001-06-22 19:59:02 +0000 |
---|---|---|
committer | buytenh <buytenh> | 2001-06-22 19:59:02 +0000 |
commit | 38837a8e19540690c80f5a3b0971e0e1495a4a3e (patch) | |
tree | c1136c0d3a50a9887a866c403c416e3f6efb1a07 /brctl/brctld.c | |
download | android_external_brctl-38837a8e19540690c80f5a3b0971e0e1495a4a3e.tar.gz android_external_brctl-38837a8e19540690c80f5a3b0971e0e1495a4a3e.tar.bz2 android_external_brctl-38837a8e19540690c80f5a3b0971e0e1495a4a3e.zip |
Initial revision
Diffstat (limited to 'brctl/brctld.c')
-rw-r--r-- | brctl/brctld.c | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/brctl/brctld.c b/brctl/brctld.c new file mode 100644 index 0000000..ad9ef1f --- /dev/null +++ b/brctl/brctld.c @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2000 Lennert Buytenhek + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <netinet/in.h> +#include <signal.h> +#include <sys/resource.h> +#include <sys/time.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> +#include <asm/param.h> +#include "libbridge.h" +#include "brctl.h" + +char *help_message = +"addbr\t\t\t\t\tadd bridge\n" +"addif\t\t\t<device>\tadd interface to bridge\n" +"bridge\t\t\t<bridge>\tselect bridge to work in\n" +"delbr\t\t\t\t\tdelete bridge\n" +"delif\t\t\t<device>\tdelete interface from bridge\n" +"setageing\t\t<time>\t\tset ageing time\n" +"setbridgeprio\t\t<prio>\t\tset bridge priority\n" +"setfd\t\t\t<time>\t\tset bridge forward delay\n" +"setgcint\t\t<time>\t\tset garbage collection interval\n" +"sethello\t\t<time>\t\tset hello time\n" +"setmaxage\t\t<time>\t\tset max message age\n" +"setpathcost\t\t<port> <cost>\tset path cost\n" +"setportprio\t\t<port> <prio>\tset port priority\n" +"show\t\t\t\t\tshow a list of bridges\n" +"showmacs\t\t\t\tshow a list of mac addrs\n" +"showstp\t\t\t\t\tshow bridge stp info\n" +"stp\t\t\t<state>\t\tturn stp on/off\n" +"quit\t\t\t\t\texit this session\n" +"\n"; + +void help() +{ + fprintf(stderr, help_message); +} + +struct bridge *br = NULL; + +int forkaway() +{ + int f; + + f = fork(); + if (f < 0) { + perror("fork"); + exit(-1); + } + + return f; +} + +void runchild(int sock) +{ + char hostname[128]; + + if (forkaway()) + return; + + /* Hack. */ + close(0); dup(sock); + close(1); dup(sock); + close(2); dup(sock); + + br_init(); + gethostname(hostname, 128); + + printf("\n\n\n\n"); + printf("brctld\t\tCopyright (C) 2000 Lennert Buytenhek <buytenh@gnu.org>\n"); + printf("======================================================================"); + printf("\n\n\n\n"); + + while (1) { + char arg0[128]; + char arg1[128]; + char cmd[128]; + struct command *cmdptr; + char line[1024]; + int numcmd; + + printf("<%s> ", hostname); + fflush(stdout); + line[1023] = 0; + fgets(line, 1023, stdin); + while (strlen(line) > 0 && + (line[strlen(line)-1] == '\r' || + line[strlen(line)-1] == '\n')) + line[strlen(line)-1] = 0; + + numcmd = sscanf(line, "%s %s %s", cmd, arg0, arg1); + + if (!strcmp(cmd, "help")) { + help(); + continue; + } else if (!strcmp(cmd, "bridge")) { + if (numcmd != 2) { + fprintf(stderr, "invalid number of arguments\n"); + continue; + } + + br = br_find_bridge(arg0); + if (br != NULL) + printf("now using bridge %s\n\n", arg0); + else + printf("can't find bridge %s\n\n", arg0); + continue; + } else if (!strcmp(cmd, "quit")) { + break; + } + + if ((cmdptr = br_command_lookup(cmd)) == NULL) { + printf("unknown command '%s'\n\n", line); + continue; + } + + if (cmdptr->needs_bridge_argument && br == NULL) { + printf("this command needs a bridge\n\n"); + continue; + } + + br_refresh(); + cmdptr->func(br, arg0, arg1); + printf("\n"); + } + + shutdown(sock, 2); + exit(0); +} + +void sigchild(int sig) +{ + int status; + + wait3(&status, WNOHANG, NULL); +} + +int main(int argc, char *argv[]) +{ + struct sockaddr_in addr; + int sock; + int x; + + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + perror("socket"); + return 1; + } + + x = 1; + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)) < 0) { + perror("setsockopt"); + return 1; + } + + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + addr.sin_port = htons(31338); + if (bind(sock, &addr, sizeof(addr)) < 0) { + perror("bind"); + return 1; + } + + if (listen(sock, 1) < 0) { + perror("listen"); + return 1; + } + + if (forkaway()) + return 0; + + setsid(); + signal(SIGCHLD, sigchild); + + while (1) { + int len; + int newsock; + + len = sizeof(addr); + if ((newsock = accept(sock, &addr, &len)) < 0) { + perror("accept"); + return 1; + } + + runchild(newsock); + } + + return 0; +} |