]> rtime.felk.cvut.cz Git - lisovros/iproute2_canprio.git/blob - ip/tunnel.c
Detect 6rd kernel missing support / 6rd tunnel scope
[lisovros/iproute2_canprio.git] / ip / tunnel.c
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 <errno.h>
30 #include <sys/types.h>
31 #include <sys/socket.h>
32 #include <sys/ioctl.h>
33 #include <netinet/in.h>
34 #include <linux/if.h>
35 #include <linux/ip.h>
36 #include <linux/if_tunnel.h>
37
38 #include "utils.h"
39 #include "tunnel.h"
40
41 const char *tnl_strproto(__u8 proto)
42 {
43         static char buf[16];
44
45         switch (proto) {
46         case IPPROTO_IPIP:
47                 strcpy(buf, "ip");
48                 break;
49         case IPPROTO_GRE:
50                 strcpy(buf, "gre");
51                 break;
52         case IPPROTO_IPV6:
53                 strcpy(buf, "ipv6");
54                 break;
55         case 0:
56                 strcpy(buf, "any");
57                 break;
58         default:
59                 strcpy(buf, "unknown");
60                 break;
61         }
62
63         return buf;
64 }
65
66 int tnl_ioctl_get_ifindex(const char *dev)
67 {
68         struct ifreq ifr;
69         int fd;
70         int err;
71
72         strncpy(ifr.ifr_name, dev, IFNAMSIZ);
73         fd = socket(preferred_family, SOCK_DGRAM, 0);
74         err = ioctl(fd, SIOCGIFINDEX, &ifr);
75         if (err) {
76                 perror("ioctl");
77                 return 0;
78         }
79         close(fd);
80         return ifr.ifr_ifindex;
81 }
82
83 int tnl_ioctl_get_iftype(const char *dev)
84 {
85         struct ifreq ifr;
86         int fd;
87         int err;
88
89         strncpy(ifr.ifr_name, dev, IFNAMSIZ);
90         fd = socket(preferred_family, SOCK_DGRAM, 0);
91         err = ioctl(fd, SIOCGIFHWADDR, &ifr);
92         if (err) {
93                 perror("ioctl");
94                 return -1;
95         }
96         close(fd);
97         return ifr.ifr_addr.sa_family;
98 }
99
100
101 char * tnl_ioctl_get_ifname(int idx)
102 {
103         static struct ifreq ifr;
104         int fd;
105         int err;
106
107         ifr.ifr_ifindex = idx;
108         fd = socket(preferred_family, SOCK_DGRAM, 0);
109         err = ioctl(fd, SIOCGIFNAME, &ifr);
110         if (err) {
111                 perror("ioctl");
112                 return NULL;
113         }
114         close(fd);
115         return ifr.ifr_name;
116 }
117
118 int tnl_get_ioctl(const char *basedev, void *p)
119 {
120         struct ifreq ifr;
121         int fd;
122         int err;
123
124         strncpy(ifr.ifr_name, basedev, IFNAMSIZ);
125         ifr.ifr_ifru.ifru_data = (void*)p;
126         fd = socket(preferred_family, SOCK_DGRAM, 0);
127         err = ioctl(fd, SIOCGETTUNNEL, &ifr);
128         if (err)
129                 perror("ioctl");
130         close(fd);
131         return err;
132 }
133
134 int tnl_add_ioctl(int cmd, const char *basedev, const char *name, void *p)
135 {
136         struct ifreq ifr;
137         int fd;
138         int err;
139
140         if (cmd == SIOCCHGTUNNEL && name[0])
141                 strncpy(ifr.ifr_name, name, IFNAMSIZ);
142         else
143                 strncpy(ifr.ifr_name, basedev, IFNAMSIZ);
144         ifr.ifr_ifru.ifru_data = p;
145         fd = socket(preferred_family, SOCK_DGRAM, 0);
146         err = ioctl(fd, cmd, &ifr);
147         if (err)
148                 perror("ioctl");
149         close(fd);
150         return err;
151 }
152
153 int tnl_del_ioctl(const char *basedev, const char *name, void *p)
154 {
155         struct ifreq ifr;
156         int fd;
157         int err;
158
159         if (name[0])
160                 strncpy(ifr.ifr_name, name, IFNAMSIZ);
161         else
162                 strncpy(ifr.ifr_name, basedev, IFNAMSIZ);
163         ifr.ifr_ifru.ifru_data = p;
164         fd = socket(preferred_family, SOCK_DGRAM, 0);
165         err = ioctl(fd, SIOCDELTUNNEL, &ifr);
166         if (err)
167                 perror("ioctl");
168         close(fd);
169         return err;
170 }
171
172 static int tnl_gen_ioctl(int cmd, const char *name, void *p, int skiperr)
173 {
174         struct ifreq ifr;
175         int fd;
176         int err;
177
178         strncpy(ifr.ifr_name, name, IFNAMSIZ);
179         ifr.ifr_ifru.ifru_data = p;
180         fd = socket(preferred_family, SOCK_DGRAM, 0);
181         err = ioctl(fd, cmd, &ifr);
182         if (err && errno != skiperr)
183                 perror("ioctl");
184         close(fd);
185         return err;
186 }
187
188 int tnl_prl_ioctl(int cmd, const char *name, void *p)
189 {
190         return tnl_gen_ioctl(cmd, name, p, -1);
191 }
192
193 int tnl_6rd_ioctl(int cmd, const char *name, void *p)
194 {
195         return tnl_gen_ioctl(cmd, name, p, -1);
196 }
197
198 int tnl_ioctl_get_6rd(const char *name, void *p)
199 {
200         return tnl_gen_ioctl(SIOCGET6RD, name, p, EINVAL);
201 }