OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / freeswan / klips / utils / klipsdebug.c
1 /*
2  * control KLIPS debugging options
3  * Copyright (C) 1996  John Ioannidis.
4  * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs <rgb@freeswan.org>
5  *                                 2001  Michael Richardson <mcr@freeswan.org>
6  * 
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the
9  * Free Software Foundation; either version 2 of the License, or (at your
10  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
11  * 
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15  * for more details.
16  */
17
18 char klipsdebug_c_version[] = "RCSID $Id: klipsdebug.c,v 1.45 2002/03/08 21:44:04 rgb Exp $";
19
20
21 #include <sys/types.h>
22 #include <linux/types.h> /* new */
23 #include <string.h>
24 #include <errno.h>
25 #include <stdlib.h> /* system(), strtoul() */
26 #include <sys/stat.h> /* open() */
27 #include <fcntl.h> /* open() */
28
29 #include <sys/socket.h>
30
31 #include <netinet/in.h>
32 #include <arpa/inet.h>
33
34
35
36 #include <unistd.h>
37 #include <freeswan.h>
38 #if 0
39 #include <linux/autoconf.h>     /* CONFIG_IPSEC_PFKEYv2 */
40 #endif
41 /* permanently turn it on since netlink support has been disabled */
42      #include <signal.h>
43      #include <pfkeyv2.h>
44      #include <pfkey.h>
45 #include "radij.h"
46 #include "ipsec_encap.h"
47 #ifndef CONFIG_IPSEC_DEBUG
48 #define CONFIG_IPSEC_DEBUG
49 #endif /* CONFIG_IPSEC_DEBUG */
50 #include "ipsec_netlink.h"
51 #include "ipsec_tunnel.h"
52
53 #include <stdio.h>
54 #include <getopt.h>
55
56 __u32 bigbuf[1024];
57 char *program_name;
58 char me[] = "ipsec klipsdebug";
59 extern unsigned int pfkey_lib_debug; /* used by libfreeswan/pfkey_v2_build */
60 int pfkey_sock;
61 fd_set pfkey_socks;
62 uint32_t pfkey_seq = 0;
63
64 static void
65 usage(char * arg)
66 {
67         fprintf(stdout, "usage: %s {--set|--clear} {tunnel|tunnel-xmit|netlink|xform|eroute|spi|radij|esp|ah|rcv|pfkey|ipcomp|verbose}\n", arg);
68         fprintf(stdout, "       %s {--all|--none}\n", arg);
69         fprintf(stdout, "       %s --help\n", arg);
70         fprintf(stdout, "       %s --version\n", arg);
71         fprintf(stdout, "       %s\n", arg);
72         fprintf(stdout, "        [ --debug ] is optional to any %s command\n", arg);
73         fprintf(stdout, "        [ --label <label> ] is optional to any %s command.\n", arg);
74         exit(1);
75 }
76
77 static struct option const longopts[] =
78 {
79         {"set", 1, 0, 's'},
80         {"clear", 1, 0, 'c'},
81         {"all", 0, 0, 'a'},
82         {"none", 0, 0, 'n'},
83         {"help", 0, 0, 'h'},
84         {"version", 0, 0, 'v'},
85         {"label", 1, 0, 'l'},
86         {"optionsfrom", 1, 0, '+'},
87         {"debug", 0, 0, 'd'},
88         {0, 0, 0, 0}
89 };
90
91 int
92 main(int argc, char **argv)
93 {
94 /*      int fd; */
95         unsigned char action = 0;
96         unsigned int i;
97         int *bitfieldp;
98         int c, previous = -1;
99         
100         struct encap_msghdr *em = (struct encap_msghdr *)bigbuf;
101         int debug = 0;
102         int error = 0;
103         int argcount = argc;
104
105         struct sadb_ext *extensions[SADB_EXT_MAX + 1];
106         struct sadb_msg *pfkey_msg;
107         
108         bitfieldp = (int *)&em->em_db_tn;
109
110         program_name = argv[0];
111
112         while((c = getopt_long(argc, argv, ""/*"s:c:anhvl:+:d"*/, longopts, 0)) != EOF) {
113                 switch(c) {
114                 case 'd':
115                         debug = 1;
116                         pfkey_lib_debug = 1;
117                         argcount--;
118                         break;
119                 case 's':
120                         if(action) {
121                                 fprintf(stderr, "%s: Only one of '--set', '--clear', '--all' or '--none' options permitted.\n",
122                                         program_name);
123                                 exit(1);
124                         }
125                         action = 's';
126                         for (i = 0; i < (sizeof(em->Eu.Dbg)/sizeof(int)); i++) {
127                                 *(bitfieldp++) = 0;
128                         }
129                         if(strcmp(optarg, "tunnel") == 0) {
130                                 em->em_db_tn = -1L;
131                         } else if(strcmp(optarg, "tunnel-xmit") == 0) {
132                                 em->em_db_tn = DB_TN_XMIT;
133                         } else if(strcmp(optarg, "netlink") == 0) {
134                                 em->em_db_nl = -1L;
135                         } else if(strcmp(optarg, "xform") == 0) {
136                                 em->em_db_xf = -1L;
137                         } else if(strcmp(optarg, "eroute") == 0) {
138                                 em->em_db_er = -1L;
139                         } else if(strcmp(optarg, "spi") == 0) {
140                                 em->em_db_sp = -1L;
141                         } else if(strcmp(optarg, "radij") == 0) {
142                                 em->em_db_rj = -1L;
143                         } else if(strcmp(optarg, "esp") == 0) {
144                                 em->em_db_es = -1L;
145                         } else if(strcmp(optarg, "ah") == 0) {
146                                 em->em_db_ah = -1L;
147                         } else if(strcmp(optarg, "rcv") == 0) {
148                                 em->em_db_rx = -1L;
149                         } else if(strcmp(optarg, "pfkey") == 0) {
150                                 em->em_db_ky = -1L;
151                         } else if(strcmp(optarg, "comp") == 0) {
152                                 em->em_db_gz = -1L;
153                         } else if(strcmp(optarg, "verbose") == 0) {
154                                 em->em_db_vb = -1L;
155                         } else {
156                                 usage(program_name);
157                         }
158                         em->em_db_nl |= 1 << (sizeof(em->em_db_nl) * 8 -1);
159                         break;
160                 case 'c':
161                         if(action) {
162                                 fprintf(stderr, "%s: Only one of '--set', '--clear', '--all' or '--none' options permitted.\n",
163                                         program_name);
164                                 exit(1);
165                         }
166                         action = 'c';
167                         for (i = 0; i < (sizeof(em->Eu.Dbg)/sizeof(int)); i++) {
168                                 *(bitfieldp++) = -1;
169                         }
170                         if(strcmp(optarg, "tunnel") == 0) {
171                                 em->em_db_tn = 0;
172                         } else if(strcmp(optarg, "tunnel-xmit") == 0) {
173                                 em->em_db_tn = ~DB_TN_XMIT;
174                         } else if(strcmp(optarg, "netlink") == 0) {
175                                 em->em_db_nl = 0;
176                         } else if(strcmp(optarg, "xform") == 0) {
177                                 em->em_db_xf = 0;
178                         } else if(strcmp(optarg, "eroute") == 0) {
179                                 em->em_db_er = 0;
180                         } else if(strcmp(optarg, "spi") == 0) {
181                                 em->em_db_sp = 0;
182                         } else if(strcmp(optarg, "radij") == 0) {
183                                 em->em_db_rj = 0;
184                         } else if(strcmp(optarg, "esp") == 0) {
185                                 em->em_db_es = 0;
186                         } else if(strcmp(optarg, "ah") == 0) {
187                                 em->em_db_ah = 0;
188                         } else if(strcmp(optarg, "rcv") == 0) {
189                                 em->em_db_rx = 0;
190                         } else if(strcmp(optarg, "pfkey") == 0) {
191                                 em->em_db_ky = 0;
192                         } else if(strcmp(optarg, "comp") == 0) {
193                                 em->em_db_gz = 0;
194                         } else if(strcmp(optarg, "verbose") == 0) {
195                                 em->em_db_vb = 0;
196                         } else {
197                                 usage(program_name);
198                         }
199                         em->em_db_nl &= ~(1 << (sizeof(em->em_db_nl) * 8 -1));
200                         break;
201                 case 'a':
202                         if(action) {
203                                 fprintf(stderr, "%s: Only one of '--set', '--clear', '--all' or '--none' options permitted.\n",
204                                         program_name);
205                                 exit(1);
206                         }
207                         action = 'a';
208                         for (i = 0; i < (sizeof(em->Eu.Dbg)/sizeof(int)) - 1; i++) {
209                                 *(bitfieldp++) = -1;
210                         }
211                         *(bitfieldp++) = 0;
212                         break;
213                 case 'n':
214                         if(action) {
215                                 fprintf(stderr, "%s: Only one of '--set', '--clear', '--all' or '--none' options permitted.\n",
216                                         program_name);
217                                 exit(1);
218                         }
219                         action = 'n';
220                         for (i = 0; i < (sizeof(em->Eu.Dbg)/sizeof(int)); i++) {
221                                 *(bitfieldp++) = 0;
222                         }
223                         break;
224                 case 'h':
225                 case '?':
226                         usage(program_name);
227                         exit(1);
228                 case 'v':
229                         fprintf(stdout, "%s %s\n", me, ipsec_version_code());
230                         fprintf(stdout, "See `ipsec --copyright' for copyright information.\n");
231                         exit(0);
232                 case 'l':
233                         program_name = malloc(strlen(argv[0])
234                                               + 10 /* update this when changing the sprintf() */
235                                               + strlen(optarg));
236                         sprintf(program_name, "%s --label %s",
237                                 argv[0],
238                                 optarg);
239                         argcount -= 2;
240                         break;
241                 case '+': /* optionsfrom */
242                         optionsfrom(optarg, &argc, &argv, optind, stderr);
243                         /* no return on error */
244                         break;
245                 default:
246                         break;
247                 }
248                 previous = c;
249         }
250
251         if(argcount == 1) {
252                 system("cat /proc/net/ipsec_klipsdebug");
253                 exit(0);
254         }
255
256         em->em_magic = EM_MAGIC;
257         em->em_version = 0;
258         if(action) {
259                 em->em_type = EMT_SETDEBUG;
260         } else {
261 #if 0
262                 em->em_type = EMT_GETDEBUG;
263 #else
264                 usage(program_name);
265 #endif
266         }
267         em->em_msglen = EMT_SETDEBUG_FLEN;
268
269         if((pfkey_sock = socket(PF_KEY, SOCK_RAW, PF_KEY_V2) ) < 0) {
270                 fprintf(stderr, "%s: Trouble openning PF_KEY family socket with error: ",
271                         program_name);
272                 switch(errno) {
273                 case ENOENT:
274                         fprintf(stderr, "device does not exist.  See FreeS/WAN installation procedure.\n");
275                         break;
276                 case EACCES:
277                         fprintf(stderr, "access denied.  ");
278                         if(getuid() == 0) {
279                                 fprintf(stderr, "Check permissions.  Should be 600.\n");
280                         } else {
281                                 fprintf(stderr, "You must be root to open this file.\n");
282                         }
283                         break;
284                 case EUNATCH:
285                         fprintf(stderr, "Netlink not enabled OR KLIPS not loaded.\n");
286                         break;
287                 case ENODEV:
288                         fprintf(stderr, "KLIPS not loaded or enabled.\n");
289                         break;
290                 case EBUSY:
291                         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");
292                         break;
293                 case EINVAL:
294                         fprintf(stderr, "Invalid argument, KLIPS not loaded or check kernel log messages for specifics.\n");
295                         break;
296                 case ENOBUFS:
297                         fprintf(stderr, "No kernel memory to allocate SA.\n");
298                         break;
299                 case ESOCKTNOSUPPORT:
300                         fprintf(stderr, "Algorithm support not available in the kernel.  Please compile in support.\n");
301                         break;
302                 case EEXIST:
303                         fprintf(stderr, "SA already in use.  Delete old one first.\n");
304                         break;
305                 case ENXIO:
306                         fprintf(stderr, "SA does not exist.  Cannot delete.\n");
307                         break;
308                 case EAFNOSUPPORT:
309                         fprintf(stderr, "KLIPS not loaded or enabled.\n");
310                         break;
311                 default:
312                         fprintf(stderr, "Unknown file open error %d.  Please report as much detail as possible to development team.\n", errno);
313                 }
314                 exit(1);
315         }
316
317         pfkey_extensions_init(extensions);
318
319         if((error = pfkey_msg_hdr_build(&extensions[0],
320                                         SADB_X_DEBUG,
321                                         0,
322                                         0,
323                                         ++pfkey_seq,
324                                         getpid()))) {
325                 fprintf(stderr, "%s: Trouble building message header, error=%d.\n",
326                         program_name, error);
327                 pfkey_extensions_free(extensions);
328                 exit(1);
329         }
330         
331         if((error = pfkey_x_debug_build(&extensions[SADB_X_EXT_DEBUG],
332                                         em->em_db_tn,
333                                         em->em_db_nl,
334                                         em->em_db_xf,
335                                         em->em_db_er,
336                                         em->em_db_sp,
337                                         em->em_db_rj,
338                                         em->em_db_es,
339                                         em->em_db_ah,
340                                         em->em_db_rx,
341                                         em->em_db_ky,
342                                         em->em_db_gz,
343                                         em->em_db_vb))) {
344                 fprintf(stderr, "%s: Trouble building message header, error=%d.\n",
345                         program_name, error);
346                 pfkey_extensions_free(extensions);
347                 exit(1);
348         }
349         
350         if((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_IN))) {
351                 fprintf(stderr, "%s: Trouble building pfkey message, error=%d.\n",
352                         program_name, error);
353                 pfkey_extensions_free(extensions);
354                 pfkey_msg_free(&pfkey_msg);
355                 exit(1);
356         }
357         
358         if((error = write(pfkey_sock,
359                           pfkey_msg,
360                           pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)) !=
361            pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
362                 fprintf(stderr, "%s: pfkey write failed, tried to write %ld octets, returning %d with errno=%d.\n",
363                         program_name, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN, error, errno);
364                 pfkey_extensions_free(extensions);
365                 pfkey_msg_free(&pfkey_msg);
366                 switch(errno) {
367                 case EACCES:
368                         fprintf(stderr, "access denied.  ");
369                         if(getuid() == 0) {
370                                 fprintf(stderr, "Check permissions.  Should be 600.\n");
371                         } else {
372                                 fprintf(stderr, "You must be root to open this file.\n");
373                         }
374                         break;
375                 case EUNATCH:
376                         fprintf(stderr, "Netlink not enabled OR KLIPS not loaded.\n");
377                         break;
378                 case EBUSY:
379                         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");
380                         break;
381                 case EINVAL:
382                         fprintf(stderr, "Invalid argument, check kernel log messages for specifics.\n");
383                         break;
384                 case ENODEV:
385                         fprintf(stderr, "KLIPS not loaded or enabled.\n");
386                         fprintf(stderr, "No device?!?\n");
387                         break;
388                 case ENOBUFS:
389                         fprintf(stderr, "No kernel memory to allocate SA.\n");
390                         break;
391                 case ESOCKTNOSUPPORT:
392                         fprintf(stderr, "Algorithm support not available in the kernel.  Please compile in support.\n");
393                         break;
394                 case EEXIST:
395                         fprintf(stderr, "SA already in use.  Delete old one first.\n");
396                         break;
397                 case ENOENT:
398                         fprintf(stderr, "device does not exist.  See FreeS/WAN installation procedure.\n");
399                         break;
400                 case ENXIO:
401                         fprintf(stderr, "SA does not exist.  Cannot delete.\n");
402                         break;
403                 default:
404                         fprintf(stderr, "Unknown socket write error %d.  Please report as much detail as possible to development team.\n", errno);
405                 }
406                 exit(1);
407         }
408
409         if(pfkey_msg) {
410                 pfkey_extensions_free(extensions);
411                 pfkey_msg_free(&pfkey_msg);
412         }
413
414         (void) close(pfkey_sock);  /* close the socket */
415         exit(0);
416 }
417 /*
418  * $Log: klipsdebug.c,v $
419  * Revision 1.45  2002/03/08 21:44:04  rgb
420  * Update for all GNU-compliant --version strings.
421  *
422  * Revision 1.44  2001/11/23 07:23:14  mcr
423  *      pulled up klips2 Makefile and pf_key code.
424  *
425  * Revision 1.43  2001/11/22 05:44:01  henry
426  * new version stuff
427  *
428  * Revision 1.42.2.1  2001/10/13 18:22:21  mcr
429  *      usage string was missing "netlink" and "pf_key" debug options.
430  *
431  * Revision 1.42  2001/09/07 22:24:07  rgb
432  * Added EAFNOSUPPORT socket open error code in case KLIPS is not loaded.
433  *
434  * Revision 1.41  2001/06/14 19:35:14  rgb
435  * Update copyright date.
436  *
437  * Revision 1.40  2001/05/21 02:02:54  rgb
438  * Eliminate 1-letter options.
439  *
440  * Revision 1.39  2001/05/16 05:07:19  rgb
441  * Fixed --label option in KLIPS manual utils to add the label to the
442  * command name rather than replace it in error text.
443  * Fix 'print table' non-option in KLIPS manual utils to deal with --label
444  * and --debug options.
445  *
446  * Revision 1.38  2000/10/11 03:56:54  rgb
447  * Initialise verbose field to zero on --all.
448  *
449  * Revision 1.37  2000/10/11 03:48:44  henry
450  * add a couple of overlooked parameters to a call
451  *
452  * Revision 1.36  2000/10/10 20:10:19  rgb
453  * Added support for debug_ipcomp and debug_verbose to klipsdebug.
454  *
455  * Revision 1.35  2000/09/08 19:16:51  rgb
456  * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
457  * Removed all references to CONFIG_IPSEC_PFKEYv2.
458  *
459  * Revision 1.34  2000/08/27 01:48:30  rgb
460  * Update copyright.
461  *
462  * Revision 1.33  2000/07/26 03:41:46  rgb
463  * Changed all printf's to fprintf's.  Fixed tncfg's usage to stderr.
464  *
465  * Revision 1.32  2000/06/28 05:53:09  rgb
466  * Mention that netlink is obsolete.
467  *
468  * Revision 1.31  2000/06/21 16:51:27  rgb
469  * Added no additional argument option to usage text.
470  *
471  * Revision 1.30  2000/03/16 06:40:49  rgb
472  * Hardcode PF_KEYv2 support.
473  *
474  * Revision 1.29  2000/01/21 06:23:34  rgb
475  * Added pfkeyv2 support to completely avoid netlink.
476  * Added --debug switch to command line.
477  * Changed name of debug switch bitfield pointer to avoid name
478  * conflict with command line debug switch.
479  *
480  * Revision 1.28  2000/01/13 08:10:38  rgb
481  * Added finer-grained 'tunnel-xmit' switch for debugging.
482  *
483  * Revision 1.27  1999/12/07 18:28:34  rgb
484  * Added headers to silence fussy compilers.
485  * Converted local functions to static to limit scope.
486  * Removed unused cruft.
487  * Changed types to unsigned to quiet compiler.
488  * Changed printf type from Lx to x to quiet compiler.
489  *
490  * Revision 1.26  1999/11/25 09:07:59  rgb
491  * Comment out unused variable.
492  *
493  * Revision 1.25  1999/11/23 23:06:26  rgb
494  * Sort out pfkey and freeswan headers, putting them in a library path.
495  *
496  * Revision 1.24  1999/06/10 16:11:15  rgb
497  * Add autoconf to use pfkey.
498  * Add argc==1 to use /proc/net/ipsec_klipsdebug output.
499  * Add error return code description for ECONNREFUSED.
500  *
501  * Revision 1.23  1999/05/05 22:02:34  rgb
502  * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
503  *
504  * Revision 1.22  1999/04/29 15:26:15  rgb
505  * Add pfkey debugging support.
506  *
507  * Revision 1.21  1999/04/15 15:37:27  rgb
508  * Forward check changes from POST1_00 branch.
509  *
510  * Revision 1.15.2.2  1999/04/13 20:55:45  rgb
511  * Add experimental 'getdebug'.
512  *
513  * Revision 1.15.2.1  1999/03/30 17:01:37  rgb
514  * Make main() return type explicit.
515  *
516  * Revision 1.20  1999/04/12 01:27:10  henry
517  * Eric Young waived his advertising clause
518  *
519  * Revision 1.19  1999/04/11 01:24:53  henry
520  * tidy up --version, add copyright notice
521  *
522  * Revision 1.18  1999/04/11 00:12:08  henry
523  * GPL boilerplate
524  *
525  * Revision 1.17  1999/04/06 04:54:38  rgb
526  * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
527  * patch shell fixes.
528  *
529  * Revision 1.16  1999/03/17 15:40:54  rgb
530  * Make explicit main() return type of int.
531  *
532  * Revision 1.15  1999/01/22 06:35:19  rgb
533  * 64-bit clean-up.
534  * Added algorithm switch code.
535  *
536  * Revision 1.14  1998/11/12 21:08:04  rgb
537  * Add --label option to identify caller from scripts.
538  *
539  * Revision 1.13  1998/10/31 06:35:16  rgb
540  * Fixed up comments in #endif directives.
541  *
542  * Revision 1.12  1998/10/22 06:36:22  rgb
543  * Added freeswan.h inclusion.
544  *
545  * Revision 1.11  1998/10/09 18:47:30  rgb
546  * Add 'optionfrom' to get more options from a named file.
547  *
548  * Revision 1.10  1998/10/09 04:35:31  rgb
549  * Changed help output from stderr to stdout.
550  * Changed error messages from stdout to stderr.
551  * Deleted old commented out cruft.
552  *
553  * Revision 1.9  1998/08/28 03:13:05  rgb
554  * Tidy up old cruft.
555  *
556  * Revision 1.8  1998/08/05 22:24:45  rgb
557  * Change includes to accomodate RH5.x
558  *
559  * Revision 1.7  1998/07/29 21:36:37  rgb
560  * Converted to long option names.
561  *
562  * Revision 1.6  1998/07/14 18:23:11  rgb
563  * Remove unused skbuff header.
564  *
565  * Revision 1.5  1998/07/09 18:14:10  rgb
566  * Added error checking to IP's and keys.
567  * Made most error messages more specific rather than spamming usage text.
568  * Added more descriptive kernel error return codes and messages.
569  * Converted all spi translations to unsigned.
570  * Removed all invocations of perror.
571  *
572  * Revision 1.4  1998/05/27 18:48:21  rgb
573  * Adding --help and --version directives.
574  *
575  * Revision 1.3  1998/05/18 21:19:09  rgb
576  * Added options for finer control of debugging switches.
577  *
578  * Revision 1.2  1998/05/12 02:26:27  rgb
579  * Fixed compile errors with IPSEC_DEBUG shut off in the kernel config.
580  *
581  * Revision 1.1  1998/04/23 21:07:34  rgb
582  * Added a userspace utility to change klips kernelspace debug switches.
583  *
584  * Revision 1.1.1.1  1998/04/08 05:35:09  henry
585  * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
586  *
587  * Revision 0.3  1996/11/20 14:51:32  ji
588  * Fixed problems with #include paths.
589  * Changed (incorrect) references to ipsp into ipsec.
590  *
591  * Revision 0.2  1996/11/08 15:46:29  ji
592  * First limited release.
593  *
594  *
595  */