- 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 @@
ikeping
+57
View File
@@ -0,0 +1,57 @@
# Makefile for the KLIPS interface utilities
# Copyright (C) 1998, 1999 Henry Spencer.
# Copyright (C) 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.
#
# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:27 as Exp $
FREESWANSRCDIR=../..
include ${FREESWANSRCDIR}/Makefile.inc
PROGRAM=ikeping
LIBS=${FREESWANLIB}
ifeq ($(USE_IKEPING),false)
NOINSTALL=true
install:
# do nothing
install_file_list:
# do nothing
endif
include ../Makefile.program
#
# $Log: Makefile,v $
# Revision 1.1 2004/03/15 20:35:27 as
# added files from freeswan-2.04-x509-1.5.3
#
# Revision 1.4 2003/06/29 21:34:49 mcr
# added "NOINSTALL" to omit install: target from common
# Makefile so that it can be overridden
#
# Revision 1.3 2003/06/25 03:57:45 mcr
# build, but do not install "ikeping" even when we do not
# want it as part of the system.
#
# Revision 1.2 2002/06/02 22:02:14 mcr
# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
# kernel sense.)
#
# Revision 1.1 2002/04/24 07:55:32 mcr
# #include patches and Makefiles for post-reorg compilation.
#
#
#
+71
View File
@@ -0,0 +1,71 @@
.TH IPSEC_IKEPING 8 "23 Feb 2002"
.\" RCSID $Id: ikeping.8,v 1.1 2004/03/15 20:35:27 as Exp $
.SH NAME
ipsec ikeping \- send/receive ISAKMP/IKE echo requests/replies
.SH SYNOPSIS
.B ipsec
.B ikeping
[
.B \-\-listen
] [
.B \-\-verbose
] [
.B \-\-wait
time ] [
.B \-\-exchangenum
num ] [
.B \-\-ikeport
localport ] [
.B \-\-ikeaddress
address ] [
.B \-\-inet
] [
.B \-\-inet6
] destaddr[/dstport] ...
.SH DESCRIPTION
.I Ikeping
sends and receives ISAKMP/IKE echo request and echo reply packets. These
packets are intended for diagnostics purposes, in a manner similar to
.IR ping (8)
does for ICMP echo request/reply packets.
.PP
At the time of this writing, the ISAKMP echo request/reply exchange is still
an internet-draft, and is therefore completely non-standard.
.PP
.I Ikeping
will bind to the local address given by
.B \-\-ikeaddress
and the port number given by
.B \-\-ikeport
defaulting to the wildcard address and the ISAKMP port 500. An ISAKMP
exchange of type 244 (a private use number) is sent to each of the
address/ports listed on the command line. The exchange number may be
overridden by the
.B \-\-exchangenum
option.
.PP
.I Ikeping
then listens for replies, printing them as they are received. Replies
are of exchange type 245 or the specified exchange number plus 1.
.I Ikeping
will keep listening until it either receives as many echo responses as it sent,
or until the timeout period (10 seconds) has been reached. Receipt of a
packet will reset the timer. The
.B \-\-wait
option can be used to specify a different timeout period.
.PP
If the
.B \-\-listen
option is given, then
.I ikeping
will not send any packets. Instead, it will listen for them and reply to
each request received.
.SH FILES
no external files
.SH SEE ALSO
ping(8), ipsec_pluto(8)
.SH HISTORY
Written for the Linux FreeS/WAN project
<http://www.freeswan.org>
by Michael Richardson.
.SH BUGS
+483
View File
@@ -0,0 +1,483 @@
/* send out an IKE "ping" packet.
* Copyright (C) 2002 Michael Richardson
* Copyright (C) 2002 D. Hugh Redelmeier.
*
* 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: ikeping.c,v 1.1 2004/03/15 20:35:27 as Exp $
*/
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <getopt.h>
#include <assert.h>
#include <poll.h>
#include <freeswan.h>
#include "../pluto/constants.h"
#include "../pluto/packet.h"
#ifndef ISAKMP_XCHG_ECHOREQUEST
#define ISAKMP_XCHG_ECHOREQUEST 30 /* Echo Request */
#define ISAKMP_XCHG_ECHOREPLY 31 /* Echo Reply */
#endif
#ifndef ISAKMP_XCGH_ECHOREQUEST_PRIV
#define ISAKMP_XCHG_ECHOREQUEST_PRIV 244 /* Private Echo Request */
#define ISAKMP_XCHG_ECHOREPLY_PRIV 245 /* Private Echo Reply */
#endif
/* what exchange number to use for outgoing requests */
static int exchange_number;
static void
help(void)
{
fprintf(stderr,
"Usage:\n\n"
"ikeping"
" [--listen] causes IKEping to open a socket and reply to requests.\n"
" [--verbose] causes IKEping to hexdump all packets sent/received.\n"
" [--ikeport <port-number>] port to listen on/send from\n"
" [--ikeaddress <address>] address to listen on/send from\n"
" [--inet] just send/listen on IPv4 socket\n"
" [--inet6] just send/listen on IPv6 socket\n"
" [--version] just dump version number and exit\n"
" [--exchangenum num] use num instead of 244 for the exchange type.\n"
" [--wait seconds] time to wait for replies, defaults to 10 seconds.\n"
" host/port ...\n\n"
"FreeS/WAN %s\n",
ipsec_version_code());
}
static void
hton_ping(struct isakmp_hdr *ih)
{
u_int32_t *ihp;
ihp=(u_int32_t *)ih;
/* put it in network byte order. */
/* cookies are byte viewed anyway */
ihp[4]=htonl(ihp[4]);
ih->isa_msgid = htonl(ih->isa_msgid);
ih->isa_length = htonl(ih->isa_length);
}
static void
ntoh_ping(struct isakmp_hdr *ih)
{
u_int32_t *ihp;
ihp=(u_int32_t *)ih;
/* put it in network byte order. */
/* cookies are byte viewed anyway */
ihp[4]=ntohl(ihp[4]);
ih->isa_msgid = ntohl(ih->isa_msgid);
ih->isa_length = ntohl(ih->isa_length);
}
/*
* send an IKE ping
*
*/
static void
send_ping(int afamily,
int s,
ip_address *raddr,
int rport)
{
struct isakmp_hdr ih;
int i, raddrlen;
raddrlen=0;
for(i=0; i<COOKIE_SIZE; i++) {
ih.isa_icookie[i]=rand()&0xff;
}
for(i=0; i<COOKIE_SIZE; i++) {
ih.isa_rcookie[i]=rand()&0xff;
}
ih.isa_np = NOTHING_WRONG;
ih.isa_version = (1 << ISA_MAJ_SHIFT) | 0;
ih.isa_xchg = (exchange_number ?
exchange_number : ISAKMP_XCHG_ECHOREQUEST_PRIV);
ih.isa_flags =0;
ih.isa_msgid =rand();
ih.isa_length=0;
switch(afamily) {
case AF_INET:
raddr->u.v4.sin_port = htons(rport);
raddrlen=sizeof(raddr->u.v4);
break;
case AF_INET6:
raddr->u.v6.sin6_port = htons(rport);
raddrlen=sizeof(raddr->u.v6);
break;
}
hton_ping(&ih);
if(sendto(s, &ih, sizeof(ih), 0, (struct sockaddr *)raddr, raddrlen) < 0) {
perror("sendto");
exit(5);
}
}
/*
* send an IKE ping
*
*/
static void
reply_packet(int afamily,
int s,
ip_address *dst_addr,
int dst_len,
struct isakmp_hdr *op)
{
int i, tmp;
tmp=afamily; /* shut up compiler */
for(i=0; i<COOKIE_SIZE; i++) {
tmp=op->isa_icookie[i];
op->isa_icookie[i]=op->isa_rcookie[i];
op->isa_rcookie[i]=tmp;
}
op->isa_np = NOTHING_WRONG;
op->isa_version = (1 << ISA_MAJ_SHIFT) | 0;
op->isa_xchg = ISAKMP_XCHG_ECHOREPLY;
op->isa_flags =0;
op->isa_msgid =rand();
op->isa_length=0;
hton_ping(op);
if(sendto(s, op, sizeof(*op), 0, (struct sockaddr *)dst_addr, dst_len) < 0) {
perror("sendto");
exit(5);
}
}
/*
* receive and decode packet.
*
*/
static void
receive_ping(int afamily, int s, int reply)
{
ip_address sender;
struct isakmp_hdr ih;
char buf[64];
int n, rport, sendlen;
const char *xchg_name;
int xchg;
rport = 500;
xchg = 0;
sendlen=sizeof(sender);
n = recvfrom(s, &ih, sizeof(ih), 0, (struct sockaddr *)&sender, &sendlen);
addrtot(&sender, 0, buf, sizeof(buf));
switch(afamily) {
case AF_INET:
rport = sender.u.v4.sin_port;
break;
case AF_INET6:
rport = sender.u.v6.sin6_port;
break;
}
if((unsigned int)n < sizeof(ih)) {
fprintf(stderr, "read short packet (%d) from %s/%d\n",
n, buf, rport);
return;
}
/* translate from network byte order */
ntoh_ping(&ih);
if(ih.isa_xchg == ISAKMP_XCHG_ECHOREQUEST ||
ih.isa_xchg == ISAKMP_XCHG_ECHOREQUEST_PRIV ||
(exchange_number!=0 && ih.isa_xchg == exchange_number)) {
xchg_name="echo-request";
xchg=ISAKMP_XCHG_ECHOREQUEST;
} else if(ih.isa_xchg == ISAKMP_XCHG_ECHOREPLY ||
ih.isa_xchg == ISAKMP_XCHG_ECHOREPLY_PRIV ||
(exchange_number!=0 && ih.isa_xchg == exchange_number+1)) {
xchg_name="echo-reply";
} else {
xchg_name="";
}
printf("received %d(%s) packet from %s/%d of len: %d\n",
ih.isa_xchg, xchg_name, buf, ntohs(rport), n);
printf("\trcookie=%08x_%08x icookie=%08x_%08x msgid=%08x\n",
*(u_int32_t *)(ih.isa_icookie),
*(u_int32_t *)(ih.isa_icookie+4),
*(u_int32_t *)(ih.isa_rcookie),
*(u_int32_t *)(ih.isa_rcookie+4),
ih.isa_msgid);
printf("\tnp=%03d version=%d.%d xchg=%s(%d)\n",
ih.isa_np,
ih.isa_version >> ISA_MAJ_SHIFT,
ih.isa_version & ISA_MIN_MASK,
xchg_name,
ih.isa_xchg);
if(reply && xchg==ISAKMP_XCHG_ECHOREQUEST) {
reply_packet(afamily, s, &sender, sendlen, &ih);
}
}
static const struct option long_opts[] = {
/* name, has_arg, flag, val */
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'V' },
{ "verbose", no_argument, NULL, 'v' },
{ "listen", no_argument, NULL, 's' },
{ "ikeport", required_argument, NULL, 'p' },
{ "ikeaddress", required_argument, NULL, 'b' },
{ "inet", no_argument, NULL, '4' },
{ "inet6", no_argument, NULL, '6' },
{ "exchangenum", required_argument, NULL, 'n' },
{ "wait", required_argument, NULL, 'w' },
{ 0,0,0,0 }
};
int
main(int argc, char **argv)
{
char *foo;
const char *errstr;
int s;
int listen_only;
int lport,dport;
int afamily;
int pfamily;
int c;
int numSenders, numReceived, noDNS;
int waitTime;
int verbose, timedOut;
ip_address laddr, raddr;
afamily=AF_INET;
pfamily=PF_INET;
lport=500;
dport=500;
waitTime=10;
verbose=0;
listen_only=0;
noDNS=0;
bzero(&laddr, sizeof(laddr));
while((c = getopt_long(argc, argv, "hVnvsp:b:46E:w:", long_opts, 0))!=EOF) {
switch (c) {
case 'h': /* --help */
help();
return 0; /* GNU coding standards say to stop here */
case 'V': /* --version */
fprintf(stderr, "FreeS/WAN %s\n", ipsec_version_code());
return 0; /* GNU coding standards say to stop here */
case 'v': /* --label <string> */
verbose++;
continue;
case 'n':
noDNS=1;
break;
case 'E':
exchange_number=strtol(optarg, &foo, 0);
if(optarg==foo || exchange_number < 1 || exchange_number>255) {
fprintf(stderr, "Invalid exchange number '%s' (should be 1<=x<255)\n",
optarg);
exit(1);
}
continue;
case 's':
listen_only++;
continue;
case 'p':
lport=strtol(optarg, &foo, 0);
if(optarg==foo || lport <0 || lport>65535) {
fprintf(stderr, "Invalid port number '%s' (should be 0<=x<65536)\n",
optarg);
exit(1);
}
continue;
case 'w':
waitTime=strtol(optarg, &foo, 0);
if(optarg==foo || waitTime < 0) {
fprintf(stderr, "Invalid waittime number '%s' (should be 0<=x)\n",
optarg);
exit(1);
}
continue;
case 'b':
errstr = ttoaddr(optarg, strlen(optarg), afamily, &laddr);
if(errstr!=NULL) {
fprintf(stderr, "Invalid local address '%s': %s\n",
optarg, errstr);
exit(1);
}
continue;
case '4':
afamily=AF_INET;
pfamily=PF_INET;
continue;
case '6':
afamily=AF_INET6;
pfamily=PF_INET6;
continue;
default:
assert(FALSE); /* unknown return value */
}
}
s=socket(pfamily, SOCK_DGRAM, IPPROTO_UDP);
if(s < 0) {
perror("socket");
exit(3);
}
switch(afamily) {
case AF_INET:
laddr.u.v4.sin_port = htons(lport);
if(bind(s, (struct sockaddr *)&laddr.u.v4, sizeof(laddr.u.v4)) < 0) {
perror("v4 bind");
exit(5);
}
break;
case AF_INET6:
laddr.u.v6.sin6_port = htons(lport);
if(bind(s, (struct sockaddr *)&laddr.u.v6, sizeof(laddr.u.v6)) < 0) {
perror("v6 bind");
exit(5);
}
break;
}
numSenders = 0;
if(!listen_only) {
while(optind < argc) {
char *port;
char *host;
char namebuf[128];
host = argv[optind];
port = strchr(host, '/');
dport=500;
if(port) {
*port='\0';
port++;
dport= strtol(port, &foo, 0);
if(port==foo || dport < 0 || dport > 65535) {
fprintf(stderr, "Invalid port number '%s' "
"(should be 0<=x<65536)\n",
port);
exit(1);
}
}
errstr = ttoaddr(host, strlen(host),
afamily, &raddr);
if(errstr!=NULL) {
fprintf(stderr, "Invalid remote address '%s': %s\n",
host, errstr);
exit(1);
}
addrtot(&raddr, 0, namebuf, sizeof(namebuf));
printf("Sending packet to %s/%d\n", namebuf, dport);
send_ping(afamily, s, &raddr, dport);
numSenders++;
optind++;
}
}
timedOut = 0;
numReceived=0;
/* really should catch ^C and print stats on exit */
while(numSenders > 0 || listen_only) {
struct pollfd ready;
int n;
ready.fd = s;
ready.events = POLLIN;
n = poll(&ready, 1, waitTime);
if(n < 0) {
perror("poll");
exit(1);
}
if(n == 0 && !listen_only) {
break;
}
if(n == 1) {
numReceived++;
receive_ping(afamily, s, listen_only);
}
}
if(numReceived > 0) {
printf("%d packets sent, %d packets received. %d packet loss\n",
numSenders, numReceived, numSenders*100/numReceived);
}
exit(0);
}
/*
* Local variables:
* c-file-style: "linux"
* c-basic-offset: 4
* End:
*
*/