summaryrefslogtreecommitdiff
path: root/networking/libiproute/iptunnel.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/libiproute/iptunnel.c')
-rw-r--r--networking/libiproute/iptunnel.c80
1 files changed, 34 insertions, 46 deletions
diff --git a/networking/libiproute/iptunnel.c b/networking/libiproute/iptunnel.c
index b12bceb45..90d0e1186 100644
--- a/networking/libiproute/iptunnel.c
+++ b/networking/libiproute/iptunnel.c
@@ -14,8 +14,6 @@
14 * Phil Karn <karn@ka9q.ampr.org> 990408: "pmtudisc" flag 14 * Phil Karn <karn@ka9q.ampr.org> 990408: "pmtudisc" flag
15 */ 15 */
16 16
17//#include <sys/socket.h>
18//#include <sys/ioctl.h>
19#include <netinet/ip.h> 17#include <netinet/ip.h>
20#include <net/if.h> 18#include <net/if.h>
21#include <net/if_arp.h> 19#include <net/if_arp.h>
@@ -38,9 +36,7 @@ static int do_ioctl_get_ifindex(char *dev)
38 36
39 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); 37 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
40 fd = xsocket(AF_INET, SOCK_DGRAM, 0); 38 fd = xsocket(AF_INET, SOCK_DGRAM, 0);
41 if (ioctl(fd, SIOCGIFINDEX, &ifr)) { 39 xioctl(fd, SIOCGIFINDEX, &ifr);
42 bb_perror_msg_and_die("SIOCGIFINDEX");
43 }
44 close(fd); 40 close(fd);
45 return ifr.ifr_ifindex; 41 return ifr.ifr_ifindex;
46} 42}
@@ -49,30 +45,26 @@ static int do_ioctl_get_iftype(char *dev)
49{ 45{
50 struct ifreq ifr; 46 struct ifreq ifr;
51 int fd; 47 int fd;
48 int err;
52 49
53 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); 50 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
54 fd = xsocket(AF_INET, SOCK_DGRAM, 0); 51 fd = xsocket(AF_INET, SOCK_DGRAM, 0);
55 if (ioctl(fd, SIOCGIFHWADDR, &ifr)) { 52 err = ioctl_or_warn(fd, SIOCGIFHWADDR, &ifr);
56 bb_perror_msg("SIOCGIFHWADDR");
57 return -1;
58 }
59 close(fd); 53 close(fd);
60 return ifr.ifr_addr.sa_family; 54 return err ? -1 : ifr.ifr_addr.sa_family;
61} 55}
62 56
63static char *do_ioctl_get_ifname(int idx) 57static char *do_ioctl_get_ifname(int idx)
64{ 58{
65 struct ifreq ifr; 59 struct ifreq ifr;
66 int fd; 60 int fd;
61 int err;
67 62
68 ifr.ifr_ifindex = idx; 63 ifr.ifr_ifindex = idx;
69 fd = xsocket(AF_INET, SOCK_DGRAM, 0); 64 fd = xsocket(AF_INET, SOCK_DGRAM, 0);
70 if (ioctl(fd, SIOCGIFNAME, &ifr)) { 65 err = ioctl_or_warn(fd, SIOCGIFNAME, &ifr);
71 bb_perror_msg("SIOCGIFNAME");
72 return NULL;
73 }
74 close(fd); 66 close(fd);
75 return xstrndup(ifr.ifr_name, sizeof(ifr.ifr_name)); 67 return err ? NULL : xstrndup(ifr.ifr_name, sizeof(ifr.ifr_name));
76} 68}
77 69
78static int do_get_ioctl(const char *basedev, struct ip_tunnel_parm *p) 70static int do_get_ioctl(const char *basedev, struct ip_tunnel_parm *p)
@@ -84,10 +76,7 @@ static int do_get_ioctl(const char *basedev, struct ip_tunnel_parm *p)
84 strncpy(ifr.ifr_name, basedev, sizeof(ifr.ifr_name)); 76 strncpy(ifr.ifr_name, basedev, sizeof(ifr.ifr_name));
85 ifr.ifr_ifru.ifru_data = (void*)p; 77 ifr.ifr_ifru.ifru_data = (void*)p;
86 fd = xsocket(AF_INET, SOCK_DGRAM, 0); 78 fd = xsocket(AF_INET, SOCK_DGRAM, 0);
87 err = ioctl(fd, SIOCGETTUNNEL, &ifr); 79 err = ioctl_or_warn(fd, SIOCGETTUNNEL, &ifr);
88 if (err) {
89 bb_perror_msg("SIOCGETTUNNEL");
90 }
91 close(fd); 80 close(fd);
92 return err; 81 return err;
93} 82}
@@ -105,9 +94,15 @@ static int do_add_ioctl(int cmd, const char *basedev, struct ip_tunnel_parm *p)
105 } 94 }
106 ifr.ifr_ifru.ifru_data = (void*)p; 95 ifr.ifr_ifru.ifru_data = (void*)p;
107 fd = xsocket(AF_INET, SOCK_DGRAM, 0); 96 fd = xsocket(AF_INET, SOCK_DGRAM, 0);
108 if (ioctl(fd, cmd, &ifr)) { 97#if ENABLE_IOCTL_HEX2STR_ERROR
109 bb_perror_msg_and_die("ioctl"); 98 /* #define magic will turn ioctl# into string */
110 } 99 if (cmd == SIOCCHGTUNNEL)
100 xioctl(fd, SIOCCHGTUNNEL, &ifr);
101 else
102 xioctl(fd, SIOCADDTUNNEL, &ifr);
103#else
104 xioctl(fd, cmd, &ifr);
105#endif
111 close(fd); 106 close(fd);
112 return 0; 107 return 0;
113} 108}
@@ -125,9 +120,7 @@ static int do_del_ioctl(const char *basedev, struct ip_tunnel_parm *p)
125 } 120 }
126 ifr.ifr_ifru.ifru_data = (void*)p; 121 ifr.ifr_ifru.ifru_data = (void*)p;
127 fd = xsocket(AF_INET, SOCK_DGRAM, 0); 122 fd = xsocket(AF_INET, SOCK_DGRAM, 0);
128 if (ioctl(fd, SIOCDELTUNNEL, &ifr)) { 123 xioctl(fd, SIOCDELTUNNEL, &ifr);
129 bb_perror_msg_and_die("SIOCDELTUNNEL");
130 }
131 close(fd); 124 close(fd);
132 return 0; 125 return 0;
133} 126}
@@ -526,29 +519,24 @@ static int do_show(int argc, char **argv)
526/* Return value becomes exitcode. It's okay to not return at all */ 519/* Return value becomes exitcode. It's okay to not return at all */
527int do_iptunnel(int argc, char **argv) 520int do_iptunnel(int argc, char **argv)
528{ 521{
529 static const char * const keywords[] = { 522 static const char *const keywords[] = {
530 "add", "change", "delete", "show", "list", "lst", NULL 523 "add", "change", "delete", "show", "list", "lst", NULL
531 }; 524 };
532 enum {ARG_add = 1, ARG_change, ARG_del, ARG_show, ARG_list, ARG_lst}; 525 enum { ARG_add = 0, ARG_change, ARG_del, ARG_show, ARG_list, ARG_lst };
533 smalluint key = 4; /* show */ 526 int key;
534 if (argc > 0) { 527
535 key = index_in_substr_array(keywords, *argv) +1; 528 if (argc) {
529 key = index_in_substr_array(keywords, *argv);
530 if (key < 0)
531 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);
536 --argc; 532 --argc;
537 ++argv; 533 ++argv;
538 } else 534 if (key == ARG_add)
539 return do_show(0, NULL); 535 return do_add(SIOCADDTUNNEL, argc, argv);
540 if (key < ARG_add) 536 if (key == ARG_change)
541 bail: 537 return do_add(SIOCCHGTUNNEL, argc, argv);
542 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name); 538 if (key == ARG_del)
543 539 return do_del(argc, argv);
544 if (key == ARG_add) 540 }
545 return do_add(SIOCADDTUNNEL, argc, argv); 541 return do_show(argc, argv);
546 if (key == ARG_change)
547 return do_add(SIOCCHGTUNNEL, argc, argv);
548 if (key == ARG_del)
549 return do_del(argc, argv);
550 if (key == ARG_show || key == ARG_list || key == ARG_lst)
551 return do_show(argc, argv);
552 /* be gentle to gcc; avoid warning about non returning */
553 goto bail; /* never reached */
554} 542}