1dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/* 2dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * iptunnel.c "ip tunnel" 3dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 4dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * This program is free software; you can redistribute it and/or 5dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * modify it under the terms of the GNU General Public License 6dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * as published by the Free Software Foundation; either version 7dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 2 of the License, or (at your option) any later version. 8dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 9dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 10dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 11dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat */ 12dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 13dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <stdio.h> 14dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <stdlib.h> 15dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <string.h> 16dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <unistd.h> 17dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <sys/types.h> 18dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <sys/socket.h> 19dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <arpa/inet.h> 20dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <sys/ioctl.h> 21dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <linux/if.h> 22dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <linux/if_arp.h> 23dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <linux/ip.h> 24dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <linux/if_tunnel.h> 25dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 26dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "rt_names.h" 27dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "utils.h" 28dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "ip_common.h" 29dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "tunnel.h" 30dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 31dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void usage(void) __attribute__((noreturn)); 32dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 33dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void usage(void) 34dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 351a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(stderr, "Usage: ip tunnel { add | change | del | show | prl | 6rd } [ NAME ]\n"); 36dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " [ mode { ipip | gre | sit | isatap } ] [ remote ADDR ] [ local ADDR ]\n"); 37dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " [ [i|o]seq ] [ [i|o]key KEY ] [ [i|o]csum ]\n"); 38dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " [ prl-default ADDR ] [ prl-nodefault ADDR ] [ prl-delete ADDR ]\n"); 391a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(stderr, " [ 6rd-prefix ADDR ] [ 6rd-relay_prefix ADDR ] [ 6rd-reset ]\n"); 40dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " [ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]\n"); 41dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "\n"); 42dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Where: NAME := STRING\n"); 43dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " ADDR := { IP_ADDRESS | any }\n"); 44dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " TOS := { NUMBER | inherit }\n"); 45dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " TTL := { 1..255 | inherit }\n"); 46dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " KEY := { DOTTED_QUAD | NUMBER }\n"); 47dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 48dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 49dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 50dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p) 51dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 52dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int count = 0; 53dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char medium[IFNAMSIZ]; 54dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int isatap = 0; 55dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 56dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(p, 0, sizeof(*p)); 57dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&medium, 0, sizeof(medium)); 58dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 59dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->iph.version = 4; 60dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->iph.ihl = 5; 61dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#ifndef IP_DF 62dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#define IP_DF 0x4000 /* Flag: "Don't Fragment" */ 63dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#endif 64dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->iph.frag_off = htons(IP_DF); 65dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 66dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat while (argc > 0) { 67dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(*argv, "mode") == 0) { 68dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 69dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(*argv, "ipip") == 0 || 70dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcmp(*argv, "ip/ip") == 0) { 71dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (p->iph.protocol && p->iph.protocol != IPPROTO_IPIP) { 72dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr,"You managed to ask for more than one tunnel mode.\n"); 73dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 74dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 75dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->iph.protocol = IPPROTO_IPIP; 76dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "gre") == 0 || 77dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcmp(*argv, "gre/ip") == 0) { 78dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (p->iph.protocol && p->iph.protocol != IPPROTO_GRE) { 79dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr,"You managed to ask for more than one tunnel mode.\n"); 80dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 81dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 82dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->iph.protocol = IPPROTO_GRE; 83dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "sit") == 0 || 84dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcmp(*argv, "ipv6/ip") == 0) { 85dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (p->iph.protocol && p->iph.protocol != IPPROTO_IPV6) { 86dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr,"You managed to ask for more than one tunnel mode.\n"); 87dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 88dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 89dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->iph.protocol = IPPROTO_IPV6; 90dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "isatap") == 0) { 91dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (p->iph.protocol && p->iph.protocol != IPPROTO_IPV6) { 92dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "You managed to ask for more than one tunnel mode.\n"); 93dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 94dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 95dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->iph.protocol = IPPROTO_IPV6; 96dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat isatap++; 97dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 98dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr,"Cannot guess tunnel mode.\n"); 99dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 100dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 101dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "key") == 0) { 102dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned uval; 103dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 104dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->i_flags |= GRE_KEY; 105dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->o_flags |= GRE_KEY; 106dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strchr(*argv, '.')) 107dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->i_key = p->o_key = get_addr32(*argv); 108dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else { 109dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_unsigned(&uval, *argv, 0)<0) { 110dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "invalid value of \"key\"\n"); 111dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 112dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 113dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->i_key = p->o_key = htonl(uval); 114dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 115dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "ikey") == 0) { 116dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned uval; 117dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 118dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->i_flags |= GRE_KEY; 119dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strchr(*argv, '.')) 120dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->i_key = get_addr32(*argv); 121dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else { 122dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_unsigned(&uval, *argv, 0)<0) { 123dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "invalid value of \"ikey\"\n"); 124dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 125dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 126dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->i_key = htonl(uval); 127dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 128dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "okey") == 0) { 129dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned uval; 130dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 131dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->o_flags |= GRE_KEY; 132dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strchr(*argv, '.')) 133dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->o_key = get_addr32(*argv); 134dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else { 135dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_unsigned(&uval, *argv, 0)<0) { 136dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "invalid value of \"okey\"\n"); 137dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 138dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 139dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->o_key = htonl(uval); 140dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 141dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "seq") == 0) { 142dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->i_flags |= GRE_SEQ; 143dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->o_flags |= GRE_SEQ; 144dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "iseq") == 0) { 145dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->i_flags |= GRE_SEQ; 146dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "oseq") == 0) { 147dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->o_flags |= GRE_SEQ; 148dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "csum") == 0) { 149dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->i_flags |= GRE_CSUM; 150dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->o_flags |= GRE_CSUM; 151dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "icsum") == 0) { 152dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->i_flags |= GRE_CSUM; 153dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "ocsum") == 0) { 154dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->o_flags |= GRE_CSUM; 155dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "nopmtudisc") == 0) { 156dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->iph.frag_off = 0; 157dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "pmtudisc") == 0) { 158dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->iph.frag_off = htons(IP_DF); 159dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "remote") == 0) { 160dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 161dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(*argv, "any")) 162dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->iph.daddr = get_addr32(*argv); 163dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "local") == 0) { 164dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 165dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(*argv, "any")) 166dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->iph.saddr = get_addr32(*argv); 167dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "dev") == 0) { 168dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 169dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strncpy(medium, *argv, IFNAMSIZ-1); 170dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "ttl") == 0 || 171dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcmp(*argv, "hoplimit") == 0) { 172dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned uval; 173dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 174dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(*argv, "inherit") != 0) { 175dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_unsigned(&uval, *argv, 0)) 176dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat invarg("invalid TTL\n", *argv); 177dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (uval > 255) 178dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat invarg("TTL must be <=255\n", *argv); 179dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->iph.ttl = uval; 180dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 181dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "tos") == 0 || 182dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcmp(*argv, "tclass") == 0 || 183dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat matches(*argv, "dsfield") == 0) { 184dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 uval; 185dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 186dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(*argv, "inherit") != 0) { 187dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rtnl_dsfield_a2n(&uval, *argv)) 188dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat invarg("bad TOS value", *argv); 189dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->iph.tos = uval; 190dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else 191dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->iph.tos = 1; 192dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 193dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(*argv, "name") == 0) { 194dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 195dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "help") == 0) 196dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat usage(); 197dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (p->name[0]) 198dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat duparg2("name", *argv); 199dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strncpy(p->name, *argv, IFNAMSIZ); 200dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (cmd == SIOCCHGTUNNEL && count == 0) { 201dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ip_tunnel_parm old_p; 202dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&old_p, 0, sizeof(old_p)); 203dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tnl_get_ioctl(*argv, &old_p)) 204dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 205dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *p = old_p; 206dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 207dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 208dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat count++; 209dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat argc--; argv++; 210dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 211dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 212dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 213dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (p->iph.protocol == 0) { 214dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (memcmp(p->name, "gre", 3) == 0) 215dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->iph.protocol = IPPROTO_GRE; 216dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else if (memcmp(p->name, "ipip", 4) == 0) 217dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->iph.protocol = IPPROTO_IPIP; 218dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else if (memcmp(p->name, "sit", 3) == 0) 219dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->iph.protocol = IPPROTO_IPV6; 220dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else if (memcmp(p->name, "isatap", 6) == 0) { 221dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->iph.protocol = IPPROTO_IPV6; 222dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat isatap++; 223dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 224dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 225dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 226dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (p->iph.protocol == IPPROTO_IPIP || p->iph.protocol == IPPROTO_IPV6) { 227dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((p->i_flags & GRE_KEY) || (p->o_flags & GRE_KEY)) { 228dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Keys are not allowed with ipip and sit.\n"); 229dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 230dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 231dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 232dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 233dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (medium[0]) { 234dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->link = tnl_ioctl_get_ifindex(medium); 235dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (p->link == 0) 236dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 237dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 238dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 239dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (p->i_key == 0 && IN_MULTICAST(ntohl(p->iph.daddr))) { 240dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->i_key = p->iph.daddr; 241dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->i_flags |= GRE_KEY; 242dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 243dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (p->o_key == 0 && IN_MULTICAST(ntohl(p->iph.daddr))) { 244dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->o_key = p->iph.daddr; 245dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->o_flags |= GRE_KEY; 246dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 247dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (IN_MULTICAST(ntohl(p->iph.daddr)) && !p->iph.saddr) { 248dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Broadcast tunnel requires a source address.\n"); 249dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 250dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 251dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (isatap) 252dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->i_flags |= SIT_ISATAP; 253dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 254dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 255dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 256dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 257dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 258dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int do_add(int cmd, int argc, char **argv) 259dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 260dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ip_tunnel_parm p; 261dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 262dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (parse_args(argc, argv, cmd, &p) < 0) 263dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 264dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 265dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (p.iph.ttl && p.iph.frag_off == 0) { 266dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "ttl != 0 and noptmudisc are incompatible\n"); 267dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 268dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 269dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 270dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat switch (p.iph.protocol) { 271dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat case IPPROTO_IPIP: 272dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return tnl_add_ioctl(cmd, "tunl0", p.name, &p); 273dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat case IPPROTO_GRE: 274dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return tnl_add_ioctl(cmd, "gre0", p.name, &p); 275dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat case IPPROTO_IPV6: 276dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return tnl_add_ioctl(cmd, "sit0", p.name, &p); 277dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat default: 278dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "cannot determine tunnel mode (ipip, gre or sit)\n"); 279dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 280dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 281dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 282dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 283dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 284dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int do_del(int argc, char **argv) 285dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 286dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ip_tunnel_parm p; 287dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 288dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (parse_args(argc, argv, SIOCDELTUNNEL, &p) < 0) 289dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 290dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 291dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat switch (p.iph.protocol) { 292dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat case IPPROTO_IPIP: 293dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return tnl_del_ioctl("tunl0", p.name, &p); 294dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat case IPPROTO_GRE: 295dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return tnl_del_ioctl("gre0", p.name, &p); 296dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat case IPPROTO_IPV6: 297dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return tnl_del_ioctl("sit0", p.name, &p); 298dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat default: 299dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return tnl_del_ioctl(p.name, p.name, &p); 300dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 301dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 302dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 303dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 304dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void print_tunnel(struct ip_tunnel_parm *p) 305dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 3061a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt struct ip_tunnel_6rd ip6rd; 307dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char s1[1024]; 308dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char s2[1024]; 309dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char s3[64]; 310dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char s4[64]; 311dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 3121a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt memset(&ip6rd, 0, sizeof(ip6rd)); 313dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat inet_ntop(AF_INET, &p->i_key, s3, sizeof(s3)); 314dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat inet_ntop(AF_INET, &p->o_key, s4, sizeof(s4)); 315dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 316dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* Do not use format_host() for local addr, 317dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * symbolic name will not be useful. 318dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat */ 319dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf("%s: %s/ip remote %s local %s ", 320dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->name, 321dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tnl_strproto(p->iph.protocol), 322dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->iph.daddr ? format_host(AF_INET, 4, &p->iph.daddr, s1, sizeof(s1)) : "any", 323dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->iph.saddr ? rt_addr_n2a(AF_INET, 4, &p->iph.saddr, s2, sizeof(s2)) : "any"); 324dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 325dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (p->i_flags & SIT_ISATAP) { 326dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ip_tunnel_prl prl[16]; 327dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int i; 328dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 329dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(prl, 0, sizeof(prl)); 330dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat prl[0].datalen = sizeof(prl) - sizeof(prl[0]); 331dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat prl[0].addr = htonl(INADDR_ANY); 332dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 333dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!tnl_prl_ioctl(SIOCGETPRL, p->name, prl)) 334dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (i = 1; i < sizeof(prl) / sizeof(prl[0]); i++) 335dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat { 336dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (prl[i].addr != htonl(INADDR_ANY)) { 337dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf(" %s %s ", 338dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat (prl[i].flags & PRL_DEFAULT) ? "pdr" : "pr", 339dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat format_host(AF_INET, 4, &prl[i].addr, s1, sizeof(s1))); 340dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 341dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 342dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 343dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 344dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (p->link) { 345dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *n = tnl_ioctl_get_ifname(p->link); 346dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (n) 347dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf(" dev %s ", n); 348dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 349dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 350dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (p->iph.ttl) 351dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf(" ttl %d ", p->iph.ttl); 352dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 353dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf(" ttl inherit "); 354dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 355dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (p->iph.tos) { 356dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat SPRINT_BUF(b1); 357dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf(" tos"); 358dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (p->iph.tos&1) 359dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf(" inherit"); 360dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (p->iph.tos&~1) 361dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf("%c%s ", p->iph.tos&1 ? '/' : ' ', 362dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat rtnl_dsfield_n2a(p->iph.tos&~1, b1, sizeof(b1))); 363dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 364dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 365dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!(p->iph.frag_off&htons(IP_DF))) 366dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf(" nopmtudisc"); 367dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 3681a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt if (p->iph.protocol == IPPROTO_IPV6 && !tnl_ioctl_get_6rd(p->name, &ip6rd) && ip6rd.prefixlen) { 3691a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt printf(" 6rd-prefix %s/%u ", 3701a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt inet_ntop(AF_INET6, &ip6rd.prefix, s1, sizeof(s1)), 3711a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt ip6rd.prefixlen); 3721a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt if (ip6rd.relay_prefix) { 3731a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt printf("6rd-relay_prefix %s/%u ", 3741a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt format_host(AF_INET, 4, &ip6rd.relay_prefix, s1, sizeof(s1)), 3751a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt ip6rd.relay_prefixlen); 3761a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt } 3771a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt } 3781a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt 379dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((p->i_flags&GRE_KEY) && (p->o_flags&GRE_KEY) && p->o_key == p->i_key) 380dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf(" key %s", s3); 381dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else if ((p->i_flags|p->o_flags)&GRE_KEY) { 382dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (p->i_flags&GRE_KEY) 383dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf(" ikey %s ", s3); 384dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (p->o_flags&GRE_KEY) 385dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf(" okey %s ", s4); 386dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 387dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 388dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (p->i_flags&GRE_SEQ) 389dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf("%s Drop packets out of sequence.\n", _SL_); 390dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (p->i_flags&GRE_CSUM) 391dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf("%s Checksum in received packet is required.", _SL_); 392dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (p->o_flags&GRE_SEQ) 393dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf("%s Sequence packets on output.", _SL_); 394dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (p->o_flags&GRE_CSUM) 395dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf("%s Checksum output packets.", _SL_); 396dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 397dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 398dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int do_tunnels_list(struct ip_tunnel_parm *p) 399dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 400dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char name[IFNAMSIZ]; 401dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned long rx_bytes, rx_packets, rx_errs, rx_drops, 402dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat rx_fifo, rx_frame, 403dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tx_bytes, tx_packets, tx_errs, tx_drops, 404dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tx_fifo, tx_colls, tx_carrier, rx_multi; 405dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int type; 406dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ip_tunnel_parm p1; 407dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 408dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char buf[512]; 409dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat FILE *fp = fopen("/proc/net/dev", "r"); 410dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (fp == NULL) { 411dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat perror("fopen"); 412dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 413dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 414dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 415dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fgets(buf, sizeof(buf), fp); 416dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fgets(buf, sizeof(buf), fp); 417dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 418dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat while (fgets(buf, sizeof(buf), fp) != NULL) { 419dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *ptr; 420dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat buf[sizeof(buf) - 1] = 0; 421dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((ptr = strchr(buf, ':')) == NULL || 422dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat (*ptr++ = 0, sscanf(buf, "%s", name) != 1)) { 423dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Wrong format of /proc/net/dev. Sorry.\n"); 424982de674c9fac89418509c048548471435c0c7dfRobert CH Chou fclose(fp); 425dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 426dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 427dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (sscanf(ptr, "%ld%ld%ld%ld%ld%ld%ld%*d%ld%ld%ld%ld%ld%ld%ld", 428dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat &rx_bytes, &rx_packets, &rx_errs, &rx_drops, 429dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat &rx_fifo, &rx_frame, &rx_multi, 430dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat &tx_bytes, &tx_packets, &tx_errs, &tx_drops, 431dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat &tx_fifo, &tx_colls, &tx_carrier) != 14) 432dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat continue; 433dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (p->name[0] && strcmp(p->name, name)) 434dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat continue; 435dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat type = tnl_ioctl_get_iftype(name); 436dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (type == -1) { 437dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Failed to get type of [%s]\n", name); 438dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat continue; 439dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 440dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (type != ARPHRD_TUNNEL && type != ARPHRD_IPGRE && type != ARPHRD_SIT) 441dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat continue; 442dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&p1, 0, sizeof(p1)); 443dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tnl_get_ioctl(name, &p1)) 444dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat continue; 445dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((p->link && p1.link != p->link) || 446dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat (p->name[0] && strcmp(p1.name, p->name)) || 447dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat (p->iph.daddr && p1.iph.daddr != p->iph.daddr) || 448dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat (p->iph.saddr && p1.iph.saddr != p->iph.saddr) || 449dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat (p->i_key && p1.i_key != p->i_key)) 450dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat continue; 451dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat print_tunnel(&p1); 452dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (show_stats) { 453dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf("%s", _SL_); 454dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf("RX: Packets Bytes Errors CsumErrs OutOfSeq Mcasts%s", _SL_); 455dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf(" %-10ld %-12ld %-6ld %-8ld %-8ld %-8ld%s", 456dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat rx_packets, rx_bytes, rx_errs, rx_frame, rx_fifo, rx_multi, _SL_); 457dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf("TX: Packets Bytes Errors DeadLoop NoRoute NoBufs%s", _SL_); 458dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf(" %-10ld %-12ld %-6ld %-8ld %-8ld %-6ld", 459dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tx_packets, tx_bytes, tx_errs, tx_colls, tx_carrier, tx_drops); 460dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 461dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf("\n"); 462dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 463982de674c9fac89418509c048548471435c0c7dfRobert CH Chou fclose(fp); 464dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 465dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 466dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 467dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int do_show(int argc, char **argv) 468dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 469dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int err; 470dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ip_tunnel_parm p; 471dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 472dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (parse_args(argc, argv, SIOCGETTUNNEL, &p) < 0) 473dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 474dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 475dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat switch (p.iph.protocol) { 476dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat case IPPROTO_IPIP: 477dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat err = tnl_get_ioctl(p.name[0] ? p.name : "tunl0", &p); 478dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat break; 479dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat case IPPROTO_GRE: 480dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat err = tnl_get_ioctl(p.name[0] ? p.name : "gre0", &p); 481dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat break; 482dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat case IPPROTO_IPV6: 483dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat err = tnl_get_ioctl(p.name[0] ? p.name : "sit0", &p); 484dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat break; 485dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat default: 486dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat do_tunnels_list(&p); 487dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 488dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 489dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (err) 490dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 491dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 492dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat print_tunnel(&p); 493dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf("\n"); 494dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 495dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 496dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 497dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int do_prl(int argc, char **argv) 498dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 499dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ip_tunnel_prl p; 500dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int count = 0; 501dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int devname = 0; 502dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int cmd = 0; 503dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char medium[IFNAMSIZ]; 504dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 505dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&p, 0, sizeof(p)); 506dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&medium, 0, sizeof(medium)); 507dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 508dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat while (argc > 0) { 509dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(*argv, "prl-default") == 0) { 510dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 511dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat cmd = SIOCADDPRL; 512dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p.addr = get_addr32(*argv); 513dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p.flags |= PRL_DEFAULT; 514dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat count++; 515dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "prl-nodefault") == 0) { 516dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 517dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat cmd = SIOCADDPRL; 518dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p.addr = get_addr32(*argv); 519dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat count++; 520dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "prl-delete") == 0) { 521dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 522dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat cmd = SIOCDELPRL; 523dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p.addr = get_addr32(*argv); 524dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat count++; 525dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "dev") == 0) { 526dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 527dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strncpy(medium, *argv, IFNAMSIZ-1); 528dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat devname++; 529dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 530dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr,"%s: Invalid PRL parameter.\n", *argv); 531dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 532dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 533dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (count > 1) { 534dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr,"One PRL entry at a time.\n"); 535dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 536dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 537dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat argc--; argv++; 538dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 539dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (devname == 0) { 540dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Must specify dev.\n"); 541dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 542dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 543dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 544dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return tnl_prl_ioctl(cmd, medium, &p); 545dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 546dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 5471a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidtstatic int do_6rd(int argc, char **argv) 5481a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt{ 5491a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt struct ip_tunnel_6rd ip6rd; 5501a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt int devname = 0; 5511a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt int cmd = 0; 5521a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt char medium[IFNAMSIZ]; 5531a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt inet_prefix prefix; 5541a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt 5551a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt memset(&ip6rd, 0, sizeof(ip6rd)); 5561a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt memset(&medium, 0, sizeof(medium)); 5571a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt 5581a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt while (argc > 0) { 5591a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt if (strcmp(*argv, "6rd-prefix") == 0) { 5601a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt NEXT_ARG(); 5611a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt if (get_prefix(&prefix, *argv, AF_INET6)) 5621a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt invarg("invalid 6rd_prefix\n", *argv); 5631a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt cmd = SIOCADD6RD; 5641a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt memcpy(&ip6rd.prefix, prefix.data, 16); 5651a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt ip6rd.prefixlen = prefix.bitlen; 5661a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt } else if (strcmp(*argv, "6rd-relay_prefix") == 0) { 5671a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt NEXT_ARG(); 5681a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt if (get_prefix(&prefix, *argv, AF_INET)) 5691a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt invarg("invalid 6rd-relay_prefix\n", *argv); 5701a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt cmd = SIOCADD6RD; 5711a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt memcpy(&ip6rd.relay_prefix, prefix.data, 4); 5721a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt ip6rd.relay_prefixlen = prefix.bitlen; 5731a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt } else if (strcmp(*argv, "6rd-reset") == 0) { 5741a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt cmd = SIOCDEL6RD; 5751a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt } else if (strcmp(*argv, "dev") == 0) { 5761a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt NEXT_ARG(); 5771a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt strncpy(medium, *argv, IFNAMSIZ-1); 5781a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt devname++; 5791a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt } else { 5801a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(stderr,"%s: Invalid 6RD parameter.\n", *argv); 5811a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt exit(-1); 5821a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt } 5831a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt argc--; argv++; 5841a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt } 5851a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt if (devname == 0) { 5861a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(stderr, "Must specify dev.\n"); 5871a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt exit(-1); 5881a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt } 5891a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt 5901a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt return tnl_6rd_ioctl(cmd, medium, &ip6rd); 5911a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt} 5921a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt 593dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint do_iptunnel(int argc, char **argv) 594dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 595dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat switch (preferred_family) { 596dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat case AF_UNSPEC: 597dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat preferred_family = AF_INET; 598dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat break; 599dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat case AF_INET: 600dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat break; 601dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* 602dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * This is silly enough but we have no easy way to make it 603dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * protocol-independent because of unarranged structure between 604dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * IPv4 and IPv6. 605dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat */ 606dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat case AF_INET6: 607dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return do_ip6tunnel(argc, argv); 608dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat default: 609dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Unsupported family:%d\n", preferred_family); 610dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 611dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 612dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 613dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (argc > 0) { 614dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "add") == 0) 615dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return do_add(SIOCADDTUNNEL, argc-1, argv+1); 616dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "change") == 0) 617dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return do_add(SIOCCHGTUNNEL, argc-1, argv+1); 618dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "del") == 0) 619dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return do_del(argc-1, argv+1); 620dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "show") == 0 || 621dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat matches(*argv, "lst") == 0 || 622dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat matches(*argv, "list") == 0) 623dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return do_show(argc-1, argv+1); 624dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "prl") == 0) 625dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return do_prl(argc-1, argv+1); 6261a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt if (matches(*argv, "6rd") == 0) 6271a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt return do_6rd(argc-1, argv+1); 628dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "help") == 0) 629dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat usage(); 630dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else 631dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return do_show(0, NULL); 632dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 633dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Command \"%s\" is unknown, try \"ip tunnel help\".\n", *argv); 634dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 635dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 636