Beispiel #1
0
void
ikev2_msg_cb(int fd, short event, void *arg)
{
	struct iked_socket	*sock = arg;
	struct iked		*env = sock->sock_env;
	struct iked_message	 msg;
	struct ike_header	 hdr;
	u_int32_t		 natt = 0x00000000;
	u_int8_t		 buf[IKED_MSGBUF_MAX];
	ssize_t			 len;
	off_t			 off;
	struct iovec		 iov[2];

	bzero(&msg, sizeof(msg));
	bzero(buf, sizeof(buf));

	msg.msg_peerlen = sizeof(msg.msg_peer);
	msg.msg_locallen = sizeof(msg.msg_local);
	msg.msg_parent = &msg;
	memcpy(&msg.msg_local, &sock->sock_addr, sizeof(sock->sock_addr));

	if ((len = recvfromto(fd, buf, sizeof(buf), 0,
	    (struct sockaddr *)&msg.msg_peer, &msg.msg_peerlen,
	    (struct sockaddr *)&msg.msg_local, &msg.msg_locallen)) <
	    (ssize_t)sizeof(natt))
		return;

	if (socket_getport(&msg.msg_local) == IKED_NATT_PORT) {
		if (bcmp(&natt, buf, sizeof(natt)) != 0)
			return;
		msg.msg_natt = 1;
		off = sizeof(natt);
	} else
		off = 0;

	if ((size_t)(len - off) <= sizeof(hdr))
		return;
	memcpy(&hdr, buf + off, sizeof(hdr));

	if ((msg.msg_data = ibuf_new(buf + off, len - off)) == NULL)
		return;

	if (hdr.ike_version == IKEV1_VERSION) {
		iov[0].iov_base = &msg;
		iov[0].iov_len = sizeof(msg);
		iov[1].iov_base = buf;
		iov[1].iov_len = len;

		proc_composev_imsg(env, PROC_IKEV1, IMSG_IKE_MESSAGE, -1,
		    iov, 2);
		goto done;
	}
	TAILQ_INIT(&msg.msg_proposals);

	msg.msg_fd = fd;
	ikev2_recv(env, &msg);

 done:
	ikev2_msg_cleanup(env, &msg);
}
Beispiel #2
0
void
ikev2_msg_cb(int fd, short event, void *arg)
{
	struct iked_socket	*sock = arg;
	struct iked		*env = sock->sock_env;
	struct iked_message	 msg;
	struct ike_header	 hdr;
	uint32_t		 natt = 0x00000000;
	uint8_t			 buf[IKED_MSGBUF_MAX];
	ssize_t			 len;
	off_t			 off;

	bzero(&msg, sizeof(msg));
	bzero(buf, sizeof(buf));

	msg.msg_peerlen = sizeof(msg.msg_peer);
	msg.msg_locallen = sizeof(msg.msg_local);
	msg.msg_parent = &msg;
	memcpy(&msg.msg_local, &sock->sock_addr, sizeof(sock->sock_addr));

	if ((len = recvfromto(fd, buf, sizeof(buf), 0,
	    (struct sockaddr *)&msg.msg_peer, &msg.msg_peerlen,
	    (struct sockaddr *)&msg.msg_local, &msg.msg_locallen)) <
	    (ssize_t)sizeof(natt))
		return;

	if (socket_getport((struct sockaddr *)&msg.msg_local) ==
	    IKED_NATT_PORT) {
		if (memcmp(&natt, buf, sizeof(natt)) != 0)
			return;
		msg.msg_natt = 1;
		off = sizeof(natt);
	} else
		off = 0;

	if ((size_t)(len - off) <= sizeof(hdr))
		return;
	memcpy(&hdr, buf + off, sizeof(hdr));

	if ((msg.msg_data = ibuf_new(buf + off, len - off)) == NULL)
		return;

	TAILQ_INIT(&msg.msg_proposals);
	msg.msg_fd = fd;

	if (hdr.ike_version == IKEV1_VERSION)
		ikev1_recv(env, &msg);
	else
		ikev2_recv(env, &msg);

	ikev2_msg_cleanup(env, &msg);
}
Beispiel #3
0
static struct rtp_packet *
rtpp_socket_rtp_recv(struct rtpp_socket *self, const struct rtpp_timestamp *dtime,
  struct sockaddr *laddr, int port)
{
    struct rtpp_socket_priv *pvt;
    struct rtp_packet *packet;
    struct timeval rtime;
    size_t llen;

    packet = rtp_packet_alloc();
    if (packet == NULL) {
        return NULL;
    }

    pvt = PUB2PVT(self);

    packet->rlen = sizeof(packet->raddr);
    llen = sizeof(packet->_laddr);
    memset(&rtime, '\0', sizeof(rtime));
    packet->size = recvfromto(pvt->fd, packet->data.buf, sizeof(packet->data.buf),
      sstosa(&packet->raddr), &packet->rlen, sstosa(&packet->_laddr), &llen,
      &rtime);

    if (packet->size == -1) {
        rtp_packet_free(packet);
        return (NULL);
    }
    if (llen > 0) {
        packet->laddr = sstosa(&packet->_laddr);
        packet->lport = getport(packet->laddr);
    } else {
        packet->laddr = laddr;
        packet->lport = port;
    }
    if (!timevaliszero(&rtime)) {
        packet->rtime.wall = timeval2dtime(&rtime);
    } else {
        packet->rtime.wall = dtime->wall;
    }
    RTPP_DBG_ASSERT(packet->rtime.wall > 0);
    packet->rtime.mono = dtime->mono;

    return (packet);
}
Beispiel #4
0
void
ikev1_msg_cb(int fd, short event, void *arg)
{
	struct iked_socket	*sock = arg;
	struct iked		*env = sock->sock_env;
	struct iked_message	 msg;
	struct ike_header	 hdr;
	uint8_t			 buf[IKED_MSGBUF_MAX];
	size_t			 len;
	struct iovec		 iov[2];

	msg.msg_peerlen = sizeof(msg.msg_peer);
	msg.msg_locallen = sizeof(msg.msg_local);

	if ((len = recvfromto(fd, buf, sizeof(buf), 0,
	    (struct sockaddr*)&msg.msg_peer, &msg.msg_peerlen,
	    (struct sockaddr*)&msg.msg_local, &msg.msg_locallen)) < 1)
		return;

	if ((size_t)len <= sizeof(hdr))
		return;
	memcpy(&hdr, buf, sizeof(hdr));

	if ((msg.msg_data = ibuf_new(buf, len)) == NULL)
		return;

	if (hdr.ike_version == IKEV2_VERSION) {
		iov[0].iov_base = &msg;
		iov[0].iov_len = sizeof(msg);
		iov[1].iov_base = buf;
		iov[1].iov_len = len;

		proc_composev_imsg(&env->sc_ps, PROC_IKEV2, -1,
		    IMSG_IKE_MESSAGE, -1, iov, 2);
		goto done;
	}

	ikev1_recv(env, &msg);

 done:
	ikev2_msg_cleanup(env, &msg);
}
Beispiel #5
0
static void read_loop(int fd) {

  struct sockaddr_in from;
  struct sockaddr_in to;
  socklen_t fromlen = sizeof(from);
  socklen_t tolen = sizeof(to);
  int ifindex = -1;
  uint8_t buf[10000];
  int rd;

  char str_from[100];
  char str_to[100];
  char ifname[100];

  for (;;) {
    rd = recvfromto(fd, buf, sizeof buf,
		    &from, &fromlen,
		    &to, &tolen,
		    &ifindex);
    if (rd < 0) {
      fprintf(stderr,
	      "%s: error: errno=%d: %s\n",
	      prog_name, errno, strerror(errno));
      continue;
    }

    inet_ntop(AF_INET, &from.sin_addr, str_from, sizeof str_from);
    inet_ntop(AF_INET, &to.sin_addr, str_to, sizeof str_to);
    index_to_name(ifindex, ifname, sizeof ifname);
    
    printf("%s: read %d bytes from %s:%d to %s:%d on %s ifindex=%d\n",
	   prog_name, rd, str_from, ntohs(from.sin_port), str_to, ntohs(to.sin_port),
	   ifname, ifindex);
  }
  
}
Beispiel #6
0
int main(int argc, char **argv)
{
	int			ret = EX_OK;
	int			i;
	struct group		*grgid;
	struct passwd		*pwuid;
	timer_t			timerid_mld, timerid_pim;
	struct pollfd		fds[4];
	nfds_t			nfds = 0;
	struct sockaddr_storage	from, to;
	socklen_t		addrlen = sizeof(struct sockaddr_storage);
	unsigned int		from_ifindex;
	char			*buf;

	ret = parse_args(argc, argv);
	if (ret)
		return -ret;

	if (getuid()) {
		fprintf(stderr, "need to run as root\n");
		return EX_NOPERM;
	}

	if (!nofork) {
		pid_t pid = fork();

		if (pid < 0) {
			perror("fork()");
			return EX_OSERR;
		} else if (pid > 0)
			return EX_OK;

		if (setsid() < 0) {
			perror("setsid()");
			return EX_OSERR;
		}

		if (chdir("/") < 0) {
			perror("chdir(\"/\")");
			return EX_OSERR;
		}

		openlog(basename(argv[0]), LOG_PID, LOG_DAEMON);
	} else
		openlog(basename(argv[0]), LOG_PID | LOG_PERROR, LOG_DAEMON);
	setlogmask(LOG_UPTO(debug));

	logger(LOG_NOTICE, 0, "started");

	errno = 0;
	mroute4 = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP);
	if (mroute4 >= 0) {
		if (pktinfo(mroute4) < 0) {
			close(mroute4);
			mroute4 = -1;
		} else {
			pim4 = pim_init(mroute4);
			if (pim4 < 0) {
				close(mroute4);
				mroute4 = -1;
			} else {
				add_poll(fds, &nfds, mroute4);
				add_poll(fds, &nfds, pim4);
			}
		}
	}
	if (mroute4 < 0)
		logger(LOG_WARNING, errno, "no IPv4 support");
	errno = 0;
	mroute6 = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
	if (mroute6 >= 0) {
		if (pktinfo(mroute6) < 0) {
			close(mroute6);
			mroute6 = -1;
		} else {
			pim6 = pim_init(mroute6);
			if (pim6 < 0) {
				close(mroute6);
				mroute6 = -1;
			} else {
				add_poll(fds, &nfds, mroute6);
				add_poll(fds, &nfds, pim6);
			}
		}
	}
	if (mroute6 < 0)
		logger(LOG_WARNING, errno, "no IPv6 support");

	if (mroute4 < 0 && mroute6 < 0) {
		logger(LOG_ERR, 0, "multicast routing unavailable");
		ret = -EX_OSERR;
		goto exit;
	}

	ret = route_init();
	if (ret)
		goto mroute;

	errno = 0;
	grgid = getgrnam(gid);
	if (grgid) {
		if (setgid(grgid->gr_gid))
			logger(LOG_WARNING, errno, "unable to drop group privileges");
	} else
		logger(LOG_WARNING, errno, "unable to find group '%s' to drop privileges to", gid);
	errno = 0;
	pwuid = getpwnam(uid);
	if (pwuid) {
		if (setuid(pwuid->pw_uid))
			logger(LOG_WARNING, errno, "unable to drop user privileges");
	} else
		logger(LOG_WARNING, errno, "unable to find user '%s' to drop privileges to", uid);

	ret = signals(&sig_handler);
	if (ret)
		goto route;

	ret = prime_timers(&timerid_mld, &timerid_pim);
	if (ret)
		goto signal;

	buf = malloc(SOCK_BUFLEN);
	if (buf == NULL) {
		logger(LOG_ERR, 0, "malloc()");
		ret = -EX_OSERR;
		goto timer;
	}

	while (running) {
		ret = poll(fds, nfds, -1);
		if (ret == -1) {
			if (errno == EINTR)
				continue;

			logger(LOG_ERR, errno, "poll()");
			ret = -EX_OSERR;
			running = 0;
			continue;
		}

		for (i = 0; i < nfds; i++) {
			/* TODO handle errors */
			assert(!(fds[i].revents & (POLLERR | POLLHUP)));

			/* either a non-event or there is something to read */
			assert(!fds[i].revents || fds[i].revents & POLLIN);

			if (!fds[i].revents)
				continue;

			if (fds[i].revents & POLLIN) {
				ret = recvfromto(fds[i].fd, buf, SOCK_BUFLEN, 0,
						(struct sockaddr *)&from,
						(struct sockaddr *)&to,
						&addrlen, &from_ifindex);
				if (ret == -1)
					continue;

				if (fds[i].fd == pim4 || fds[i].fd == pim6)
					pim_recv(fds[i].fd, buf, ret,
							&from, &to, addrlen,
							from_ifindex);
				else
					mld_recv(fds[i].fd, buf, ret,
							&from, &to, addrlen,
							from_ifindex);
			}
		}
	}

	free(buf);

timer:
	timer_delete(timerid_mld);
	timer_delete(timerid_pim);
signal:
	signals(SIG_IGN);
route:
	route_shutdown();
mroute:
	if (mroute4 > 0) {
		close(pim4);
		pim_shutdown(mroute4);
	}
	if (mroute6 > 0) {
		close(pim6);
		pim_shutdown(mroute6);
	}
exit:
	logger(LOG_NOTICE, 0, "exiting");

	closelog();

	assert(ret <= 0);

	return -ret;
}
Beispiel #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);
}
Beispiel #8
0
/*
 *	Wrapper for recvfrom, which handles recvfromto, IPv6, and all
 *	possible combinations.
 *
 *	FIXME:  This is copied from rad_recvfrom, with minor edits.
 */
static ssize_t vqp_recvfrom(int sockfd, uint8_t **pbuf, int flags,
			    fr_ipaddr_t *src_ipaddr, uint16_t *src_port,
			    fr_ipaddr_t *dst_ipaddr, uint16_t *dst_port)
{
	struct sockaddr_storage	src;
	struct sockaddr_storage	dst;
	socklen_t		sizeof_src = sizeof(src);
	socklen_t	        sizeof_dst = sizeof(dst);
	ssize_t			data_len;
	uint8_t			header[4];
	void			*buf;
	size_t			len;
	int			port;

	memset(&src, 0, sizeof_src);
	memset(&dst, 0, sizeof_dst);

	/*
	 *	Get address family, etc. first, so we know if we
	 *	need to do udpfromto.
	 *
	 *	FIXME: udpfromto also does this, but it's not
	 *	a critical problem.
	 */
	if (getsockname(sockfd, (struct sockaddr *)&dst,
			&sizeof_dst) < 0) return -1;

	/*
	 *	Read the length of the packet, from the packet.
	 *	This lets us allocate the buffer to use for
	 *	reading the rest of the packet.
	 */
	data_len = recvfrom(sockfd, header, sizeof(header), MSG_PEEK,
			    (struct sockaddr *)&src, &sizeof_src);
	if (data_len < 0) return -1;

	/*
	 *	Too little data is available, discard the packet.
	 */
	if (data_len < 4) {
		recvfrom(sockfd, header, sizeof(header), flags, 
			 (struct sockaddr *)&src, &sizeof_src);
		return 0;

		/*
		 *	Invalid version, packet type, or too many
		 *	attributes.  Die.
		 */
	} else if ((header[0] != VQP_VERSION) ||
		   (header[1] < 1) ||
		   (header[1] > 4) ||
		   (header[3] > VQP_MAX_ATTRIBUTES)) {
		recvfrom(sockfd, header, sizeof(header), flags,
			 (struct sockaddr *)&src, &sizeof_src);
		return 0;

	} else {		/* we got 4 bytes of data. */
		/*
		 *	We don't care about the contents for now...
		 */
#if 0
		/*
		 *	How many attributes are in the packet.
		 */
		len = header[3];

		if ((header[1] == 1) || (header[1] == 3)) {
			if (len != VQP_MAX_ATTRIBUTES) {
				recvfrom(sockfd, header, sizeof(header), 0,
					 (struct sockaddr *)&src, &sizeof_src);
				return 0;
			}
			/*
			 *	Maximum length we support.
			 */
			len = (12 * (4 + 4 + MAX_VMPS_LEN));

		} else {
			if (len != 2) {
				recvfrom(sockfd, header, sizeof(header), 0, 
				 (struct sockaddr *)&src, &sizeof_src);
				return 0;
			}
			/*
			 *	Maximum length we support.
			 */
			len = (12 * (4 + 4 + MAX_VMPS_LEN));
		}
#endif
	}

	/*
	 *	For now, be generous.
	 */
	len = (12 * (4 + 4 + MAX_VMPS_LEN));

	buf = malloc(len);
	if (!buf) return -1;

	/*
	 *	Receive the packet.  The OS will discard any data in the
	 *	packet after "len" bytes.
	 */
#ifdef WITH_UDPFROMTO
	if (dst.ss_family == AF_INET) {
		data_len = recvfromto(sockfd, buf, len, flags,
				      (struct sockaddr *)&src, &sizeof_src, 
				      (struct sockaddr *)&dst, &sizeof_dst);
	} else
#endif
		/*
		 *	No udpfromto, OR an IPv6 socket.  Fail gracefully.
		 */
		data_len = recvfrom(sockfd, buf, len, flags, 
				    (struct sockaddr *)&src, &sizeof_src);
	if (data_len < 0) {
		free(buf);
		return data_len;
	}

	if (!fr_sockaddr2ipaddr(&src, sizeof_src, src_ipaddr, &port)) {
		free(buf);
		return -1;	/* Unknown address family, Die Die Die! */
	}
	*src_port = port;

	fr_sockaddr2ipaddr(&dst, sizeof_dst, dst_ipaddr, &port);
	*dst_port = port;

	/*
	 *	Different address families should never happen.
	 */
	if (src.ss_family != dst.ss_family) {
		free(buf);
		return -1;
	}

	/*
	 *	Tell the caller about the data
	 */
	*pbuf = buf;

	return data_len;
}