⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pf_key.c

📁 This a good VPN source
💻 C
字号:
/* * @(#) pfkey socket manipulator/observer * * Copyright (C) 2001  Richard Guy Briggs  <rgb@freeswan.org> *                 and Michael Richardson  <mcr@freeswan.org> *  * 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: pf_key.c,v 1.18 2004/04/04 01:50:56 ken Exp $ * *//*  * This program opens a pfkey socket or a file * and prints all messages that it sees. * * This can be used to diagnose problems. * */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <getopt.h>#include <errno.h>#include <setjmp.h>#include <signal.h>#include <sys/socket.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <stdint.h>#include <openswan.h>#include <pfkeyv2.h>#include <pfkey.h>char *progname;uint32_t pfkey_seq = 0;int pfkey_sock;static voidUsage(char *progname){	fprintf(stderr, "%s: Usage: %s [--help]\n"		"\tby default listens for AH, ESP, IPIP and IPCOMP\n"		"\t--daemon <file>     fork before printing, stuffing the PID in the file\n"		"\t--dumpfile <file>   decode file of pfkey messages\n"		"\t--encodefile <file> encode file of pfkey messages\n"		"\t--esp               listen for ESP messages\n"		"\t--ah                listen for AH messages\n"		"\t--esp               listen for ESP messages\n"		"\t--ipip              listen for IPIP messages\n"		"\t--ipcomp            listen for IPCOMP messages\n",		progname, progname);	exit(1);}voidpfkey_register(uint8_t satype) {	/* for registering SA types that can be negotiated */	int error = 0;	struct sadb_ext *extensions[SADB_EXT_MAX + 1];	struct sadb_msg *pfkey_msg;	pfkey_extensions_init(extensions);	if((error = pfkey_msg_hdr_build(&extensions[0],					SADB_REGISTER,					satype,					0,					++pfkey_seq,					getpid()))) {		fprintf(stderr, "%s: Trouble building message header, error=%d.\n",			progname, error);		pfkey_extensions_free(extensions);		exit(1);	}	if((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_IN))) {		fprintf(stderr, "%s: Trouble building pfkey message, error=%d.\n",			progname, error);		pfkey_extensions_free(extensions);		pfkey_msg_free(&pfkey_msg);		exit(1);	}	if(write(pfkey_sock, pfkey_msg,		 pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) !=	   (ssize_t)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)) {		/* cleanup code here */		fprintf(stderr, "%s: Trouble writing to channel PF_KEY.\n", progname);		pfkey_extensions_free(extensions);		pfkey_msg_free(&pfkey_msg);		exit(1);	}	pfkey_extensions_free(extensions);	pfkey_msg_free(&pfkey_msg);}int dienow;void controlC(int foo){	fflush(stdout);	printf("%s: Exiting on signal 15\n", progname);	fflush(stderr);	exit(0);}intmain(int argc, char *argv[]){	int opt;	ssize_t readlen;	unsigned char pfkey_buf[256];	struct sadb_msg *msg;	int fork_after_register;	char *pidfilename;	char *infilename;	char *outfilename;	static int ah_register;	static int esp_register;	static int ipip_register;	static int ipcomp_register;	static struct option long_options[] =	{		{"help",        no_argument, 0, 'h'},		{"daemon",      required_argument, 0, 'f'},		{"dumpfile",    required_argument, 0, 'd'},		{"encodefile",  required_argument, 0, 'e'},		{"ah",          no_argument, &ah_register, 1},		{"esp",         no_argument, &esp_register, 1},		{"ipip",        no_argument, &ipip_register, 1},		{"ipcomp",      no_argument, &ipcomp_register, 1},	};	ah_register   = 0;	esp_register  = 0;	ipip_register = 0;	ipcomp_register=0;	dienow = 0;	fork_after_register=0;	pidfilename = NULL;	infilename  = NULL;	outfilename = NULL;		progname = argv[0];	if(strrchr(progname, '/')) {		progname=strrchr(progname, '/')+1;	}		while((opt = getopt_long(argc, argv, "hd:e:f:",				 long_options, NULL)) !=  EOF) {		switch(opt) {		case 'f':			pidfilename=optarg;			fork_after_register=1;			break;		case 'd':			infilename = optarg;			break;					case 'e':			outfilename = optarg;			break;					case 'h':			Usage(progname);			break;		case '0':			/* it was a long option with a flag */			break;		}	}	if(infilename  == NULL &&	   outfilename == NULL)	{		if((pfkey_sock = socket(PF_KEY, SOCK_RAW, PF_KEY_V2) ) < 0)		{			fprintf(stderr, "%s: failed to open PF_KEY family socket: %s\n",				progname, strerror(errno));			exit(1);		}		if(ah_register == 0 &&		   esp_register== 0 &&		   ipip_register==0 &&		   ipcomp_register==0) {			ah_register=1;			esp_register=1;			ipip_register=1;			ipcomp_register=1;		}				if(ah_register) {			pfkey_register(SADB_SATYPE_AH);		}		if(esp_register) {			pfkey_register(SADB_SATYPE_ESP);		}		if(ipip_register) {			pfkey_register(SADB_X_SATYPE_IPIP);		}		if(ipcomp_register) {			pfkey_register(SADB_X_SATYPE_COMP);		}		if(fork_after_register) {			/*			 * to aid in regression testing, we offer to register 			 * everything first, and then we fork. As part of this			 * we write the PID of the new process to a file			 * provided.			 */			int pid;			FILE *pidfile;						fflush(stdout);			fflush(stderr);						pid=fork();			if(pid!=0) {				/* in parent! */				exit(0);			}						if((pidfile=fopen(pidfilename, "w"))==NULL) {				perror(pidfilename);			} else {				fprintf(pidfile, "%d", getpid());				fclose(pidfile);			}		}	} else if(infilename != NULL) {		pfkey_sock = open(infilename, O_RDONLY);		if(pfkey_sock < 0) {			fprintf(stderr, "%s: failed to open %s: %s\n",				progname, infilename, strerror(errno));			exit(1);		}	} else if(outfilename != NULL) {		/* call encoder */		exit(1);	}				signal(SIGINT,  controlC);	signal(SIGTERM, controlC);	while((readlen = read(pfkey_sock, pfkey_buf, sizeof(pfkey_buf))) > 0) {		msg = (struct sadb_msg *)pfkey_buf;				/* first, see if we got enough for an sadb_msg */		if((size_t)readlen < sizeof(struct sadb_msg)) {			printf("%s: runt packet of size: %d (<%lu)\n",			       progname, (int)readlen, (unsigned long)sizeof(struct sadb_msg));			continue;		}				/* okay, we got enough for a message, print it out */		printf("\npfkey v%d msg. type=%d(%s) seq=%d len=%d pid=%d errno=%d satype=%d(%s)\n",		       msg->sadb_msg_version,		       msg->sadb_msg_type,		       pfkey_v2_sadb_type_string(msg->sadb_msg_type),		       msg->sadb_msg_seq,		       msg->sadb_msg_len,		       msg->sadb_msg_pid,		       msg->sadb_msg_errno,		       msg->sadb_msg_satype,		       satype2name(msg->sadb_msg_satype));				if((size_t)readlen != msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)		{			printf("%s: packet size read from socket=%d doesn't equal sadb_msg_len %d * %u; message not decoded\n",			       progname,			       (int) readlen, 			       msg->sadb_msg_len,			       (int) IPSEC_PFKEYv2_ALIGN);			continue;		}		pfkey_print(msg, stdout);	}	printf("%s: exited normally\n", progname);	exit(0);}	/* * $Log: pf_key.c,v $ * Revision 1.18  2004/04/04 01:50:56  ken * Use openswan includes * * Revision 1.17  2003/11/07 01:36:55  ken * Cast to (int) for readlen * * Revision 1.16  2003/10/31 02:33:00  mcr * 	new printing routines for pf_key. * * Revision 1.15.2.1  2003/10/29 01:38:21  mcr * 	use new pfkey printer. * * Revision 1.15  2003/09/10 00:01:30  mcr * 	fixes for gcc 3.3 from Matthias Bethke <Matthias.Bethke@gmx.net> * * Revision 1.14  2002/10/09 03:12:05  dhr * * [kenb+dhr] 64-bit fixes * * Revision 1.13  2002/09/20 05:02:15  rgb * Cleaned up pfkey_lib_debug usage. * * Revision 1.12  2002/09/13 23:02:23  rgb * Type fiddling to tame ia64 compiler. * Added text labels to elucidate numeric values presented. * * Revision 1.11  2002/08/26 03:05:25  mcr * 	duh, pf_key much catch SIGTERM as well as SIGINT... * * Revision 1.10  2002/08/13 19:01:27  mcr * 	patches from kenb to permit compilation of FreeSWAN on ia64. * 	des library patched to use proper DES_LONG type for ia64. * * Revision 1.9  2002/07/16 02:53:42  mcr * 	added --daemon <pidfile> to "ipsec pf_key" command. * 	this is used in *-trap-* tests to avoid race conditions between * 	registration of PF_KEY listeners and arrival of first test packet. * * Revision 1.8  2002/06/17 04:32:55  mcr * 	exit nicely from pf_key when SIGINT (^C) is sent. * 	This is needed so that the stdout will flush properly. * * Revision 1.7  2002/04/24 07:55:32  mcr * 	#include patches and Makefiles for post-reorg compilation. * * Revision 1.6  2002/04/24 07:35:39  mcr * Moved from ./klips/utils/pf_key.c,v * * Revision 1.5  2002/03/08 21:44:04  rgb * Update for all GNU-compliant --version strings. * * Revision 1.4  2001/11/27 05:19:06  mcr * 	added extra newline between packets. * 	set pfkey_lib_debug to enum rather than just to "1". * * Revision 1.3  2001/11/27 03:35:29  rgb * Added stdlib *again*. * * Revision 1.2  2001/11/23 07:23:14  mcr * 	pulled up klips2 Makefile and pf_key code. * * Revision 1.1.2.5  2001/10/23 18:49:12  mcr * 	renamed man page to section 8. * 	added --ah, --esp, --ipcomp and --ipip to control which * 	protocols are printed. * 	incomplete messages which include at least an sadb header are printed. * * Revision 1.1.2.4  2001/10/22 21:50:51  rgb * Added pfkey register for AH, ESP, IPIP and COMP. * * Revision 1.1.2.3  2001/10/21 21:51:06  rgb * Bug fixes to get working. * * Revision 1.1.2.2  2001/10/20 22:45:31  rgb * Added check for exact length and a call to message parser to get some * idea of the contents of each extension. * * Revision 1.1.2.1  2001/10/17 23:25:37  mcr * 	added "pk_key" program to dump raw kernel pf messages. * 	(program is still skeletal) * * * Local variables: * c-file-style: "linux" * End: * */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -