summaryrefslogtreecommitdiff
path: root/programs/ikeping/ikeping.c
diff options
context:
space:
mode:
Diffstat (limited to 'programs/ikeping/ikeping.c')
-rw-r--r--programs/ikeping/ikeping.c483
1 files changed, 0 insertions, 483 deletions
diff --git a/programs/ikeping/ikeping.c b/programs/ikeping/ikeping.c
deleted file mode 100644
index 7efb26ad7..000000000
--- a/programs/ikeping/ikeping.c
+++ /dev/null
@@ -1,483 +0,0 @@
-/* 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:
- *
- */