Exemplo n.º 1
0
/*
 * get_dev_ip: fetches the ip currently assigned to the interface named `dev'
 * and stores it to `ip'.
 * On success 0 is returned, -1 otherwise.
 */
int get_dev_ip(inet_prefix *ip, int family, char *dev)
{
	int s=-1;
	int ret=0;

	setzero(ip, sizeof(inet_prefix));

	if((s=new_socket(family)) < 0) {
		error("Error while setting \"%s\" ip: Cannot open socket", dev);
		return -1;
	}

	if(family == AF_INET) {
		struct ifreq req;

		strncpy(req.ifr_name, dev, IFNAMSIZ);
		req.ifr_addr.sa_family = family;
		
		if(ioctl(s, SIOCGIFADDR, &req))
			ERROR_FINISH(ret, -1, finish);

		sockaddr_to_inet(&req.ifr_addr, ip, 0);
	} else if(family == AF_INET6) {
		struct in6_ifreq req6;

		/*
		 * XXX: NOT TESTED
		 */

		req6.ifr6_ifindex=ll_name_to_index(dev);
		req6.ifr6_prefixlen=0;

		if(ioctl(s, SIOCGIFADDR, &req6))
			ERROR_FINISH(ret, -1, finish);

		inet_setip(ip, (u_int *)&req6.ifr6_addr, family);
	}

finish:
	if(s != -1)
		close(s);
	return ret;
}
Exemplo n.º 2
0
void *
tcp_daemon(void *door)
{
	pthread_t thread;
	pthread_attr_t t_attr;

	PACKET rpkt;
	struct sockaddr_storage addr;
	socklen_t addrlen = sizeof addr;
	inet_prefix ip;

	fd_set fdset;
	int fd, ret, err, i;

	interface *ifs;
	int max_sk_idx, dev_sk[me.cur_ifs_n];

	u_short tcp_port = *(u_short *) door;
	const char *ntop;

	pthread_attr_init(&t_attr);
	pthread_attr_setdetachstate(&t_attr, PTHREAD_CREATE_DETACHED);

	debug(DBG_SOFT, "Preparing the tcp listening socket on port %d",
		  tcp_port);

	err = sockets_all_ifs(my_family, SOCK_STREAM, tcp_port, me.cur_ifs,
						  me.cur_ifs_n, dev_sk, &max_sk_idx);
	if (!err)
		return NULL;
	else if (err < 0)
		fatal("Creation of the %s daemon aborted. "
			  "Is there another ntkd running?", "tcp");

	pthread_mutex_init(&tcp_exec_lock, 0);

	for (i = 0; i < me.cur_ifs_n; i++) {
		if (!dev_sk[i])
			continue;
		/* 
		 * While we are accepting the connections we keep the socket non
		 * blocking.
		 */
		if (set_nonblock_sk(dev_sk[i])) {
			pthread_mutex_unlock(&tcp_daemon_lock);
			return NULL;
		}

		/* Shhh, it's listening... */
		if (listen(dev_sk[i], 5) == -1) {
			inet_close(&dev_sk[i]);
			pthread_mutex_unlock(&tcp_daemon_lock);
			return NULL;
		}
	}

	debug(DBG_NORMAL, "Tcp daemon on port %d up & running", tcp_port);
	pthread_mutex_unlock(&tcp_daemon_lock);
	for (;;) {
		FD_ZERO(&fdset);

		if (!me.cur_ifs_n) {
			/* All the devices have been removed while ntkd was
			 * running, sleep well */
			sleep(1);
			continue;
		}

		for (i = 0; i < me.cur_ifs_n; i++)
			if (dev_sk[i])
				FD_SET(dev_sk[i], &fdset);

		ret = select(dev_sk[max_sk_idx] + 1, &fdset, NULL, NULL, NULL);
		if (sigterm_timestamp)
			/* NetsukukuD has been closed */
			break;
		if (ret < 0 && errno != EINTR)
			error("daemon_tcp: select error: %s", strerror(errno));
		if (ret < 0)
			continue;

		for (i = 0; i < me.cur_ifs_n; i++) {
			ifs = &me.cur_ifs[i];
			if (!dev_sk[i])
				continue;

			if (!FD_ISSET(dev_sk[i], &fdset))
				continue;

			fd = accept(dev_sk[i], (struct sockaddr *) &addr, &addrlen);
			if (fd == -1) {
				if (errno != EINTR && errno != EWOULDBLOCK)
					error("daemon_tcp: accept(): %s", strerror(errno));
				continue;
			}

			setzero(&rpkt, sizeof(PACKET));
			pkt_addsk(&rpkt, my_family, fd, SKT_TCP);
			pkt_add_dev(&rpkt, ifs, 0);
			rpkt.flags = MSG_WAITALL;
			pkt_addport(&rpkt, tcp_port);

			ntop = 0;
			sockaddr_to_inet((struct sockaddr *) &addr, &ip, 0);
			pkt_addfrom(&rpkt, &ip);
			if (server_opt.dbg_lvl)
				ntop = inet_to_str(ip);

			if ((ret = add_accept(ip, 0))) {
				debug(DBG_NORMAL, "ACPT: drop connection with %s: "
					  "Accept table full.", ntop);

				/* Omg, we cannot take it anymore, go away: ACK_NEGATIVE */
				pkt_err(rpkt, ret, 1);
				inet_close(&fd);
				continue;
			} else {
				/* 
				 * Ok, the connection is good, send back the
				 * ACK_AFFERMATIVE.
				 */
				pkt_addto(&rpkt, &rpkt.from);
				send_rq(&rpkt, 0, ACK_AFFERMATIVE, 0, 0, 0, 0);
			}

			if (unset_nonblock_sk(fd))
				continue;

			pthread_mutex_lock(&tcp_exec_lock);
			err =
				pthread_create(&thread, &t_attr, tcp_recv_loop,
							   (void *) &rpkt);
			pthread_detach(thread);
			pthread_mutex_lock(&tcp_exec_lock);
			pthread_mutex_unlock(&tcp_exec_lock);
		}
	}
	return NULL;
}