HEAD: WvIStreamList would not call pre_select() on its children if its alarm
[wvapps.git] / wvipsec / wvisakmptest.cc
blob84d511c6f0ea3a370e5f5b2cd852fbe96ce683ec
1 /*
2 * Worldvisions IPSec Software:
3 * Copyright (C) 1997-2003 Net Integration Technologies, Inc.
4 *
5 * Main routine for WvIPSec.
6 */
8 #include "wvver.h"
9 #include "wvudp.h"
10 #include "wvconfemu.h"
11 #include "wvcrypto.h"
12 #include "strutils.h"
13 #include "wvcrash.h"
14 #include "wvistreamlist.h"
16 #include "wvisakmp.h"
18 #include <signal.h>
19 #include <assert.h>
20 #include <argp.h>
21 #include <error.h>
22 #include <errno.h>
24 #define MAX_PACKET_SIZE 65516
26 #define min(a, b) ((a) < (b) ? (a) : (b))
28 static volatile bool want_to_die = false;
30 const char *argp_program_version = "wvisakmp -0.5";
31 const char *argp_program_bug_address = "bugs@nit.ca";
32 static char doc[] =
33 "WvIsaKmpTest is a program that does IKE(ISAKMP) negociations.";
35 static struct argp_option options[] = {
36 {"connection", 'c', "NUM", 0, "Connection to [WvIpSec]Connection NUM"},
37 {"public", 'p', "IPADDR", 0, "Use IPADDR as local IP address"},
38 {"remote", 'r', "HOST", 0, "Connection to remote host" },
39 {"start", 's', 0, 0, "Initiate connection"},
40 {"nostart", 'n', 0, 0, "Do not initiate connection"},
41 { 0 }
44 void signal_handler(int signum)
46 fprintf(stderr, "\nCaught signal %d; cleaning up and terminating.\n",
47 signum);
48 want_to_die = true;
49 signal(signum, SIG_DFL);
52 static error_t parse_opt (int key, char *arg, struct argp_state *state)
54 WvConf *cfg = static_cast<WvConf*>(state->input);
56 switch (key)
58 case 'r':
59 cfg->set("WvIpSec", "connection", arg);
60 break;
61 case 's':
62 cfg->setint("WvIpSec", "start", 1);
63 break;
64 case 'n':
65 cfg->setint("WvIpSec", "start", 0);
66 break;
67 case 'c':
69 WvString connection("connection %s", arg);
70 cfg->set("WvIpSec", "connection",
71 cfg->get("WvIpSec", connection, NULL));
72 break;
74 case 'p':
75 cfg->set("WvIpSec", "ipaddr", arg);
76 break;
77 case ARGP_KEY_ARG:
78 wvcon->print("Unknown option %s\n", arg);
79 argp_usage(state);
80 break;
83 return 0;
86 static struct argp argp = { options, parse_opt, 0, doc };
88 void callback(int spi, WvCryptoEncoder *enc, WvCryptoEncoder *dec, WvIsaKmp::actions action)
90 fprintf(stdout,"Ready to start ESP Stream stuff...\n");
91 want_to_die = true;
93 return;
96 int main(int argc, char *argv[])
98 // Set up WvCrash
99 wvcrash_setup(argv[0]);
101 // make sure electric fence works
102 free(malloc(1));
104 // set up the signal handlers
105 signal(SIGPIPE, SIG_IGN);
106 signal(SIGINT, signal_handler);
107 signal(SIGTERM, signal_handler);
109 WvConf cfg("ipsec.ini", 0600);
110 WvIStreamList l;
112 argp_parse(&argp, argc, argv, 0, 0, &cfg);
114 if (getuid() != 0)
116 wverr->print("WvIsaKmpTest ERROR: This won't work, you're not root!\n");
117 return -1;
120 // Set up the bits that we need for WvIsaKmp to do sane things...
121 WvString remote = cfg.get("WvIpSec", "connection", "10.1.0.10");
122 WvString local = cfg.get("WvIpSec", "ipaddr", "10.2.0.10");
123 bool initiate = cfg.getint("WvIpSec", "start", false);
124 WvString shared_secret = cfg.get("WvIpSec", "Preshared key", NULL);
126 WvIsaKmp conn1(cfg, initiate, shared_secret, local, remote);
127 conn1.set_espcallback(WvIsaKmp::EspCallback(callback));
128 l.append(&conn1, false);
130 // The WvStreamList, l, can't go !isok() unless we force it to, which we
131 // aren't doing so this check is mostly useless, but is good for style.
132 while (conn1.isok() && l.isok() && !want_to_die)
134 if (l.select(1000))
135 l.callback();
138 if (!conn1.isok())
140 wverr->print("WvIsaKmpTest ERROR: %s", conn1.errstr().edit());
141 return -1;
144 cfg.save();
146 return 0;