Exemple #1
0
err_t ipsec_policy_init(void)
{
  struct sockaddr_un sn;

  if(policy_query_socket != -1) {
    return NULL;
  }

  policy_query_socket = safe_socket(PF_UNIX, SOCK_STREAM, 0);
  if(policy_query_socket == -1) {
    return "failed to open policy socket";
  }

  /* now connect it */
  sn.sun_family = AF_UNIX;
  strcpy(sn.sun_path, IPSEC_POLICY_SOCKET);
  
  if(connect(policy_query_socket, (struct sockaddr *)&sn, sizeof(sn)) != 0) {
    int saveerrno = errno;
    close(policy_query_socket);
    policy_query_socket=-1;
    errno = saveerrno;
    return "failed to connect policy socket";
  }

  /* okay, I think we are done */
  return NULL;
}
Exemple #2
0
int open_udp_sock(unsigned short port)
{
	struct sockaddr_in s;
	int one;
	int fd;

	fd = safe_socket(PF_INET, SOCK_DGRAM, 0);
	if(fd == -1) {
		perror("socket");
		exit(10);
	}

	memset(&s, 0, sizeof(struct sockaddr_in));
	s.sin_family = AF_INET;
	s.sin_port   = htons(port);
	s.sin_addr.s_addr = INADDR_ANY;

	if(bind(fd, (struct sockaddr *)&s, sizeof(struct sockaddr_in))==-1) {
		perror("bind");
		exit(11);
	}

	one = 1;

#if !(defined(macintosh) || (defined(__MACH__) && defined(__APPLE__)))
	if(setsockopt(fd, SOL_IP, IP_IPSEC_REFINFO, &one, sizeof(one)) != 0) {
		perror("setsockopt recvref");
		exit(12);
	}
#endif
	return fd;
}
Exemple #3
0
int starter_ifaces_load (char **ifaces, unsigned int omtu, int nat_t)
{
	char *tmp_phys, *phys;
	unsigned int n;
	char **i;
	int sock;
	int j, found;
	int ret = 0;

	starter_log(LOG_LEVEL_DEBUG, "starter_ifaces_load()");

	sock = safe_socket(AF_INET, SOCK_DGRAM, 0);
	if (sock < 0) return -1;

	for (j=0; j<N_IPSEC_IF; j++) {
		found = 0;
		for (i=ifaces; i && *i; i++) {
			if ((valid_str(*i, &n, &tmp_phys)) && (tmp_phys) &&
			(n>=0) && (n<N_IPSEC_IF)) {
				if (n==j) {
					if (found) {
						starter_log(LOG_LEVEL_ERR,
							"ignoring duplicate entry for interface ipsec%d",
							j);
					}
					else {
						found++;
						phys = starter_find_physical_iface(sock, tmp_phys);
						if (phys) {
							ret += _iface_up (sock, &(_ipsec_if[n]), phys,
								omtu, nat_t);
						}
						else {
							ret += _iface_down (sock, &(_ipsec_if[n]));
						}
					}
				}
			}
			else if (j==0) {
				/**
				 * Only log in the first loop
				 */
				starter_log(LOG_LEVEL_ERR, "ignoring invalid interface '%s'",
					*i);
			}
		}
		if (!found)
			ret += _iface_down (sock, &(_ipsec_if[j]));
	}

	close(sock);
	return ret; /* = number of changes - 'whack --listen' if > 0 */
}
Exemple #4
0
void starter_ifaces_clear (void)
{
	int sock;
	unsigned int i;

	sock = safe_socket(AF_INET, SOCK_DGRAM, 0);
	if (sock < 0) return;

	for (i=0; i<N_IPSEC_IF; i++) {
		_iface_down (sock, &(_ipsec_if[i]));
	}
}
Exemple #5
0
int starter_iface_find(char *iface, int af, ip_address *dst, ip_address *nh)
{
	char *phys;
	struct ifreq req;
	struct sockaddr_in *sa = (struct sockaddr_in *)(&req.ifr_addr);
	int sock;

	if (!iface) return -1;

	sock = safe_socket(af, SOCK_DGRAM, 0);
	if (sock < 0) return -1;

	phys = starter_find_physical_iface(sock, iface);
	if (!phys) goto failed;

	strncpy(req.ifr_name, phys, IFNAMSIZ);
	if (ioctl(sock, SIOCGIFFLAGS, &req)!=0) goto failed;
	if (!(req.ifr_flags & IFF_UP)) goto failed;

	if ((req.ifr_flags & IFF_POINTOPOINT) && (nh) &&
		(ioctl(sock, SIOCGIFDSTADDR, &req)==0)) {
		if (sa->sin_family == af) {
			initaddr((const void *)&sa->sin_addr,
				sizeof(struct in_addr), af, nh);
		}
	}
	if ((dst) && (ioctl(sock, SIOCGIFADDR, &req)==0)) {
		if (sa->sin_family == af) {
			initaddr((const void *)&sa->sin_addr,
				sizeof(struct in_addr), af, dst);
		}
	}
	close(sock);
	return 0;

failed:
	close(sock);
	return -1;
}
Exemple #6
0
/*******************************************************************************
函数名称: init_ws_ctl_socket
功能描述: 初始化web_services control套接字
输入参数:                          
输出参数: 无
返 回 值    :  err_t:返回错误信息,成功返回NULL
--------------------------------------------------------------------------------
最近一次修改记录 :
修改作者: tiangu        
修改目的: 创建新函数
修改日期: 2010-4-20
*******************************************************************************/
err_t init_ws_ctl_socket(void)
{
   err_t failed = NULL;

    delete_ws_ctl_socket();	/* preventative medicine */
    ws_ctl_fd = safe_socket(AF_UNIX, SOCK_STREAM, 0);
    int size = offsetof(struct sockaddr_un, sun_path) + strlen(ws_ctl_addr.sun_path);

    if (ws_ctl_fd == -1)
	{
	    failed = "create";    
    }
    else if (setsockopt(ws_ctl_fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof(on)) < 0)
    {
        failed = "setsockopt";
    }
    else
    {	   
	    mode_t ou = umask(0);
    
    	if (bind(ws_ctl_fd, (struct sockaddr *)&ws_ctl_addr, size) < 0)
    	{
    	    failed = "bind";
        }
        
	    umask(ou);
    }

   
    if (failed == NULL && listen(ws_ctl_fd, 5) < 0)
    {
        failed = "listen() on";
    }
    
    return failed == NULL? NULL : builddiag("could not %s ws_ctl socket: %d %s"
	    , failed, errno, strerror(errno));
    
}
Exemple #7
0
int main(int argc, char **argv)
{
	struct sockaddr_in from, to, in;
	char buf[TESTLEN];
	char *destip = DESTIP;
	int port = DEF_PORT;
	int n, server_socket, client_socket, fl, tl, pid;

	if (argc > 1) destip = argv[1];
	if (argc > 2) port = atoi(argv[2]);

	in.sin_family = AF_INET;
#ifdef NEED_SIN_LEN
	in.sin_len = sizeof( struct sockaddr_in );
#endif
	in.sin_addr.s_addr = INADDR_ANY;
	in.sin_port = htons(port);
	fl = tl = sizeof(struct sockaddr_in);
	memset(&from, 0, sizeof(from));
	memset(&to,   0, sizeof(to));

	switch(pid = fork()) {
		case -1:
			perror("fork");
			return 0;
		case 0:
			/* child */
			usleep(100000);
			goto client;
	}

	/* parent: server */
	server_socket = safe_socket(PF_INET, SOCK_DGRAM, 0);
	if (udpfromto_init(server_socket) != 0) {
		perror("udpfromto_init\n");
		waitpid(pid, NULL, WNOHANG);
		return 0;
	}

	if (bind(server_socket, (struct sockaddr *)&in, sizeof(in)) < 0) {
		perror("server: bind");
		waitpid(pid, NULL, WNOHANG);
		return 0;
	}

	printf("server: waiting for packets on INADDR_ANY:%d\n", port);
	if ((n = recvfromto(server_socket, buf, sizeof(buf), 0,
	    (struct sockaddr *)&from, &fl,
	    (struct sockaddr *)&to, &tl)) < 0) {
		perror("server: recvfromto");
		waitpid(pid, NULL, WNOHANG);
		return 0;
	}

	printf("server: received a packet of %d bytes [%s] ", n, buf);
	printf("(src ip:port %s:%d ",
		inet_ntoa(from.sin_addr), ntohs(from.sin_port));
	printf(" dst ip:port %s:%d)\n",
		inet_ntoa(to.sin_addr), ntohs(to.sin_port));

	printf("server: replying from address packet was received on to source address\n");

	if ((n = sendfromto(server_socket, buf, n, 0,
		(struct sockaddr *)&to, tl,
		(struct sockaddr *)&from, fl)) < 0) {
		perror("server: sendfromto");
	}

	waitpid(pid, NULL, 0);
	return 0;

client:
	close(server_socket);
	client_socket = safe_socket(PF_INET, SOCK_DGRAM, 0);
	if (udpfromto_init(client_socket) != 0) {
		perror("udpfromto_init");
		_exit(0);
	}
	/* bind client on different port */
	in.sin_port = htons(port+1);
	if (bind(client_socket, (struct sockaddr *)&in, sizeof(in)) < 0) {
		perror("client: bind");
		_exit(0);
	}

	in.sin_port = htons(port);
	in.sin_addr.s_addr = inet_addr(destip);

	printf("client: sending packet to %s:%d\n", destip, port);
	if (sendto(client_socket, TESTSTRING, TESTLEN, 0,
			(struct sockaddr *)&in, sizeof(in)) < 0) {
		perror("client: sendto");
		_exit(0);
	}

	printf("client: waiting for reply from server on INADDR_ANY:%d\n", port+1);

	if ((n = recvfromto(client_socket, buf, sizeof(buf), 0,
	    (struct sockaddr *)&from, &fl,
	    (struct sockaddr *)&to, &tl)) < 0) {
		perror("client: recvfromto");
		_exit(0);
	}

	printf("client: received a packet of %d bytes [%s] ", n, buf);
	printf("(src ip:port %s:%d",
		inet_ntoa(from.sin_addr), ntohs(from.sin_port));
	printf(" dst ip:port %s:%d)\n",
		inet_ntoa(to.sin_addr), ntohs(to.sin_port));

	_exit(0);
}
Exemple #8
0
int main(int argc, char *argv[])
{
	struct ifreq ifr;

	zero(&ifr);
	program_name = argv[0];

	s = safe_socket(AF_INET, SOCK_DGRAM, 0);
	if (s == -1) {
		fprintf(stderr, "%s: Socket creation failed:%s ",
			program_name, strerror(errno));
		exit(1);
	}

	/* if (ioctl(fd, SIOCDEVPRIVATE, &ifr) >= 0) { */

	if (ioctl(s, shc->cf_cmd, &ifr) == -1) {
		if (shc->cf_cmd == IPSEC_SET_DEV) {
			fprintf(stderr,
				"%s: Socket ioctl failed on attach -- ",
				program_name);
			switch (errno) {
			case EINVAL:
				fprintf(stderr,
					"Invalid argument, check kernel log messages for specifics.\n");
				break;
			case ENODEV:
				fprintf(stderr,
					"No such device.  Is the virtual device valid?  Is the ipsec module linked into the kernel or loaded as a module?\n");
				break;
			case ENXIO:
				fprintf(stderr,
					"No such device.  Is the physical device valid?\n");
				break;
			case EBUSY:
				fprintf(stderr,
					"Device busy.  Virtual device %s is already attached to a physical device -- Use detach first.\n",
					ifr.ifr_name);
				break;
			default:
				fprintf(stderr, "Unknown socket error %d.\n",
					errno);
			}
			exit(1);
		}
		if (shc->cf_cmd == IPSEC_DEL_DEV) {
			fprintf(stderr,
				"%s: Socket ioctl failed on detach -- ",
				program_name);
			switch (errno) {
			case EINVAL:
				fprintf(stderr,
					"Invalid argument, check kernel log messages for specifics.\n");
				break;
			case ENODEV:
				fprintf(stderr,
					"No such device.  Is the virtual device valid?  The ipsec module may not be linked into the kernel or loaded as a module.\n");
				break;
			case ENXIO:
				fprintf(stderr,
					"Device requested is not linked to any physical device.\n");
				break;
			default:
				fprintf(stderr, "Unknown socket error %d.\n",
					errno);
			}
			exit(1);
		}
		if (shc->cf_cmd == IPSEC_CLR_DEV) {
			fprintf(stderr, "%s: Socket ioctl failed on clear -- ",
				program_name);
			switch (errno) {
			case EINVAL:
				fprintf(stderr,
					"Invalid argument, check kernel log messages for specifics.\n");
				break;
			case ENODEV:
				fprintf(stderr,
					"Failed.  Is the ipsec module linked into the kernel or loaded as a module?.\n");
				break;
			default:
				fprintf(stderr, "Unknown socket error %d.\n",
					errno);
			}
			exit(1);
		}
	}
	exit(0);
}
Exemple #9
0
int main(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();
			break;
		case '0':
			/* it was a long option with a flag */
			break;
		}
	}

	if (infilename  == NULL &&
	    outfilename == NULL) {
		if ((pfkey_sock =
			     safe_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(K_SADB_SATYPE_AH);
		if (esp_register)
			pfkey_register(K_SADB_SATYPE_ESP);
		if (ipip_register)
			pfkey_register(K_SADB_X_SATYPE_IPIP);
		if (ipcomp_register)
			pfkey_register(K_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);
}
Exemple #10
0
struct raw_iface *
find_raw_ifaces4(void)
{
    static const int on = TRUE;	/* by-reference parameter; constant, we hope */
    int j;	/* index into buf */
    static int    num=64;    /* number of interfaces */
    struct ifconf ifconf;
    struct ifreq *buf;	     /* for list of interfaces -- arbitrary limit */
    struct raw_iface *rifaces = NULL;
    int master_sock = safe_socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);    /* Get a UDP socket */

    /* get list of interfaces with assigned IPv4 addresses from system */

    if (master_sock == -1)
	exit_log_errno((e, "socket() failed in find_raw_ifaces4()"));

    if (setsockopt(master_sock, SOL_SOCKET, SO_REUSEADDR
		   , (const void *)&on, sizeof(on)) < 0)
	    exit_log_errno((e, "setsockopt() in find_raw_ifaces4()"));

    /* bind the socket */
    {
	ip_address any;

	happy(anyaddr(AF_INET, &any));
	setportof(htons(pluto_port), &any);
	if (bind(master_sock, sockaddrof(&any), sockaddrlenof(&any)) < 0)
	    exit_log_errno((e, "bind() failed in find_raw_ifaces4()"));
    }

    buf = NULL;
   
    /* a million interfaces is probably the maximum, ever... */
    while(num < (1024*1024)) {
	    /* Get local interfaces.  See netdevice(7). */
	    ifconf.ifc_len = num * sizeof(struct ifreq);
	    buf = (void *) realloc(buf, ifconf.ifc_len);
	    if (!buf)
		    exit_log_errno((e, "realloc of %d in find_raw_ifaces4()",
				    ifconf.ifc_len));
	    memset(buf, 0, num*sizeof(struct ifreq));
	    ifconf.ifc_buf = (void *) buf;
	    
	    if (ioctl(master_sock, SIOCGIFCONF, &ifconf) == -1)
		    exit_log_errno((e, "ioctl(SIOCGIFCONF) in find_raw_ifaces4()"));
	    
	    /* if we got back less than we asked for, we have them all */
	    if (ifconf.ifc_len < (int)(sizeof(struct ifreq) * num))
		    break;
	    
	    /* try again and ask for more this time */
	    num *= 2;
    }
  
    /* Add an entry to rifaces for each interesting interface. */
    for (j = 0; (j+1) * sizeof(struct ifreq) <= (size_t)ifconf.ifc_len; j++)
    {
	struct raw_iface ri;
	const struct sockaddr_in *rs = (struct sockaddr_in *) &buf[j].ifr_addr;
	struct ifreq auxinfo;

	/* ignore all but AF_INET interfaces */
	if (rs->sin_family != AF_INET)
	    continue;	/* not interesting */

	/* build a NUL-terminated copy of the rname field */
	memcpy(ri.name, buf[j].ifr_name, IFNAMSIZ);
	ri.name[IFNAMSIZ] = '\0';

	/* ignore if our interface names were specified, and this isn't one */
	if (pluto_ifn_roof != 0)
	{
	    int i;

	    for (i = 0; i != pluto_ifn_roof; i++)
		if (streq(ri.name, pluto_ifn[i]))
		    break;
	    if (i == pluto_ifn_roof)
		continue;	/* not found -- skip */
	}

	/* Find out stuff about this interface.  See netdevice(7). */
	zero(&auxinfo);	/* paranoia */
	memcpy(auxinfo.ifr_name, buf[j].ifr_name, IFNAMSIZ);
	if (ioctl(master_sock, SIOCGIFFLAGS, &auxinfo) == -1)
	    exit_log_errno((e
		, "ioctl(SIOCGIFFLAGS) for %s in find_raw_ifaces4()"
		, ri.name));
	if (!(auxinfo.ifr_flags & IFF_UP))
	   {
		DBG(DBG_CONTROL, DBG_log("Ignored interface %s - it is not up"
	    , ri.name));
	    continue;	/* ignore an interface that isn't UP */
	   }
        if (auxinfo.ifr_flags & IFF_SLAVE)
	   {
		DBG(DBG_CONTROL, DBG_log("Ignored interface %s - it is a slave interface"
	    , ri.name));
            continue;   /* ignore slave interfaces; they share IPs with their master */
	   }

	/* ignore unconfigured interfaces */
	if (rs->sin_addr.s_addr == 0)
	   {
		DBG(DBG_CONTROL, DBG_log("Ignored interface %s - it is unconfigured"
	    , ri.name));
	    continue;
	   }

	happy(initaddr((const void *)&rs->sin_addr, sizeof(struct in_addr)
	    , AF_INET, &ri.addr));

	DBG(DBG_CONTROL, DBG_log("found %s with address %s"
	    , ri.name, ip_str(&ri.addr)));
	ri.next = rifaces;
	rifaces = clone_thing(ri, "struct raw_iface");
    }

    close(master_sock);

    return rifaces;
}
Exemple #11
0
int
main(int argc, char **argv)
{
/*	int fd; */
	unsigned char action = 0;
	int c;
	
	int error = 0;
	int argcount = argc;
	int em_db_tn, em_db_nl, em_db_xf, em_db_er, em_db_sp;
	int em_db_rj, em_db_es, em_db_ah, em_db_rx, em_db_ky;
	int em_db_gz, em_db_vb;

	struct sadb_ext *extensions[K_SADB_EXT_MAX + 1];
	struct sadb_msg *pfkey_msg;
	
	em_db_tn=em_db_nl=em_db_xf=em_db_er=em_db_sp=0;
	em_db_rj=em_db_es=em_db_ah=em_db_rx=em_db_ky=0;
	em_db_gz=em_db_vb=0;


	program_name = argv[0];

	while((c = getopt_long(argc, argv, ""/*"s:c:anhvl:+:d"*/, longopts, 0)) != EOF) {
		switch(c) {
		case 'd':
			pfkey_lib_debug = PF_KEY_DEBUG_PARSE_MAX;
			argcount--;
			break;
		case 's':
			if(action) {
				fprintf(stderr, "%s: Only one of '--set', '--clear', '--all' or '--none' options permitted.\n",
					program_name);
				exit(1);
			}
			action = 's';
			em_db_tn=em_db_nl=em_db_xf=em_db_er=em_db_sp=0;
			em_db_rj=em_db_es=em_db_ah=em_db_rx=em_db_ky=0;
			em_db_gz=em_db_vb=0;
			if(strcmp(optarg, "all") == 0) {
				em_db_tn=em_db_nl=em_db_xf=em_db_er=em_db_sp=-1;
				em_db_rj=em_db_es=em_db_ah=em_db_rx=em_db_ky=-1;
				em_db_gz=-1;
				em_db_vb= 0;
			} else if(strcmp(optarg, "tunnel") == 0) {
				em_db_tn = -1L;
			} else if(strcmp(optarg, "tncfg") == 0) {
			        em_db_tn = DB_TN_REVEC;
			} else if(strcmp(optarg, "xmit") == 0
					|| strcmp(optarg, "tunnel-xmit") == 0) {
				em_db_tn = DB_TN_XMIT;
			} else if(strcmp(optarg, "netlink") == 0) {
				em_db_nl = -1L;
			} else if(strcmp(optarg, "xform") == 0) {
				em_db_xf = -1L;
			} else if(strcmp(optarg, "eroute") == 0) {
				em_db_er = -1L;
			} else if(strcmp(optarg, "spi") == 0) {
				em_db_sp = -1L;
			} else if(strcmp(optarg, "radij") == 0) {
				em_db_rj = -1L;
			} else if(strcmp(optarg, "esp") == 0) {
				em_db_es = -1L;
			} else if(strcmp(optarg, "ah") == 0) {
				em_db_ah = -1L;
			} else if(strcmp(optarg, "rcv") == 0) {
				em_db_rx = -1L;
			} else if(strcmp(optarg, "pfkey") == 0) {
				em_db_ky = -1L;
			} else if(strcmp(optarg, "comp") == 0) {
				em_db_gz = -1L;
			} else if(strcmp(optarg, "verbose") == 0) {
				em_db_vb = -1L;
			} else {
				fprintf(stdout, "%s: unknown set argument '%s'\n",
						program_name, optarg);
				usage(program_name);
			}
			em_db_nl |= 1 << (sizeof(em_db_nl) * 8 -1);
			break;
		case 'c':
			if(action) {
				fprintf(stderr, "%s: Only one of '--set', '--clear', '--all' or '--none' options permitted.\n",
					program_name);
				exit(1);
			}
			em_db_tn=em_db_nl=em_db_xf=em_db_er=em_db_sp=-1;
			em_db_rj=em_db_es=em_db_ah=em_db_rx=em_db_ky=-1;
			em_db_gz=em_db_vb=-1;

			action = 'c';
			if(strcmp(optarg, "all") == 0) {
				em_db_tn=em_db_nl=em_db_xf=em_db_er=em_db_sp=0;
				em_db_rj=em_db_es=em_db_ah=em_db_rx=em_db_ky=0;
				em_db_gz=em_db_vb=0;
			} else if(strcmp(optarg, "tunnel") == 0) {
				em_db_tn = 0;
			} else if(strcmp(optarg, "tunnel-xmit") == 0
				  || strcmp(optarg, "xmit") == 0) {
				em_db_tn = ~DB_TN_XMIT;
			} else if(strcmp(optarg, "netlink") == 0) {
				em_db_nl = 0;
			} else if(strcmp(optarg, "xform") == 0) {
				em_db_xf = 0;
			} else if(strcmp(optarg, "eroute") == 0) {
				em_db_er = 0;
			} else if(strcmp(optarg, "spi") == 0) {
				em_db_sp = 0;
			} else if(strcmp(optarg, "radij") == 0) {
				em_db_rj = 0;
			} else if(strcmp(optarg, "esp") == 0) {
				em_db_es = 0;
			} else if(strcmp(optarg, "ah") == 0) {
				em_db_ah = 0;
			} else if(strcmp(optarg, "rcv") == 0) {
				em_db_rx = 0;
			} else if(strcmp(optarg, "pfkey") == 0) {
				em_db_ky = 0;
			} else if(strcmp(optarg, "comp") == 0) {
				em_db_gz = 0;
			} else if(strcmp(optarg, "verbose") == 0) {
				em_db_vb = 0;
			} else {
				fprintf(stdout, "%s: unknown clear argument '%s'\n",
						program_name, optarg);
				usage(program_name);
			}
			em_db_nl &= ~(1 << (sizeof(em_db_nl) * 8 -1));
			break;
		case 'a':
			if(action) {
				fprintf(stderr, "%s: Only one of '--set', '--clear', '--all' or '--none' options permitted.\n",
					program_name);
				exit(1);
			}
			action = 'a';
			em_db_tn=em_db_nl=em_db_xf=em_db_er=em_db_sp=-1;
			em_db_rj=em_db_es=em_db_ah=em_db_rx=em_db_ky=-1;
			em_db_gz=-1;
			em_db_vb= 0;
			break;
		case 'n':
			if(action) {
				fprintf(stderr, "%s: Only one of '--set', '--clear', '--all' or '--none' options permitted.\n",
					program_name);
				exit(1);
			}
			action = 'n';
			em_db_tn=em_db_nl=em_db_xf=em_db_er=em_db_sp=0;
			em_db_rj=em_db_es=em_db_ah=em_db_rx=em_db_ky=0;
			em_db_gz=em_db_vb=0;
			break;
		case 'h':
		case '?':
			usage(program_name);
			exit(1);
		case 'v':
			fprintf(stdout, "klipsdebug (Openswan %s) \n",
				ipsec_version_code());
			fputs(copyright, stdout);
			exit(0);
		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 '+': /* optionsfrom */
			optionsfrom(optarg, &argc, &argv, optind, stderr);
			/* no return on error */
			break;
		default:
			fprintf(stdout, "%s: unknown option '%s'\n",
					program_name, argv[optind]);
			break;
		}
	}

	if(argcount == 1) {
		int ret = system("cat /proc/net/ipsec_klipsdebug");
		exit(ret != -1 && WIFEXITED(ret) ? WEXITSTATUS(ret) : 1);
	}

	if(!action) {
		usage(program_name);
	}

	if((pfkey_sock = safe_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, "Netlink not enabled OR 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:
			fprintf(stderr, "No kernel memory to allocate SA.\n");
			break;
		case ESOCKTNOSUPPORT:
			fprintf(stderr, "Algorithm support not available in the kernel.  Please compile in support.\n");
			break;
		case EEXIST:
			fprintf(stderr, "SA already in use.  Delete old one first.\n");
			break;
		case ENXIO:
			fprintf(stderr, "SA does not exist.  Cannot delete.\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);
	}

	pfkey_extensions_init(extensions);

	if((error = pfkey_msg_hdr_build(&extensions[0],
					SADB_X_DEBUG,
					0,
					0,
					++pfkey_seq,
					getpid()))) {
		fprintf(stderr, "%s: Trouble building message header, error=%d.\n",
			program_name, error);
		pfkey_extensions_free(extensions);
		exit(1);
	}
	
	if((error = pfkey_x_debug_build(&extensions[SADB_X_EXT_DEBUG],
					em_db_tn,
					em_db_nl,
					em_db_xf,
					em_db_er,
					em_db_sp,
					em_db_rj,
					em_db_es,
					em_db_ah,
					em_db_rx,
					em_db_ky,
					em_db_gz,
					em_db_vb))) {
		fprintf(stderr, "%s: Trouble building message header, error=%d.\n",
			program_name, 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",
			program_name, error);
		pfkey_extensions_free(extensions);
		pfkey_msg_free(&pfkey_msg);
		exit(1);
	}
	
	if((error = write(pfkey_sock,
			  pfkey_msg,
			  pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)) !=
	   (ssize_t)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)) {
		fprintf(stderr,
			"%s: pfkey write failed, tried to write %u octets, returning %d with errno=%d.\n",
			program_name,
			(unsigned)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN),
			error,
			errno);
		pfkey_extensions_free(extensions);
		pfkey_msg_free(&pfkey_msg);
		switch(errno) {
		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, "Netlink not enabled OR KLIPS not loaded.\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, check kernel log messages for specifics.\n");
			break;
		case ENODEV:
			fprintf(stderr, "KLIPS not loaded or enabled.\n");
			fprintf(stderr, "No device?!?\n");
			break;
		case ENOBUFS:
			fprintf(stderr, "No kernel memory to allocate SA.\n");
			break;
		case ESOCKTNOSUPPORT:
			fprintf(stderr, "Algorithm support not available in the kernel.  Please compile in support.\n");
			break;
		case EEXIST:
			fprintf(stderr, "SA already in use.  Delete old one first.\n");
			break;
		case ENOENT:
			fprintf(stderr, "device does not exist.  See FreeS/WAN installation procedure.\n");
			break;
		case ENXIO:
			fprintf(stderr, "SA does not exist.  Cannot delete.\n");
			break;
		case ENOSPC:
			fprintf(stderr, "no room in kernel SAref table.  Cannot process request.\n");
			break;
		case ESPIPE:
			fprintf(stderr, "kernel SAref table internal error.  Cannot process request.\n");
			break;
		default:
			fprintf(stderr, "Unknown socket write error %d.  Please report as much detail as possible to development team.\n", errno);
		}
		exit(1);
	}

	if(pfkey_msg) {
		pfkey_extensions_free(extensions);
		pfkey_msg_free(&pfkey_msg);
	}

	(void) close(pfkey_sock);  /* close the socket */
	exit(0);
}
struct raw_iface *find_raw_ifaces4(void)
{
	static const int on = TRUE;	/* by-reference parameter; constant, we hope */
	int j;	/* index into buf */
	struct ifconf ifconf;
	struct ifreq *buf = NULL;	/* for list of interfaces -- arbitrary limit */
	struct ifreq *bp;	/* cursor into buf */
	struct raw_iface *rifaces = NULL;
	int master_sock = safe_socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);        /* Get a UDP socket */

	/*
	 * Current upper bound on number of interfaces.
	 * Tricky: because this is a static, we won't have to start from
	 * 64 in subsequent calls.
	 */
	static int num = 64;	/* number of interfaces */

	/* get list of interfaces with assigned IPv4 addresses from system */

	if (master_sock == -1)
		exit_log_errno((e, "socket() failed in find_raw_ifaces4()"));

	if (setsockopt(master_sock, SOL_SOCKET, SO_REUSEADDR,
		       (const void *)&on, sizeof(on)) < 0)
		exit_log_errno((e, "setsockopt() in find_raw_ifaces4()"));

	/* bind the socket */
	{
		ip_address any;

		happy(anyaddr(AF_INET, &any));
		setportof(htons(pluto_port), &any);
		if (bind(master_sock, sockaddrof(&any),
			 sockaddrlenof(&any)) < 0)
			exit_log_errno((e,
					"bind() failed in find_raw_ifaces4()"));
	}

	/* a million interfaces is probably the maximum, ever... */
	for (; num < (1024 * 1024); num *= 2) {
		/* Get num local interfaces.  See netdevice(7). */
		ifconf.ifc_len = num * sizeof(struct ifreq);
		buf = realloc(buf, ifconf.ifc_len);
		if (buf == NULL) {
			exit_log_errno((e,
					"realloc of %d in find_raw_ifaces4()",
					ifconf.ifc_len));
		}
		memset(buf, 0xDF, ifconf.ifc_len);	/* stomp */
		ifconf.ifc_buf = (void *) buf;

		if (ioctl(master_sock, SIOCGIFCONF, &ifconf) == -1)
			exit_log_errno((e,
					"ioctl(SIOCGIFCONF) in find_raw_ifaces4()"));


		/* if we got back less than we asked for, we have them all */
		if (ifconf.ifc_len < (int)(sizeof(struct ifreq) * num))
			break;
	}

	/* Add an entry to rifaces for each interesting interface.
	   On Apple, the size of struct ifreq depends on the contents of
	   the union. See if.h */
	for (bp = buf, j = 0;
	     bp < (unsigned char *)buf + (size_t)ifconf.ifc_len;
	     bp = (struct ifreq *)
		((unsigned char *)bp +_SIZEOF_ADDR_IFREQ(*bp)),
	     j++) {
		struct raw_iface ri;
		const struct sockaddr_in *rs =
			(struct sockaddr_in *) &bp->ifr_addr;
		struct ifreq auxinfo;

		/* ignore all but AF_INET interfaces */
		if (rs->sin_family != AF_INET)
			continue; /* not interesting */

		/* build a NUL-terminated copy of the rname field */
		memcpy(ri.name, bp->ifr_name, IFNAMSIZ);
		ri.name[IFNAMSIZ] = '\0';

		/* ignore if our interface names were specified, and this isn't one */
		if (pluto_ifn_roof != 0) {
			int i;

			for (i = 0; i != pluto_ifn_roof; i++)
				if (streq(ri.name, pluto_ifn[i]))
					break;
			if (i == pluto_ifn_roof)
				continue; /* not found -- skip */
		}

		/* Find out stuff about this interface.  See netdevice(7). */
		zero(&auxinfo); /* paranoia */
		memcpy(auxinfo.ifr_name, bp->ifr_name, IFNAMSIZ);
		if (ioctl(master_sock, SIOCGIFFLAGS, &auxinfo) == -1) {
			exit_log_errno((e,
					"ioctl(SIOCGIFFLAGS) for %s in find_raw_ifaces4()",
					ri.name));
		}
		if (!(auxinfo.ifr_flags & IFF_UP))
			continue; /* ignore an interface that isn't UP */

		/* ignore unconfigured interfaces */
		if (rs->sin_addr.s_addr == 0)
			continue;

		happy(initaddr((const void *)&rs->sin_addr,
			       sizeof(struct in_addr),
			       AF_INET, &ri.addr));

		DBG(DBG_CONTROL, {
			ipstr_buf b;
			DBG_log("found %s with address %s",
				ri.name, ipstr(&ri.addr, &b));
		});
		ri.next = rifaces;
		rifaces = clone_thing(ri, "struct raw_iface");
	}
Exemple #13
0
int
main(int argc, char **argv)
{
  char *foo;
  const char *errstr;
  int   s;
  int   listen_only;
  int   lport,dport;
  int   afamily;
  int   pfamily;
  int   c;
  int   numSenders, numReceived;
  int   natt;
  int   waitTime;
  int   verbose;
  ip_address laddr, raddr;
  char *afam = "";

  progname = argv[0];

  afamily=AF_INET;
  pfamily=PF_INET;
  lport=500;
  dport=500;
  waitTime=3*1000;
  verbose=0;
  natt=0;
  listen_only=0;
  bzero(&laddr, sizeof(laddr));

  while((c = getopt_long(argc, argv, "hVvsp:b:46E:w:", long_opts, 0))!=EOF) {
      switch (c) {
      case 'h':	        /* --help */
	  help();
	  return 0;	/* GNU coding standards say to stop here */

      case 'V':               /* --version */
	  fprintf(stderr, "Openswan %s\n", ipsec_version_code());
	  return 0;	/* GNU coding standards say to stop here */

      case 'v':	/* --label <string> */
	  verbose++;
	  continue;

      case 'T':
	  natt++;
	  break;

      case 'E':
	  exchange_number=strtol(optarg, &foo, 0);
	  if(optarg==foo || exchange_number < 1 || exchange_number>255) {
	      fprintf(stderr, "Invalid exchange number '%s' (should be 1<=x<255)\n",
		      optarg);
	      exit(1);
	  }
	  continue;


      case 's':
	  listen_only++;
	  continue;

      case 'p':
	  lport=strtol(optarg, &foo, 0);
	  if(optarg==foo || lport <0 || lport>65535) {
	      fprintf(stderr, "Invalid port number '%s' (should be 0<=x<65536)\n",
		      optarg);
	      exit(1);
	  }
          fprintf(stderr, "setting source port to %u\n", lport);
	  continue;

      case 'w':
	  /* convert msec to sec */
	  waitTime=strtol(optarg, &foo, 0)*500;
	  if(optarg==foo || waitTime < 0) {
	      fprintf(stderr, "Invalid waittime number '%s' (should be 0<=x)\n",
		      optarg);
	      exit(1);
	  }
	  continue;

      case 'b':
	  errstr = ttoaddr(optarg, strlen(optarg), afamily, &laddr);
	  if(errstr!=NULL) {
	      fprintf(stderr, "Invalid local address '%s': %s\n",
		      optarg, errstr);
	      exit(1);
	  }
	  continue;

      case '4':
	  afamily=AF_INET;
	  pfamily=PF_INET;
	  afam = "IPv4";
	  continue;

      case '6':
	  afamily=AF_INET6;
	  pfamily=PF_INET6;
	  afam = "IPv6";
	  continue;

      default:
          help();
      }
  }

  s=safe_socket(pfamily, SOCK_DGRAM, IPPROTO_UDP);
  if(s < 0) {
    perror("socket");
    exit(3);
  }

  switch(afamily) {
  case AF_INET:
	  laddr.u.v4.sin_family= AF_INET;
	  laddr.u.v4.sin_port = htons(lport);
	  if(bind(s, (struct sockaddr *)&laddr.u.v4, sizeof(laddr.u.v4)) < 0) {
              fprintf(stderr, "warning, unable to bind v4 socket port %u: %s"
                      , lport, strerror(errno));
	  }
	  break;

  case AF_INET6:
	  laddr.u.v6.sin6_family= AF_INET6;
	  laddr.u.v6.sin6_port = htons(lport);
	  if(bind(s, (struct sockaddr *)&laddr.u.v6, sizeof(laddr.u.v6)) < 0) {
              fprintf(stderr, "warning, unable to bind v6 socket to port %u: %s"
                      , lport, strerror(errno));
	  }
	  break;
  }

  if(natt) {
      int r;

      /* only support RFC method */
      int type = ESPINUDP_WITH_NON_ESP;
      r = setsockopt(s, SOL_UDP, UDP_ESPINUDP, &type, sizeof(type));
      if ((r<0) && (errno == ENOPROTOOPT)) {
	  fprintf(stderr,
		 "NAT-Traversal: ESPINUDP(%d) not supported by kernel for family %s"
		 , type, afam);
      }
  }

  numSenders = 0;

  if(!listen_only) {
	  while(optind < argc) {
		  char *port;
		  char *host;
		  char  namebuf[128];

		  host = argv[optind];

		  port = strchr(host, '/');
		  dport=500;
		  if(port) {
			 *port='\0';
			  port++;
			  dport= strtol(port, &foo, 0);
			  if(port==foo || dport < 0 || dport > 65535) {
				  fprintf(stderr, "Invalid port number '%s' "
					  "(should be 0<=x<65536)\n",
					  port);
				  exit(1);
			  }
		  }

		  errstr = ttoaddr(host, strlen(host),
				   afamily, &raddr);
		  if(errstr!=NULL) {
			  fprintf(stderr, "Invalid remote address '%s': %s\n",
				  host, errstr);
			  exit(1);
		  }

		  addrtot(&raddr, 0, namebuf, sizeof(namebuf));

		  printf("Sending packet to %s/%d\n", namebuf, dport);

		  send_ping(afamily, s, &raddr, dport);
		  numSenders++;
		  optind++;
	  }
  }

  numReceived=0;

  /* really should catch ^C and print stats on exit */
  while(numSenders > 0 || listen_only) {
	  struct pollfd  ready;
	  int n;

	  ready.fd = s;
	  ready.events = POLLIN;

	  n = poll(&ready, 1, waitTime);
	  if(n < 0) {
	      if(errno != EINTR) {
		  perror("poll");
		  exit(1);
	      }
	  }

	  if(n == 0 && !listen_only) {
		  break;
	  }

	  if(n == 1) {
		  numReceived++;
		  receive_ping(afamily, s, listen_only, natt);
	  }
  }

   printf("%d packets sent, %d packets received. %d%% packet loss\n",
	  numSenders,
	  numReceived,
	  numSenders > 0 ? 100-numReceived*100/numSenders : 0);
   exit(numSenders - numReceived);
}
Exemple #14
0
int
main(int argc, char *argv[])
{
	struct ifreq ifr;
	struct ipsectunnelconf shc;
	int s;
	int c;
	int argcount = argc;
	int createdelete = 0;
	char virtname[64];
        struct stat sts;
     
	memset(&ifr, 0, sizeof(ifr));
	memset(&shc, 0, sizeof(shc));
	virtname[0]='\0';
	progname = argv[0];

	tool_init_log();

	while((c = getopt_long_only(argc, argv, ""/*"adchvV:P:l:+:"*/, longopts, 0)) != EOF) {
		switch(c) {
		case 'g':
			debug = 1;
			argcount--;
			break;
		case 'a':
			check_conflict(shc.cf_cmd, createdelete);
			shc.cf_cmd = IPSEC_SET_DEV;
			break;
		case 'd':
			check_conflict(shc.cf_cmd, createdelete);
			shc.cf_cmd = IPSEC_DEL_DEV;
			break;
		case 'c':
			check_conflict(shc.cf_cmd, createdelete);
			shc.cf_cmd = IPSEC_CLR_DEV;
			break;
		case 'h':
			usage(progname);
			break;
		case 'v':
			if(optarg) {
				fprintf(stderr, "%s: warning; '-v' and '--version' options don't expect arguments, arg '%s' found, perhaps unintended.\n",
					progname, optarg);
			}
			fprintf(stdout, "%s, use ipsec --version instead\n", progname);
			exit(1);
			break;

		case 'C':
			check_conflict(shc.cf_cmd, createdelete);
			createdelete = SADB_X_PLUMBIF;
			strncat(virtname, optarg, sizeof(virtname)-1);
			break;
		case 'D':
			check_conflict(shc.cf_cmd, createdelete);
			createdelete = SADB_X_UNPLUMBIF;
			strncat(virtname, optarg, sizeof(virtname)-1);
			break;

		case 'V':
			strncpy(ifr.ifr_name, optarg, sizeof(ifr.ifr_name));
			break;
		case 'P':
			strncpy(shc.cf_name, optarg, sizeof(shc.cf_name));
			break;
		case 'l':
			progname = malloc(strlen(argv[0])
					      + 10 /* update this when changing the sprintf() */
					      + strlen(optarg));
			sprintf(progname, "%s --label %s",
				argv[0],
				optarg);
			argcount -= 2;
			break;
		case '+': /* optionsfrom */
			optionsfrom(optarg, &argc, &argv, optind, stderr);
			/* no return on error */
			break;
		default:
			usage(progname);
			break;
		}
	}

        if ( ((stat ("/proc/net/pfkey", &sts)) == 0) )  {
                fprintf(stderr, "%s: NETKEY does not support virtual interfaces.\n",progname);
                exit(1);
        }

        if(argcount == 1) {
                int ret = 1;
                if ((stat ("/proc/net/ipsec_tncfg", &sts)) != 0)  {
                        fprintf(stderr, "%s: No tncfg - no IPsec support in kernel (are the modules loaded?)\n", progname);
                } else {
                        ret = system("cat /proc/net/ipsec_tncfg");
                        ret = ret != -1 && WIFEXITED(ret) ? WEXITSTATUS(ret) : 1;
                }
                exit(ret);
        }

	/* overlay our struct ipsectunnel onto ifr.ifr_ifru union (hope it fits!) */
	if (sizeof(ifr.ifr_ifru) < sizeof(shc)) {
	    fprintf(stderr, "%s: Internal error: struct ipsectunnelconf won't fit inside struct ifreq\n",
		progname);
	    exit(1);
	}
	memcpy(&ifr.ifr_ifru.ifru_newname, &shc, sizeof(shc));

	/* are we creating/deleting a virtual (mastXXX/ipsecXXX) interface? */
	if(createdelete) {
		exit(createdelete_virtual(createdelete, virtname));
	}

	switch(shc.cf_cmd) {
	case IPSEC_SET_DEV:
		if(!shc.cf_name[0]) {
			fprintf(stderr, "%s: physical I/F parameter missing.\n",
				progname);
			exit(1);
		}
	case IPSEC_DEL_DEV:
		if(!ifr.ifr_name[0]) {
			fprintf(stderr, "%s: virtual I/F parameter missing.\n",
				progname);
			exit(1);
		}
		break;
	case IPSEC_CLR_DEV:
		strncpy(ifr.ifr_name, "ipsec0", sizeof(ifr.ifr_name));
		break;
	default:
		fprintf(stderr, "%s: exactly one of '--attach', '--detach' or '--clear' options must be specified.\n"
			"Try %s --help' for usage information.\n",
			progname, progname);
		exit(1);
	}

	s=safe_socket(AF_INET, SOCK_DGRAM,0);
	if(s==-1)
	{
		fprintf(stderr, "%s: Socket creation failed -- ", progname);
		switch(errno)
		{
		case EACCES:
			if(getuid()==0)
				fprintf(stderr, "Root denied permission!?!\n");
			else
				fprintf(stderr, "Run as root user.\n");
			break;
		case EPROTONOSUPPORT:
			fprintf(stderr, "Internet Protocol not enabled");
			break;
		case EMFILE:
		case ENFILE:
		case ENOBUFS:
			fprintf(stderr, "Insufficient system resources.\n");
			break;
		case ENODEV:
			fprintf(stderr, "No such device.  Is the virtual device valid?  Is the ipsec module linked into the kernel or loaded as a module?\n");
			break;
		default:
			fprintf(stderr, "Unknown socket error %d.\n", errno);
		}
		exit(1);
	}
	if(ioctl(s, shc.cf_cmd, &ifr)==-1)
	{
		switch (shc.cf_cmd)
		{
		case IPSEC_SET_DEV:
			fprintf(stderr, "%s: Socket ioctl failed on attach -- ", progname);
			switch(errno)
			{
			case EINVAL:
				fprintf(stderr, "Invalid argument, check kernel log messages for specifics.\n");
				break;
			case ENODEV:
				fprintf(stderr, "No such device.  Is the virtual device valid?  Is the ipsec module linked into the kernel or loaded as a module?\n");
				break;
			case ENXIO:
				fprintf(stderr, "No such device.  Is the physical device valid?\n");
				break;
			case EBUSY:
				fprintf(stderr, "Device busy.  Virtual device %s is already attached to a physical device -- Use detach first.\n",
				       ifr.ifr_name);
				break;
			default:
				fprintf(stderr, "Unknown socket error %d.\n", errno);
			}
			exit(1);

		case IPSEC_DEL_DEV:
			fprintf(stderr, "%s: Socket ioctl failed on detach -- ", progname);
			switch(errno)
			{
			case EINVAL:
				fprintf(stderr, "Invalid argument, check kernel log messages for specifics.\n");
				break;
			case ENODEV:
				fprintf(stderr, "No such device.  Is the virtual device valid?  The ipsec module may not be linked into the kernel or loaded as a module.\n");
				break;
			case ENXIO:
				fprintf(stderr, "Device requested is not linked to any physical device.\n");
				break;
			default:
				fprintf(stderr, "Unknown socket error %d.\n", errno);
			}
			exit(1);

		case IPSEC_CLR_DEV:
			fprintf(stderr, "%s: Socket ioctl failed on clear -- ", progname);
			switch(errno)
			{
			case EINVAL:
				fprintf(stderr, "Invalid argument, check kernel log messages for specifics.\n");
				break;
			case ENODEV:
				fprintf(stderr, "Failed.  Is the ipsec module linked into the kernel or loaded as a module?.\n");
				break;
			default:
				fprintf(stderr, "Unknown socket error %d.\n", errno);
			}
			exit(1);
		default:
			fprintf(stderr, "%s: Socket ioctl failed on unknown operation %u -- %s", progname, (unsigned) shc.cf_cmd, strerror(errno));
			exit(1);
		}
	}
	exit(0);
}
Exemple #15
0
int pfkey_open_sock_with_error(void)
{
	int pfkey_sock = -1;

	if ((pfkey_sock = safe_socket(PF_KEY, SOCK_RAW, PF_KEY_V2) ) < 0) {
		fprintf(stderr,
			"%s: Trouble opening PF_KEY family socket with error: ",
			progname);
		switch (errno) {
		case ENOENT:
			fprintf(stderr,
				"device does not exist.  See Libreswan 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;
#ifdef EUNATCH
		case EUNATCH:
			fprintf(stderr,
				"Netlink not enabled OR KLIPS not loaded.\n");
			break;
#endif
		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:
			fprintf(stderr, "No kernel memory to allocate SA.\n");
			break;
		case ESOCKTNOSUPPORT:
			fprintf(stderr,
				"Algorithm support not available in the kernel.  Please compile in support.\n");
			break;
		case EEXIST:
			fprintf(stderr,
				"SA already in use.  Delete old one first.\n");
			break;
		case ENXIO:
			fprintf(stderr,
				"SA does not exist.  Cannot delete.\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);
	}

	return pfkey_sock;
}