tunnel.c revision 4d98ab00de90bac916f526c83c68012d7159f712
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, see <http://www.gnu.org/licenses>. 16 */ 17/* 18 * split from ip_tunnel.c 19 */ 20/* 21 * Author: 22 * Masahide NAKAMURA @USAGI 23 */ 24 25#include <stdio.h> 26#include <string.h> 27#include <unistd.h> 28#include <errno.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 case 0: 55 strcpy(buf, "any"); 56 break; 57 default: 58 strcpy(buf, "unknown"); 59 break; 60 } 61 62 return buf; 63} 64 65int tnl_get_ioctl(const char *basedev, void *p) 66{ 67 struct ifreq ifr; 68 int fd; 69 int err; 70 71 strncpy(ifr.ifr_name, basedev, IFNAMSIZ); 72 ifr.ifr_ifru.ifru_data = (void*)p; 73 fd = socket(preferred_family, SOCK_DGRAM, 0); 74 err = ioctl(fd, SIOCGETTUNNEL, &ifr); 75 if (err) 76 fprintf(stderr, "get tunnel \"%s\" failed: %s\n", basedev, 77 strerror(errno)); 78 79 close(fd); 80 return err; 81} 82 83int tnl_add_ioctl(int cmd, const char *basedev, const char *name, void *p) 84{ 85 struct ifreq ifr; 86 int fd; 87 int err; 88 89 if (cmd == SIOCCHGTUNNEL && name[0]) 90 strncpy(ifr.ifr_name, name, IFNAMSIZ); 91 else 92 strncpy(ifr.ifr_name, basedev, IFNAMSIZ); 93 ifr.ifr_ifru.ifru_data = p; 94 fd = socket(preferred_family, SOCK_DGRAM, 0); 95 err = ioctl(fd, cmd, &ifr); 96 if (err) 97 fprintf(stderr, "add tunnel \"%s\" failed: %s\n", ifr.ifr_name, 98 strerror(errno)); 99 close(fd); 100 return err; 101} 102 103int tnl_del_ioctl(const char *basedev, const char *name, void *p) 104{ 105 struct ifreq ifr; 106 int fd; 107 int err; 108 109 if (name[0]) 110 strncpy(ifr.ifr_name, name, IFNAMSIZ); 111 else 112 strncpy(ifr.ifr_name, basedev, IFNAMSIZ); 113 114 ifr.ifr_ifru.ifru_data = p; 115 fd = socket(preferred_family, SOCK_DGRAM, 0); 116 err = ioctl(fd, SIOCDELTUNNEL, &ifr); 117 if (err) 118 fprintf(stderr, "delete tunnel \"%s\" failed: %s\n", 119 ifr.ifr_name, strerror(errno)); 120 close(fd); 121 return err; 122} 123 124static int tnl_gen_ioctl(int cmd, const char *name, 125 void *p, int skiperr) 126{ 127 struct ifreq ifr; 128 int fd; 129 int err; 130 131 strncpy(ifr.ifr_name, name, IFNAMSIZ); 132 ifr.ifr_ifru.ifru_data = p; 133 fd = socket(preferred_family, SOCK_DGRAM, 0); 134 err = ioctl(fd, cmd, &ifr); 135 if (err && errno != skiperr) 136 fprintf(stderr, "%s: ioctl %x failed: %s\n", name, 137 cmd, strerror(errno)); 138 close(fd); 139 return err; 140} 141 142int tnl_prl_ioctl(int cmd, const char *name, void *p) 143{ 144 return tnl_gen_ioctl(cmd, name, p, -1); 145} 146 147int tnl_6rd_ioctl(int cmd, const char *name, void *p) 148{ 149 return tnl_gen_ioctl(cmd, name, p, -1); 150} 151 152int tnl_ioctl_get_6rd(const char *name, void *p) 153{ 154 return tnl_gen_ioctl(SIOCGET6RD, name, p, EINVAL); 155} 156