📄 spi.c
字号:
/* * All-in-one program to set Security Association parameters * Copyright (C) 1996 John Ioannidis. * Copyright (C) 1997, 1998, 1999, 2000, 2001 Richard Guy Briggs. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */char spi_c_version[] = "RCSID $Id: spi.c,v 1.74 2001/06/14 19:35:14 rgb Exp $";#include <asm/types.h>#include <sys/types.h>#include <sys/ioctl.h>/* #include <linux/netdevice.h> */#include <net/if.h>/* #include <linux/types.h> */ /* new */#include <sys/stat.h>#include <fcntl.h>#include <string.h>#include <errno.h>/* #include <sys/socket.h> */#include <netinet/in.h>#include <arpa/inet.h>/* #include <linux/ip.h> */#include <netdb.h>#include <unistd.h>#include <getopt.h>#include <ctype.h>#include <stdio.h>#include <stdlib.h>#include <freeswan.h>#if 0#include <linux/autoconf.h> /* CONFIG_IPSEC_PFKEYv2 */#endif #include <signal.h> #include <sys/socket.h> #include <pfkeyv2.h> #include <pfkey.h>#include "radij.h"#include "ipsec_encap.h"#include "ipsec_netlink.h"#include "ipsec_xform.h"#include "ipsec_ipe4.h"#include "ipsec_ah.h"#include "ipsec_esp.h"struct encap_msghdr *em;char *program_name;int debug = 0;char *command;extern char *optarg;extern int optind, opterr, optopt;char scratch[2];char *iv = NULL, *enckey = NULL, *authkey = NULL;size_t ivlen = 0, enckeylen = 0, authkeylen = 0;ip_address edst, dst, src;int address_family = 0;unsigned char proto = 0;int alg = 0;int replay_window = 0;char *iv_opt, *akey_opt, *ekey_opt, *alg_opt, *edst_opt, *spi_opt, *proto_opt, *af_opt, *said_opt, *dst_opt, *src_opt;char sa[SATOT_BUF];extern unsigned int pfkey_lib_debug; /* used by libfreeswan/pfkey_v2_build */int pfkey_sock;fd_set pfkey_socks;uint32_t pfkey_seq = 0;#define streql(_a,_b) (!strcmp((_a),(_b)))static const char *usage_string = "\Usage:\n\ in the following, <SA> is: --af <inet | inet6> --edst <dstaddr> --spi <spi> --proto <proto>\n\ OR: --said <proto><.|:><spi>@<dstaddr>spi --clear\n\spi --help\n\spi --version\n\spi\n\spi --del <SA>\n\spi --ip4 <SA> --src <encap-src> --dst <encap-dst>\n\spi --ip6 <SA> --src <encap-src> --dst <encap-dst>\n\spi --ah <algo> <SA> [ --replay_window <replay_window> ] --authkey <key>\n\ where <algo> is one of: hmac-md5-96 | hmac-sha1-96\n\spi --esp <algo> <SA> [ --replay_window <replay-window> ] --enckey <ekey> --authkey <akey>\n\ where <algo> is one of: 3des-md5-96 | 3des-sha1-96\n\spi --esp <algo> <SA> [ --replay_window <replay-window> ] --enckey <ekey>\n\ where <algo> is: 3des\n\spi --comp <algo> <SA>\n\ where <algo> is: deflate\n\[ --debug ] is optional to any spi command.\n\[ --label <label> ] is optional to any spi command.";static voidusage(char *s, FILE *f){ /* s argument is actually ignored, at present */ fprintf(f, "%s:%s", s, usage_string); exit(-1);}#ifdef SIGS_FROM_BELOWstatic voidpfkey_sig_handler(int x){ int len; int error = 0;#if 0 int i; fd_set l_pfkey_socks;#endif unsigned char buffer[PFKEYv2_MAX_MSGSIZE]; struct sadb_ext *extensions_parse[SADB_EXT_MAX + 1]; struct sadb_msg *pfkey_msg; /* if(signal.type == SIGIO) } */ while(1) {#if 0 memcpy(&l_pfkey_socks, &pfkey_socks, sizeof(pfkey_socks)); fprintf(stdout, "%s:pfkey_sig_handler: " "entering select for pfkey_sock=%d.\n", program_name, pfkey_sock); if((i = select(pfkey_sock + 1, &l_pfkey_socks, NULL, NULL, NULL)) < 0) { fprintf(stderr, "%s:system error:pfkey_sig_handler: " "select returned errno:%d.\n", program_name, errno); break; } if(!i) { fprintf(stdout, "%s:pfkey_sig_handler: " "select returned %d.\n", program_name, i); return; } ret = recvmsg(pfkey_sock, /* struct msghdr * */msg, /* unsigned int */flags); if(ret == -1) { fprintf(stderr, "%s: pfkey recvmsg failed.\n", program_name); switch(errno) { case EBADF: case ENOTCONN: case ENOTSOCK: case EWOULDBLOCK: case EINTR: case EFAULT: fprintf(stderr, "system error:%d\n", errno); exit(1); default: fprintf(stderr, "unknown error:%d\n", errno); exit(1); } }#endif fprintf(stdout, "%s:pfkey_sig_handler: " "entering read for pfkey_sock=%d.\n", program_name, pfkey_sock); if((len = read(pfkey_sock, buffer, sizeof(buffer))) < 0) { fprintf(stderr, "%s: pfkey read failed.\n", program_name); switch(errno) { case EBADF: case ENOTCONN: case ENOTSOCK: case EWOULDBLOCK: case EINTR: case EFAULT: fprintf(stderr, "%s:system error:%d\n", program_name, errno); exit(1); default: fprintf(stderr, "%s:unknown error:%d\n", program_name, errno); exit(1); } break; } if(len < sizeof(struct sadb_msg)) { fprintf(stderr, "%s:system error:pfkey_sig_handler: " "read returned only %d octets of a minimum of %d octets for the message header.\n", program_name, len, sizeof(struct sadb_msg)); break; } fprintf(stdout, "%s:pfkey_sig_handler: " "read %d octets from pfkey_sock=%d.\n", program_name, len, pfkey_sock); pfkey_msg = (struct sadb_msg*)buffer; if(pfkey_msg->sadb_msg_version != PF_KEY_V2) { fprintf(stderr, "system error:pfkey_sig_handler: not PF_KEY_V2 msg.\n"); break; } if(len != pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) { fprintf(stderr, "system error:pfkey_sig_handler: bogus msg len of %d, not %d byte aligned.\n", len, IPSEC_PFKEYv2_ALIGN); break; } /* XXX when this becomes a lib, keying daemons must be able to receive errors */ if(pfkey_msg->sadb_msg_errno) { fprintf(stderr, "system error:pfkey_sig_handler: errno set to %d.\n", pfkey_msg->sadb_msg_errno); break; } /* check PID */ if(pfkey_msg->sadb_msg_pid != getpid()) { fprintf(stderr, "system error:pfkey_sig_handler: pid (%d) does not equal originating process pid (%d).\n", pfkey_msg->sadb_msg_pid, getpid()); break; } if(pfkey_msg->sadb_msg_seq != pfkey_seq) { fprintf(stderr, "system error:pfkey_sig_handler: seq (%d) does not equal original message seq (%d).\n", pfkey_msg->sadb_msg_seq, pfkey_seq); break; } if(pfkey_msg->sadb_msg_reserved) { fprintf(stderr, "system error:pfkey_sig_handler: reserved field must be zero, set to %d.\n", pfkey_msg->sadb_msg_reserved); break; } if((pfkey_msg->sadb_msg_type > SADB_MAX) || (!pfkey_msg->sadb_msg_type)){ fprintf(stderr, "system error:pfkey_sig_handler: msg type too large or small:%d.\n", pfkey_msg->sadb_msg_type); break; } if((error = pfkey_msg_parse(pfkey_msg, NULL, extensions_parse, EXT_BITS_OUT))) { fprintf(stderr, "system error:pfkey_sig_handler: pfkey_msg_parse returns %d.\n", error); } else { fprintf(stdout, "%s:pfkey_sig_handler: return (msg would normally be sent for parsing).\n", program_name); } break; } return;}#endif /* SIGS_FROM_BELOW */static struct option const longopts[] ={ {"ah", 1, 0, 'H'}, {"esp", 1, 0, 'P'}, {"comp", 1, 0, 'Z'}, {"ip4", 0, 0, '4'}, {"ip6", 0, 0, '6'}, {"del", 0, 0, 'd'}, {"authkey", 1, 0, 'A'}, {"enckey", 1, 0, 'E'}, {"edst", 1, 0, 'e'}, {"spi", 1, 0, 's'}, {"proto", 1, 0, 'p'}, {"af", 1, 0, 'a'}, {"replay_window", 1, 0, 'w'}, {"iv", 1, 0, 'i'}, {"dst", 1, 0, 'D'}, {"src", 1, 0, 'S'}, {"said", 1, 0, 'I'}, {"help", 0, 0, 'h'}, {"version", 0, 0, 'v'}, {"clear", 0, 0, 'c'}, {"label", 1, 0, 'l'}, {"debug", 0, 0, 'g'}, {"optionsfrom", 1, 0, '+'}, {0, 0, 0, 0}};intmain(int argc, char *argv[]){ char *endptr; __u32 spi = 0; int c, previous = -1;/* int ret; */ ip_said said; size_t sa_len; const char* error_s; char ipaddr_txt[ADDRTOT_BUF]; char ipsaid_txt[SATOT_BUF]; int error = 0; int argcount = argc; unsigned char authalg, encryptalg; struct sadb_ext *extensions[SADB_EXT_MAX + 1]; struct sadb_msg *pfkey_msg;#if 0 ip_address pfkey_address_p_ska; ip_address pfkey_ident_s_ska; ip_address pfkey_ident_d_ska;#endif program_name = argv[0]; memset(&said, 0, sizeof(said)); iv_opt = akey_opt = ekey_opt = alg_opt = edst_opt = spi_opt = proto_opt = af_opt = said_opt = dst_opt = src_opt = NULL; while((c = getopt_long(argc, argv, ""/*"H:P:Z:46dcA:E:e:s:a:w:i:D:S:hvgl:+:"*/, longopts, 0)) != EOF) { switch(c) { case 'g': debug = 1; pfkey_lib_debug = 1; argcount--; break; case 'l': program_name = malloc(strlen(argv[0]) + 10 /* update this when changing the sprintf() */ + strlen(optarg)); sprintf(program_name, "%s --label %s", argv[0], optarg); argcount -= 2; break; case 'H': if(alg) { fprintf(stderr, "%s: Only one of '--ah', '--esp', '--comp', '--ip4', '--ip6', '--del' or '--clear' options permitted.\n", program_name); exit(1); } if (!strcmp(optarg, "hmac-md5-96")) { alg = XF_AHHMACMD5; } else if(!strcmp(optarg, "hmac-sha1-96")) { alg = XF_AHHMACSHA1; } else { fprintf(stderr, "%s: Unknown authentication algorithm '%s' follows '--ah' option.\n", program_name, optarg); exit(1); } if(debug) { fprintf(stdout, "Algorithm %d selected.\n", alg); } alg_opt = optarg; break; case 'P': if(alg) { fprintf(stderr, "%s: Only one of '--ah', '--esp', '--comp', '--ip4', '--ip6', '--del' or '--clear' options permitted.\n", program_name); exit(1); } if (!strcmp(optarg, "3des-md5-96")) { alg = XF_ESP3DESMD596; } else if(!strcmp(optarg, "3des-sha1-96")) { alg = XF_ESP3DESSHA196; } else if(!strcmp(optarg, "3des")) { alg = XF_ESP3DES; } else { fprintf(stderr, "%s: Invalid encryption algorithm '%s' follows '--esp' option.\n", program_name, optarg); exit(1); } if(debug) { fprintf(stdout, "Algorithm %d selected.\n", alg); } alg_opt = optarg; break; case 'Z': if(alg) { fprintf(stderr, "%s: Only one of '--ah', '--esp', '--comp', '--ip4', '--ip6', '--del' or '--clear' options permitted.\n", program_name); exit(1); } if (!strcmp(optarg, "deflate")) { alg = XF_COMPDEFLATE; } else { fprintf(stderr, "%s: Unknown compression algorithm '%s' follows '--comp' option.\n", program_name, optarg); exit(1); } if(debug) { fprintf(stdout, "Algorithm %d selected.\n", alg); } alg_opt = optarg; break; case '4': if(alg) { fprintf(stderr, "%s: Only one of '--ah', '--esp', '--comp', '--ip4', '--ip6', '--del' or '--clear' options permitted.\n", program_name); exit(1); } alg = XF_IP4; address_family = AF_INET; if(debug) { fprintf(stdout, "Algorithm %d selected.\n", alg); } alg_opt = optarg; break; case '6': if(alg) { fprintf(stderr, "%s: Only one of '--ah', '--esp', '--comp', '--ip4', '--ip6', '--del' or '--clear' options permitted.\n", program_name); exit(1); } alg = XF_IP6; address_family = AF_INET6; if(debug) { fprintf(stdout, "Algorithm %d selected.\n", alg); } alg_opt = optarg; break; case 'd': if(alg) { fprintf(stderr, "%s: Only one of '--ah', '--esp', '--comp', '--ip4', '--ip6', '--del' or '--clear' options permitted.\n", program_name); exit(1); } alg = XF_DEL; if(debug) { fprintf(stdout, "Algorithm %d selected.\n", alg); } alg_opt = optarg; break; case 'c':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -