OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / freeswan / klips / utils / spigrp.c
1 /*
2  * SA grouping
3  * Copyright (C) 1996  John Ioannidis.
4  * Copyright (C) 1997, 1998, 1999, 2000, 2001  Richard Guy Briggs.
5  * 
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the
8  * Free Software Foundation; either version 2 of the License, or (at your
9  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
10  * 
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * for more details.
15  */
16
17 char spigrp_c_version[] = "RCSID $Id: spigrp.c,v 1.41 2002/03/08 21:44:05 rgb Exp $";
18
19
20 #include <sys/types.h>
21 #include <linux/types.h> /* new */
22 #include <string.h>
23 #include <errno.h>
24 #include <sys/stat.h> /* open() */
25 #include <fcntl.h> /* open() */
26 #include <stdlib.h> /* system(), strtoul() */
27
28 #include <sys/socket.h>
29
30 #include <netinet/in.h>
31 #include <arpa/inet.h>
32 /* #include <linux/ip.h> */
33
34 #include <unistd.h>
35 #include <stdio.h>
36 #include <netdb.h>
37 #include <freeswan.h>
38 #if 0
39 #include <linux/autoconf.h>     /* CONFIG_IPSEC_PFKEYv2 */
40 #endif
41      #include <signal.h>
42      #include <pfkeyv2.h>
43      #include <pfkey.h>
44 #include "radij.h"
45 #include "ipsec_encap.h"
46 #include "ipsec_netlink.h"
47 #include "ipsec_ah.h"
48
49
50 char *program_name;
51 char me[] = "ipsec spigrp";
52 extern unsigned int pfkey_lib_debug; /* used by libfreeswan/pfkey_v2_build */
53 int pfkey_sock;
54 fd_set pfkey_socks;
55 uint32_t pfkey_seq = 0;
56  
57 struct said_af {
58         int af;
59         ip_said said;
60 }; /* to store the given saids and their address families in an array */
61  /* XXX: Note that we do *not* check if the address families of all SAID?s are the same.
62   *      This can make it possible to group SAs for IPv4 addresses with SAs for
63   *      IPv6 addresses (perhaps some kind of IPv4-over-secIPv6 or vice versa).
64   *      Do not know, if this is a bug or feature */
65
66 static void
67 usage(char *s)
68 {
69         fprintf(stdout, "usage: Note: position of options and arguments is important!\n");
70         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);
71         fprintf(stdout, "usage: %s [ --debug ] [ --label <label> ] --said <SA1> [ <SA2> [ <SA3> [ <SA4> ] ] ]\n", s);
72         fprintf(stdout, "usage: %s --help\n", s);
73         fprintf(stdout, "usage: %s --version\n", s);
74         fprintf(stdout, "usage: %s\n", s);
75         fprintf(stdout, "        [ --debug ] is optional to any %s command.\n", s);
76         fprintf(stdout, "        [ --label <label> ] is optional to any %s command.\n", s);
77 }
78
79         
80 int
81 main(int argc, char **argv)
82 {
83         int i, nspis;
84         char *endptr;
85         int said_opt = 0;
86
87         const char* error_s = NULL;
88         char ipaddr_txt[ADDRTOT_BUF];
89         int debug = 0;
90         int j;
91         struct said_af said_af_array[4];
92
93         int error = 0;
94
95         struct sadb_ext *extensions[SADB_EXT_MAX + 1];
96         struct sadb_msg *pfkey_msg;
97 #if 0
98         ip_address pfkey_address_s_ska;
99 #endif
100         
101         program_name = argv[0];
102         for(i = 0; i < 4; i++) {
103                 memset(&said_af_array[i], 0, sizeof(struct said_af));
104         }
105
106         if(argc > 1 && strcmp(argv[1], "--debug") == 0) {
107                 debug = 1;
108                 if(debug) {
109                         fprintf(stdout, "\"--debug\" option requested.\n");
110                 }
111                 argv += 1;
112                 argc -= 1;
113                 pfkey_lib_debug = 1;
114         }
115
116         if(debug) {
117                 fprintf(stdout, "argc=%d (%d incl. --debug option).\n",
118                         argc,
119                         argc + 1);
120         }
121
122         if(argc > 1 && strcmp(argv[1], "--label") == 0) {
123                 if(argc > 2) {
124                         program_name = malloc(strlen(argv[0])
125                                               + 10 /* update this when changing the sprintf() */
126                                               + strlen(argv[2]));
127                         sprintf(program_name, "%s --label %s",
128                                 argv[0],
129                                 argv[2]);
130                         if(debug) {
131                                 fprintf(stdout, "using \"%s\" as a label.\n", program_name);
132                         }
133                         argv += 2;
134                         argc -= 2;
135                 } else {
136                         fprintf(stderr, "%s: --label option requires an argument.\n",
137                                 program_name);
138                         exit(1);
139                 }
140         }
141   
142         if(debug) {
143                 fprintf(stdout, "...After check for --label option.\n");
144         }
145
146         if(argc == 1) {
147                 system("cat /proc/net/ipsec_spigrp");
148                 exit(0);
149         }
150
151         if(debug) {
152                 fprintf(stdout, "...After check for no option to print /proc/net/ipsec_spigrp.\n");
153         }
154
155         if(strcmp(argv[1], "--help") == 0) {
156                 if(debug) {
157                         fprintf(stdout, "\"--help\" option requested.\n");
158                 }
159                 usage(program_name);
160                 exit(1);
161         }
162
163         if(debug) {
164                 fprintf(stdout, "...After check for --help option.\n");
165         }
166
167         if(strcmp(argv[1], "--version") == 0) {
168                 if(debug) {
169                         fprintf(stdout, "\"--version\" option requested.\n");
170                 }
171                 fprintf(stdout, "%s %s\n", me, ipsec_version_code());
172                 fprintf(stdout, "See `ipsec --copyright' for copyright information.\n");
173                 exit(1);
174         }
175
176         if(debug) {
177                 fprintf(stdout, "...After check for --version option.\n");
178         }
179
180         if(strcmp(argv[1], "--said") == 0) {
181                 if(debug) {
182                         fprintf(stdout, "processing %d args with --said flag.\n", argc);
183                 }
184                 said_opt = 1;
185         }
186         
187         if(debug) {
188                 fprintf(stdout, "...After check for --said option.\n");
189         }
190
191         if(said_opt) {
192                 if (argc < 3 /*|| argc > 5*/) {
193                         fprintf(stderr, "expecting 3 or more args with --said, got %d.\n", argc);
194                         usage(program_name);
195                         exit(1);
196                 }
197                 nspis = argc - 2;
198         } else {
199                 if ((argc < 5) || (argc > 17) || ((argc % 4) != 1)) {
200                         fprintf(stderr, "expecting 5 or more args without --said, got %d.\n", argc);
201                         usage(program_name);
202                         exit(1);
203                 }
204                 nspis = argc / 4;
205         }
206
207         if(debug) {
208                 fprintf(stdout, "processing %d nspis.\n", nspis);
209         }
210
211         for(i = 0; i < nspis; i++) {
212                 if(debug) {
213                         fprintf(stdout, "processing spi #%d.\n", i);
214                 }
215
216                 if(said_opt) {
217                         error_s = ttosa((const char *)argv[i+2], 0, (ip_said*)&(said_af_array[i].said));
218                         if(error_s != NULL) {
219                                 fprintf(stderr, "%s: Error, %s converting --sa argument:%s\n",
220                                         program_name, error_s, argv[i+2]);
221                                 exit (1);
222                         }
223                         said_af_array[i].af = addrtypeof(&(said_af_array[i].said.dst));
224                         if(debug) {
225                                 addrtot(&said_af_array[i].said.dst, 0, ipaddr_txt, sizeof(ipaddr_txt));
226                                 fprintf(stdout, "said[%d].dst=%s.\n", i, ipaddr_txt);
227                         }
228                 } else {
229                         if(!strcmp(argv[i*4+4], "ah")) {
230                                 said_af_array[i].said.proto = SA_AH;
231                         }
232                         if(!strcmp(argv[i*4+4], "esp")) {
233                                 said_af_array[i].said.proto = SA_ESP;
234                         }
235                         if(!strcmp(argv[i*4+4], "tun")) {
236                                 said_af_array[i].said.proto = SA_IPIP;
237                         }
238                         if(!strcmp(argv[i*4+4], "comp")) {
239                                 said_af_array[i].said.proto = SA_COMP;
240                         }
241                         if(said_af_array[i].said.proto == 0) {
242                                 fprintf(stderr, "%s: Badly formed proto: %s\n",
243                                         program_name, argv[i*4+4]);
244                                 exit(1);
245                         }
246                         said_af_array[i].said.spi = htonl(strtoul(argv[i*4+3], &endptr, 0));
247                         if(!(endptr == argv[i*4+3] + strlen(argv[i*4+3]))) {
248                                 fprintf(stderr, "%s: Badly formed spi: %s\n",
249                                         program_name, argv[i*4+3]);
250                                 exit(1);
251                         }
252                         if(!strcmp(argv[i*4+1], "inet")) {
253                                 said_af_array[i].af = AF_INET;
254                         }
255                         if(!strcmp(argv[i*4+1], "inet6")) {
256                                 said_af_array[i].af = AF_INET6;
257                         }
258                         if((said_af_array[i].af != AF_INET) && (said_af_array[i].af != AF_INET6)) {
259                                 fprintf(stderr, "%s: Address family %s not supported\n",
260                                         program_name, argv[i*4+1]);
261                                 exit(1);
262                         }
263                         error_s = ttoaddr(argv[i*4+2], 0, said_af_array[i].af, &(said_af_array[i].said.dst));
264                         if(error_s != NULL) {
265                                 fprintf(stderr, "%s: Error, %s converting %dth address argument:%s\n",
266                                         program_name, error_s, i, argv[i*4+2]);
267                                 exit (1);
268                         }
269                 }
270                 if(debug) {
271                         fprintf(stdout, "SA %d contains: ", i+1);
272                         fprintf(stdout, "\n");
273                         fprintf(stdout, "proto = %d\n", said_af_array[i].said.proto);
274                         fprintf(stdout, "spi = %08x\n", said_af_array[i].said.spi);
275                         addrtot(&said_af_array[i].said.dst, 0, ipaddr_txt, sizeof(ipaddr_txt));
276                         fprintf(stdout, "edst = %s\n", ipaddr_txt);
277                 }
278         }       
279
280         if(debug) {
281                 fprintf(stdout, "Opening pfkey socket.\n");
282         }
283
284         if((pfkey_sock = socket(PF_KEY, SOCK_RAW, PF_KEY_V2) ) < 0) {
285                 fprintf(stderr, "%s: Trouble opening PF_KEY family socket with error: ",
286                         program_name);
287                 switch(errno) {
288                 case ENOENT:
289                         fprintf(stderr, "device does not exist.  See FreeS/WAN installation procedure.\n");
290                         break;
291                 case EACCES:
292                         fprintf(stderr, "access denied.  ");
293                         if(getuid() == 0) {
294                                 fprintf(stderr, "Check permissions.  Should be 600.\n");
295                         } else {
296                                 fprintf(stderr, "You must be root to open this file.\n");
297                         }
298                         break;
299                 case EUNATCH:
300                         fprintf(stderr, "Netlink not enabled OR KLIPS not loaded.\n");
301                         break;
302                 case ENODEV:
303                         fprintf(stderr, "KLIPS not loaded or enabled.\n");
304                         break;
305                 case EBUSY:
306                         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");
307                         break;
308                 case EINVAL:
309                         fprintf(stderr, "Invalid argument, KLIPS not loaded or check kernel log messages for specifics.\n");
310                         break;
311                 case ENOBUFS:
312                         fprintf(stderr, "No kernel memory to allocate SA.\n");
313                         break;
314                 case ESOCKTNOSUPPORT:
315                         fprintf(stderr, "Algorithm support not available in the kernel.  Please compile in support.\n");
316                         break;
317                 case EEXIST:
318                         fprintf(stderr, "SA already in use.  Delete old one first.\n");
319                         break;
320                 case ENXIO:
321                         fprintf(stderr, "SA does not exist.  Cannot delete.\n");
322                         break;
323                 case EAFNOSUPPORT:
324                         fprintf(stderr, "KLIPS not loaded or enabled.\n");
325                         break;
326                 default:
327                         fprintf(stderr, "Unknown file open error %d.  Please report as much detail as possible to development team.\n", errno);
328                 }
329                 exit(1);
330         }
331
332         for(i = 0; i < (((nspis - 1) < 2) ? 1 : (nspis - 1)); i++) {
333                 if(debug) {
334                         fprintf(stdout, "processing %dth pfkey message.\n", i);
335                 }
336
337                 pfkey_extensions_init(extensions);
338                 for(j = 0; j < ((nspis == 1) ? 1 : 2); j++) {
339                         if(debug) {
340                                 fprintf(stdout, "processing %dth said of %dth pfkey message.\n", j, i);
341                         }
342
343                         /* Build an SADB_X_GRPSA message to send down. */
344                         /* It needs <base, SA, SA2, address(D,D2) > minimum. */
345                         if(!j) {
346                                 if((error = pfkey_msg_hdr_build(&extensions[0],
347                                                                 SADB_X_GRPSA,
348                                                                 proto2satype(said_af_array[i].said.proto),
349                                                                 0,
350                                                                 ++pfkey_seq,
351                                                                 getpid()))) {
352                                         fprintf(stderr, "%s: Trouble building message header, error=%d.\n",
353                                                 program_name, error);
354                                         pfkey_extensions_free(extensions);
355                                         exit(1);
356                                 }
357                         } else {
358                                 if(debug) {
359                                         fprintf(stdout, "setting x_satype proto=%d satype=%d\n",
360                                                 said_af_array[i+j].said.proto,
361                                                 proto2satype(said_af_array[i+j].said.proto)
362                                                 );
363                                 }
364
365                                 if((error = pfkey_x_satype_build(&extensions[SADB_X_EXT_SATYPE2],
366                                                                  proto2satype(said_af_array[i+j].said.proto)
367                                         ))) {
368                                         fprintf(stderr, "%s: Trouble building message header, error=%d.\n",
369                                                 program_name, error);
370                                         pfkey_extensions_free(extensions);
371                                         exit(1);
372                                 }
373                         }
374
375                         if((error = pfkey_sa_build(&extensions[!j ? SADB_EXT_SA : SADB_X_EXT_SA2],
376                                                    !j ? SADB_EXT_SA : SADB_X_EXT_SA2,
377                                                    said_af_array[i+j].said.spi, /* in network order */
378                                                    0,
379                                                    0,
380                                                    0,
381                                                    0,
382                                                    0))) {
383                                 fprintf(stderr, "%s: Trouble building sa extension, error=%d.\n",
384                                         program_name, error);
385                                 pfkey_extensions_free(extensions);
386                                 exit(1);
387                         }
388                         
389 #if 0
390                         if(!j) {
391                                 anyaddr(said_af_array[i].af, &pfkey_address_s_ska); /* Is the address family correct ?? */
392                                 if((error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
393                                                                 SADB_EXT_ADDRESS_SRC,
394                                                                 0,
395                                                                 0,
396                                                                 sockaddrof(&pfkey_address_s_ska)))) {
397                                         addrtot(&pfkey_address_s_ska, 0, ipaddr_txt, sizeof(ipaddr_txt));
398                                         fprintf(stderr, "%s: Trouble building address_s extension (%s), error=%d.\n",
399                                                 program_name, ipaddr_txt, error);
400                                         pfkey_extensions_free(extensions);
401                                         exit(1);
402                                 }
403                         }
404 #endif                  
405                         if((error = pfkey_address_build(&extensions[!j ? SADB_EXT_ADDRESS_DST : SADB_X_EXT_ADDRESS_DST2],
406                                                         !j ? SADB_EXT_ADDRESS_DST : SADB_X_EXT_ADDRESS_DST2,
407                                                         0,
408                                                         0,
409                                                         sockaddrof(&said_af_array[i+j].said.dst)))) {
410                                 addrtot(&said_af_array[i+j].said.dst,
411                                         0, ipaddr_txt, sizeof(ipaddr_txt));
412                                 fprintf(stderr, "%s: Trouble building address_d extension (%s), error=%d.\n",
413                                         program_name, ipaddr_txt, error);
414                                 pfkey_extensions_free(extensions);
415                                 exit(1);
416                         }
417                         
418                 }
419
420                 if((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_IN))) {
421                         fprintf(stderr, "%s: Trouble building pfkey message, error=%d.\n",
422                                 program_name, error);
423                         pfkey_extensions_free(extensions);
424                         pfkey_msg_free(&pfkey_msg);
425                         exit(1);
426                 }
427                 
428                 if((error = write(pfkey_sock,
429                                   pfkey_msg,
430                                   pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)) !=
431                    pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
432                         fprintf(stderr, "%s: pfkey write failed, returning %d with errno=%d.\n",
433                                 program_name, error, errno);
434                         pfkey_extensions_free(extensions);
435                         pfkey_msg_free(&pfkey_msg);
436                         switch(errno) {
437                         case EACCES:
438                                 fprintf(stderr, "access denied.  ");
439                                 if(getuid() == 0) {
440                                         fprintf(stderr, "Check permissions.  Should be 600.\n");
441                                 } else {
442                                         fprintf(stderr, "You must be root to open this file.\n");
443                                 }
444                                 break;
445                         case EUNATCH:
446                                 fprintf(stderr, "Netlink not enabled OR KLIPS not loaded.\n");
447                                 break;
448                         case EBUSY:
449                                 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");
450                                 break;
451                         case EINVAL:
452                                 fprintf(stderr, "Invalid argument, check kernel log messages for specifics.\n");
453                                 break;
454                         case ENODEV:
455                                 fprintf(stderr, "KLIPS not loaded or enabled.\n");
456                                 fprintf(stderr, "No device?!?\n");
457                                 break;
458                         case ENOBUFS:
459                                 fprintf(stderr, "No kernel memory to allocate SA.\n");
460                                 break;
461                         case ESOCKTNOSUPPORT:
462                                 fprintf(stderr, "Algorithm support not available in the kernel.  Please compile in support.\n");
463                                 break;
464                         case EEXIST:
465                                 fprintf(stderr, "SA already in use.  Delete old one first.\n");
466                                 break;
467                         case ENOENT:
468                                 fprintf(stderr, "device does not exist.  See FreeS/WAN installation procedure.\n");
469                                 break;
470                         case ENXIO:
471                                 fprintf(stderr, "SA does not exist.  Cannot delete.\n");
472                                 break;
473                         default:
474                                 fprintf(stderr, "Unknown socket write error %d.  Please report as much detail as possible to development team.\n", errno);
475                         }
476                         exit(1);
477                 }
478                 if(pfkey_msg) {
479                         pfkey_extensions_free(extensions);
480                         pfkey_msg_free(&pfkey_msg);
481                 }
482         }
483
484         (void) close(pfkey_sock);  /* close the socket */
485         exit(0);
486 }
487 /*
488  * $Log: spigrp.c,v $
489  * Revision 1.41  2002/03/08 21:44:05  rgb
490  * Update for all GNU-compliant --version strings.
491  *
492  * Revision 1.40  2001/10/02 17:17:17  rgb
493  * Check error return for all "tto*" calls and report errors.  This, in
494  * conjuction with the fix to "tto*" will detect AF not set.
495  *
496  * Revision 1.39  2001/09/07 22:24:42  rgb
497  * Added EAFNOSUPPORT socket open error code in case KLIPS is not loaded.
498  *
499  * Revision 1.38  2001/06/14 19:35:15  rgb
500  * Update copyright date.
501  *
502  * Revision 1.37  2001/05/16 05:07:20  rgb
503  * Fixed --label option in KLIPS manual utils to add the label to the
504  * command name rather than replace it in error text.
505  * Fix 'print table' non-option in KLIPS manual utils to deal with --label
506  * and --debug options.
507  *
508  * Revision 1.36  2001/01/23 20:24:12  rgb
509  * Fix comment to reflect reality that src is not needed for grouping.
510  *
511  * Revision 1.35  2000/09/17 18:56:48  rgb
512  * Added IPCOMP support.
513  *
514  * Revision 1.34  2000/09/16 04:56:32  rgb
515  * Added Svenning's ipcomp patch.
516  *
517  * Revision 1.33  2000/09/12 22:36:45  rgb
518  * Gerhard's IPv6 support.
519  *
520  * Revision 1.32  2000/09/08 19:17:31  rgb
521  * Removed all references to CONFIG_IPSEC_PFKEYv2.
522  *
523  * Revision 1.31  2000/08/27 01:46:52  rgb
524  * Update copyright dates and remove no longer used resolve_ip().
525  *
526  * Revision 1.30  2000/06/21 16:51:27  rgb
527  * Added no additional argument option to usage text.
528  *
529  * Revision 1.29  2000/06/20 22:37:24  rgb
530  * Fixed bug in no-arg invocation that caused a core-dump when it should
531  * have printed out /proc/net/ipsec_spigrp.
532  * Added debug statements.
533  *
534  * Revision 1.28  2000/03/16 06:40:50  rgb
535  * Hardcode PF_KEYv2 support.
536  *
537  * Revision 1.27  2000/01/25 14:38:52  rgb
538  * Fixed variable declaration bug so it will compile with pfkey off.
539  *
540  * Revision 1.26  2000/01/22 23:22:47  rgb
541  * Use new function proto2satype().
542  *
543  * Revision 1.25  2000/01/21 09:42:32  rgb
544  * Replace resolve_ip() with atoaddr() from freeswanlib.
545  *
546  * Revision 1.24  2000/01/21 06:25:51  rgb
547  * Added pfkeyv2 support to completely avoid netlink.
548  * Added --debug switch to command line.
549  * Added --said processing to command line.
550  *
551  * Revision 1.23  1999/12/07 18:30:26  rgb
552  * Added headers to silence fussy compilers.
553  * Converted local functions to static to limit scope.
554  * Removed unused cruft.
555  * Converted main() to prototyped declaration.
556  *
557  * Revision 1.22  1999/11/25 09:09:43  rgb
558  * Comment out unused variables.
559  * Clarified assignment in conditional with parens.
560  *
561  * Revision 1.21  1999/11/23 23:06:27  rgb
562  * Sort out pfkey and freeswan headers, putting them in a library path.
563  *
564  * Revision 1.20  1999/10/16 00:27:14  rgb
565  * Removed cruft.
566  *
567  * Revision 1.19  1999/04/15 15:37:28  rgb
568  * Forward check changes from POST1_00 branch.
569  *
570  * Revision 1.15.2.2  1999/04/13 20:58:10  rgb
571  * Add argc==1 --> /proc/net/ipsec_*.
572  *
573  * Revision 1.15.2.1  1999/03/30 17:01:36  rgb
574  * Make main() return type explicit.
575  *
576  * Revision 1.18  1999/04/11 00:12:09  henry
577  * GPL boilerplate
578  *
579  * Revision 1.17  1999/04/06 04:54:39  rgb
580  * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
581  * patch shell fixes.
582  *
583  * Revision 1.16  1999/03/17 15:40:54  rgb
584  * Make explicit main() return type of int.
585  *
586  * Revision 1.15  1999/01/28 23:20:49  rgb
587  * Replace hard-coded numbers in macros and code with meaningful values
588  * automatically generated from sizeof() and offsetof() to further the
589  * goal of platform independance.
590  *
591  * Revision 1.14  1999/01/22 06:36:46  rgb
592  * 64-bit clean-up.
593  *
594  * Revision 1.13  1998/11/12 21:08:04  rgb
595  * Add --label option to identify caller from scripts.
596  *
597  * Revision 1.12  1998/10/26 01:28:38  henry
598  * use SA_* protocol names, not IPPROTO_*, to avoid compile problems
599  *
600  * Revision 1.11  1998/10/25 02:47:09  rgb
601  * Fix bug in size of stucture passed in from user space for grpspi command.
602  * Added debugging code to find spigrp stucture size mismatch bug.
603  * Convert switch to loop for more efficient coding and redundant code elimination.
604  *
605  * Revision 1.10  1998/10/19 18:58:56  rgb
606  * Added inclusion of freeswan.h.
607  * a_id structure implemented and used: now includes protocol.
608  *
609  * Revision 1.9  1998/10/09 04:36:32  rgb
610  * Changed help output from stderr to stdout.
611  * Avoid use of argv[0] after first use.
612  *
613  * Revision 1.8  1998/08/05 22:24:45  rgb
614  * Change includes to accomodate RH5.x
615  *
616  * Revision 1.7  1998/07/29 21:43:17  rgb
617  * Convert to 0x-prefixed spis.
618  * Support dns lookups for hostnames.
619  *
620  * Revision 1.6  1998/07/14 18:24:05  rgb
621  * Remove unused skbuff header.
622  *
623  * Revision 1.5  1998/07/09 18:14:11  rgb
624  * Added error checking to IP's and keys.
625  * Made most error messages more specific rather than spamming usage text.
626  * Added more descriptive kernel error return codes and messages.
627  * Converted all spi translations to unsigned.
628  * Removed all invocations of perror.
629  *
630  * Revision 1.4  1998/06/30 18:04:32  rgb
631  * Fix compiler warning: couldn't find 'struct option' prototype.
632  *
633  * Revision 1.3  1998/05/27 18:48:20  rgb
634  * Adding --help and --version directives.
635  *
636  * Revision 1.2  1998/05/18 21:14:16  rgb
637  * Modifications to be able to ungroup spi's.
638  *
639  * Revision 1.1.1.1  1998/04/08 05:35:09  henry
640  * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
641  *
642  * Revision 0.3  1996/11/20 14:51:32  ji
643  * Fixed problems with #include paths.
644  * Changed (incorrect) references to ipsp into ipsec.
645  *
646  * Revision 0.2  1996/11/08 15:46:29  ji
647  * First limited release.
648  *
649  *
650  */