diff options
Diffstat (limited to 'networking/brctl.c')
-rw-r--r-- | networking/brctl.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/networking/brctl.c b/networking/brctl.c new file mode 100644 index 000000000..21d528f91 --- /dev/null +++ b/networking/brctl.c | |||
@@ -0,0 +1,87 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Small implementation of brctl for busybox. | ||
4 | * | ||
5 | * Copyright (C) 2008 by Bernhard Fischer | ||
6 | * | ||
7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | ||
8 | */ | ||
9 | #include "libbb.h" | ||
10 | #include <linux/sockios.h> | ||
11 | #include <net/if.h> | ||
12 | |||
13 | #ifdef ENABLE_FEATURE_BRCTL_SHOW | ||
14 | #error Remove these | ||
15 | #endif | ||
16 | #define ENABLE_FEATURE_BRCTL_SHOW 0 | ||
17 | #define USE_FEATURE_BRCTL_SHOW(...) | ||
18 | |||
19 | |||
20 | /* Fancy diagnostics -- printing add/del -- costs 49 bytes. */ | ||
21 | #if 0 | ||
22 | #define BRCTL_VERBOSE(...) __VA_ARGS__ | ||
23 | #else | ||
24 | #define BRCTL_VERBOSE(...) | ||
25 | #endif | ||
26 | |||
27 | int brctl_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
28 | int brctl_main(int argc, char **argv) | ||
29 | { | ||
30 | int fd; | ||
31 | static const char keywords[] ALIGN1 = | ||
32 | "addbr\0" "delbr\0" "addif\0" "delif\0" | ||
33 | USE_FEATURE_BRCTL_SHOW("show\0"); | ||
34 | enum { ARG_addbr = 1, ARG_delbr, ARG_addif, ARG_delif | ||
35 | USE_FEATURE_BRCTL_SHOW(, ARG_show) }; | ||
36 | smalluint key; | ||
37 | static char info[] = BRCTL_VERBOSE("%s ")"bridge %s\0 iface %s"; | ||
38 | |||
39 | argv++; | ||
40 | while (*argv) { | ||
41 | BRCTL_VERBOSE(char *op;) | ||
42 | |||
43 | key = index_in_strings(keywords, *argv) + 1; | ||
44 | if (key == 0) /* no match found in keywords array, bail out. */ | ||
45 | bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name); | ||
46 | argv++; | ||
47 | #if ENABLE_FEATURE_BRCTL_SHOW | ||
48 | if (key == ARG_show) { /* show */ | ||
49 | ; | ||
50 | } | ||
51 | #endif | ||
52 | BRCTL_VERBOSE(op = (char*)((key % 2) ? "add" : "del");) | ||
53 | fd = xsocket(AF_INET, SOCK_STREAM, 0); | ||
54 | if (key < 3) {/* addbr or delbr */ | ||
55 | char *br; | ||
56 | |||
57 | br = *(argv++); | ||
58 | if (ioctl(fd, key == ARG_addbr ? SIOCBRADDBR : SIOCBRDELBR, br) < 0) | ||
59 | { | ||
60 | info[9 BRCTL_VERBOSE(+3)] = '\0'; | ||
61 | bb_perror_msg_and_die(info, BRCTL_VERBOSE(op,) br); | ||
62 | } | ||
63 | } | ||
64 | if (key > 2) { /* addif or delif */ | ||
65 | struct ifreq ifr; | ||
66 | char *br, *brif; | ||
67 | |||
68 | br = *(argv++); | ||
69 | if (!*argv) | ||
70 | bb_show_usage(); | ||
71 | brif = *(argv++); | ||
72 | |||
73 | if (!(ifr.ifr_ifindex = if_nametoindex(brif))) { | ||
74 | bb_perror_msg_and_die(info+11 BRCTL_VERBOSE(+3), brif); | ||
75 | } | ||
76 | safe_strncpy(ifr.ifr_name, br, IFNAMSIZ); | ||
77 | if (ioctl(fd, | ||
78 | key == ARG_addif ? SIOCBRADDIF : SIOCBRDELIF, &ifr) < 0) { | ||
79 | info[9 BRCTL_VERBOSE(+3)] = ','; | ||
80 | bb_perror_msg_and_die (info, BRCTL_VERBOSE(op,) br, brif); | ||
81 | } | ||
82 | } | ||
83 | if (ENABLE_FEATURE_CLEAN_UP) | ||
84 | close(fd); | ||
85 | } | ||
86 | return EXIT_SUCCESS; | ||
87 | } | ||