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