aboutsummaryrefslogtreecommitdiff
path: root/networking/libiproute/iplink.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/libiproute/iplink.c')
-rw-r--r--networking/libiproute/iplink.c75
1 files changed, 39 insertions, 36 deletions
diff --git a/networking/libiproute/iplink.c b/networking/libiproute/iplink.c
index 0943726e1..5feab1e49 100644
--- a/networking/libiproute/iplink.c
+++ b/networking/libiproute/iplink.c
@@ -42,10 +42,7 @@ static int get_ctl_fd(void)
42 fd = socket(PF_PACKET, SOCK_DGRAM, 0); 42 fd = socket(PF_PACKET, SOCK_DGRAM, 0);
43 if (fd >= 0) 43 if (fd >= 0)
44 return fd; 44 return fd;
45 fd = socket(PF_INET6, SOCK_DGRAM, 0); 45 return xsocket(PF_INET6, SOCK_DGRAM, 0);
46 if (fd >= 0)
47 return fd;
48 bb_perror_msg_and_die("cannot create control socket");
49} 46}
50 47
51/* Exits on error */ 48/* Exits on error */
@@ -125,10 +122,7 @@ static int get_address(char *dev, int *htype)
125 socklen_t alen; 122 socklen_t alen;
126 int s; 123 int s;
127 124
128 s = socket(PF_PACKET, SOCK_DGRAM, 0); 125 s = xsocket(PF_PACKET, SOCK_DGRAM, 0);
129 if (s < 0) {
130 bb_perror_msg_and_die("socket(PF_PACKET)");
131 }
132 126
133 memset(&ifr, 0, sizeof(ifr)); 127 memset(&ifr, 0, sizeof(ifr));
134 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); 128 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
@@ -140,9 +134,7 @@ static int get_address(char *dev, int *htype)
140 me.sll_family = AF_PACKET; 134 me.sll_family = AF_PACKET;
141 me.sll_ifindex = ifr.ifr_ifindex; 135 me.sll_ifindex = ifr.ifr_ifindex;
142 me.sll_protocol = htons(ETH_P_LOOP); 136 me.sll_protocol = htons(ETH_P_LOOP);
143 if (bind(s, (struct sockaddr*)&me, sizeof(me)) == -1) { 137 xbind(s, (struct sockaddr*)&me, sizeof(me));
144 bb_perror_msg_and_die("bind");
145 }
146 138
147 alen = sizeof(me); 139 alen = sizeof(me);
148 if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) { 140 if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) {
@@ -195,54 +187,63 @@ static int do_set(int argc, char **argv)
195 struct ifreq ifr0, ifr1; 187 struct ifreq ifr0, ifr1;
196 char *newname = NULL; 188 char *newname = NULL;
197 int htype, halen; 189 int htype, halen;
190 static const char * const keywords[] = {
191 "up", "down", "name", "mtu", "multicast", "arp", "addr", "dev",
192 "on", "off", NULL
193 };
194 enum { ARG_up = 1, ARG_down, ARG_name, ARG_mtu, ARG_multicast, ARG_arp,
195 ARG_addr, ARG_dev, PARM_on, PARM_off };
196 smalluint key;
198 197
199 while (argc > 0) { 198 while (argc > 0) {
200 if (strcmp(*argv, "up") == 0) { 199 key = index_in_str_array(keywords, *argv) + 1;
200 if (key == ARG_up) {
201 mask |= IFF_UP; 201 mask |= IFF_UP;
202 flags |= IFF_UP; 202 flags |= IFF_UP;
203 } else if (strcmp(*argv, "down") == 0) { 203 } else if (key == ARG_down) {
204 mask |= IFF_UP; 204 mask |= IFF_UP;
205 flags &= ~IFF_UP; 205 flags &= ~IFF_UP;
206 } else if (strcmp(*argv, "name") == 0) { 206 } else if (key == ARG_name) {
207 NEXT_ARG(); 207 NEXT_ARG();
208 newname = *argv; 208 newname = *argv;
209 } else if (strcmp(*argv, "mtu") == 0) { 209 } else if (key == ARG_mtu) {
210 NEXT_ARG(); 210 NEXT_ARG();
211 if (mtu != -1) 211 if (mtu != -1)
212 duparg("mtu", *argv); 212 duparg("mtu", *argv);
213 if (get_integer(&mtu, *argv, 0)) 213 if (get_integer(&mtu, *argv, 0))
214 invarg(*argv, "mtu"); 214 invarg(*argv, "mtu");
215 } else if (strcmp(*argv, "multicast") == 0) { 215 } else if (key == ARG_multicast) {
216 NEXT_ARG(); 216 NEXT_ARG();
217 mask |= IFF_MULTICAST; 217 mask |= IFF_MULTICAST;
218 if (strcmp(*argv, "on") == 0) { 218 key = index_in_str_array(keywords, *argv) + 1;
219 if (key == PARM_on) {
219 flags |= IFF_MULTICAST; 220 flags |= IFF_MULTICAST;
220 } else if (strcmp(*argv, "off") == 0) { 221 } else if (key == PARM_off) {
221 flags &= ~IFF_MULTICAST; 222 flags &= ~IFF_MULTICAST;
222 } else 223 } else
223 on_off("multicast"); 224 on_off("multicast");
224 } else if (strcmp(*argv, "arp") == 0) { 225 } else if (key == ARG_arp) {
225 NEXT_ARG(); 226 NEXT_ARG();
226 mask |= IFF_NOARP; 227 mask |= IFF_NOARP;
227 if (strcmp(*argv, "on") == 0) { 228 key = index_in_str_array(keywords, *argv) + 1;
229 if (key == PARM_on) {
228 flags &= ~IFF_NOARP; 230 flags &= ~IFF_NOARP;
229 } else if (strcmp(*argv, "off") == 0) { 231 } else if (key == PARM_off) {
230 flags |= IFF_NOARP; 232 flags |= IFF_NOARP;
231 } else 233 } else
232 on_off("noarp"); 234 on_off("arp");
233 } else if (strcmp(*argv, "addr") == 0) { 235 } else if (key == ARG_addr) {
234 NEXT_ARG(); 236 NEXT_ARG();
235 newaddr = *argv; 237 newaddr = *argv;
236 } else { 238 } else {
237 if (strcmp(*argv, "dev") == 0) { 239 if (key == ARG_dev) {
238 NEXT_ARG(); 240 NEXT_ARG();
239 } 241 }
240 if (dev) 242 if (dev)
241 duparg2("dev", *argv); 243 duparg2("dev", *argv);
242 dev = *argv; 244 dev = *argv;
243 } 245 }
244 argc--; 246 argc--; argv++;
245 argv++;
246 } 247 }
247 248
248 if (!dev) { 249 if (!dev) {
@@ -291,16 +292,18 @@ static int ipaddr_list_link(int argc, char **argv)
291/* Return value becomes exitcode. It's okay to not return at all */ 292/* Return value becomes exitcode. It's okay to not return at all */
292int do_iplink(int argc, char **argv) 293int do_iplink(int argc, char **argv)
293{ 294{
295 static const char * const keywords[] = {
296 "set", "show", "lst", "list", NULL
297 };
298 smalluint key;
294 if (argc <= 0) 299 if (argc <= 0)
295 return ipaddr_list_link(0, NULL); 300 return ipaddr_list_link(0, NULL);
296 301 key = index_in_substr_array(keywords, *argv) + 1;
297 if (matches(*argv, "set") == 0) 302 if (key == 0)
298 return do_set(argc-1, argv+1); 303 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);
299 304 argc--; argv++;
300 if (matches(*argv, "show") == 0 || 305 if (key == 1) /* set */
301 matches(*argv, "lst") == 0 || 306 return do_set(argc, argv);
302 matches(*argv, "list") == 0) 307 else /* show, lst, list */
303 return ipaddr_list_link(argc-1, argv+1); 308 return ipaddr_list_link(argc, argv);
304
305 bb_error_msg_and_die("command \"%s\" is unknown", *argv);
306} 309}