Пример #1
0
static void server_init(void)
{
	struct addrinfo hints;
	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = AF_INET6;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = AI_PASSIVE;
	if (getaddrinfo(NULL, tcp_port, &hints, &local_addrinfo) != 0)
		tst_brkm(TBROK | TERRNO, cleanup, "getaddrinfo failed");

	/* IPv6 socket is also able to access IPv4 protocol stack */
	sfd = SAFE_SOCKET(cleanup, AF_INET6, SOCK_STREAM, 0);

	tst_resm(TINFO, "assigning a name to the server socket...");
	if (!local_addrinfo)
		tst_brkm(TBROK, cleanup, "failed to get the address");

	SAFE_BIND(cleanup, sfd, local_addrinfo->ai_addr,
		local_addrinfo->ai_addrlen);

	freeaddrinfo(local_addrinfo);

	const int flag = 1;
	setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));

	if (fastopen_api == TFO_ENABLED) {
		if (setsockopt(sfd, IPPROTO_TCP, TCP_FASTOPEN, &tfo_queue_size,
			sizeof(tfo_queue_size)) == -1)
			tst_brkm(TBROK, cleanup, "Can't set TFO sock. options");
	}

	SAFE_LISTEN(cleanup, sfd, max_queue_len);
	tst_resm(TINFO, "Listen on the socket '%d', port '%s'", sfd, tcp_port);
}
Пример #2
0
static int read_iface_prefix(const char *ip_str, int is_ipv6)
{
	uint8_t family = is_ipv6 ? AF_INET6 : AF_INET;

	char buf[16384];
	unsigned int len;

	struct {
		struct nlmsghdr nlhdr;
		struct ifaddrmsg addrmsg;
	} msg;

	struct nlmsghdr *retmsg;

	int sock = SAFE_SOCKET(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);

	memset(&msg, 0, sizeof(msg));
	msg.nlhdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
	msg.nlhdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
	msg.nlhdr.nlmsg_type = RTM_GETADDR;
	msg.addrmsg.ifa_family = family;

	SAFE_SEND(1, sock, &msg, msg.nlhdr.nlmsg_len, 0);
	len = recv(sock, buf, sizeof(buf), 0);
	retmsg = (struct nlmsghdr *)buf;

	while NLMSG_OK(retmsg, len) {
		char ifname[IFNAMSIZ];
		struct ifaddrmsg *retaddr;
		struct rtattr *retrta;
		char pradd[128];
		int attlen;

		retaddr = (struct ifaddrmsg *)NLMSG_DATA(retmsg);
		retrta = (struct rtattr *)IFA_RTA(retaddr);
		attlen = IFA_PAYLOAD(retmsg);

		while RTA_OK(retrta, attlen) {
			if (retrta->rta_type == IFA_ADDRESS) {
				inet_ntop(family, RTA_DATA(retrta), pradd,
					  sizeof(pradd));

				if_indextoname(retaddr->ifa_index, ifname);

				if (!strcmp(pradd, ip_str)) {
					prefix = retaddr->ifa_prefixlen;
					iface = strdup(ifname);
					return 0;
				}
			}
			retrta = RTA_NEXT(retrta, attlen);
		}
		retmsg = NLMSG_NEXT(retmsg, len);
	}

	return -1;
}
Пример #3
0
static int create_skbuf(unsigned int sizeof_priv)
{
	int ver = TPACKET_V3;
	struct tpacket_req3 req = {};

	req.tp_block_size = pgsz;
	req.tp_block_nr = 2;
	req.tp_frame_size = req.tp_block_size;
	req.tp_frame_nr = req.tp_block_nr;
	req.tp_retire_blk_tov = 100;

	req.tp_sizeof_priv = sizeof_priv;

	sk = SAFE_SOCKET(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
	TEST(setsockopt(sk, SOL_PACKET, PACKET_VERSION, &ver, sizeof(ver)));
	if (TST_RET && TST_ERR == EINVAL)
		tst_brk(TCONF | TTERRNO, "TPACKET_V3 not supported");
	if (TST_RET)
		tst_brk(TBROK | TTERRNO, "setsockopt(sk, SOL_PACKET, PACKET_VERSION, TPACKET_V3)");

	return setsockopt(sk, SOL_PACKET, PACKET_RX_RING, &req, sizeof(req));
}
Пример #4
0
static void verify_recvmsg(void)
{
	struct sockaddr_in6 addr_init = {
		.sin6_family	= AF_INET6,
		.sin6_port	= htons(0),
		.sin6_addr	= IN6ADDR_LOOPBACK_INIT,
	};
	struct sockaddr_in6 addr_r, addr_w, addr_f;
	socklen_t addrlen_r, addrlen_w;
	struct iovec iov = {
		.iov_base	= buff,
		.iov_len	= sizeof(buff),
	};
	struct msghdr msghdr = {
		.msg_name	= &addr_f,
		.msg_namelen	= sizeof(addr_f),
		.msg_iov	= &iov,
		.msg_iovlen	= 1,
		.msg_control	= NULL,
		.msg_controllen	= 0,
		.msg_flags	= 0,
	};
	int R;

	sdr = SAFE_SOCKET(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_IP);
	SAFE_BIND(sdr, (struct sockaddr*)&addr_init, sizeof(addr_init));
	addrlen_r = sizeof(addr_r);
	SAFE_GETSOCKNAME(sdr, (struct sockaddr*)&addr_r, &addrlen_r);
	sdw = SAFE_SOCKET(PF_INET6, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_IP);
	SAFE_BIND(sdw, (struct sockaddr*)&addr_init, sizeof(addr_init));
	addrlen_w = sizeof(addr_w);
	SAFE_GETSOCKNAME(sdw, (struct sockaddr*)&addr_w, &addrlen_w);

	R = sendto(sdw, msg, msglen, 0, (struct sockaddr*)&addr_r, addrlen_r);
	if (R < 0)
		tst_brk(TBROK | TERRNO, "sendto()");

	R = recvmsg(sdr, &msghdr, MSG_PEEK);
	if (R < 0) {
		tst_res(TFAIL | TERRNO, "recvmsg(..., MSG_PEEK)");
		return;
	}

	tst_res(TINFO, "received %d bytes", R);

	if ((R == bufflen) && !memcmp(msg, buff, R))
		tst_res(TPASS, "recvmsg(..., MSG_PEEK) works fine");
	else
		tst_res(TPASS, "recvmsg(..., MSG_PEEK) failed");

	SAFE_CLOSE(sdw);
	SAFE_CLOSE(sdr);
}

static void cleanup(void)
{
	if (sdw > 0 && close(sdw))
		tst_res(TWARN | TERRNO, "close(sdw) failed");

	if (sdr > 0 && close(sdr))
		tst_res(TWARN | TERRNO, "close(sdr) failed");
}

static struct tst_test test = {
	.tid = "recvmsg02",
	.min_kver = "2.6.27",
	.test_all = verify_recvmsg,
	.cleanup = cleanup,
};