Home | History | Annotate | Download | only in ip
      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 
     40 const 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 
     65 int tnl_ioctl_get_ifindex(const char *dev)
     66 {
     67 	struct ifreq ifr;
     68 	int fd;
     69 	int err;
     70 
     71 	strncpy(ifr.ifr_name, dev, IFNAMSIZ);
     72 	fd = socket(preferred_family, SOCK_DGRAM, 0);
     73 	err = ioctl(fd, SIOCGIFINDEX, &ifr);
     74 	if (err) {
     75 		perror("ioctl");
     76 		return 0;
     77 	}
     78 	close(fd);
     79 	return ifr.ifr_ifindex;
     80 }
     81 
     82 int tnl_ioctl_get_iftype(const char *dev)
     83 {
     84 	struct ifreq ifr;
     85 	int fd;
     86 	int err;
     87 
     88 	strncpy(ifr.ifr_name, dev, IFNAMSIZ);
     89 	fd = socket(preferred_family, SOCK_DGRAM, 0);
     90 	err = ioctl(fd, SIOCGIFHWADDR, &ifr);
     91 	if (err) {
     92 		perror("ioctl");
     93 		return -1;
     94 	}
     95 	close(fd);
     96 	return ifr.ifr_addr.sa_family;
     97 }
     98 
     99 
    100 char * tnl_ioctl_get_ifname(int idx)
    101 {
    102 	static struct ifreq ifr;
    103 	int fd;
    104 	int err;
    105 
    106 	ifr.ifr_ifindex = idx;
    107 	fd = socket(preferred_family, SOCK_DGRAM, 0);
    108 	err = ioctl(fd, SIOCGIFNAME, &ifr);
    109 	if (err) {
    110 		perror("ioctl");
    111 		return NULL;
    112 	}
    113 	close(fd);
    114 	return ifr.ifr_name;
    115 }
    116 
    117 int tnl_get_ioctl(const char *basedev, void *p)
    118 {
    119 	struct ifreq ifr;
    120 	int fd;
    121 	int err;
    122 
    123 	strncpy(ifr.ifr_name, basedev, IFNAMSIZ);
    124 	ifr.ifr_ifru.ifru_data = (void*)p;
    125 	fd = socket(preferred_family, SOCK_DGRAM, 0);
    126 	err = ioctl(fd, SIOCGETTUNNEL, &ifr);
    127 	if (err)
    128 		perror("ioctl");
    129 	close(fd);
    130 	return err;
    131 }
    132 
    133 int tnl_add_ioctl(int cmd, const char *basedev, const char *name, void *p)
    134 {
    135 	struct ifreq ifr;
    136 	int fd;
    137 	int err;
    138 
    139 	if (cmd == SIOCCHGTUNNEL && name[0])
    140 		strncpy(ifr.ifr_name, name, IFNAMSIZ);
    141 	else
    142 		strncpy(ifr.ifr_name, basedev, IFNAMSIZ);
    143 	ifr.ifr_ifru.ifru_data = p;
    144 	fd = socket(preferred_family, SOCK_DGRAM, 0);
    145 	err = ioctl(fd, cmd, &ifr);
    146 	if (err)
    147 		perror("ioctl");
    148 	close(fd);
    149 	return err;
    150 }
    151 
    152 int tnl_del_ioctl(const char *basedev, const char *name, void *p)
    153 {
    154 	struct ifreq ifr;
    155 	int fd;
    156 	int err;
    157 
    158 	if (name[0])
    159 		strncpy(ifr.ifr_name, name, IFNAMSIZ);
    160 	else
    161 		strncpy(ifr.ifr_name, basedev, IFNAMSIZ);
    162 	ifr.ifr_ifru.ifru_data = p;
    163 	fd = socket(preferred_family, SOCK_DGRAM, 0);
    164 	err = ioctl(fd, SIOCDELTUNNEL, &ifr);
    165 	if (err)
    166 		perror("ioctl");
    167 	close(fd);
    168 	return err;
    169 }
    170 
    171 int tnl_prl_ioctl(int cmd, const char *name, void *p)
    172 {
    173 	struct ifreq ifr;
    174 	int fd;
    175 	int err;
    176 
    177 	strncpy(ifr.ifr_name, name, IFNAMSIZ);
    178 	ifr.ifr_ifru.ifru_data = p;
    179 	fd = socket(preferred_family, SOCK_DGRAM, 0);
    180 	err = ioctl(fd, cmd, &ifr);
    181 	if (err)
    182 		perror("ioctl");
    183 	close(fd);
    184 	return err;
    185 }
    186