xfrm_state.c revision af1b6a41d4c7ed8aab98cfdcdafd55ec6c638b07
1c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger/* $USAGI: $ */ 2c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 3c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger/* 4c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * Copyright (C)2004 USAGI/WIDE Project 5c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * 6c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * This program is free software; you can redistribute it and/or modify 7c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * it under the terms of the GNU General Public License as published by 8c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * the Free Software Foundation; either version 2 of the License, or 9c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * (at your option) any later version. 10c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * 11c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * This program is distributed in the hope that it will be useful, 12c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * but WITHOUT ANY WARRANTY; without even the implied warranty of 13c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * GNU General Public License for more details. 15c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * 16c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * You should have received a copy of the GNU General Public License 17c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * along with this program; if not, write to the Free Software 18c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger */ 20c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger/* 21c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * based on iproute.c 22c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger */ 23c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger/* 24c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * Authors: 25c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * Masahide NAKAMURA @USAGI 26c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger */ 27c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 28c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#include <stdio.h> 29c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#include <stdlib.h> 30c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#include <string.h> 31c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#include <netdb.h> 32c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#include <linux/xfrm.h> 33c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#include "utils.h" 34c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#include "xfrm.h" 35c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#include "ip_common.h" 36c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 379bec1a436335457f3067a17de6ddb913bd95a184shemminger//#define NLMSG_DELETEALL_BUF_SIZE (4096-512) 389bec1a436335457f3067a17de6ddb913bd95a184shemminger#define NLMSG_DELETEALL_BUF_SIZE 8192 39c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 40c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger/* 41c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * Receiving buffer defines: 42c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * nlmsg 43c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * data = struct xfrm_usersa_info 44c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * rtattr 45c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * rtattr 462534613eeba36f2a59a7876dbe1b291c76fcb4damax count of rtattr is XFRM_MAX+ * ... (max count of rtattr is XFRM_MAX+1 47c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * 48c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * each rtattr data = struct xfrm_algo(dynamic size) or xfrm_address_t 49c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger */ 50c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#define NLMSG_BUF_SIZE 4096 51c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#define RTA_BUF_SIZE 2048 52c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#define XFRM_ALGO_KEY_BUF_SIZE 512 53c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 54c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic void usage(void) __attribute__((noreturn)); 55c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 56c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic void usage(void) 57c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{ 58c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger fprintf(stderr, "Usage: ip xfrm state { add | update } ID [ ALGO-LIST ] [ mode MODE ]\n"); 59fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv fprintf(stderr, " [ reqid REQID ] [ seq SEQ ] [ replay-window SIZE ] [ flag FLAG-LIST ]\n"); 605cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger fprintf(stderr, " [ encap ENCAP ] [ sel SELECTOR ] [ LIMIT-LIST ]\n"); 61fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv fprintf(stderr, "Usage: ip xfrm state allocspi ID [ mode MODE ] [ reqid REQID ] [ seq SEQ ]\n"); 62fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv fprintf(stderr, " [ min SPI max SPI ]\n"); 63c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger fprintf(stderr, "Usage: ip xfrm state { delete | get } ID\n"); 649bec1a436335457f3067a17de6ddb913bd95a184shemminger fprintf(stderr, "Usage: ip xfrm state { deleteall | list } [ ID ] [ mode MODE ] [ reqid REQID ]\n"); 65eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger fprintf(stderr, " [ flag FLAG_LIST ]\n"); 669bec1a436335457f3067a17de6ddb913bd95a184shemminger fprintf(stderr, "Usage: ip xfrm state flush [ proto XFRM_PROTO ]\n"); 67c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 68c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger fprintf(stderr, "ID := [ src ADDR ] [ dst ADDR ] [ proto XFRM_PROTO ] [ spi SPI ]\n"); 6929aa4dd76c0c1877d50b2d643eb081d5477ceadforg[shemminger]!nakam //fprintf(stderr, "XFRM_PROTO := [ esp | ah | comp ]\n"); 709e566a46f24fd89e104dea064d5233ab614f490bnet[shemminger]!shemminger fprintf(stderr, "XFRM_PROTO := [ "); 7129aa4dd76c0c1877d50b2d643eb081d5477ceadforg[shemminger]!nakam fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_ESP)); 7229aa4dd76c0c1877d50b2d643eb081d5477ceadforg[shemminger]!nakam fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_AH)); 7329aa4dd76c0c1877d50b2d643eb081d5477ceadforg[shemminger]!nakam fprintf(stderr, "%s ", strxf_xfrmproto(IPPROTO_COMP)); 747809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger fprintf(stderr, "]\n"); 759e566a46f24fd89e104dea064d5233ab614f490bnet[shemminger]!shemminger 76c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger //fprintf(stderr, "SPI - security parameter index(default=0)\n"); 77c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 78c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger fprintf(stderr, "MODE := [ transport | tunnel ](default=transport)\n"); 79c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger //fprintf(stderr, "REQID - number(default=0)\n"); 80c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 81eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger fprintf(stderr, "FLAG-LIST := [ FLAG-LIST ] FLAG\n"); 82eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger fprintf(stderr, "FLAG := [ noecn | decap-dscp ]\n"); 835cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger 845cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger fprintf(stderr, "ENCAP := ENCAP-TYPE SPORT DPORT OADDR\n"); 855cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger fprintf(stderr, "ENCAP-TYPE := espinudp | espinudp-nonike\n"); 86c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 877809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger fprintf(stderr, "ALGO-LIST := [ ALGO-LIST ] | [ ALGO ]\n"); 88c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger fprintf(stderr, "ALGO := ALGO_TYPE ALGO_NAME ALGO_KEY\n"); 897809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger fprintf(stderr, "ALGO_TYPE := [ "); 907809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger fprintf(stderr, "%s | ", strxf_algotype(XFRMA_ALG_CRYPT)); 917809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger fprintf(stderr, "%s | ", strxf_algotype(XFRMA_ALG_AUTH)); 927809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger fprintf(stderr, "%s ", strxf_algotype(XFRMA_ALG_COMP)); 937809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger fprintf(stderr, "]\n"); 947809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger 95c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger //fprintf(stderr, "ALGO_NAME - algorithm name\n"); 96c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger //fprintf(stderr, "ALGO_KEY - algorithm key\n"); 97c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 98eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger fprintf(stderr, "SELECTOR := src ADDR[/PLEN] dst ADDR[/PLEN] [ UPSPEC ] [ dev DEV ]\n"); 99c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 100c70b36d231afba1700d6bb4ca1181fd9bb76c77borg[shemminger]!nakam fprintf(stderr, "UPSPEC := proto PROTO [ [ sport PORT ] [ dport PORT ] |\n"); 101c70b36d231afba1700d6bb4ca1181fd9bb76c77borg[shemminger]!nakam fprintf(stderr, " [ type NUMBER ] [ code NUMBER ] ]\n"); 102c70b36d231afba1700d6bb4ca1181fd9bb76c77borg[shemminger]!nakam 103c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 104c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger //fprintf(stderr, "DEV - device name(default=none)\n"); 105c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger fprintf(stderr, "LIMIT-LIST := [ LIMIT-LIST ] | [ limit LIMIT ]\n"); 106c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger fprintf(stderr, "LIMIT := [ [time-soft|time-hard|time-use-soft|time-use-hard] SECONDS ] |\n"); 107c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger fprintf(stderr, " [ [byte-soft|byte-hard] SIZE ] | [ [packet-soft|packet-hard] COUNT ]\n"); 108c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger exit(-1); 109c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger} 110c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 111c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_algo_parse(struct xfrm_algo *alg, enum xfrm_attr_type_t type, 112c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger char *name, char *key, int max) 113c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{ 114c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger int len; 1157809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger int slen = strlen(key); 116c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 117eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger#if 0 118c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger /* XXX: verifying both name and key is required! */ 119c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger fprintf(stderr, "warning: ALGONAME/ALGOKEY will send to kernel promiscuously!(verifying them isn't implemented yet)\n"); 120c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#endif 121c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 122c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger strncpy(alg->alg_name, name, sizeof(alg->alg_name)); 123c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 1247809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger if (slen > 2 && strncmp(key, "0x", 2) == 0) { 12554f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam /* split two chars "0x" from the top */ 12654f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam char *p = key + 2; 12754f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam int plen = slen - 2; 12854f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam int i; 12954f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam int j; 13054f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam 13154f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam /* Converting hexadecimal numbered string into real key; 13254f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam * Convert each two chars into one char(value). If number 13354f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam * of the length is odd, add zero on the top for rounding. 134c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger */ 1357809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger 13654f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam /* calculate length of the converted values(real key) */ 13754f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam len = (plen + 1) / 2; 13854f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam if (len > max) 13954f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam invarg("\"ALGOKEY\" makes buffer overflow\n", key); 140c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 14154f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam for (i = - (plen % 2), j = 0; j < len; i += 2, j++) { 14254f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam char vbuf[3]; 143737f15f6da0ed7512220f6fa5244a39777de4e0dshemminger __u8 val; 144c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 14554f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam vbuf[0] = i >= 0 ? p[i] : '0'; 14654f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam vbuf[1] = p[i + 1]; 14754f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam vbuf[2] = '\0'; 148c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 14954f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam if (get_u8(&val, vbuf, 16)) 15054f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam invarg("\"ALGOKEY\" is invalid", key); 1517809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger 15254f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam alg->alg_key[j] = val; 153c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } 154c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } else { 1557809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger len = slen; 156c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (len > 0) { 157c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (len > max) 158c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger invarg("\"ALGOKEY\" makes buffer overflow\n", key); 159c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 160c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger strncpy(alg->alg_key, key, len); 161c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } 162c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } 163c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 164c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger alg->alg_key_len = len * 8; 165c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 166c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger return 0; 167c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger} 168c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 169fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipvstatic int xfrm_seq_parse(__u32 *seq, int *argcp, char ***argvp) 170fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv{ 171fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv int argc = *argcp; 172fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv char **argv = *argvp; 173fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv 174fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv if (get_u32(seq, *argv, 0)) 175fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv invarg("\"SEQ\" is invalid", *argv); 176fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv 177fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv *seq = htonl(*seq); 178fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv 179fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv *argcp = argc; 180fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv *argvp = argv; 181fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv 182fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv return 0; 183fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv} 184fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv 185c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_state_flag_parse(__u8 *flags, int *argcp, char ***argvp) 186c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{ 187c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger int argc = *argcp; 188c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger char **argv = *argvp; 1899e566a46f24fd89e104dea064d5233ab614f490bnet[shemminger]!shemminger int len = strlen(*argv); 1909e566a46f24fd89e104dea064d5233ab614f490bnet[shemminger]!shemminger 1919e566a46f24fd89e104dea064d5233ab614f490bnet[shemminger]!shemminger if (len > 2 && strncmp(*argv, "0x", 2) == 0) { 1929e566a46f24fd89e104dea064d5233ab614f490bnet[shemminger]!shemminger __u8 val = 0; 193c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 1949e566a46f24fd89e104dea064d5233ab614f490bnet[shemminger]!shemminger if (get_u8(&val, *argv, 16)) 1959e566a46f24fd89e104dea064d5233ab614f490bnet[shemminger]!shemminger invarg("\"FLAG\" is invalid", *argv); 1969e566a46f24fd89e104dea064d5233ab614f490bnet[shemminger]!shemminger *flags = val; 1979e566a46f24fd89e104dea064d5233ab614f490bnet[shemminger]!shemminger } else { 198eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger while (1) { 199eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger if (strcmp(*argv, "noecn") == 0) 200eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger *flags |= XFRM_STATE_NOECN; 201eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger else if (strcmp(*argv, "decap-dscp") == 0) 202eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger *flags |= XFRM_STATE_DECAP_DSCP; 203eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger else { 204eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger PREV_ARG(); /* back track */ 205eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger break; 206eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger } 207eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger 208eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger if (!NEXT_ARG_OK()) 209eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger break; 210eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger NEXT_ARG(); 211eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger } 2129e566a46f24fd89e104dea064d5233ab614f490bnet[shemminger]!shemminger } 213c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 214c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger filter.state_flags_mask = XFRM_FILTER_MASK_FULL; 215c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 216c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger *argcp = argc; 217c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger *argvp = argv; 218c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 219c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger return 0; 220c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger} 221c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 222c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_state_modify(int cmd, unsigned flags, int argc, char **argv) 223c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{ 224c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger struct rtnl_handle rth; 225c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger struct { 226c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger struct nlmsghdr n; 227c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger struct xfrm_usersa_info xsinfo; 228c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger char buf[RTA_BUF_SIZE]; 229c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } req; 230c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger char *idp = NULL; 231c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger char *ealgop = NULL; 232c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger char *aalgop = NULL; 233c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger char *calgop = NULL; 234c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 235c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger memset(&req, 0, sizeof(req)); 236c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 237c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xsinfo)); 238c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger req.n.nlmsg_flags = NLM_F_REQUEST|flags; 239c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger req.n.nlmsg_type = cmd; 240c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger req.xsinfo.family = preferred_family; 241c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 242c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger req.xsinfo.lft.soft_byte_limit = XFRM_INF; 243c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger req.xsinfo.lft.hard_byte_limit = XFRM_INF; 244c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger req.xsinfo.lft.soft_packet_limit = XFRM_INF; 245c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger req.xsinfo.lft.hard_packet_limit = XFRM_INF; 246c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 247c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger while (argc > 0) { 2487809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger if (strcmp(*argv, "mode") == 0) { 249c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger NEXT_ARG(); 250c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger xfrm_mode_parse(&req.xsinfo.mode, &argc, &argv); 251c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } else if (strcmp(*argv, "reqid") == 0) { 252c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger NEXT_ARG(); 253c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger xfrm_reqid_parse(&req.xsinfo.reqid, &argc, &argv); 254fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv } else if (strcmp(*argv, "seq") == 0) { 255fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv NEXT_ARG(); 256fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv xfrm_seq_parse(&req.xsinfo.seq, &argc, &argv); 257eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger } else if (strcmp(*argv, "replay-window") == 0) { 258eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger NEXT_ARG(); 259eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger if (get_u8(&req.xsinfo.replay_window, *argv, 0)) 260eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger invarg("\"replay-window\" value is invalid", *argv); 261c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } else if (strcmp(*argv, "flag") == 0) { 262c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger NEXT_ARG(); 263c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger xfrm_state_flag_parse(&req.xsinfo.flags, &argc, &argv); 264c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } else if (strcmp(*argv, "sel") == 0) { 265c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger NEXT_ARG(); 266c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger xfrm_selector_parse(&req.xsinfo.sel, &argc, &argv); 267c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } else if (strcmp(*argv, "limit") == 0) { 268c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger NEXT_ARG(); 269c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger xfrm_lifetime_cfg_parse(&req.xsinfo.lft, &argc, &argv); 2705cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger } else if (strcmp(*argv, "encap") == 0) { 2715cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger struct xfrm_encap_tmpl encap; 2725cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger inet_prefix oa; 2735cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger NEXT_ARG(); 2745cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger xfrm_encap_type_parse(&encap.encap_type, &argc, &argv); 2755cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger NEXT_ARG(); 2765cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger if (get_u16(&encap.encap_sport, *argv, 0)) 2775cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger invarg("\"encap\" sport value is invalid", *argv); 2785cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger encap.encap_sport = htons(encap.encap_sport); 2795cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger NEXT_ARG(); 2805cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger if (get_u16(&encap.encap_dport, *argv, 0)) 2815cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger invarg("\"encap\" dport value is invalid", *argv); 2825cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger encap.encap_dport = htons(encap.encap_dport); 2835cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger NEXT_ARG(); 2845cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger get_addr(&oa, *argv, AF_UNSPEC); 2855cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger memcpy(&encap.encap_oa, &oa.data, sizeof(encap.encap_oa)); 2865cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger addattr_l(&req.n, sizeof(req.buf), XFRMA_ENCAP, 2875cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger (void *)&encap, sizeof(encap)); 288c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } else { 2897809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger /* try to assume ALGO */ 2907809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger int type = xfrm_algotype_getbyname(*argv); 2917809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger switch (type) { 2927809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger case XFRMA_ALG_CRYPT: 2937809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger case XFRMA_ALG_AUTH: 2947809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger case XFRMA_ALG_COMP: 2957809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger { 2967809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger /* ALGO */ 2977809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger struct { 2987809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger struct xfrm_algo alg; 2997809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger char buf[XFRM_ALGO_KEY_BUF_SIZE]; 3007809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger } alg; 3017809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger int len; 3027809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger char *name; 3037809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger char *key; 3047809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger 3057809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger switch (type) { 3067809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger case XFRMA_ALG_CRYPT: 3077809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger if (ealgop) 3087809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger duparg("ALGOTYPE", *argv); 3097809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger ealgop = *argv; 3107809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger break; 3117809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger case XFRMA_ALG_AUTH: 3127809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger if (aalgop) 3137809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger duparg("ALGOTYPE", *argv); 3147809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger aalgop = *argv; 3157809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger break; 3167809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger case XFRMA_ALG_COMP: 3177809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger if (calgop) 3187809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger duparg("ALGOTYPE", *argv); 3197809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger calgop = *argv; 3207809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger break; 3217809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger default: 3227809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger /* not reached */ 3237809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger invarg("\"ALGOTYPE\" is invalid\n", *argv); 3247809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger } 3257809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger 3267809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger if (!NEXT_ARG_OK()) 3277809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger missarg("ALGONAME"); 3287809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger NEXT_ARG(); 3297809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger name = *argv; 3307809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger 3317809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger if (!NEXT_ARG_OK()) 3327809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger missarg("ALGOKEY"); 3337809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger NEXT_ARG(); 3347809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger key = *argv; 3357809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger 3367809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger memset(&alg, 0, sizeof(alg)); 3377809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger 3387809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger xfrm_algo_parse((void *)&alg, type, name, key, 3397809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger sizeof(alg.buf)); 3407809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger len = sizeof(struct xfrm_algo) + alg.alg.alg_key_len; 3417809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger 3427809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger addattr_l(&req.n, sizeof(req.buf), type, 3437809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger (void *)&alg, len); 3447809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger break; 3457809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger } 3467809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger default: 3477809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger /* try to assume ID */ 3487809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger if (idp) 3497809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger invarg("unknown", *argv); 3507809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger idp = *argv; 3517809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger 3527809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger /* ID */ 3537809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger xfrm_id_parse(&req.xsinfo.saddr, &req.xsinfo.id, 3547809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger &req.xsinfo.family, 0, &argc, &argv); 3557809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger if (preferred_family == AF_UNSPEC) 3567809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger preferred_family = req.xsinfo.family; 3577809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger } 358c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } 359c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger argc--; argv++; 360c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } 361c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 362c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (!idp) { 363c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger fprintf(stderr, "Not enough information: \"ID\" is required\n"); 364c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger exit(1); 365c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } 366c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 367c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (ealgop || aalgop || calgop) { 368c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (req.xsinfo.id.proto != IPPROTO_ESP && 369c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger req.xsinfo.id.proto != IPPROTO_AH && 370c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger req.xsinfo.id.proto != IPPROTO_COMP) { 37129aa4dd76c0c1877d50b2d643eb081d5477ceadforg[shemminger]!nakam fprintf(stderr, "\"ALGO\" is invalid with proto=%s\n", strxf_xfrmproto(req.xsinfo.id.proto)); 372c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger exit(1); 373c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } 374c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } else { 375c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (req.xsinfo.id.proto == IPPROTO_ESP || 376c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger req.xsinfo.id.proto == IPPROTO_AH || 377c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger req.xsinfo.id.proto == IPPROTO_COMP) { 37829aa4dd76c0c1877d50b2d643eb081d5477ceadforg[shemminger]!nakam fprintf(stderr, "\"ALGO\" is required with proto=%s\n", strxf_xfrmproto(req.xsinfo.id.proto)); 379c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger exit (1); 380c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } 381c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } 382c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 383c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0) 384c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger exit(1); 385c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 386c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (req.xsinfo.family == AF_UNSPEC) 387c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger req.xsinfo.family = AF_INET; 388c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 389c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) 390c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger exit(2); 391c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 392c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger rtnl_close(&rth); 393c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 394c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger return 0; 395c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger} 396c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 397fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipvstatic int xfrm_state_allocspi(int argc, char **argv) 398fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv{ 399fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv struct rtnl_handle rth; 400fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv struct { 401fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv struct nlmsghdr n; 402fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv struct xfrm_userspi_info xspi; 403fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv char buf[RTA_BUF_SIZE]; 404fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv } req; 405fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv char *idp = NULL; 406fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv char *minp = NULL; 407fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv char *maxp = NULL; 408fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv char res_buf[NLMSG_BUF_SIZE]; 409fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv struct nlmsghdr *res_n = (struct nlmsghdr *)res_buf; 410fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv 411fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv memset(res_buf, 0, sizeof(res_buf)); 412fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv 413fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv memset(&req, 0, sizeof(req)); 414fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv 415fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xspi)); 416fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv req.n.nlmsg_flags = NLM_F_REQUEST; 417fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv req.n.nlmsg_type = XFRM_MSG_ALLOCSPI; 418fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv req.xspi.info.family = preferred_family; 419fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv 420fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv#if 0 421fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv req.xsinfo.lft.soft_byte_limit = XFRM_INF; 422fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv req.xsinfo.lft.hard_byte_limit = XFRM_INF; 423fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv req.xsinfo.lft.soft_packet_limit = XFRM_INF; 424fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv req.xsinfo.lft.hard_packet_limit = XFRM_INF; 425fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv#endif 426fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv 427fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv while (argc > 0) { 428fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv if (strcmp(*argv, "mode") == 0) { 429fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv NEXT_ARG(); 430fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv xfrm_mode_parse(&req.xspi.info.mode, &argc, &argv); 431fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv } else if (strcmp(*argv, "reqid") == 0) { 432fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv NEXT_ARG(); 433fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv xfrm_reqid_parse(&req.xspi.info.reqid, &argc, &argv); 434fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv } else if (strcmp(*argv, "seq") == 0) { 435fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv NEXT_ARG(); 436fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv xfrm_seq_parse(&req.xspi.info.seq, &argc, &argv); 437fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv } else if (strcmp(*argv, "min") == 0) { 438fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv if (minp) 439fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv duparg("min", *argv); 440fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv minp = *argv; 441fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv 442fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv NEXT_ARG(); 443fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv 444fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv if (get_u32(&req.xspi.min, *argv, 0)) 445fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv invarg("\"min\" value is invalid", *argv); 446fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv } else if (strcmp(*argv, "max") == 0) { 447fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv if (maxp) 448fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv duparg("max", *argv); 449fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv maxp = *argv; 450fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv 451fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv NEXT_ARG(); 452fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv 453fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv if (get_u32(&req.xspi.max, *argv, 0)) 454fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv invarg("\"max\" value is invalid", *argv); 455fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv } else { 456fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv /* try to assume ID */ 457fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv if (idp) 458fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv invarg("unknown", *argv); 459fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv idp = *argv; 460fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv 461fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv /* ID */ 462fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv xfrm_id_parse(&req.xspi.info.saddr, &req.xspi.info.id, 463fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv &req.xspi.info.family, 0, &argc, &argv); 464fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv if (req.xspi.info.id.spi) { 465fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv fprintf(stderr, "\"SPI\" must be zero\n"); 466fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv exit(1); 467fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv } 468fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv if (preferred_family == AF_UNSPEC) 469fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv preferred_family = req.xspi.info.family; 470fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv } 471fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv argc--; argv++; 472fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv } 473fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv 474fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv if (!idp) { 475fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv fprintf(stderr, "Not enough information: \"ID\" is required\n"); 476fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv exit(1); 477fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv } 478fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv 479fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv if (minp) { 480fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv if (!maxp) { 481fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv fprintf(stderr, "\"max\" is missing\n"); 482fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv exit(1); 483fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv } 484fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv if (req.xspi.min > req.xspi.max) { 485fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv fprintf(stderr, "\"min\" valie is larger than \"max\" one\n"); 486fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv exit(1); 487fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv } 488fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv } else { 489fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv if (maxp) { 490fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv fprintf(stderr, "\"min\" is missing\n"); 491fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv exit(1); 492fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv } 493fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv 494fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv /* XXX: Default value defined in PF_KEY; 495fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv * See kernel's net/key/af_key.c(pfkey_getspi). 496fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv */ 497fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv req.xspi.min = 0x100; 498fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv req.xspi.max = 0x0fffffff; 499fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv 500fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv /* XXX: IPCOMP spi is 16-bits; 501fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv * See kernel's net/xfrm/xfrm_user(verify_userspi_info). 502fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv */ 503fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv if (req.xspi.info.id.proto == IPPROTO_COMP) 504fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv req.xspi.max = 0xffff; 505fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv } 506fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv 507fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0) 508fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv exit(1); 509fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv 510fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv if (req.xspi.info.family == AF_UNSPEC) 511fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv req.xspi.info.family = AF_INET; 512fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv 513fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv 514fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv if (rtnl_talk(&rth, &req.n, 0, 0, res_n, NULL, NULL) < 0) 515fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv exit(2); 516fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv 517fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv if (xfrm_state_print(NULL, res_n, (void*)stdout) < 0) { 518fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv fprintf(stderr, "An error :-)\n"); 519fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv exit(1); 520fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv } 521fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv 522fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv rtnl_close(&rth); 523fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv 524fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv return 0; 525fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv} 526fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv 527c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_state_filter_match(struct xfrm_usersa_info *xsinfo) 528c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{ 529c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (!filter.use) 530c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger return 1; 531c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 532c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (filter.id_src_mask) 533eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger if (xfrm_addr_match(&xsinfo->saddr, &filter.xsinfo.saddr, 534eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger filter.id_src_mask)) 535c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger return 0; 536c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (filter.id_dst_mask) 537eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger if (xfrm_addr_match(&xsinfo->id.daddr, &filter.xsinfo.id.daddr, 538eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger filter.id_dst_mask)) 539c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger return 0; 540c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if ((xsinfo->id.proto^filter.xsinfo.id.proto)&filter.id_proto_mask) 541c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger return 0; 542c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if ((xsinfo->id.spi^filter.xsinfo.id.spi)&filter.id_spi_mask) 543c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger return 0; 544c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if ((xsinfo->mode^filter.xsinfo.mode)&filter.mode_mask) 545c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger return 0; 546c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if ((xsinfo->reqid^filter.xsinfo.reqid)&filter.reqid_mask) 547c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger return 0; 548c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (filter.state_flags_mask) 549c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if ((xsinfo->flags & filter.xsinfo.flags) == 0) 550c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger return 0; 551c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 552c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger return 1; 553c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger} 554c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 555fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipvint xfrm_state_print(const struct sockaddr_nl *who, struct nlmsghdr *n, 556fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv void *arg) 557c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{ 558c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger FILE *fp = (FILE*)arg; 559c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger struct rtattr * tb[XFRMA_MAX+1]; 56090f93024a0818dc691138d8401721e797004b042shemminger struct rtattr * rta; 561c595c790a08366db90654c01aba02a1bd97d73e2shemminger struct xfrm_usersa_info *xsinfo = NULL; 562c595c790a08366db90654c01aba02a1bd97d73e2shemminger struct xfrm_user_expire *xexp = NULL; 563c595c790a08366db90654c01aba02a1bd97d73e2shemminger struct xfrm_usersa_id *xsid = NULL; 564c595c790a08366db90654c01aba02a1bd97d73e2shemminger int len = n->nlmsg_len; 565c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 566c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (n->nlmsg_type != XFRM_MSG_NEWSA && 56790f93024a0818dc691138d8401721e797004b042shemminger n->nlmsg_type != XFRM_MSG_DELSA && 568669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger n->nlmsg_type != XFRM_MSG_UPDSA && 56990f93024a0818dc691138d8401721e797004b042shemminger n->nlmsg_type != XFRM_MSG_EXPIRE) { 570c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger fprintf(stderr, "Not a state: %08x %08x %08x\n", 571c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); 572c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger return 0; 573c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } 574c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 575669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger if (n->nlmsg_type == XFRM_MSG_DELSA) { 576669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger /* Dont blame me for this .. Herbert made me do it */ 577669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger xsid = NLMSG_DATA(n); 578af1b6a41d4c7ed8aab98cfdcdafd55ec6c638b07Andy Gay len -= NLMSG_SPACE(sizeof(*xsid)); 579669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger } else if (n->nlmsg_type == XFRM_MSG_EXPIRE) { 58090f93024a0818dc691138d8401721e797004b042shemminger xexp = NLMSG_DATA(n); 58190f93024a0818dc691138d8401721e797004b042shemminger xsinfo = &xexp->state; 582af1b6a41d4c7ed8aab98cfdcdafd55ec6c638b07Andy Gay len -= NLMSG_SPACE(sizeof(*xexp)); 58390f93024a0818dc691138d8401721e797004b042shemminger } else { 58490f93024a0818dc691138d8401721e797004b042shemminger xexp = NULL; 58590f93024a0818dc691138d8401721e797004b042shemminger xsinfo = NLMSG_DATA(n); 586af1b6a41d4c7ed8aab98cfdcdafd55ec6c638b07Andy Gay len -= NLMSG_SPACE(sizeof(*xsinfo)); 58790f93024a0818dc691138d8401721e797004b042shemminger } 58890f93024a0818dc691138d8401721e797004b042shemminger 589c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (len < 0) { 590c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); 591c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger return -1; 592c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } 593c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 594669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger if (xsinfo && !xfrm_state_filter_match(xsinfo)) 595c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger return 0; 596c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 597669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger if (n->nlmsg_type == XFRM_MSG_DELSA) 598c595c790a08366db90654c01aba02a1bd97d73e2shemminger fprintf(fp, "Deleted "); 599669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger else if (n->nlmsg_type == XFRM_MSG_UPDSA) 600669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger fprintf(fp, "Updated "); 601c595c790a08366db90654c01aba02a1bd97d73e2shemminger else if (n->nlmsg_type == XFRM_MSG_EXPIRE) 602c595c790a08366db90654c01aba02a1bd97d73e2shemminger fprintf(fp, "Expired "); 603c595c790a08366db90654c01aba02a1bd97d73e2shemminger 604669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger if (n->nlmsg_type == XFRM_MSG_DELSA) 605669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger rta = XFRMSID_RTA(xsid); 606669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger else if (n->nlmsg_type == XFRM_MSG_EXPIRE) 60790f93024a0818dc691138d8401721e797004b042shemminger rta = XFRMEXP_RTA(xexp); 608c595c790a08366db90654c01aba02a1bd97d73e2shemminger else 60990f93024a0818dc691138d8401721e797004b042shemminger rta = XFRMS_RTA(xsinfo); 61090f93024a0818dc691138d8401721e797004b042shemminger 61190f93024a0818dc691138d8401721e797004b042shemminger parse_rtattr(tb, XFRMA_MAX, rta, len); 612c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 613c595c790a08366db90654c01aba02a1bd97d73e2shemminger if (n->nlmsg_type == XFRM_MSG_DELSA) { 614669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger //xfrm_policy_id_print(); 615669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger 616669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger if (!tb[XFRMA_SA]) { 617669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger fprintf(stderr, "Buggy XFRM_MSG_DELSA: no XFRMA_SA\n"); 618669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger return -1; 619669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger } 620669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger if (RTA_PAYLOAD(tb[XFRMA_SA]) < sizeof(*xsinfo)) { 621669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger fprintf(stderr, "Buggy XFRM_MSG_DELPOLICY: too short XFRMA_POLICY len\n"); 622669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger return -1; 623c595c790a08366db90654c01aba02a1bd97d73e2shemminger } 624669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger xsinfo = (struct xfrm_usersa_info *)RTA_DATA(tb[XFRMA_SA]); 625c595c790a08366db90654c01aba02a1bd97d73e2shemminger } 626c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 627fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv xfrm_state_info_print(xsinfo, tb, fp, NULL, NULL); 628c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 62990f93024a0818dc691138d8401721e797004b042shemminger if (n->nlmsg_type == XFRM_MSG_EXPIRE) { 63090f93024a0818dc691138d8401721e797004b042shemminger fprintf(fp, "\t"); 63190f93024a0818dc691138d8401721e797004b042shemminger fprintf(fp, "hard %u", xexp->hard); 63290f93024a0818dc691138d8401721e797004b042shemminger fprintf(fp, "%s", _SL_); 63390f93024a0818dc691138d8401721e797004b042shemminger } 63490f93024a0818dc691138d8401721e797004b042shemminger 6357809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger if (oneline) 6367809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger fprintf(fp, "\n"); 637669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger fflush(fp); 6387809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger 639c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger return 0; 640c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger} 641c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 642c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_state_get_or_delete(int argc, char **argv, int delete) 643c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{ 644c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger struct rtnl_handle rth; 645c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger struct { 646c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger struct nlmsghdr n; 647c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger struct xfrm_usersa_id xsid; 648c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } req; 649c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger struct xfrm_id id; 650c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger char *idp = NULL; 651c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 652c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger memset(&req, 0, sizeof(req)); 653c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 654c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xsid)); 655c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger req.n.nlmsg_flags = NLM_F_REQUEST; 656c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger req.n.nlmsg_type = delete ? XFRM_MSG_DELSA : XFRM_MSG_GETSA; 657c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger req.xsid.family = preferred_family; 658c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 659c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger while (argc > 0) { 660c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger /* 661c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * XXX: Source address is not used and ignore it to follow 662c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * XXX: a manner of setkey e.g. in the case of deleting/getting 663c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * XXX: message of IPsec SA. 664c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger */ 665c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger xfrm_address_t ignore_saddr; 666c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 667c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (idp) 668c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger invarg("unknown", *argv); 669c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger idp = *argv; 670c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 671c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger /* ID */ 672c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger memset(&id, 0, sizeof(id)); 6737809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger xfrm_id_parse(&ignore_saddr, &id, &req.xsid.family, 0, 674c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger &argc, &argv); 675c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 676c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger memcpy(&req.xsid.daddr, &id.daddr, sizeof(req.xsid.daddr)); 677c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger req.xsid.spi = id.spi; 678c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger req.xsid.proto = id.proto; 679c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 680c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger argc--; argv++; 681c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } 682c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 683c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0) 684c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger exit(1); 685c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 686c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (req.xsid.family == AF_UNSPEC) 687c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger req.xsid.family = AF_INET; 688c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 689c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (delete) { 690c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) 691c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger exit(2); 692c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } else { 693c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger char buf[NLMSG_BUF_SIZE]; 694c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger struct nlmsghdr *res_n = (struct nlmsghdr *)buf; 695c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 696c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger memset(buf, 0, sizeof(buf)); 697c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 698c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (rtnl_talk(&rth, &req.n, 0, 0, res_n, NULL, NULL) < 0) 699c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger exit(2); 700c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 701c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (xfrm_state_print(NULL, res_n, (void*)stdout) < 0) { 702c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger fprintf(stderr, "An error :-)\n"); 703c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger exit(1); 704c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } 705c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } 706c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 707c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger rtnl_close(&rth); 708c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 709c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger return 0; 710c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger} 711c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 712c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger/* 713c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * With an existing state of nlmsg, make new nlmsg for deleting the state 714c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * and store it to buffer. 715c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger */ 7166dc9f016347441fbf94cf851c054b0f45ba32c1cosdl.net!shemmingerstatic int xfrm_state_keep(const struct sockaddr_nl *who, 71750772dc51ac02239958e1ebcdb21277fcdf133a7osdl.net!shemminger struct nlmsghdr *n, 7186dc9f016347441fbf94cf851c054b0f45ba32c1cosdl.net!shemminger void *arg) 719c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{ 720c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger struct xfrm_buffer *xb = (struct xfrm_buffer *)arg; 721c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger struct rtnl_handle *rth = xb->rth; 722c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger struct xfrm_usersa_info *xsinfo = NLMSG_DATA(n); 723c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger int len = n->nlmsg_len; 724c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger struct nlmsghdr *new_n; 725c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger struct xfrm_usersa_id *xsid; 726c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 727c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (n->nlmsg_type != XFRM_MSG_NEWSA) { 728c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger fprintf(stderr, "Not a state: %08x %08x %08x\n", 729c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); 730c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger return 0; 731c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } 732c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 733c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger len -= NLMSG_LENGTH(sizeof(*xsinfo)); 734c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (len < 0) { 735c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); 736c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger return -1; 737c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } 738c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 739c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (!xfrm_state_filter_match(xsinfo)) 740c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger return 0; 741c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 742c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (xb->offset > xb->size) { 7439bec1a436335457f3067a17de6ddb913bd95a184shemminger fprintf(stderr, "State buffer overflow\n"); 744c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger return -1; 745c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } 746c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 747c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger new_n = (struct nlmsghdr *)(xb->buf + xb->offset); 748c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger new_n->nlmsg_len = NLMSG_LENGTH(sizeof(*xsid)); 749c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger new_n->nlmsg_flags = NLM_F_REQUEST; 750c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger new_n->nlmsg_type = XFRM_MSG_DELSA; 751c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger new_n->nlmsg_seq = ++rth->seq; 752c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 753c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger xsid = NLMSG_DATA(new_n); 754c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger xsid->family = xsinfo->family; 755c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger memcpy(&xsid->daddr, &xsinfo->id.daddr, sizeof(xsid->daddr)); 756c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger xsid->spi = xsinfo->id.spi; 757c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger xsid->proto = xsinfo->id.proto; 758c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 759c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger xb->offset += new_n->nlmsg_len; 760c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger xb->nlmsg_count ++; 761c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 762c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger return 0; 763c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger} 764c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 7659bec1a436335457f3067a17de6ddb913bd95a184shemmingerstatic int xfrm_state_list_or_deleteall(int argc, char **argv, int deleteall) 766c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{ 767c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger char *idp = NULL; 768c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger struct rtnl_handle rth; 769c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 770bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam if(argc > 0) 771bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam filter.use = 1; 772c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger filter.xsinfo.family = preferred_family; 773c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 774c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger while (argc > 0) { 775c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (strcmp(*argv, "mode") == 0) { 776c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger NEXT_ARG(); 777c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger xfrm_mode_parse(&filter.xsinfo.mode, &argc, &argv); 778c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 779c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger filter.mode_mask = XFRM_FILTER_MASK_FULL; 780c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 781c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } else if (strcmp(*argv, "reqid") == 0) { 782c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger NEXT_ARG(); 783c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger xfrm_reqid_parse(&filter.xsinfo.reqid, &argc, &argv); 784c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 785c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger filter.reqid_mask = XFRM_FILTER_MASK_FULL; 786c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 787c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } else if (strcmp(*argv, "flag") == 0) { 788c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger NEXT_ARG(); 789c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger xfrm_state_flag_parse(&filter.xsinfo.flags, &argc, &argv); 790c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 791c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger filter.state_flags_mask = XFRM_FILTER_MASK_FULL; 792c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 793c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } else { 794c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (idp) 795c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger invarg("unknown", *argv); 796c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger idp = *argv; 797c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 798c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger /* ID */ 7997809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger xfrm_id_parse(&filter.xsinfo.saddr, &filter.xsinfo.id, 8007809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger &filter.xsinfo.family, 1, &argc, &argv); 801c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (preferred_family == AF_UNSPEC) 802c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger preferred_family = filter.xsinfo.family; 803c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } 804c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger argc--; argv++; 805c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } 806c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 807c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0) 808c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger exit(1); 809c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 8109bec1a436335457f3067a17de6ddb913bd95a184shemminger if (deleteall) { 811c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger struct xfrm_buffer xb; 8129bec1a436335457f3067a17de6ddb913bd95a184shemminger char buf[NLMSG_DELETEALL_BUF_SIZE]; 813c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger int i; 814c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 815c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger xb.buf = buf; 816c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger xb.size = sizeof(buf); 817c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger xb.rth = &rth; 818c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 819c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger for (i = 0; ; i++) { 820c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger xb.offset = 0; 821c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger xb.nlmsg_count = 0; 822c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 823c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (show_stats > 1) 8249bec1a436335457f3067a17de6ddb913bd95a184shemminger fprintf(stderr, "Delete-all round = %d\n", i); 825c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 826c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (rtnl_wilddump_request(&rth, preferred_family, XFRM_MSG_GETSA) < 0) { 827c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger perror("Cannot send dump request"); 828c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger exit(1); 829c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } 830c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 831c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (rtnl_dump_filter(&rth, xfrm_state_keep, &xb, NULL, NULL) < 0) { 8329bec1a436335457f3067a17de6ddb913bd95a184shemminger fprintf(stderr, "Delete-all terminated\n"); 833c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger exit(1); 834c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } 835c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (xb.nlmsg_count == 0) { 836c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (show_stats > 1) 8379bec1a436335457f3067a17de6ddb913bd95a184shemminger fprintf(stderr, "Delete-all completed\n"); 838c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger break; 839c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } 840c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 841c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (rtnl_send(&rth, xb.buf, xb.offset) < 0) { 8429bec1a436335457f3067a17de6ddb913bd95a184shemminger perror("Failed to send delete-all request\n"); 843c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger exit(1); 844c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } 845c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (show_stats > 1) 8469bec1a436335457f3067a17de6ddb913bd95a184shemminger fprintf(stderr, "Delete-all nlmsg count = %d\n", xb.nlmsg_count); 847c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 848c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger xb.offset = 0; 849c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger xb.nlmsg_count = 0; 850c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } 851c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 852c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } else { 853c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (rtnl_wilddump_request(&rth, preferred_family, XFRM_MSG_GETSA) < 0) { 854c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger perror("Cannot send dump request"); 855c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger exit(1); 856c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } 857c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 858c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (rtnl_dump_filter(&rth, xfrm_state_print, stdout, NULL, NULL) < 0) { 859c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger fprintf(stderr, "Dump terminated\n"); 860c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger exit(1); 861c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } 862c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger } 863c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 864c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger rtnl_close(&rth); 865c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 866c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger exit(0); 867c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger} 868c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 8699bec1a436335457f3067a17de6ddb913bd95a184shemmingerstatic int xfrm_state_flush(int argc, char **argv) 870bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam{ 871bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam struct rtnl_handle rth; 872bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam struct { 873bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam struct nlmsghdr n; 874bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam struct xfrm_usersa_flush xsf; 875bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam } req; 8769bec1a436335457f3067a17de6ddb913bd95a184shemminger char *protop = NULL; 877bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam 878bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam memset(&req, 0, sizeof(req)); 879bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam 880bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xsf)); 881bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam req.n.nlmsg_flags = NLM_F_REQUEST; 882bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam req.n.nlmsg_type = XFRM_MSG_FLUSHSA; 883bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam req.xsf.proto = IPSEC_PROTO_ANY; 884bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam 8859bec1a436335457f3067a17de6ddb913bd95a184shemminger while (argc > 0) { 8869bec1a436335457f3067a17de6ddb913bd95a184shemminger if (strcmp(*argv, "proto") == 0) { 8879bec1a436335457f3067a17de6ddb913bd95a184shemminger int ret; 8889bec1a436335457f3067a17de6ddb913bd95a184shemminger 8899bec1a436335457f3067a17de6ddb913bd95a184shemminger if (protop) 8909bec1a436335457f3067a17de6ddb913bd95a184shemminger duparg("proto", *argv); 8919bec1a436335457f3067a17de6ddb913bd95a184shemminger protop = *argv; 8929bec1a436335457f3067a17de6ddb913bd95a184shemminger 8939bec1a436335457f3067a17de6ddb913bd95a184shemminger NEXT_ARG(); 8949bec1a436335457f3067a17de6ddb913bd95a184shemminger 8959bec1a436335457f3067a17de6ddb913bd95a184shemminger ret = xfrm_xfrmproto_getbyname(*argv); 8969bec1a436335457f3067a17de6ddb913bd95a184shemminger if (ret < 0) 8979bec1a436335457f3067a17de6ddb913bd95a184shemminger invarg("\"XFRM_PROTO\" is invalid", *argv); 8989bec1a436335457f3067a17de6ddb913bd95a184shemminger 8999bec1a436335457f3067a17de6ddb913bd95a184shemminger req.xsf.proto = (__u8)ret; 9009bec1a436335457f3067a17de6ddb913bd95a184shemminger } else 9019bec1a436335457f3067a17de6ddb913bd95a184shemminger invarg("unknown", *argv); 9029bec1a436335457f3067a17de6ddb913bd95a184shemminger 9039bec1a436335457f3067a17de6ddb913bd95a184shemminger argc--; argv++; 9049bec1a436335457f3067a17de6ddb913bd95a184shemminger } 9059bec1a436335457f3067a17de6ddb913bd95a184shemminger 906bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0) 907bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam exit(1); 908bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam 909bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam if (show_stats > 1) 9109bec1a436335457f3067a17de6ddb913bd95a184shemminger fprintf(stderr, "Flush state proto=%s\n", 9119bec1a436335457f3067a17de6ddb913bd95a184shemminger (req.xsf.proto == IPSEC_PROTO_ANY) ? "any" : 9129bec1a436335457f3067a17de6ddb913bd95a184shemminger strxf_xfrmproto(req.xsf.proto)); 913bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam 914bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) 915bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam exit(2); 916bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam 917bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam rtnl_close(&rth); 918bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam 919bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam return 0; 920bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam} 921bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam 922c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerint do_xfrm_state(int argc, char **argv) 923c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{ 924c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (argc < 1) 9259bec1a436335457f3067a17de6ddb913bd95a184shemminger return xfrm_state_list_or_deleteall(0, NULL, 0); 926c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 927c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (matches(*argv, "add") == 0) 928c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger return xfrm_state_modify(XFRM_MSG_NEWSA, 0, 929c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger argc-1, argv+1); 930c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (matches(*argv, "update") == 0) 931c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger return xfrm_state_modify(XFRM_MSG_UPDSA, 0, 932c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger argc-1, argv+1); 933fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv if (matches(*argv, "allocspi") == 0) 934fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv return xfrm_state_allocspi(argc-1, argv+1); 9359bec1a436335457f3067a17de6ddb913bd95a184shemminger if (matches(*argv, "delete") == 0) 936c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger return xfrm_state_get_or_delete(argc-1, argv+1, 1); 9379bec1a436335457f3067a17de6ddb913bd95a184shemminger if (matches(*argv, "deleteall") == 0 || matches(*argv, "delall") == 0) 9389bec1a436335457f3067a17de6ddb913bd95a184shemminger return xfrm_state_list_or_deleteall(argc-1, argv+1, 1); 939c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0 940c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger || matches(*argv, "lst") == 0) 9419bec1a436335457f3067a17de6ddb913bd95a184shemminger return xfrm_state_list_or_deleteall(argc-1, argv+1, 0); 942c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (matches(*argv, "get") == 0) 943c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger return xfrm_state_get_or_delete(argc-1, argv+1, 0); 9449bec1a436335457f3067a17de6ddb913bd95a184shemminger if (matches(*argv, "flush") == 0) 9459bec1a436335457f3067a17de6ddb913bd95a184shemminger return xfrm_state_flush(argc-1, argv+1); 946c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger if (matches(*argv, "help") == 0) 947c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger usage(); 948c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger fprintf(stderr, "Command \"%s\" is unknown, try \"ip xfrm state help\".\n", *argv); 949c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger exit(-1); 950c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger} 951