- import of strongswan-2.7.0

- applied patch for charon
This commit is contained in:
Martin Willi
2006-04-28 07:14:48 +00:00
parent 52923c9acb
commit 997358a6c4
2043 changed files with 346842 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
spigrp
+52
View File
@@ -0,0 +1,52 @@
# Makefile for miscelaneous programs
# Copyright (C) 2002 Michael Richardson <[email protected]>
#
# 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.
#
# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:31 as Exp $
FREESWANSRCDIR=../..
include ${FREESWANSRCDIR}/Makefile.inc
PROGRAM=spigrp
EXTRA5PROC=${PROGRAM}.5
LIBS=${FREESWANLIB}
include ../Makefile.program
#
# $Log: Makefile,v $
# Revision 1.1 2004/03/15 20:35:31 as
# added files from freeswan-2.04-x509-1.5.3
#
# Revision 1.4 2002/06/03 20:25:31 mcr
# man page for files actually existant in /proc/net changed back to
# ipsec_foo via new EXTRA5PROC process.
#
# Revision 1.3 2002/06/02 21:51:41 mcr
# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
# kernel sense.)
#
# Revision 1.2 2002/04/26 01:21:26 mcr
# while tracking down a missing (not installed) /etc/ipsec.conf,
# MCR has decided that it is not okay for each program subdir to have
# some subset (determined with -f) of possible files.
# Each subdir that defines $PROGRAM, MUST have a PROGRAM.8 file as well as a PROGRAM file.
# Optional PROGRAM.5 files have been added to the makefiles.
#
# Revision 1.1 2002/04/24 07:55:32 mcr
# #include patches and Makefiles for post-reorg compilation.
#
#
#
+116
View File
@@ -0,0 +1,116 @@
.TH IPSEC_SPIGRP 5 "27 Jun 2000"
.\"
.\" RCSID $Id: spigrp.5,v 1.1 2004/03/15 20:35:31 as Exp $
.\"
.SH NAME
ipsec_spigrp \- list IPSEC Security Association groupings
.SH SYNOPSIS
.B ipsec
.B spigrp
.PP
.B cat
.B /proc/net/ipsec_spigrp
.PP
.SH DESCRIPTION
.I /proc/net/ipsec_spigrp
is a read-only file that lists groups of IPSEC Security Associations
(SAs).
.PP
An entry in the IPSEC extended routing table can only point (via an
SAID) to one SA. If more than one transform must be applied to a given
type of packet, this can be accomplished by setting up several SAs with
the same destination address but potentially different SPIs and
protocols, and grouping them with
.IR ipsec_spigrp(8) .
.PP
The SA groups are listed, one line per connection/group, as a sequence
of SAs to be applied (or that should have been applied, in the case of
an incoming packet) from inside to outside the packet. An SA is
identified by its SAID, which consists of protocol ("ah", "esp", "comp" or
"tun"), SPI (with '.' for IPv4 or ':' for IPv6 prefixed hexadecimal number ) and destination address
(IPv4 dotted quad or IPv6 coloned hex) prefixed by '@', in the format <proto><af><spi>@<dest>.
.SH EXAMPLES
.TP
.B [email protected]
.B [email protected]
.B [email protected]
.B [email protected]
.LP
is a group of 3 SAs, destined for
.BR 192.168.2.110
with an IPv4-in-IPv4 tunnel SA applied first with an SPI of
.BR 3d0
in hexadecimal, followed by a Deflate compression header to compress
the packet with CPI of
.BR 3d0
in hexadecimal, followed by an Encapsulating Security Payload header to
encrypt the packet with SPI
.BR 187a101b
in hexadecimal, followed by an Authentication Header to authenticate the
packet with SPI
.BR 187a101a
in hexadecimal, applied from inside to outside the packet. This could
be an incoming or outgoing group, depending on the address of the local
machine.
.LP
.TP
.B tun:3d0@3049:1::2
.B comp:3d0@3049:1::2
.B esp:187a101b@3049:1::2
.B ah:187a101a@3049:1::2
.LP
is a group of 3 SAs, destined for
.BR 3049:1::2
with an IPv6-in-IPv6 tunnel SA applied first with an SPI of
.BR 3d0
in hexadecimal, followed by a Deflate compression header to compress
the packet with CPI of
.BR 3d0
in hexadecimal, followed by an Encapsulating Security Payload header to
encrypt the packet with SPI
.BR 187a101b
in hexadecimal, followed by an Authentication Header to authenticate the
packet with SPI
.BR 187a101a
in hexadecimal, applied from inside to outside the packet. This could
be an incoming or outgoing group, depending on the address of the local
machine.
.LP
.SH FILES
/proc/net/ipsec_spigrp, /usr/local/bin/ipsec
.SH "SEE ALSO"
ipsec(8), ipsec_manual(8), ipsec_tncfg(5), ipsec_eroute(5),
ipsec_spi(5), ipsec_klipsdebug(5), ipsec_spigrp(8), ipsec_version(5),
ipsec_pf_key(5)
.SH HISTORY
Written for the Linux FreeS/WAN project
<http://www.freeswan.org/>
by Richard Guy Briggs.
.SH BUGS
:-)
.\"
.\" $Log: spigrp.5,v $
.\" Revision 1.1 2004/03/15 20:35:31 as
.\" added files from freeswan-2.04-x509-1.5.3
.\"
.\" Revision 1.6 2002/04/24 07:35:40 mcr
.\" Moved from ./klips/utils/spigrp.5,v
.\"
.\" Revision 1.5 2000/09/17 18:56:48 rgb
.\" Added IPCOMP support.
.\"
.\" Revision 1.4 2000/09/13 15:54:32 rgb
.\" Added Gerhard's ipv6 updates.
.\"
.\" Revision 1.3 2000/06/30 18:21:55 rgb
.\" Update SEE ALSO sections to include ipsec_version(5) and ipsec_pf_key(5)
.\" and correct FILES sections to no longer refer to /dev/ipsec which has
.\" been removed since PF_KEY does not use it.
.\"
.\" Revision 1.2 2000/06/28 12:44:12 henry
.\" format touchup
.\"
.\" Revision 1.1 2000/06/28 05:43:00 rgb
.\" Added manpages for all 5 klips utils.
.\"
.\"
+174
View File
@@ -0,0 +1,174 @@
.TH IPSEC_SPIGRP 8 "21 Jun 2000"
.\"
.\" RCSID $Id: spigrp.8,v 1.1 2004/03/15 20:35:31 as Exp $
.\"
.SH NAME
ipsec spigrp \- group/ungroup IPSEC Security Associations
.SH SYNOPSIS
.B ipsec
.B spigrp
.PP
.B ipsec
.B spigrp
[
.B \-\-label
label ]
af1 dst1 spi1 proto1 [ af2 dst2 spi2 proto2 [ af3 dst3 spi3 proto3 [ af4 dst4 spi4 proto4 ] ] ]
.PP
.B ipsec
.B spigrp
[
.B \-\-label
label ]
.B \-\-said
SA1 [ SA2 [ SA3 [ SA4 ] ] ]
.PP
.B ipsec
.B spigrp
.B \-\-help
.PP
.B ipsec
.B spigrp
.B \-\-version
.PP
.SH DESCRIPTION
.I Spigrp
groups IPSEC Security Associations (SAs) together or ungroups
previously grouped SAs.
An entry in the IPSEC extended
routing table can only point
(via a destination address, a Security Parameters Index (SPI) and
a protocol identifier) to one SA.
If more than one transform must be applied to a given type of packet,
this can be accomplished by setting up several SAs
with the same destination address but potentially different SPIs and protocols,
and grouping them with
.IR spigrp .
.PP
The SAs to be grouped,
specified by destination address (DNS name lookup, IPv4 dotted quad or IPv6 coloned hex), SPI
('0x'-prefixed hexadecimal number) and protocol ("ah", "esp", "comp" or "tun"),
are listed from the inside transform to the
outside;
in other words, the transforms are applied in
the order of the command line and removed in the reverse
order.
The resulting SA group is referred to by its first SA (by
.IR af1 ,
.IR dst1 ,
.IR spi1
and
.IR proto1 ).
.PP
The \-\-said option indicates that the SA IDs are to be specified as
one argument each, in the format <proto><af><spi>@<dest>. The SA IDs must
all be specified as separate parameters without the \-\-said option or
all as monolithic parameters after the \-\-said option.
.PP
The SAs must already exist and must not already
be part of a group.
.PP
If
.I spigrp
is invoked with only one SA specification,
it ungroups the previously-grouped set of SAs containing
the SA specified.
.PP
The \-\-label option identifies all responses from that command
invocation with a user-supplied label, provided as an argument to the
label option. This can be helpful for debugging one invocation of the
command out of a large number.
.PP
The command form with no additional arguments lists the contents of
/proc/net/ipsec_spigrp. The format of /proc/net/ipsec_spigrp is
discussed in ipsec_spigrp(5).
.SH EXAMPLES
.TP
.B ipsec spigrp inet gw2 0x113 tun inet gw2 0x115 esp inet gw2 0x116 ah
groups 3 SAs together, all destined for
.BR gw2 ,
but with an IPv4-in-IPv4 tunnel SA applied first with SPI
.BR 0x113 ,
then an ESP header to encrypt the packet with SPI
.BR 0x115 ,
and finally an AH header to authenticate the packet with SPI
.BR 0x116 .
.LP
.TP
.B ipsec spigrp --said tun.113@gw2 esp.115@gw2 ah.116@gw2
groups 3 SAs together, all destined for
.BR gw2 ,
but with an IPv4-in-IPv4 tunnel SA applied first with SPI
.BR 0x113 ,
then an ESP header to encrypt the packet with SPI
.BR 0x115 ,
and finally an AH header to authenticate the packet with SPI
.BR 0x116 .
.LP
.TP
.B ipsec spigrp --said tun:233@3049:1::1 esp:235@3049:1::1 ah:236@3049:1::1
groups 3 SAs together, all destined for
.BR 3049:1::1,
but with an IPv6-in-IPv6 tunnel SA applied first with SPI
.BR 0x233 ,
then an ESP header to encrypt the packet with SPI
.BR 0x235 ,
and finally an AH header to authenticate the packet with SPI
.BR 0x236 .
.LP
.TP
.B ipsec spigrp inet6 3049:1::1 0x233 tun inet6 3049:1::1 0x235 esp inet6 3049:1::1 0x236 ah
groups 3 SAs together, all destined for
.BR 3049:1::1,
but with an IPv6-in-IPv6 tunnel SA applied first with SPI
.BR 0x233 ,
then an ESP header to encrypt the packet with SPI
.BR 0x235 ,
and finally an AH header to authenticate the packet with SPI
.BR 0x236 .
.LP
.SH FILES
/proc/net/ipsec_spigrp, /usr/local/bin/ipsec
.SH "SEE ALSO"
ipsec(8), ipsec_manual(8), ipsec_tncfg(8), ipsec_eroute(8),
ipsec_spi(8), ipsec_klipsdebug(8), ipsec_spigrp(5)
.SH HISTORY
Written for the Linux FreeS/WAN project
<http://www.freeswan.org/>
by Richard Guy Briggs.
.SH BUGS
Yes, it really is limited to a maximum of four SAs,
although admittedly it's hard to see why you would need more.
.\"
.\" $Log: spigrp.8,v $
.\" Revision 1.1 2004/03/15 20:35:31 as
.\" added files from freeswan-2.04-x509-1.5.3
.\"
.\" Revision 1.20 2002/04/24 07:35:41 mcr
.\" Moved from ./klips/utils/spigrp.8,v
.\"
.\" Revision 1.19 2000/09/17 18:56:48 rgb
.\" Added IPCOMP support.
.\"
.\" Revision 1.18 2000/09/13 15:54:32 rgb
.\" Added Gerhard's ipv6 updates.
.\"
.\" Revision 1.17 2000/06/30 18:21:55 rgb
.\" Update SEE ALSO sections to include ipsec_version(5) and ipsec_pf_key(5)
.\" and correct FILES sections to no longer refer to /dev/ipsec which has
.\" been removed since PF_KEY does not use it.
.\"
.\" Revision 1.16 2000/06/21 16:54:57 rgb
.\" Added 'no additional args' text for listing contents of
.\" /proc/net/ipsec_* files.
.\"
.\" Revision 1.15 2000/02/14 21:08:30 rgb
.\" Added description of --said option.
.\"
.\" Revision 1.14 1999/07/19 18:47:25 henry
.\" fix slightly-misformed comments
.\"
.\" Revision 1.13 1999/04/06 04:54:39 rgb
.\" Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
.\" patch shell fixes.
.\"
+491
View File
@@ -0,0 +1,491 @@
/*
* SA grouping
* 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 spigrp_c_version[] = "RCSID $Id: spigrp.c,v 1.2 2004/06/07 15:16:34 as Exp $";
#include <sys/types.h>
#include <linux/types.h> /* new */
#include <string.h>
#include <errno.h>
#include <sys/stat.h> /* open() */
#include <fcntl.h> /* open() */
#include <stdlib.h> /* system(), strtoul() */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
/* #include <linux/ip.h> */
#include <unistd.h>
#include <stdio.h>
#include <netdb.h>
#include <freeswan.h>
#if 0
#include <linux/autoconf.h> /* CONFIG_IPSEC_PFKEYv2 */
#endif
#include <signal.h>
#include <pfkeyv2.h>
#include <pfkey.h>
#include "freeswan/radij.h"
#include "freeswan/ipsec_encap.h"
#include "freeswan/ipsec_ah.h"
char *program_name;
int pfkey_sock;
fd_set pfkey_socks;
uint32_t pfkey_seq = 0;
struct said_af {
int af;
ip_said said;
}; /* to store the given saids and their address families in an array */
/* XXX: Note that we do *not* check if the address families of all SAID?s are the same.
* This can make it possible to group SAs for IPv4 addresses with SAs for
* IPv6 addresses (perhaps some kind of IPv4-over-secIPv6 or vice versa).
* Do not know, if this is a bug or feature */
static void
usage(char *s)
{
fprintf(stdout, "usage: Note: position of options and arguments is important!\n");
fprintf(stdout, "usage: %s [ --debug ] [ --label <label> ] af1 dst1 spi1 proto1 [ af2 dst2 spi2 proto2 [ af3 dst3 spi3 proto3 [ af4 dst4 spi4 proto4 ] ] ]\n", s);
fprintf(stdout, "usage: %s [ --debug ] [ --label <label> ] --said <SA1> [ <SA2> [ <SA3> [ <SA4> ] ] ]\n", s);
fprintf(stdout, "usage: %s --help\n", s);
fprintf(stdout, "usage: %s --version\n", s);
fprintf(stdout, "usage: %s\n", s);
fprintf(stdout, " [ --debug ] is optional to any %s command.\n", s);
fprintf(stdout, " [ --label <label> ] is optional to any %s command.\n", s);
}
int
main(int argc, char **argv)
{
int i, nspis;
char *endptr;
int said_opt = 0;
const char* error_s = NULL;
char ipaddr_txt[ADDRTOT_BUF];
int debug = 0;
int j;
struct said_af said_af_array[4];
int error = 0;
struct sadb_ext *extensions[SADB_EXT_MAX + 1];
struct sadb_msg *pfkey_msg;
#if 0
ip_address pfkey_address_s_ska;
#endif
program_name = argv[0];
for(i = 0; i < 4; i++) {
memset(&said_af_array[i], 0, sizeof(struct said_af));
}
if(argc > 1 && strcmp(argv[1], "--debug") == 0) {
debug = 1;
if(debug) {
fprintf(stdout, "\"--debug\" option requested.\n");
}
argv += 1;
argc -= 1;
pfkey_lib_debug = PF_KEY_DEBUG_PARSE_MAX;
}
if(debug) {
fprintf(stdout, "argc=%d (%d incl. --debug option).\n",
argc,
argc + 1);
}
if(argc > 1 && strcmp(argv[1], "--label") == 0) {
if(argc > 2) {
program_name = malloc(strlen(argv[0])
+ 10 /* update this when changing the sprintf() */
+ strlen(argv[2]));
sprintf(program_name, "%s --label %s",
argv[0],
argv[2]);
if(debug) {
fprintf(stdout, "using \"%s\" as a label.\n", program_name);
}
argv += 2;
argc -= 2;
} else {
fprintf(stderr, "%s: --label option requires an argument.\n",
program_name);
exit(1);
}
}
if(debug) {
fprintf(stdout, "...After check for --label option.\n");
}
if(argc == 1) {
system("cat /proc/net/ipsec_spigrp");
exit(0);
}
if(debug) {
fprintf(stdout, "...After check for no option to print /proc/net/ipsec_spigrp.\n");
}
if(strcmp(argv[1], "--help") == 0) {
if(debug) {
fprintf(stdout, "\"--help\" option requested.\n");
}
usage(program_name);
exit(1);
}
if(debug) {
fprintf(stdout, "...After check for --help option.\n");
}
if(strcmp(argv[1], "--version") == 0) {
if(debug) {
fprintf(stdout, "\"--version\" option requested.\n");
}
fprintf(stderr, "%s, %s\n", program_name, spigrp_c_version);
exit(1);
}
if(debug) {
fprintf(stdout, "...After check for --version option.\n");
}
if(strcmp(argv[1], "--said") == 0) {
if(debug) {
fprintf(stdout, "processing %d args with --said flag.\n", argc);
}
said_opt = 1;
}
if(debug) {
fprintf(stdout, "...After check for --said option.\n");
}
if(said_opt) {
if (argc < 3 /*|| argc > 5*/) {
fprintf(stderr, "expecting 3 or more args with --said, got %d.\n", argc);
usage(program_name);
exit(1);
}
nspis = argc - 2;
} else {
if ((argc < 5) || (argc > 17) || ((argc % 4) != 1)) {
fprintf(stderr, "expecting 5 or more args without --said, got %d.\n", argc);
usage(program_name);
exit(1);
}
nspis = argc / 4;
}
if(debug) {
fprintf(stdout, "processing %d nspis.\n", nspis);
}
for(i = 0; i < nspis; i++) {
if(debug) {
fprintf(stdout, "processing spi #%d.\n", i);
}
if(said_opt) {
error_s = ttosa((const char *)argv[i+2], 0, (ip_said*)&(said_af_array[i].said));
if(error_s != NULL) {
fprintf(stderr, "%s: Error, %s converting --sa argument:%s\n",
program_name, error_s, argv[i+2]);
exit (1);
}
said_af_array[i].af = addrtypeof(&(said_af_array[i].said.dst));
if(debug) {
addrtot(&said_af_array[i].said.dst, 0, ipaddr_txt, sizeof(ipaddr_txt));
fprintf(stdout, "said[%d].dst=%s.\n", i, ipaddr_txt);
}
} else {
if(!strcmp(argv[i*4+4], "ah")) {
said_af_array[i].said.proto = SA_AH;
}
if(!strcmp(argv[i*4+4], "esp")) {
said_af_array[i].said.proto = SA_ESP;
}
if(!strcmp(argv[i*4+4], "tun")) {
said_af_array[i].said.proto = SA_IPIP;
}
if(!strcmp(argv[i*4+4], "comp")) {
said_af_array[i].said.proto = SA_COMP;
}
if(said_af_array[i].said.proto == 0) {
fprintf(stderr, "%s: Badly formed proto: %s\n",
program_name, argv[i*4+4]);
exit(1);
}
said_af_array[i].said.spi = htonl(strtoul(argv[i*4+3], &endptr, 0));
if(!(endptr == argv[i*4+3] + strlen(argv[i*4+3]))) {
fprintf(stderr, "%s: Badly formed spi: %s\n",
program_name, argv[i*4+3]);
exit(1);
}
if(!strcmp(argv[i*4+1], "inet")) {
said_af_array[i].af = AF_INET;
}
if(!strcmp(argv[i*4+1], "inet6")) {
said_af_array[i].af = AF_INET6;
}
if((said_af_array[i].af != AF_INET) && (said_af_array[i].af != AF_INET6)) {
fprintf(stderr, "%s: Address family %s not supported\n",
program_name, argv[i*4+1]);
exit(1);
}
error_s = ttoaddr(argv[i*4+2], 0, said_af_array[i].af, &(said_af_array[i].said.dst));
if(error_s != NULL) {
fprintf(stderr, "%s: Error, %s converting %dth address argument:%s\n",
program_name, error_s, i, argv[i*4+2]);
exit (1);
}
}
if(debug) {
fprintf(stdout, "SA %d contains: ", i+1);
fprintf(stdout, "\n");
fprintf(stdout, "proto = %d\n", said_af_array[i].said.proto);
fprintf(stdout, "spi = %08x\n", said_af_array[i].said.spi);
addrtot(&said_af_array[i].said.dst, 0, ipaddr_txt, sizeof(ipaddr_txt));
fprintf(stdout, "edst = %s\n", ipaddr_txt);
}
}
if(debug) {
fprintf(stdout, "Opening pfkey socket.\n");
}
if((pfkey_sock = socket(PF_KEY, SOCK_RAW, PF_KEY_V2) ) < 0) {
fprintf(stderr, "%s: Trouble opening PF_KEY family socket with error: ",
program_name);
switch(errno) {
case ENOENT:
fprintf(stderr, "device does not exist. See FreeS/WAN installation procedure.\n");
break;
case EACCES:
fprintf(stderr, "access denied. ");
if(getuid() == 0) {
fprintf(stderr, "Check permissions. Should be 600.\n");
} else {
fprintf(stderr, "You must be root to open this file.\n");
}
break;
case EUNATCH:
fprintf(stderr, "Netlink not enabled OR KLIPS not loaded.\n");
break;
case ENODEV:
fprintf(stderr, "KLIPS not loaded or enabled.\n");
break;
case EBUSY:
fprintf(stderr, "KLIPS is busy. Most likely a serious internal error occured in a previous command. Please report as much detail as possible to development team.\n");
break;
case EINVAL:
fprintf(stderr, "Invalid argument, KLIPS not loaded or check kernel log messages for specifics.\n");
break;
case ENOBUFS:
fprintf(stderr, "No kernel memory to allocate SA.\n");
break;
case ESOCKTNOSUPPORT:
fprintf(stderr, "Algorithm support not available in the kernel. Please compile in support.\n");
break;
case EEXIST:
fprintf(stderr, "SA already in use. Delete old one first.\n");
break;
case ENXIO:
fprintf(stderr, "SA does not exist. Cannot delete.\n");
break;
case EAFNOSUPPORT:
fprintf(stderr, "KLIPS not loaded or enabled.\n");
break;
default:
fprintf(stderr, "Unknown file open error %d. Please report as much detail as possible to development team.\n", errno);
}
exit(1);
}
for(i = 0; i < (((nspis - 1) < 2) ? 1 : (nspis - 1)); i++) {
if(debug) {
fprintf(stdout, "processing %dth pfkey message.\n", i);
}
pfkey_extensions_init(extensions);
for(j = 0; j < ((nspis == 1) ? 1 : 2); j++) {
if(debug) {
fprintf(stdout, "processing %dth said of %dth pfkey message.\n", j, i);
}
/* Build an SADB_X_GRPSA message to send down. */
/* It needs <base, SA, SA2, address(D,D2) > minimum. */
if(!j) {
if((error = pfkey_msg_hdr_build(&extensions[0],
SADB_X_GRPSA,
proto2satype(said_af_array[i].said.proto),
0,
++pfkey_seq,
getpid()))) {
fprintf(stderr, "%s: Trouble building message header, error=%d.\n",
program_name, error);
pfkey_extensions_free(extensions);
exit(1);
}
} else {
if(debug) {
fprintf(stdout, "setting x_satype proto=%d satype=%d\n",
said_af_array[i+j].said.proto,
proto2satype(said_af_array[i+j].said.proto)
);
}
if((error = pfkey_x_satype_build(&extensions[SADB_X_EXT_SATYPE2],
proto2satype(said_af_array[i+j].said.proto)
))) {
fprintf(stderr, "%s: Trouble building message header, error=%d.\n",
program_name, error);
pfkey_extensions_free(extensions);
exit(1);
}
}
if((error = pfkey_sa_build(&extensions[!j ? SADB_EXT_SA : SADB_X_EXT_SA2],
!j ? SADB_EXT_SA : SADB_X_EXT_SA2,
said_af_array[i+j].said.spi, /* in network order */
0,
0,
0,
0,
0))) {
fprintf(stderr, "%s: Trouble building sa extension, error=%d.\n",
program_name, error);
pfkey_extensions_free(extensions);
exit(1);
}
#if 0
if(!j) {
anyaddr(said_af_array[i].af, &pfkey_address_s_ska); /* Is the address family correct ?? */
if((error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
SADB_EXT_ADDRESS_SRC,
0,
0,
sockaddrof(&pfkey_address_s_ska)))) {
addrtot(&pfkey_address_s_ska, 0, ipaddr_txt, sizeof(ipaddr_txt));
fprintf(stderr, "%s: Trouble building address_s extension (%s), error=%d.\n",
program_name, ipaddr_txt, error);
pfkey_extensions_free(extensions);
exit(1);
}
}
#endif
if((error = pfkey_address_build(&extensions[!j ? SADB_EXT_ADDRESS_DST : SADB_X_EXT_ADDRESS_DST2],
!j ? SADB_EXT_ADDRESS_DST : SADB_X_EXT_ADDRESS_DST2,
0,
0,
sockaddrof(&said_af_array[i+j].said.dst)))) {
addrtot(&said_af_array[i+j].said.dst,
0, ipaddr_txt, sizeof(ipaddr_txt));
fprintf(stderr, "%s: Trouble building address_d extension (%s), error=%d.\n",
program_name, ipaddr_txt, error);
pfkey_extensions_free(extensions);
exit(1);
}
}
if((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_IN))) {
fprintf(stderr, "%s: Trouble building pfkey message, error=%d.\n",
program_name, error);
pfkey_extensions_free(extensions);
pfkey_msg_free(&pfkey_msg);
exit(1);
}
if((error = write(pfkey_sock,
pfkey_msg,
pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)) !=
(ssize_t)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)) {
fprintf(stderr, "%s: pfkey write failed, returning %d with errno=%d.\n",
program_name, error, errno);
pfkey_extensions_free(extensions);
pfkey_msg_free(&pfkey_msg);
switch(errno) {
case EACCES:
fprintf(stderr, "access denied. ");
if(getuid() == 0) {
fprintf(stderr, "Check permissions. Should be 600.\n");
} else {
fprintf(stderr, "You must be root to open this file.\n");
}
break;
case EUNATCH:
fprintf(stderr, "Netlink not enabled OR KLIPS not loaded.\n");
break;
case EBUSY:
fprintf(stderr, "KLIPS is busy. Most likely a serious internal error occured in a previous command. Please report as much detail as possible to development team.\n");
break;
case EINVAL:
fprintf(stderr, "Invalid argument, check kernel log messages for specifics.\n");
break;
case ENODEV:
fprintf(stderr, "KLIPS not loaded or enabled.\n");
fprintf(stderr, "No device?!?\n");
break;
case ENOBUFS:
fprintf(stderr, "No kernel memory to allocate SA.\n");
break;
case ESOCKTNOSUPPORT:
fprintf(stderr, "Algorithm support not available in the kernel. Please compile in support.\n");
break;
case EEXIST:
fprintf(stderr, "SA already in use. Delete old one first.\n");
break;
case ENOENT:
fprintf(stderr, "device does not exist. See FreeS/WAN installation procedure.\n");
break;
case ENXIO:
fprintf(stderr, "SA does not exist. Cannot delete.\n");
break;
case ENOSPC:
fprintf(stderr, "no room in kernel SAref table. Cannot process request.\n");
break;
case ESPIPE:
fprintf(stderr, "kernel SAref table internal error. Cannot process request.\n");
break;
default:
fprintf(stderr, "Unknown socket write error %d. Please report as much detail as possible to development team.\n", errno);
}
exit(1);
}
if(pfkey_msg) {
pfkey_extensions_free(extensions);
pfkey_msg_free(&pfkey_msg);
}
}
(void) close(pfkey_sock); /* close the socket */
exit(0);
}