iptunnel.c revision 4282c6c52b4f1f4b5e1ef5ef377c342ca87e0b73
1aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger/*
2aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * iptunnel.c	       "ip tunnel"
3aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *
4aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		This program is free software; you can redistribute it and/or
5aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		modify it under the terms of the GNU General Public License
6aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		as published by the Free Software Foundation; either version
7aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		2 of the License, or (at your option) any later version.
8aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *
9aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
10aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *
11aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *
12aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * Changes:
13aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *
14aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * Rani Assaf <rani@magic.metawire.com> 980929:	resolve addresses
15aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * Rani Assaf <rani@magic.metawire.com> 980930:	do not allow key for ipip/sit
16aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * Phil Karn <karn@ka9q.ampr.org>	990408:	"pmtudisc" flag
17aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger */
18aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
19aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdio.h>
20aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdlib.h>
21aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <string.h>
22aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <unistd.h>
23d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA#include <sys/types.h>
24aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/socket.h>
257272ddc775845d96ad1d388ced7ecdbc8612c64eosdl.org!shemminger#include <arpa/inet.h>
26aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/ioctl.h>
27aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <linux/if.h>
28aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <linux/if_arp.h>
297272ddc775845d96ad1d388ced7ecdbc8612c64eosdl.org!shemminger#include <linux/ip.h>
30aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <linux/if_tunnel.h>
31aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
32aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "rt_names.h"
33aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "utils.h"
34288384f22ffafd2d7d888ee45d8dfcf26d3f2b1cMasahide NAKAMURA#include "ip_common.h"
35d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA#include "tunnel.h"
36aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
37aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic void usage(void) __attribute__((noreturn));
38aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
39aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic void usage(void)
40aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
41aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr, "Usage: ip tunnel { add | change | del | show } [ NAME ]\n");
42aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr, "          [ mode { ipip | gre | sit } ] [ remote ADDR ] [ local ADDR ]\n");
43aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr, "          [ [i|o]seq ] [ [i|o]key KEY ] [ [i|o]csum ]\n");
44aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr, "          [ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]\n");
45aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr, "\n");
46aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr, "Where: NAME := STRING\n");
47aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr, "       ADDR := { IP_ADDRESS | any }\n");
48aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr, "       TOS  := { NUMBER | inherit }\n");
49aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr, "       TTL  := { 1..255 | inherit }\n");
50aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr, "       KEY  := { DOTTED_QUAD | NUMBER }\n");
51aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	exit(-1);
52aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
53aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
54aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
55aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
56aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int count = 0;
57aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char medium[IFNAMSIZ];
58aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
59aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	memset(p, 0, sizeof(*p));
60aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	memset(&medium, 0, sizeof(medium));
61aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
62aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	p->iph.version = 4;
63aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	p->iph.ihl = 5;
64aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#ifndef IP_DF
65aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#define IP_DF		0x4000		/* Flag: "Don't Fragment"	*/
66aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#endif
67aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	p->iph.frag_off = htons(IP_DF);
68aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
69aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	while (argc > 0) {
70aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (strcmp(*argv, "mode") == 0) {
71aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
72aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (strcmp(*argv, "ipip") == 0 ||
73aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			    strcmp(*argv, "ip/ip") == 0) {
74aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				if (p->iph.protocol && p->iph.protocol != IPPROTO_IPIP) {
75aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					fprintf(stderr,"You managed to ask for more than one tunnel mode.\n");
76aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					exit(-1);
77aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				}
78aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				p->iph.protocol = IPPROTO_IPIP;
79aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			} else if (strcmp(*argv, "gre") == 0 ||
80aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				   strcmp(*argv, "gre/ip") == 0) {
81aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				if (p->iph.protocol && p->iph.protocol != IPPROTO_GRE) {
82aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					fprintf(stderr,"You managed to ask for more than one tunnel mode.\n");
83aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					exit(-1);
84aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				}
85aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				p->iph.protocol = IPPROTO_GRE;
86aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			} else if (strcmp(*argv, "sit") == 0 ||
87aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				   strcmp(*argv, "ipv6/ip") == 0) {
88aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				if (p->iph.protocol && p->iph.protocol != IPPROTO_IPV6) {
89aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					fprintf(stderr,"You managed to ask for more than one tunnel mode.\n");
90aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					exit(-1);
91aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				}
92aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				p->iph.protocol = IPPROTO_IPV6;
93aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			} else {
94aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				fprintf(stderr,"Cannot guess tunnel mode.\n");
95aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				exit(-1);
96aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
97aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "key") == 0) {
98aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			unsigned uval;
99aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
100aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			p->i_flags |= GRE_KEY;
101aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			p->o_flags |= GRE_KEY;
102aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (strchr(*argv, '.'))
103aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				p->i_key = p->o_key = get_addr32(*argv);
104aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			else {
105aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				if (get_unsigned(&uval, *argv, 0)<0) {
106aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					fprintf(stderr, "invalid value of \"key\"\n");
107aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					exit(-1);
108aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				}
109aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				p->i_key = p->o_key = htonl(uval);
110aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
111aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "ikey") == 0) {
112aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			unsigned uval;
113aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
114aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			p->i_flags |= GRE_KEY;
115aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (strchr(*argv, '.'))
1164282c6c52b4f1f4b5e1ef5ef377c342ca87e0b73Herbert Xu				p->i_key = get_addr32(*argv);
117aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			else {
118aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				if (get_unsigned(&uval, *argv, 0)<0) {
119aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					fprintf(stderr, "invalid value of \"ikey\"\n");
120aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					exit(-1);
121aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				}
122aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				p->i_key = htonl(uval);
123aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
124aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "okey") == 0) {
125aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			unsigned uval;
126aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
127aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			p->o_flags |= GRE_KEY;
128aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (strchr(*argv, '.'))
129aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				p->o_key = get_addr32(*argv);
130aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			else {
131aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				if (get_unsigned(&uval, *argv, 0)<0) {
132aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					fprintf(stderr, "invalid value of \"okey\"\n");
133aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					exit(-1);
134aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				}
135aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				p->o_key = htonl(uval);
136aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
137aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "seq") == 0) {
138aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			p->i_flags |= GRE_SEQ;
139aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			p->o_flags |= GRE_SEQ;
140aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "iseq") == 0) {
141aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			p->i_flags |= GRE_SEQ;
142aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "oseq") == 0) {
143aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			p->o_flags |= GRE_SEQ;
144aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "csum") == 0) {
145aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			p->i_flags |= GRE_CSUM;
146aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			p->o_flags |= GRE_CSUM;
147aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "icsum") == 0) {
148aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			p->i_flags |= GRE_CSUM;
149aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "ocsum") == 0) {
150aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			p->o_flags |= GRE_CSUM;
151aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "nopmtudisc") == 0) {
152aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			p->iph.frag_off = 0;
153aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "pmtudisc") == 0) {
154aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			p->iph.frag_off = htons(IP_DF);
155aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "remote") == 0) {
156aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
157aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (strcmp(*argv, "any"))
158aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				p->iph.daddr = get_addr32(*argv);
159aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "local") == 0) {
160aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
161aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (strcmp(*argv, "any"))
162aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				p->iph.saddr = get_addr32(*argv);
163aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "dev") == 0) {
164aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
165aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			strncpy(medium, *argv, IFNAMSIZ-1);
166aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "ttl") == 0) {
167aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			unsigned uval;
168aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
169aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (strcmp(*argv, "inherit") != 0) {
170aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				if (get_unsigned(&uval, *argv, 0))
171aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					invarg("invalid TTL\n", *argv);
172aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				if (uval > 255)
173aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					invarg("TTL must be <=255\n", *argv);
174aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				p->iph.ttl = uval;
175aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
176aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "tos") == 0 ||
177aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			   matches(*argv, "dsfield") == 0) {
178aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			__u32 uval;
179aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
180aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (strcmp(*argv, "inherit") != 0) {
181aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				if (rtnl_dsfield_a2n(&uval, *argv))
182aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					invarg("bad TOS value", *argv);
183aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				p->iph.tos = uval;
184aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			} else
185aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				p->iph.tos = 1;
186aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else {
187aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (strcmp(*argv, "name") == 0) {
188aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				NEXT_ARG();
189aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
190aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (matches(*argv, "help") == 0)
191aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				usage();
192aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (p->name[0])
193aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				duparg2("name", *argv);
194aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			strncpy(p->name, *argv, IFNAMSIZ);
195aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (cmd == SIOCCHGTUNNEL && count == 0) {
196aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				struct ip_tunnel_parm old_p;
197aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				memset(&old_p, 0, sizeof(old_p));
198d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA				if (tnl_get_ioctl(*argv, &old_p))
199aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					return -1;
200aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				*p = old_p;
201aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
202aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
203aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		count++;
204aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		argc--; argv++;
205aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
206aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
207aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
208aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (p->iph.protocol == 0) {
209aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (memcmp(p->name, "gre", 3) == 0)
210aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			p->iph.protocol = IPPROTO_GRE;
211aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		else if (memcmp(p->name, "ipip", 4) == 0)
212aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			p->iph.protocol = IPPROTO_IPIP;
213aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		else if (memcmp(p->name, "sit", 3) == 0)
214aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			p->iph.protocol = IPPROTO_IPV6;
215aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
216aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
217aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (p->iph.protocol == IPPROTO_IPIP || p->iph.protocol == IPPROTO_IPV6) {
218aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if ((p->i_flags & GRE_KEY) || (p->o_flags & GRE_KEY)) {
219aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			fprintf(stderr, "Keys are not allowed with ipip and sit.\n");
220aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return -1;
221aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
222aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
223aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
224aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (medium[0]) {
225d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA		p->link = tnl_ioctl_get_ifindex(medium);
226aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (p->link == 0)
227aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return -1;
228aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
229aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
230aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (p->i_key == 0 && IN_MULTICAST(ntohl(p->iph.daddr))) {
231aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		p->i_key = p->iph.daddr;
232aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		p->i_flags |= GRE_KEY;
233aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
234aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (p->o_key == 0 && IN_MULTICAST(ntohl(p->iph.daddr))) {
235aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		p->o_key = p->iph.daddr;
236aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		p->o_flags |= GRE_KEY;
237aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
238aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (IN_MULTICAST(ntohl(p->iph.daddr)) && !p->iph.saddr) {
239aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fprintf(stderr, "Broadcast tunnel requires a source address.\n");
240aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
241aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
242aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
243aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
244aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
245aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
246aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int do_add(int cmd, int argc, char **argv)
247aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
248aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct ip_tunnel_parm p;
249aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
250aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (parse_args(argc, argv, cmd, &p) < 0)
251aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
252aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
253aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (p.iph.ttl && p.iph.frag_off == 0) {
254aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fprintf(stderr, "ttl != 0 and noptmudisc are incompatible\n");
255aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
256aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
257aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
258aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	switch (p.iph.protocol) {
259aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	case IPPROTO_IPIP:
260d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA		return tnl_add_ioctl(cmd, "tunl0", p.name, &p);
261aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	case IPPROTO_GRE:
262d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA		return tnl_add_ioctl(cmd, "gre0", p.name, &p);
263aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	case IPPROTO_IPV6:
264d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA		return tnl_add_ioctl(cmd, "sit0", p.name, &p);
265ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger	default:
266aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fprintf(stderr, "cannot determine tunnel mode (ipip, gre or sit)\n");
267aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
268aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
269aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return -1;
270aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
271aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
272d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURAstatic int do_del(int argc, char **argv)
273aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
274aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct ip_tunnel_parm p;
275aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
276aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (parse_args(argc, argv, SIOCDELTUNNEL, &p) < 0)
277aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
278aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
279aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	switch (p.iph.protocol) {
280aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	case IPPROTO_IPIP:
281d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA		return tnl_del_ioctl("tunl0", p.name, &p);
282aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	case IPPROTO_GRE:
283d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA		return tnl_del_ioctl("gre0", p.name, &p);
284aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	case IPPROTO_IPV6:
285d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA		return tnl_del_ioctl("sit0", p.name, &p);
286ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger	default:
287d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA		return tnl_del_ioctl(p.name, p.name, &p);
288aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
289aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return -1;
290aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
291aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
292d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURAstatic void print_tunnel(struct ip_tunnel_parm *p)
293aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
294aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char s1[1024];
295aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char s2[1024];
296aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char s3[64];
297aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char s4[64];
298aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
299aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	inet_ntop(AF_INET, &p->i_key, s3, sizeof(s3));
300aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	inet_ntop(AF_INET, &p->o_key, s4, sizeof(s4));
301aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
302aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	/* Do not use format_host() for local addr,
303aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	 * symbolic name will not be useful.
304aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	 */
305aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	printf("%s: %s/ip  remote %s  local %s ",
306aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	       p->name,
307d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA	       tnl_strproto(p->iph.protocol),
308aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	       p->iph.daddr ? format_host(AF_INET, 4, &p->iph.daddr, s1, sizeof(s1))  : "any",
309aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	       p->iph.saddr ? rt_addr_n2a(AF_INET, 4, &p->iph.saddr, s2, sizeof(s2)) : "any");
310aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
311aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (p->link) {
312d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA		char *n = tnl_ioctl_get_ifname(p->link);
313aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (n)
314aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			printf(" dev %s ", n);
315aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
316aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
317aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (p->iph.ttl)
318aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		printf(" ttl %d ", p->iph.ttl);
319aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	else
320aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		printf(" ttl inherit ");
321ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger
322aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (p->iph.tos) {
323aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		SPRINT_BUF(b1);
324aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		printf(" tos");
325aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (p->iph.tos&1)
326aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			printf(" inherit");
327aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (p->iph.tos&~1)
328aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			printf("%c%s ", p->iph.tos&1 ? '/' : ' ',
329aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			       rtnl_dsfield_n2a(p->iph.tos&~1, b1, sizeof(b1)));
330aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
331aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
332aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (!(p->iph.frag_off&htons(IP_DF)))
333aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		printf(" nopmtudisc");
334aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
335aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if ((p->i_flags&GRE_KEY) && (p->o_flags&GRE_KEY) && p->o_key == p->i_key)
336aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		printf(" key %s", s3);
337aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	else if ((p->i_flags|p->o_flags)&GRE_KEY) {
338aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (p->i_flags&GRE_KEY)
339aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			printf(" ikey %s ", s3);
340aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (p->o_flags&GRE_KEY)
341aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			printf(" okey %s ", s4);
342aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
343aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
344aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (p->i_flags&GRE_SEQ)
345aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		printf("%s  Drop packets out of sequence.\n", _SL_);
346aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (p->i_flags&GRE_CSUM)
347aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		printf("%s  Checksum in received packet is required.", _SL_);
348aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (p->o_flags&GRE_SEQ)
349aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		printf("%s  Sequence packets on output.", _SL_);
350aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (p->o_flags&GRE_CSUM)
351aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		printf("%s  Checksum output packets.", _SL_);
352aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
353aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
354aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int do_tunnels_list(struct ip_tunnel_parm *p)
355aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
356aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char name[IFNAMSIZ];
357aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	unsigned long  rx_bytes, rx_packets, rx_errs, rx_drops,
358aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	rx_fifo, rx_frame,
359aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	tx_bytes, tx_packets, tx_errs, tx_drops,
360aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	tx_fifo, tx_colls, tx_carrier, rx_multi;
361aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int type;
362aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct ip_tunnel_parm p1;
363aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
364aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char buf[512];
365aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	FILE *fp = fopen("/proc/net/dev", "r");
366aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (fp == NULL) {
367aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		perror("fopen");
368aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
369aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
370aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
371aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fgets(buf, sizeof(buf), fp);
372aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fgets(buf, sizeof(buf), fp);
373aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
374aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	while (fgets(buf, sizeof(buf), fp) != NULL) {
375aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		char *ptr;
376aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		buf[sizeof(buf) - 1] = 0;
377aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if ((ptr = strchr(buf, ':')) == NULL ||
378aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		    (*ptr++ = 0, sscanf(buf, "%s", name) != 1)) {
379aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			fprintf(stderr, "Wrong format of /proc/net/dev. Sorry.\n");
380aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return -1;
381aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
382aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (sscanf(ptr, "%ld%ld%ld%ld%ld%ld%ld%*d%ld%ld%ld%ld%ld%ld%ld",
383aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			   &rx_bytes, &rx_packets, &rx_errs, &rx_drops,
384aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			   &rx_fifo, &rx_frame, &rx_multi,
385aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			   &tx_bytes, &tx_packets, &tx_errs, &tx_drops,
386aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			   &tx_fifo, &tx_colls, &tx_carrier) != 14)
387aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			continue;
388aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (p->name[0] && strcmp(p->name, name))
389aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			continue;
390d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA		type = tnl_ioctl_get_iftype(name);
391aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (type == -1) {
392aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			fprintf(stderr, "Failed to get type of [%s]\n", name);
393aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			continue;
394aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
395aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (type != ARPHRD_TUNNEL && type != ARPHRD_IPGRE && type != ARPHRD_SIT)
396aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			continue;
397aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		memset(&p1, 0, sizeof(p1));
398d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA		if (tnl_get_ioctl(name, &p1))
399aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			continue;
400aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if ((p->link && p1.link != p->link) ||
401aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		    (p->name[0] && strcmp(p1.name, p->name)) ||
402aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		    (p->iph.daddr && p1.iph.daddr != p->iph.daddr) ||
403aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		    (p->iph.saddr && p1.iph.saddr != p->iph.saddr) ||
404aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		    (p->i_key && p1.i_key != p->i_key))
405aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			continue;
406aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		print_tunnel(&p1);
407aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (show_stats) {
408aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			printf("%s", _SL_);
409aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			printf("RX: Packets    Bytes        Errors CsumErrs OutOfSeq Mcasts%s", _SL_);
410aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			printf("    %-10ld %-12ld %-6ld %-8ld %-8ld %-8ld%s",
411aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			       rx_packets, rx_bytes, rx_errs, rx_frame, rx_fifo, rx_multi, _SL_);
412aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			printf("TX: Packets    Bytes        Errors DeadLoop NoRoute  NoBufs%s", _SL_);
413aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			printf("    %-10ld %-12ld %-6ld %-8ld %-8ld %-6ld",
414aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			       tx_packets, tx_bytes, tx_errs, tx_colls, tx_carrier, tx_drops);
415aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
416aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		printf("\n");
417aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
418aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
419aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
420aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
421aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int do_show(int argc, char **argv)
422aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
423aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int err;
424aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct ip_tunnel_parm p;
425aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
426aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (parse_args(argc, argv, SIOCGETTUNNEL, &p) < 0)
427aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
428aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
429aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	switch (p.iph.protocol) {
430ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger	case IPPROTO_IPIP:
431d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA		err = tnl_get_ioctl(p.name[0] ? p.name : "tunl0", &p);
432aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		break;
433aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	case IPPROTO_GRE:
434d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA		err = tnl_get_ioctl(p.name[0] ? p.name : "gre0", &p);
435aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		break;
436aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	case IPPROTO_IPV6:
437d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA		err = tnl_get_ioctl(p.name[0] ? p.name : "sit0", &p);
438aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		break;
439aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	default:
440aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		do_tunnels_list(&p);
441aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return 0;
442aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
443aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (err)
444aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
445aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
446aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	print_tunnel(&p);
447aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	printf("\n");
448aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
449aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
450aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
451aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint do_iptunnel(int argc, char **argv)
452aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
453d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA	switch (preferred_family) {
454d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA	case AF_UNSPEC:
455d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA		preferred_family = AF_INET;
456d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA		break;
457d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA	case AF_INET:
458d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA		break;
459288384f22ffafd2d7d888ee45d8dfcf26d3f2b1cMasahide NAKAMURA	/*
460288384f22ffafd2d7d888ee45d8dfcf26d3f2b1cMasahide NAKAMURA	 * This is silly enough but we have no easy way to make it
461288384f22ffafd2d7d888ee45d8dfcf26d3f2b1cMasahide NAKAMURA	 * protocol-independent because of unarranged structure between
462288384f22ffafd2d7d888ee45d8dfcf26d3f2b1cMasahide NAKAMURA	 * IPv4 and IPv6.
463288384f22ffafd2d7d888ee45d8dfcf26d3f2b1cMasahide NAKAMURA	 */
464288384f22ffafd2d7d888ee45d8dfcf26d3f2b1cMasahide NAKAMURA	case AF_INET6:
465288384f22ffafd2d7d888ee45d8dfcf26d3f2b1cMasahide NAKAMURA		return do_ip6tunnel(argc, argv);
466d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA	default:
467d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA		fprintf(stderr, "Unsupported family:%d\n", preferred_family);
468d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA		exit(-1);
469d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA	}
470d9bd1bd945b12b52e7825aa2742fa15ffa09651aMasahide NAKAMURA
471aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (argc > 0) {
472aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (matches(*argv, "add") == 0)
473aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return do_add(SIOCADDTUNNEL, argc-1, argv+1);
474aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (matches(*argv, "change") == 0)
475aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return do_add(SIOCCHGTUNNEL, argc-1, argv+1);
476aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (matches(*argv, "del") == 0)
477aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return do_del(argc-1, argv+1);
478aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (matches(*argv, "show") == 0 ||
479aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		    matches(*argv, "lst") == 0 ||
480aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		    matches(*argv, "list") == 0)
481aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return do_show(argc-1, argv+1);
482aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (matches(*argv, "help") == 0)
483aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			usage();
484aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	} else
485aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return do_show(0, NULL);
486aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
487aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr, "Command \"%s\" is unknown, try \"ip tunnel help\".\n", *argv);
488aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	exit(-1);
489aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
490