--- netcat.c.orig Tue Feb 19 22:42:04 2002 +++ netcat.c Thu Feb 21 23:37:07 2002 @@ -37,6 +37,9 @@ #include #include +#ifdef IPSEC +#include +#endif #include #include @@ -53,6 +56,7 @@ #define PORT_MAX 65535 /* Command Line Options */ +int Eflag; /* Use IPsec ESP */ int iflag; /* Interval Flag */ int kflag; /* More than one connect */ int lflag; /* Bind to local port */ @@ -84,10 +88,16 @@ int unix_listen(char *); void usage(int); +#ifdef IPSEC +void add_ipsec_policy(int, char *); + +char *ipsec_policy[2]; +#endif + int main(int argc, char *argv[]) { - int ch, s, ret; + int ch, s, ret, ipsec_count; char *host, *uport, *endp; struct addrinfo hints; struct servent *sv; @@ -99,12 +109,13 @@ ret = 1; s = 0; + ipsec_count = 0; host = NULL; uport = NULL; endp = NULL; sv = NULL; - while ((ch = getopt(argc, argv, "46Uhi:klnp:rs:tuvw:x:z")) != -1) { + while ((ch = getopt(argc, argv, "46e:EUhi:klnp:rs:tuvw:x:z")) != -1) { switch (ch) { case '4': family = AF_INET; @@ -115,6 +126,21 @@ case 'U': family = AF_UNIX; break; + case 'e': +#ifdef IPSEC + ipsec_policy[ipsec_count++ % 2] = optarg; +#else + errx(1, "IPsec support unavailable."); +#endif + break; + case 'E': +#ifdef IPSEC + ipsec_policy[0] = "in ipsec esp/transport//require"; + ipsec_policy[1] = "out ipsec esp/transport//require"; +#else + errx(1, "IPsec support unavailable."); +#endif + break; case 'h': help(); break; @@ -422,6 +448,12 @@ if ((s = socket(res0->ai_family, res0->ai_socktype, res0->ai_protocol)) < 0) continue; +#ifdef IPSEC + if (ipsec_policy[0] != NULL) + add_ipsec_policy(s, ipsec_policy[0]); + if (ipsec_policy[1] != NULL) + add_ipsec_policy(s, ipsec_policy[1]); +#endif /* Bind to a local port or source address if specified */ if (sflag || pflag) { @@ -497,6 +529,12 @@ ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x)); if (ret == -1) err(1, NULL); +#ifdef IPSEC + if (ipsec_policy[0] != NULL) + add_ipsec_policy(s, ipsec_policy[0]); + if (ipsec_policy[1] != NULL) + add_ipsec_policy(s, ipsec_policy[1]); +#endif if (bind(s, (struct sockaddr *)res0->ai_addr, res0->ai_addrlen) == 0) @@ -690,7 +728,13 @@ usage(0); fprintf(stderr, "\tCommand Summary:\n\ \t-4 Use IPv4\n\ - \t-6 Use IPv6\n\ + \t-6 Use IPv6\n"); +#ifdef IPSEC + fprintf(stderr, "\ + \t-e policy Use specified IPsec policy\n\ + \t-E Use IPsec ESP\n"); +#endif + fprintf(stderr, "\ \t-U Use UNIX domain socket\n\ \t-h This help text\n\ \t-i secs\t Delay interval for lines sent, ports scanned\n\ @@ -707,13 +751,42 @@ \t-x addr[:port]\tSpecify socks5 proxy address and port\n\ \t-z Zero-I/O mode [used for scanning]\n\ Port numbers can be individual or ranges: lo-hi [inclusive]\n"); +#ifdef IPSEC + fprintf(stderr, "See ipsec_set_policy(3) for -e argument format\n"); +#endif exit(1); } +#ifdef IPSEC +void +add_ipsec_policy(int s, char *policy) +{ + char *raw; + int e; + + raw = ipsec_set_policy(policy, strlen(policy)); + if (raw == NULL) + errx(1, "ipsec_set_policy `%s': %s", policy, + ipsec_strerror()); + e = setsockopt(s, IPPROTO_IP, IP_IPSEC_POLICY, raw, + ipsec_get_policylen(raw)); + if (e < 0) + err(1, "ipsec policy cannot be configured"); + free(raw); + if (vflag) + fprintf(stderr, "ipsec policy configured: `%s'\n", policy); + return; +} +#endif /* IPSEC */ + void usage(int ret) { +#ifdef IPSEC + fprintf(stderr, "usage: nc [-46EUhklnrtuvz] [-e policy] [-i interval] [-p source port]\n"); +#else fprintf(stderr, "usage: nc [-46Uhklnrtuvz] [-i interval] [-p source port]\n"); +#endif fprintf(stderr, "\t [-s ip address] [-w timeout] [-x proxy address [:port]]\n"); fprintf(stderr, "\t [hostname] [port[s...]]\n"); if (ret)