1dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/*
2dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * Copyright (C)2006 USAGI/WIDE Project
3dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *
4dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * This program is free software; you can redistribute it and/or modify
5dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * it under the terms of the GNU General Public License as published by
6dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * the Free Software Foundation; either version 2 of the License, or
7dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * (at your option) any later version.
8dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *
9dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * This program is distributed in the hope that it will be useful,
10dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * but WITHOUT ANY WARRANTY; without even the implied warranty of
11dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * GNU General Public License for more details.
13dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *
14dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * You should have received a copy of the GNU General Public License
15dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * along with this program; if not, write to the Free Software
16dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat */
18dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/*
19dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * split from ip_tunnel.c
20dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat */
21dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/*
22dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * Author:
23dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *	Masahide NAKAMURA @USAGI
24dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat */
25dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
26dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <stdio.h>
27dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <string.h>
28dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <unistd.h>
29dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <sys/types.h>
30dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <sys/socket.h>
31dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <sys/ioctl.h>
32dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <netinet/in.h>
33dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <linux/if.h>
34dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <linux/ip.h>
35dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <linux/if_tunnel.h>
36dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
37dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "utils.h"
38dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "tunnel.h"
39dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
40dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatconst char *tnl_strproto(__u8 proto)
41dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
42dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	static char buf[16];
43dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
44dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	switch (proto) {
45dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	case IPPROTO_IPIP:
46dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		strcpy(buf, "ip");
47dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		break;
48dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	case IPPROTO_GRE:
49dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		strcpy(buf, "gre");
50dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		break;
51dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	case IPPROTO_IPV6:
52dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		strcpy(buf, "ipv6");
53dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		break;
54dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	case 0:
55dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		strcpy(buf, "any");
56dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		break;
57dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	default:
58dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		strcpy(buf, "unknown");
59dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		break;
60dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
61dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
62dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	return buf;
63dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}
64dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
65dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint tnl_ioctl_get_ifindex(const char *dev)
66dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
67dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	struct ifreq ifr;
68dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int fd;
69dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int err;
70dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
71dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	strncpy(ifr.ifr_name, dev, IFNAMSIZ);
72dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fd = socket(preferred_family, SOCK_DGRAM, 0);
73dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	err = ioctl(fd, SIOCGIFINDEX, &ifr);
74dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (err) {
75dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		perror("ioctl");
76dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return 0;
77dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
78dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	close(fd);
79dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	return ifr.ifr_ifindex;
80dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}
81dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
82dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint tnl_ioctl_get_iftype(const char *dev)
83dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
84dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	struct ifreq ifr;
85dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int fd;
86dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int err;
87dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
88dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	strncpy(ifr.ifr_name, dev, IFNAMSIZ);
89dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fd = socket(preferred_family, SOCK_DGRAM, 0);
90dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	err = ioctl(fd, SIOCGIFHWADDR, &ifr);
91dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (err) {
92dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		perror("ioctl");
93dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return -1;
94dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
95dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	close(fd);
96dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	return ifr.ifr_addr.sa_family;
97dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}
98dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
99dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
100dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatchar * tnl_ioctl_get_ifname(int idx)
101dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
102dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	static struct ifreq ifr;
103dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int fd;
104dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int err;
105dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
106dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	ifr.ifr_ifindex = idx;
107dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fd = socket(preferred_family, SOCK_DGRAM, 0);
108dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	err = ioctl(fd, SIOCGIFNAME, &ifr);
109dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (err) {
110dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		perror("ioctl");
111dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return NULL;
112dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
113dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	close(fd);
114dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	return ifr.ifr_name;
115dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}
116dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
117dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint tnl_get_ioctl(const char *basedev, void *p)
118dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
119dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	struct ifreq ifr;
120dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int fd;
121dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int err;
122dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
123dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	strncpy(ifr.ifr_name, basedev, IFNAMSIZ);
124dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	ifr.ifr_ifru.ifru_data = (void*)p;
125dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fd = socket(preferred_family, SOCK_DGRAM, 0);
126dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	err = ioctl(fd, SIOCGETTUNNEL, &ifr);
127dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (err)
128dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		perror("ioctl");
129dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	close(fd);
130dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	return err;
131dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}
132dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
133dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint tnl_add_ioctl(int cmd, const char *basedev, const char *name, void *p)
134dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
135dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	struct ifreq ifr;
136dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int fd;
137dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int err;
138dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
139dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (cmd == SIOCCHGTUNNEL && name[0])
140dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		strncpy(ifr.ifr_name, name, IFNAMSIZ);
141dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	else
142dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		strncpy(ifr.ifr_name, basedev, IFNAMSIZ);
143dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	ifr.ifr_ifru.ifru_data = p;
144dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fd = socket(preferred_family, SOCK_DGRAM, 0);
145dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	err = ioctl(fd, cmd, &ifr);
146dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (err)
147dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		perror("ioctl");
148dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	close(fd);
149dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	return err;
150dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}
151dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
152dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint tnl_del_ioctl(const char *basedev, const char *name, void *p)
153dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
154dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	struct ifreq ifr;
155dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int fd;
156dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int err;
157dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
158dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (name[0])
159dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		strncpy(ifr.ifr_name, name, IFNAMSIZ);
160dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	else
161dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		strncpy(ifr.ifr_name, basedev, IFNAMSIZ);
162dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	ifr.ifr_ifru.ifru_data = p;
163dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fd = socket(preferred_family, SOCK_DGRAM, 0);
164dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	err = ioctl(fd, SIOCDELTUNNEL, &ifr);
165dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (err)
166dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		perror("ioctl");
167dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	close(fd);
168dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	return err;
169dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}
170dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
171dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint tnl_prl_ioctl(int cmd, const char *name, void *p)
172dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
173dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	struct ifreq ifr;
174dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int fd;
175dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int err;
176dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
177dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	strncpy(ifr.ifr_name, name, IFNAMSIZ);
178dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	ifr.ifr_ifru.ifru_data = p;
179dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fd = socket(preferred_family, SOCK_DGRAM, 0);
180dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	err = ioctl(fd, cmd, &ifr);
181dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (err)
182dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		perror("ioctl");
183dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	close(fd);
184dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	return err;
185dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}
186