eroute.c

来自「ipsec vpn」· C语言 代码 · 共 1,018 行 · 第 1/3 页

C
1,018
字号
				fprintf(stderr, "%s: Error, --dst parameter redefined:%s, already defined as:%s\n",					program_name, optarg, dst_opt);				exit (1);			}							error_s = ttosubnet(optarg, 0, eroute_af, &d_subnet);			if (error_s != NULL) {				fprintf(stderr, "%s: Error, %s converting --dst argument: %s\n",					program_name, error_s, optarg);				exit (1);			}			dst_opt = optarg;			break;		case 'S':			if(src_opt) {				fprintf(stderr, "%s: Error, --src parameter redefined:%s, already defined as:%s\n",					program_name, optarg, src_opt);				exit (1);			}							error_s = ttosubnet(optarg, 0, eroute_af, &s_subnet);			if (error_s != NULL) {				fprintf(stderr, "%s: Error, %s converting --src argument: %s\n",					program_name, error_s, optarg);				exit (1);			}			src_opt = optarg;			break;		case 'P':			if (transport_proto_opt) {				fprintf(stderr, "%s: Error, --transport-proto"					" paramter redefined:%s, "					"already defined as:%s\n",					program_name, optarg,					transport_proto_opt);				exit(1);			}			transport_proto_opt = optarg;			break;		case 'Q':			if (src_port_opt) {				fprintf(stderr, "%s: Error, --src-port"					" parameter redefined:%s, "					"already defined as:%s\n",					program_name, optarg, src_port_opt);				exit(1);			}			src_port_opt = optarg;			break;		case 'R':			if (dst_port_opt) {				fprintf(stderr, "%s: Error, --dst-port"					" parameter redefined:%s, "					"already defined as:%s\n",					program_name, optarg, dst_port_opt);				exit(1);			}			dst_port_opt = optarg;			break;		case 'l':			program_name = malloc(strlen(argv[0])					      + 10 /* update this when changing the sprintf() */					      + strlen(optarg));			sprintf(program_name, "%s --label %s",				argv[0],				optarg);			argcount -= 2;			break;		case 'i': /* specifies the address family of the SAID, stored in said_af */			if(said_af_opt) {				fprintf(stderr, "%s: Error, address family of SAID redefined:%s, already defined as:%s\n",					program_name, optarg, said_af_opt);				exit (1);			}							if(!strcmp(optarg, "inet"))				said_af = AF_INET;			if(!strcmp(optarg, "inet6"))				said_af = AF_INET6;			if(said_af == 0) {				fprintf(stderr, "%s: Invalid address family parameter for SAID: %s\n",					program_name, optarg);				exit (1);			}			said_af_opt = optarg;			break;		case 'f': /* specifies the address family of the eroute, stored in eroute_af */			if(eroute_af_opt) {				fprintf(stderr, "%s: Error, address family of eroute redefined:%s, already defined as:%s\n",					program_name, optarg, eroute_af_opt);				exit (1);			}							if(!strcmp(optarg, "inet"))				eroute_af = AF_INET;			if(!strcmp(optarg, "inet6"))				eroute_af = AF_INET6;			if(eroute_af == 0) {				fprintf(stderr, "%s: Invalid address family parameter for eroute: %s\n",					program_name, optarg);				exit (1);			}			eroute_af_opt = optarg;			break;		case '+': /* optionsfrom */			optionsfrom(optarg, &argc, &argv, optind, stderr);			/* no return on error */			break;		default:			break;		}		previous = c;	}	if(debug) {		fprintf(stdout, "%s: DEBUG: argc=%d\n", program_name, argc);	}	        if(argcount == 1) {                struct stat sts;                if ( ((stat ("/proc/net/pfkey", &sts)) == 0) )  {                         fprintf(stderr, "%s: NETKEY does not support eroute table.\n",program_name);                        exit(1);                }                else {			int ret = 1;			if ((stat ("/proc/net/ipsec_eroute", &sts)) != 0)  {				fprintf(stderr, "%s: No eroute table - no IPsec support in kernel (are the modules loaded?)\n", program_name);			} else {				int ret = system("cat /proc/net/ipsec_eroute");				ret = ret != -1 && WIFEXITED(ret) ? WEXITSTATUS(ret) : 1;			}			exit(ret);                }        }		/* Sanity checks */	if(debug) {		fprintf(stdout, "%s: DEBUG: action_type=%d\n", program_name, action_type);	}	if (transport_proto_opt != 0) {	     struct protoent * proto = getprotobyname(transport_proto_opt);	     if (proto != 0) {		  transport_proto = proto->p_proto;	     } else {		  transport_proto = strtoul(transport_proto_opt, &endptr, 0);		  if ((*endptr != '\0') 		      || (transport_proto == 0 && endptr == transport_proto_opt)) {		       fprintf(stderr, "%s: Invalid character in --transport-proto parameter: %s\n",			       program_name, transport_proto_opt);		       exit (1);		  }		  if (transport_proto > 255) {		       fprintf(stderr, "%s: --transport-proto parameter: %s must be in the range 0 to 255 inclusive\n",			       program_name, transport_proto_opt);		       exit (1);		  }	     }	}        if (src_port_opt != 0 || dst_port_opt != 0) {		switch (transport_proto) {		case IPPROTO_UDP:		case IPPROTO_TCP:			break;		default:			fprintf(stderr, "%s: --transport-proto with either UDP or TCP must be specified if --src-port or --dst-port is used\n", program_name);			exit(1);		}        }	if (src_port_opt) {	     struct servent * ent = getservbyname(src_port_opt, 0);	     if (ent != 0) {		  src_port = ent->s_port;	     } else {		  src_port = strtoul(src_port_opt, &endptr, 0);		  if ((*endptr != '\0')		      || (src_port == 0 && endptr == src_port_opt)) {		       fprintf(stderr, "%s: Invalid character in --src-port parameter: %s\n",			       program_name, src_port_opt);		       exit (1);		  }		  if (src_port > 65535) {		       fprintf(stderr, "%s: --src-port parameter: %s must be in the range 0 to 65535 inclusive\n",			       program_name, src_port_opt);		  }		  src_port = htons(src_port);	     }	}	if (dst_port_opt) {	     struct servent * ent = getservbyname(dst_port_opt, 0);	     if (ent != 0) {		  dst_port = ent->s_port;	     } else {		  dst_port = strtoul(dst_port_opt, &endptr, 0);		  if ((*endptr != '\0')		      || (dst_port == 0 && endptr == dst_port_opt)) {		       fprintf(stderr, "%s: Invalid character in --dst-port parameter: %s\n",			       program_name, dst_port_opt);		       exit (1);		  }		  if (dst_port > 65535) {		       fprintf(stderr, "%s: --dst-port parameter: %s must be in the range 0 to 65535 inclusive\n",			       program_name, dst_port_opt);		  }		  dst_port = htons(dst_port);	     }	}	switch(action_type) {	case EMT_SETEROUTE:	case EMT_REPLACEROUTE:	case EMT_INEROUTE:		if(!(said_af_opt && edst_opt && spi_opt && proto_opt) && !(said_opt)) {			fprintf(stderr, "%s: add and addin options must have SA specified.\n",				program_name);			exit(1);		}	case EMT_DELEROUTE:		if(!src_opt) {			fprintf(stderr, "%s: Error -- %s option '--src' is required.\n",				program_name, (action_type == EMT_SETEROUTE) ? "add" : "del");			exit(1);		}		if(!dst_opt) {			fprintf(stderr, "%s: Error -- %s option '--dst' is required.\n",				program_name, (action_type == EMT_SETEROUTE) ? "add" : "del");			exit(1);		}	case EMT_CLREROUTE:		break;	default:		fprintf(stderr, "%s: exactly one of '--add', '--addin', '--replace', '--del' or '--clear' options must be specified.\n"			"Try %s --help' for usage information.\n",			program_name, program_name);		exit(1);	}	if((pfkey_sock = socket(PF_KEY, SOCK_RAW, PF_KEY_V2) ) < 0) {		fprintf(stderr, "%s: Trouble opening PF_KEY family socket with error: ",			program_name);		switch(errno) {		case ENOENT:			fprintf(stderr, "device does not exist.  See FreeS/WAN installation procedure.\n");			break;		case EACCES:			fprintf(stderr, "access denied.  ");			if(getuid() == 0) {				fprintf(stderr, "Check permissions.  Should be 600.\n");			} else {				fprintf(stderr, "You must be root to open this file.\n");			}			break;		case EUNATCH:			fprintf(stderr, "KLIPS not loaded.\n");			break;		case ENODEV:			fprintf(stderr, "KLIPS not loaded or enabled.\n");			break;		case EBUSY:			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");			break;		case EINVAL:			fprintf(stderr, "Invalid argument, KLIPS not loaded or check kernel log messages for specifics.\n");			break;		case ENOBUFS:		case ENOMEM:		case ENFILE:			fprintf(stderr, "No kernel memory to allocate socket.\n");			break;		case EMFILE:			fprintf(stderr, "Process file table overflow.\n");			break;		case ESOCKTNOSUPPORT:			fprintf(stderr, "Socket type not supported.\n");			break;		case EPROTONOSUPPORT:			fprintf(stderr, "Protocol version not supported.\n");			break;		case EAFNOSUPPORT:			fprintf(stderr, "KLIPS not loaded or enabled.\n");			break;		default:			fprintf(stderr, "Unknown file open error %d.  Please report as much detail as possible to development team.\n", errno);		}		exit(1);	}	if(debug) {		fprintf(stdout, "%s: DEBUG: PFKEYv2 socket successfully openned=%d.\n", program_name, pfkey_sock);	}	/* Build an SADB_X_ADDFLOW or SADB_X_DELFLOW message to send down. */	/* It needs <base, SA, address(SD), flow(SD), mask(SD)> minimum. */	pfkey_extensions_init(extensions);	if((error = pfkey_msg_hdr_build(&extensions[0],					(action_type == EMT_SETEROUTE					 || action_type == EMT_REPLACEROUTE					 || action_type == EMT_INEROUTE)					? SADB_X_ADDFLOW : SADB_X_DELFLOW,					proto2satype(said.proto),					0,					++pfkey_seq,					getpid()))) {		fprintf(stderr, "%s: Trouble building message header, error=%d.\n",			program_name, error);		pfkey_extensions_free(extensions);		exit(1);	}	if(debug) {		fprintf(stdout, "%s: DEBUG: pfkey_msg_hdr_build successfull.\n", program_name);	}	switch(action_type) {	case EMT_SETEROUTE:	case EMT_REPLACEROUTE:	case EMT_INEROUTE:	case EMT_CLREROUTE:		if((error = pfkey_sa_build(&extensions[SADB_EXT_SA],					   SADB_EXT_SA,					   said.spi, /* in network order */					   0,					   0,					   0,					   0,					   (action_type == EMT_CLREROUTE) ? SADB_X_SAFLAGS_CLEARFLOW : 0))) {			fprintf(stderr, "%s: Trouble building sa extension, error=%d.\n",				program_name, error);			pfkey_extensions_free(extensions);			exit(1);		}		if(debug) {			fprintf(stdout, "%s: DEBUG: pfkey_sa_build successful.\n", program_name);		}	default:		break;

⌨️ 快捷键说明

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