source: clfs-embedded/patches/busybox-1.8.2-fixes-1.patch@ 7884e98

Last change on this file since 7884e98 was fb6d46f, checked in by Joe Ciccone <jciccone@…>, 17 years ago

Update Patch.

  • Property mode set to 100644
File size: 17.9 KB
RevLine 
[fb6d46f]1Submitted By: Tashiro Tsuramoto <tsuramoto@gmail.com>
2Date: 2008-01-05
3Initial Package Version: 1.2.2.1
4Origin: Jim Gifford
5 Tashiro Tsuramoto
6 Joe Ciccone
7Upstream Status: Unknown
8Description: Upply fixes from upstream.
9 busybox-1.8.2-arping.patch
10 busybox-1.8.2-static.patch
11 busybox-1.8.2-vi.patch
12 And make iptunnel.c play nice with the sanatized kernel headers.
13
14diff -Naur busybox-1.8.2.orig/applets/applets.c busybox-1.8.2/applets/applets.c
15--- busybox-1.8.2.orig/applets/applets.c 2007-11-09 20:40:53.000000000 -0500
16+++ busybox-1.8.2/applets/applets.c 2008-01-09 19:49:05.000000000 -0500
17@@ -17,7 +17,7 @@
18 #warning See sources.redhat.com/bugzilla/show_bug.cgi?id=3400
19 #warning Note that glibc is unsuitable for static linking anyway.
20 #warning If you still want to do it, remove -Wl,--gc-sections
21-#warning from top-level Makefile and remove this warning.
22+#warning from file scripts/trylink and remove this warning.
23 #error Aborting compilation.
24 #endif
25
26diff -Naur busybox-1.8.2.orig/editors/vi.c busybox-1.8.2/editors/vi.c
27--- busybox-1.8.2.orig/editors/vi.c 2007-11-09 20:40:54.000000000 -0500
28+++ busybox-1.8.2/editors/vi.c 2008-01-09 19:49:05.000000000 -0500
29@@ -184,6 +184,7 @@
30 #if ENABLE_FEATURE_VI_COLON
31 char *initial_cmds[3]; // currently 2 entries, NULL terminated
32 #endif
33+ char readbuffer[MAX_LINELEN];
34 };
35 #define G (*ptr_to_globals)
36 #define text (G.text )
37@@ -200,6 +201,10 @@
38 #define term_orig (G.term_orig )
39 #define term_vi (G.term_vi )
40 #define initial_cmds (G.initial_cmds )
41+#define readbuffer (G.readbuffer )
42+#define INIT_G() do { \
43+ PTR_TO_GLOBALS = xzalloc(sizeof(G)); \
44+} while (0)
45
46 static int init_text_buffer(char *); // init from file or create new
47 static void edit_file(char *); // edit one file
48@@ -321,7 +326,7 @@
49 my_pid = getpid();
50 #endif
51
52- PTR_TO_GLOBALS = xzalloc(sizeof(G));
53+ INIT_G();
54
55 #if ENABLE_FEATURE_VI_CRASHME
56 srand((long) my_pid);
57@@ -2142,8 +2147,6 @@
58 return safe_poll(pfd, 1, hund*10) > 0;
59 }
60
61-#define readbuffer bb_common_bufsiz1
62-
63 static int readed_for_parse;
64
65 //----- IO Routines --------------------------------------------
66diff -Naur busybox-1.8.2.orig/networking/arping.c busybox-1.8.2/networking/arping.c
67--- busybox-1.8.2.orig/networking/arping.c 2007-11-09 20:40:47.000000000 -0500
68+++ busybox-1.8.2/networking/arping.c 2008-01-09 19:49:05.000000000 -0500
69@@ -207,7 +207,8 @@
70 }
71
72 if (last) {
73- printf(" %u.%03ums\n", last / 1000, last % 1000);
74+ unsigned diff = MONOTONIC_US() - last;
75+ printf(" %u.%03ums\n", diff / 1000, diff % 1000);
76 } else {
77 printf(" UNSOLICITED?\n");
78 }
79diff -Naur busybox-1.8.2.orig/networking/libiproute/iptunnel.c busybox-1.8.2/networking/libiproute/iptunnel.c
80--- busybox-1.8.2.orig/networking/libiproute/iptunnel.c 2007-11-09 20:40:47.000000000 -0500
81+++ busybox-1.8.2/networking/libiproute/iptunnel.c 2008-01-09 19:51:01.000000000 -0500
82@@ -14,9 +14,8 @@
83 * Phil Karn <karn@ka9q.ampr.org> 990408: "pmtudisc" flag
84 */
85
86-#include <netinet/ip.h>
87-#include <net/if.h>
88-#include <net/if_arp.h>
89+#include <linux/if.h>
90+#include <linux/if_arp.h>
91 #include <asm/types.h>
92 #ifndef __constant_htons
93 #define __constant_htons htons
94diff -Naur busybox-1.8.2.orig/networking/libiproute/iptunnel.c.orig busybox-1.8.2/networking/libiproute/iptunnel.c.orig
95--- busybox-1.8.2.orig/networking/libiproute/iptunnel.c.orig 1969-12-31 19:00:00.000000000 -0500
96+++ busybox-1.8.2/networking/libiproute/iptunnel.c.orig 2007-11-09 20:40:47.000000000 -0500
97@@ -0,0 +1,541 @@
98+/* vi: set sw=4 ts=4: */
99+/*
100+ * iptunnel.c "ip tunnel"
101+ *
102+ * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
103+ *
104+ * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
105+ *
106+ *
107+ * Changes:
108+ *
109+ * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses
110+ * Rani Assaf <rani@magic.metawire.com> 980930: do not allow key for ipip/sit
111+ * Phil Karn <karn@ka9q.ampr.org> 990408: "pmtudisc" flag
112+ */
113+
114+#include <netinet/ip.h>
115+#include <net/if.h>
116+#include <net/if_arp.h>
117+#include <asm/types.h>
118+#ifndef __constant_htons
119+#define __constant_htons htons
120+#endif
121+#include <linux/if_tunnel.h>
122+
123+#include "ip_common.h" /* #include "libbb.h" is inside */
124+#include "rt_names.h"
125+#include "utils.h"
126+
127+
128+/* Dies on error */
129+static int do_ioctl_get_ifindex(char *dev)
130+{
131+ struct ifreq ifr;
132+ int fd;
133+
134+ strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
135+ fd = xsocket(AF_INET, SOCK_DGRAM, 0);
136+ xioctl(fd, SIOCGIFINDEX, &ifr);
137+ close(fd);
138+ return ifr.ifr_ifindex;
139+}
140+
141+static int do_ioctl_get_iftype(char *dev)
142+{
143+ struct ifreq ifr;
144+ int fd;
145+ int err;
146+
147+ strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
148+ fd = xsocket(AF_INET, SOCK_DGRAM, 0);
149+ err = ioctl_or_warn(fd, SIOCGIFHWADDR, &ifr);
150+ close(fd);
151+ return err ? -1 : ifr.ifr_addr.sa_family;
152+}
153+
154+static char *do_ioctl_get_ifname(int idx)
155+{
156+ struct ifreq ifr;
157+ int fd;
158+ int err;
159+
160+ ifr.ifr_ifindex = idx;
161+ fd = xsocket(AF_INET, SOCK_DGRAM, 0);
162+ err = ioctl_or_warn(fd, SIOCGIFNAME, &ifr);
163+ close(fd);
164+ return err ? NULL : xstrndup(ifr.ifr_name, sizeof(ifr.ifr_name));
165+}
166+
167+static int do_get_ioctl(const char *basedev, struct ip_tunnel_parm *p)
168+{
169+ struct ifreq ifr;
170+ int fd;
171+ int err;
172+
173+ strncpy(ifr.ifr_name, basedev, sizeof(ifr.ifr_name));
174+ ifr.ifr_ifru.ifru_data = (void*)p;
175+ fd = xsocket(AF_INET, SOCK_DGRAM, 0);
176+ err = ioctl_or_warn(fd, SIOCGETTUNNEL, &ifr);
177+ close(fd);
178+ return err;
179+}
180+
181+/* Dies on error, otherwise returns 0 */
182+static int do_add_ioctl(int cmd, const char *basedev, struct ip_tunnel_parm *p)
183+{
184+ struct ifreq ifr;
185+ int fd;
186+
187+ if (cmd == SIOCCHGTUNNEL && p->name[0]) {
188+ strncpy(ifr.ifr_name, p->name, sizeof(ifr.ifr_name));
189+ } else {
190+ strncpy(ifr.ifr_name, basedev, sizeof(ifr.ifr_name));
191+ }
192+ ifr.ifr_ifru.ifru_data = (void*)p;
193+ fd = xsocket(AF_INET, SOCK_DGRAM, 0);
194+#if ENABLE_IOCTL_HEX2STR_ERROR
195+ /* #define magic will turn ioctl# into string */
196+ if (cmd == SIOCCHGTUNNEL)
197+ xioctl(fd, SIOCCHGTUNNEL, &ifr);
198+ else
199+ xioctl(fd, SIOCADDTUNNEL, &ifr);
200+#else
201+ xioctl(fd, cmd, &ifr);
202+#endif
203+ close(fd);
204+ return 0;
205+}
206+
207+/* Dies on error, otherwise returns 0 */
208+static int do_del_ioctl(const char *basedev, struct ip_tunnel_parm *p)
209+{
210+ struct ifreq ifr;
211+ int fd;
212+
213+ if (p->name[0]) {
214+ strncpy(ifr.ifr_name, p->name, sizeof(ifr.ifr_name));
215+ } else {
216+ strncpy(ifr.ifr_name, basedev, sizeof(ifr.ifr_name));
217+ }
218+ ifr.ifr_ifru.ifru_data = (void*)p;
219+ fd = xsocket(AF_INET, SOCK_DGRAM, 0);
220+ xioctl(fd, SIOCDELTUNNEL, &ifr);
221+ close(fd);
222+ return 0;
223+}
224+
225+/* Dies on error */
226+static void parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
227+{
228+ static const char keywords[] ALIGN1 =
229+ "mode\0""ipip\0""ip/ip\0""gre\0""gre/ip\0""sit\0""ipv6/ip\0"
230+ "key\0""ikey\0""okey\0""seq\0""iseq\0""oseq\0"
231+ "csum\0""icsum\0""ocsum\0""nopmtudisc\0""pmtudisc\0"
232+ "remote\0""any\0""local\0""dev\0"
233+ "ttl\0""inherit\0""tos\0""dsfield\0"
234+ "name\0";
235+ enum {
236+ ARG_mode, ARG_ipip, ARG_ip_ip, ARG_gre, ARG_gre_ip, ARG_sit, ARG_ip6_ip,
237+ ARG_key, ARG_ikey, ARG_okey, ARG_seq, ARG_iseq, ARG_oseq,
238+ ARG_csum, ARG_icsum, ARG_ocsum, ARG_nopmtudisc, ARG_pmtudisc,
239+ ARG_remote, ARG_any, ARG_local, ARG_dev,
240+ ARG_ttl, ARG_inherit, ARG_tos, ARG_dsfield,
241+ ARG_name
242+ };
243+ int count = 0;
244+ char medium[IFNAMSIZ];
245+ int key;
246+
247+ memset(p, 0, sizeof(*p));
248+ memset(&medium, 0, sizeof(medium));
249+
250+ p->iph.version = 4;
251+ p->iph.ihl = 5;
252+#ifndef IP_DF
253+#define IP_DF 0x4000 /* Flag: "Don't Fragment" */
254+#endif
255+ p->iph.frag_off = htons(IP_DF);
256+
257+ while (argc > 0) {
258+ key = index_in_strings(keywords, *argv);
259+ if (key == ARG_mode) {
260+ NEXT_ARG();
261+ key = index_in_strings(keywords, *argv);
262+ if (key == ARG_ipip ||
263+ key == ARG_ip_ip) {
264+ if (p->iph.protocol && p->iph.protocol != IPPROTO_IPIP) {
265+ bb_error_msg_and_die("you managed to ask for more than one tunnel mode");
266+ }
267+ p->iph.protocol = IPPROTO_IPIP;
268+ } else if (key == ARG_gre ||
269+ key == ARG_gre_ip) {
270+ if (p->iph.protocol && p->iph.protocol != IPPROTO_GRE) {
271+ bb_error_msg_and_die("you managed to ask for more than one tunnel mode");
272+ }
273+ p->iph.protocol = IPPROTO_GRE;
274+ } else if (key == ARG_sit ||
275+ key == ARG_ip6_ip) {
276+ if (p->iph.protocol && p->iph.protocol != IPPROTO_IPV6) {
277+ bb_error_msg_and_die("you managed to ask for more than one tunnel mode");
278+ }
279+ p->iph.protocol = IPPROTO_IPV6;
280+ } else {
281+ bb_error_msg_and_die("cannot guess tunnel mode");
282+ }
283+ } else if (key == ARG_key) {
284+ unsigned uval;
285+ NEXT_ARG();
286+ p->i_flags |= GRE_KEY;
287+ p->o_flags |= GRE_KEY;
288+ if (strchr(*argv, '.'))
289+ p->i_key = p->o_key = get_addr32(*argv);
290+ else {
291+ if (get_unsigned(&uval, *argv, 0)<0) {
292+ bb_error_msg_and_die("invalid value of \"key\"");
293+ }
294+ p->i_key = p->o_key = htonl(uval);
295+ }
296+ } else if (key == ARG_ikey) {
297+ unsigned uval;
298+ NEXT_ARG();
299+ p->i_flags |= GRE_KEY;
300+ if (strchr(*argv, '.'))
301+ p->o_key = get_addr32(*argv);
302+ else {
303+ if (get_unsigned(&uval, *argv, 0)<0) {
304+ bb_error_msg_and_die("invalid value of \"ikey\"");
305+ }
306+ p->i_key = htonl(uval);
307+ }
308+ } else if (key == ARG_okey) {
309+ unsigned uval;
310+ NEXT_ARG();
311+ p->o_flags |= GRE_KEY;
312+ if (strchr(*argv, '.'))
313+ p->o_key = get_addr32(*argv);
314+ else {
315+ if (get_unsigned(&uval, *argv, 0)<0) {
316+ bb_error_msg_and_die("invalid value of \"okey\"");
317+ }
318+ p->o_key = htonl(uval);
319+ }
320+ } else if (key == ARG_seq) {
321+ p->i_flags |= GRE_SEQ;
322+ p->o_flags |= GRE_SEQ;
323+ } else if (key == ARG_iseq) {
324+ p->i_flags |= GRE_SEQ;
325+ } else if (key == ARG_oseq) {
326+ p->o_flags |= GRE_SEQ;
327+ } else if (key == ARG_csum) {
328+ p->i_flags |= GRE_CSUM;
329+ p->o_flags |= GRE_CSUM;
330+ } else if (key == ARG_icsum) {
331+ p->i_flags |= GRE_CSUM;
332+ } else if (key == ARG_ocsum) {
333+ p->o_flags |= GRE_CSUM;
334+ } else if (key == ARG_nopmtudisc) {
335+ p->iph.frag_off = 0;
336+ } else if (key == ARG_pmtudisc) {
337+ p->iph.frag_off = htons(IP_DF);
338+ } else if (key == ARG_remote) {
339+ NEXT_ARG();
340+ key = index_in_strings(keywords, *argv);
341+ if (key != ARG_any)
342+ p->iph.daddr = get_addr32(*argv);
343+ } else if (key == ARG_local) {
344+ NEXT_ARG();
345+ key = index_in_strings(keywords, *argv);
346+ if (key != ARG_any)
347+ p->iph.saddr = get_addr32(*argv);
348+ } else if (key == ARG_dev) {
349+ NEXT_ARG();
350+ strncpy(medium, *argv, IFNAMSIZ-1);
351+ } else if (key == ARG_ttl) {
352+ unsigned uval;
353+ NEXT_ARG();
354+ key = index_in_strings(keywords, *argv);
355+ if (key != ARG_inherit) {
356+ if (get_unsigned(&uval, *argv, 0))
357+ invarg(*argv, "TTL");
358+ if (uval > 255)
359+ invarg(*argv, "TTL must be <=255");
360+ p->iph.ttl = uval;
361+ }
362+ } else if (key == ARG_tos ||
363+ key == ARG_dsfield) {
364+ uint32_t uval;
365+ NEXT_ARG();
366+ key = index_in_strings(keywords, *argv);
367+ if (key != ARG_inherit) {
368+ if (rtnl_dsfield_a2n(&uval, *argv))
369+ invarg(*argv, "TOS");
370+ p->iph.tos = uval;
371+ } else
372+ p->iph.tos = 1;
373+ } else {
374+ if (key == ARG_name) {
375+ NEXT_ARG();
376+ }
377+ if (p->name[0])
378+ duparg2("name", *argv);
379+ strncpy(p->name, *argv, IFNAMSIZ);
380+ if (cmd == SIOCCHGTUNNEL && count == 0) {
381+ struct ip_tunnel_parm old_p;
382+ memset(&old_p, 0, sizeof(old_p));
383+ if (do_get_ioctl(*argv, &old_p))
384+ exit(1);
385+ *p = old_p;
386+ }
387+ }
388+ count++;
389+ argc--;
390+ argv++;
391+ }
392+
393+ if (p->iph.protocol == 0) {
394+ if (memcmp(p->name, "gre", 3) == 0)
395+ p->iph.protocol = IPPROTO_GRE;
396+ else if (memcmp(p->name, "ipip", 4) == 0)
397+ p->iph.protocol = IPPROTO_IPIP;
398+ else if (memcmp(p->name, "sit", 3) == 0)
399+ p->iph.protocol = IPPROTO_IPV6;
400+ }
401+
402+ if (p->iph.protocol == IPPROTO_IPIP || p->iph.protocol == IPPROTO_IPV6) {
403+ if ((p->i_flags & GRE_KEY) || (p->o_flags & GRE_KEY)) {
404+ bb_error_msg_and_die("keys are not allowed with ipip and sit");
405+ }
406+ }
407+
408+ if (medium[0]) {
409+ p->link = do_ioctl_get_ifindex(medium);
410+ }
411+
412+ if (p->i_key == 0 && IN_MULTICAST(ntohl(p->iph.daddr))) {
413+ p->i_key = p->iph.daddr;
414+ p->i_flags |= GRE_KEY;
415+ }
416+ if (p->o_key == 0 && IN_MULTICAST(ntohl(p->iph.daddr))) {
417+ p->o_key = p->iph.daddr;
418+ p->o_flags |= GRE_KEY;
419+ }
420+ if (IN_MULTICAST(ntohl(p->iph.daddr)) && !p->iph.saddr) {
421+ bb_error_msg_and_die("broadcast tunnel requires a source address");
422+ }
423+}
424+
425+
426+/* Return value becomes exitcode. It's okay to not return at all */
427+static int do_add(int cmd, int argc, char **argv)
428+{
429+ struct ip_tunnel_parm p;
430+
431+ parse_args(argc, argv, cmd, &p);
432+
433+ if (p.iph.ttl && p.iph.frag_off == 0) {
434+ bb_error_msg_and_die("ttl != 0 and noptmudisc are incompatible");
435+ }
436+
437+ switch (p.iph.protocol) {
438+ case IPPROTO_IPIP:
439+ return do_add_ioctl(cmd, "tunl0", &p);
440+ case IPPROTO_GRE:
441+ return do_add_ioctl(cmd, "gre0", &p);
442+ case IPPROTO_IPV6:
443+ return do_add_ioctl(cmd, "sit0", &p);
444+ default:
445+ bb_error_msg_and_die("cannot determine tunnel mode (ipip, gre or sit)");
446+ }
447+}
448+
449+/* Return value becomes exitcode. It's okay to not return at all */
450+static int do_del(int argc, char **argv)
451+{
452+ struct ip_tunnel_parm p;
453+
454+ parse_args(argc, argv, SIOCDELTUNNEL, &p);
455+
456+ switch (p.iph.protocol) {
457+ case IPPROTO_IPIP:
458+ return do_del_ioctl("tunl0", &p);
459+ case IPPROTO_GRE:
460+ return do_del_ioctl("gre0", &p);
461+ case IPPROTO_IPV6:
462+ return do_del_ioctl("sit0", &p);
463+ default:
464+ return do_del_ioctl(p.name, &p);
465+ }
466+}
467+
468+static void print_tunnel(struct ip_tunnel_parm *p)
469+{
470+ char s1[256];
471+ char s2[256];
472+ char s3[64];
473+ char s4[64];
474+
475+ format_host(AF_INET, 4, &p->iph.daddr, s1, sizeof(s1));
476+ format_host(AF_INET, 4, &p->iph.saddr, s2, sizeof(s2));
477+ inet_ntop(AF_INET, &p->i_key, s3, sizeof(s3));
478+ inet_ntop(AF_INET, &p->o_key, s4, sizeof(s4));
479+
480+ printf("%s: %s/ip remote %s local %s ",
481+ p->name,
482+ p->iph.protocol == IPPROTO_IPIP ? "ip" :
483+ (p->iph.protocol == IPPROTO_GRE ? "gre" :
484+ (p->iph.protocol == IPPROTO_IPV6 ? "ipv6" : "unknown")),
485+ p->iph.daddr ? s1 : "any", p->iph.saddr ? s2 : "any");
486+ if (p->link) {
487+ char *n = do_ioctl_get_ifname(p->link);
488+ if (n) {
489+ printf(" dev %s ", n);
490+ free(n);
491+ }
492+ }
493+ if (p->iph.ttl)
494+ printf(" ttl %d ", p->iph.ttl);
495+ else
496+ printf(" ttl inherit ");
497+ if (p->iph.tos) {
498+ SPRINT_BUF(b1);
499+ printf(" tos");
500+ if (p->iph.tos & 1)
501+ printf(" inherit");
502+ if (p->iph.tos & ~1)
503+ printf("%c%s ", p->iph.tos & 1 ? '/' : ' ',
504+ rtnl_dsfield_n2a(p->iph.tos & ~1, b1, sizeof(b1)));
505+ }
506+ if (!(p->iph.frag_off & htons(IP_DF)))
507+ printf(" nopmtudisc");
508+
509+ if ((p->i_flags & GRE_KEY) && (p->o_flags & GRE_KEY) && p->o_key == p->i_key)
510+ printf(" key %s", s3);
511+ else if ((p->i_flags | p->o_flags) & GRE_KEY) {
512+ if (p->i_flags & GRE_KEY)
513+ printf(" ikey %s ", s3);
514+ if (p->o_flags & GRE_KEY)
515+ printf(" okey %s ", s4);
516+ }
517+
518+ if (p->i_flags & GRE_SEQ)
519+ printf("%c Drop packets out of sequence.\n", _SL_);
520+ if (p->i_flags & GRE_CSUM)
521+ printf("%c Checksum in received packet is required.", _SL_);
522+ if (p->o_flags & GRE_SEQ)
523+ printf("%c Sequence packets on output.", _SL_);
524+ if (p->o_flags & GRE_CSUM)
525+ printf("%c Checksum output packets.", _SL_);
526+}
527+
528+static void do_tunnels_list(struct ip_tunnel_parm *p)
529+{
530+ char name[IFNAMSIZ];
531+ unsigned long rx_bytes, rx_packets, rx_errs, rx_drops,
532+ rx_fifo, rx_frame,
533+ tx_bytes, tx_packets, tx_errs, tx_drops,
534+ tx_fifo, tx_colls, tx_carrier, rx_multi;
535+ int type;
536+ struct ip_tunnel_parm p1;
537+ char buf[512];
538+ FILE *fp = fopen_or_warn("/proc/net/dev", "r");
539+
540+ if (fp == NULL) {
541+ return;
542+ }
543+
544+ fgets(buf, sizeof(buf), fp);
545+ fgets(buf, sizeof(buf), fp);
546+
547+ while (fgets(buf, sizeof(buf), fp) != NULL) {
548+ char *ptr;
549+
550+ /*buf[sizeof(buf) - 1] = 0; - fgets is safe anyway */
551+ ptr = strchr(buf, ':');
552+ if (ptr == NULL ||
553+ (*ptr++ = 0, sscanf(buf, "%s", name) != 1)) {
554+ bb_error_msg("wrong format of /proc/net/dev");
555+ return;
556+ }
557+ if (sscanf(ptr, "%lu%lu%lu%lu%lu%lu%lu%*d%lu%lu%lu%lu%lu%lu%lu",
558+ &rx_bytes, &rx_packets, &rx_errs, &rx_drops,
559+ &rx_fifo, &rx_frame, &rx_multi,
560+ &tx_bytes, &tx_packets, &tx_errs, &tx_drops,
561+ &tx_fifo, &tx_colls, &tx_carrier) != 14)
562+ continue;
563+ if (p->name[0] && strcmp(p->name, name))
564+ continue;
565+ type = do_ioctl_get_iftype(name);
566+ if (type == -1) {
567+ bb_error_msg("cannot get type of [%s]", name);
568+ continue;
569+ }
570+ if (type != ARPHRD_TUNNEL && type != ARPHRD_IPGRE && type != ARPHRD_SIT)
571+ continue;
572+ memset(&p1, 0, sizeof(p1));
573+ if (do_get_ioctl(name, &p1))
574+ continue;
575+ if ((p->link && p1.link != p->link) ||
576+ (p->name[0] && strcmp(p1.name, p->name)) ||
577+ (p->iph.daddr && p1.iph.daddr != p->iph.daddr) ||
578+ (p->iph.saddr && p1.iph.saddr != p->iph.saddr) ||
579+ (p->i_key && p1.i_key != p->i_key))
580+ continue;
581+ print_tunnel(&p1);
582+ bb_putchar('\n');
583+ }
584+}
585+
586+/* Return value becomes exitcode. It's okay to not return at all */
587+static int do_show(int argc, char **argv)
588+{
589+ int err;
590+ struct ip_tunnel_parm p;
591+
592+ parse_args(argc, argv, SIOCGETTUNNEL, &p);
593+
594+ switch (p.iph.protocol) {
595+ case IPPROTO_IPIP:
596+ err = do_get_ioctl(p.name[0] ? p.name : "tunl0", &p);
597+ break;
598+ case IPPROTO_GRE:
599+ err = do_get_ioctl(p.name[0] ? p.name : "gre0", &p);
600+ break;
601+ case IPPROTO_IPV6:
602+ err = do_get_ioctl(p.name[0] ? p.name : "sit0", &p);
603+ break;
604+ default:
605+ do_tunnels_list(&p);
606+ return 0;
607+ }
608+ if (err)
609+ return -1;
610+
611+ print_tunnel(&p);
612+ bb_putchar('\n');
613+ return 0;
614+}
615+
616+/* Return value becomes exitcode. It's okay to not return at all */
617+int do_iptunnel(int argc, char **argv)
618+{
619+ static const char keywords[] ALIGN1 =
620+ "add\0""change\0""delete\0""show\0""list\0""lst\0";
621+ enum { ARG_add = 0, ARG_change, ARG_del, ARG_show, ARG_list, ARG_lst };
622+ int key;
623+
624+ if (argc) {
625+ key = index_in_substrings(keywords, *argv);
626+ if (key < 0)
627+ bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);
628+ --argc;
629+ ++argv;
630+ if (key == ARG_add)
631+ return do_add(SIOCADDTUNNEL, argc, argv);
632+ if (key == ARG_change)
633+ return do_add(SIOCCHGTUNNEL, argc, argv);
634+ if (key == ARG_del)
635+ return do_del(argc, argv);
636+ }
637+ return do_show(argc, argv);
638+}
Note: See TracBrowser for help on using the repository browser.