[LTP] [PATCH v9 7/8] lib6: Rename

Zeng Linggang zenglg.jy@cn.fujitsu.com
Wed Oct 14 10:21:23 CEST 2015


rename:    asapi_04.c -> asapi_01.c
rename:    asapi_05.c -> asapi_02.c
rename:    asapi_06.c -> asapi_03.c

Signed-off-by: Zeng Linggang <zenglg.jy@cn.fujitsu.com>
---
 runtest/ipv6_lib                  |   6 +-
 testcases/network/.gitignore      |   6 +-
 testcases/network/lib6/asapi_01.c | 460 ++++++++++++++++++++++++++++++++++++++
 testcases/network/lib6/asapi_02.c | 261 +++++++++++++++++++++
 testcases/network/lib6/asapi_03.c | 385 +++++++++++++++++++++++++++++++
 testcases/network/lib6/asapi_04.c | 460 --------------------------------------
 testcases/network/lib6/asapi_05.c | 261 ---------------------
 testcases/network/lib6/asapi_06.c | 385 -------------------------------
 8 files changed, 1112 insertions(+), 1112 deletions(-)
 create mode 100644 testcases/network/lib6/asapi_01.c
 create mode 100644 testcases/network/lib6/asapi_02.c
 create mode 100644 testcases/network/lib6/asapi_03.c
 delete mode 100644 testcases/network/lib6/asapi_04.c
 delete mode 100644 testcases/network/lib6/asapi_05.c
 delete mode 100644 testcases/network/lib6/asapi_06.c

diff --git a/runtest/ipv6_lib b/runtest/ipv6_lib
index 203e275..636232b 100644
--- a/runtest/ipv6_lib
+++ b/runtest/ipv6_lib
@@ -2,6 +2,6 @@
 in6_01 in6_01
 in6_02 in6_02
 getaddrinfo_01 getaddrinfo_01
-asapi_04 asapi_04
-asapi_05 asapi_05
-asapi_06 asapi_06
+asapi_01 asapi_01
+asapi_02 asapi_02
+asapi_03 asapi_03
diff --git a/testcases/network/.gitignore b/testcases/network/.gitignore
index 18b0203..77a350b 100644
--- a/testcases/network/.gitignore
+++ b/testcases/network/.gitignore
@@ -1,9 +1,9 @@
 /can/filter-tests/can_filter
 /can/filter-tests/can_rcv_own_msgs
 /datafiles/
-/lib6/asapi_04
-/lib6/asapi_05
-/lib6/asapi_06
+/lib6/asapi_01
+/lib6/asapi_02
+/lib6/asapi_03
 /lib6/getaddrinfo_01
 /lib6/in6_01
 /lib6/in6_02
diff --git a/testcases/network/lib6/asapi_01.c b/testcases/network/lib6/asapi_01.c
new file mode 100644
index 0000000..df26494
--- /dev/null
+++ b/testcases/network/lib6/asapi_01.c
@@ -0,0 +1,460 @@
+/*
+ * Copyright (c) 2015 Fujitsu Ltd.
+ * Copyright (c) International Business Machines  Corp., 2001
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: David L Stevens
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <netdb.h>
+#include <libgen.h>
+#include <pthread.h>
+#include <semaphore.h>
+
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include "test.h"
+#include "safe_macros.h"
+
+char *TCID = "asapi_04";
+
+static pid_t pid;
+
+static struct {
+	char *prt_name;
+	int prt_value;
+} ptab[] = {
+	{"hopopt", 0},
+	{"ipv6", 41},
+	{"ipv6-route", 43},
+	{"ipv6-frag", 44},
+	{"esp", 50},
+	{"ah", 51},
+	{"ipv6-icmp", 58},
+	{"ipv6-nonxt", 59},
+	{"ipv6-opts", 60},
+};
+
+#define PTCOUNT		ARRAY_SIZE(ptab)
+#define READ_TIMEOUT	5
+
+static void do_tests(void);
+static void setup(void);
+static void csum_test(void);
+
+int main(int argc, char *argv[])
+{
+	int lc;
+
+	tst_parse_opts(argc, argv, 0, 0);
+
+	setup();
+
+	for (lc = 0; TEST_LOOPING(lc); ++lc)
+		do_tests();
+
+	tst_exit();
+}
+
+static void do_tests(void)
+{
+	unsigned int i;
+
+/* RFC 3542, Section 2.3 */
+#ifndef IN6_ARE_ADDR_EQUAL
+	tst_resm(TCONF, "IN6_ARE_ADDR_EQUAL not present");
+#else /* IN6_ARE_ADDR_EQUAL */
+	/*
+	 * set each bit in an address and check for unequal; then set
+	 * in the second address and check for equal. Covers all bits, all
+	 * combinations.
+	 */
+	struct in6_addr a1, a2;
+	int word, bit;
+	int rv = 1;
+
+	memset(&a1, 0, sizeof(a1));
+	memset(&a2, 0, sizeof(a2));
+
+	rv = IN6_ARE_ADDR_EQUAL(&a1, &a2);
+
+	for (word = 0; word < 4; ++word) {
+		for (bit = 0; bit < 32; ++bit) {
+			uint32_t newbit = 1U << bit;
+
+			a1.s6_addr32[word] |= newbit;
+			rv &= !IN6_ARE_ADDR_EQUAL(&a1, &a2);
+			a2.s6_addr32[word] |= newbit;
+			rv &= IN6_ARE_ADDR_EQUAL(&a1, &a2);
+		}
+	}
+
+	tst_resm(rv ? TPASS : TFAIL, "IN6_ARE_ADDR_EQUAL");
+#endif /* IN6_ARE_ADDR_EQUAL */
+
+/* RFC 3542, Section 2.4 */
+	for (i = 0; i < PTCOUNT; ++i) {
+		struct protoent *pe;
+		int pass;
+
+		pe = getprotobyname(ptab[i].prt_name);
+		pass = pe && pe->p_proto == ptab[i].prt_value;
+		tst_resm(pass ? TPASS : TFAIL, "\"%s\" protocols entry",
+			 ptab[i].prt_name);
+	}
+/* RFC 3542, Section 3.1 */
+	csum_test();
+}
+
+/*
+ * this next-header value shouldn't be a real protocol!!
+ * 0x9f = 01 0 11111
+ *         | |     |
+ *         | |     |--- rest- ~0
+ *         | |--------- chg - "no change enroute"
+ *         |----------- act - "discard unknown"
+ */
+#define	NH_TEST	0x9f
+
+struct tprot {
+	int tp_pid;		/* sender PID */
+	int tp_seq;		/* sequence # */
+	int tp_offset;		/* offset of cksum */
+	int tp_dlen;		/* tp_dat length */
+	unsigned char tp_dat[0];	/* user data */
+};
+
+static unsigned char tpbuf[sizeof(struct tprot) + 2048];
+static unsigned char rpbuf[sizeof(struct tprot) + 2048];
+
+static struct csent {
+	int cs_offset;
+	int cs_dlen;
+	int cs_setresult;	/* setsockopt expected result */
+	int cs_seterrno;	/* setsockopt expected errno */
+	int cs_sndresult;	/* send expected result */
+	int cs_snderrno;	/* send expected errno */
+} cstab[] = {
+	{0, 5, 0, 0, 0, 0},
+	{6, 30, 0, 0, 0, 0},
+	{3, 20, -1, EINVAL, -1, -1},	/* non-aligned offset */
+	{4, 5, 0, 0, -1, EINVAL},	/* not enough space */
+	{50, 5, 0, 0, -1, EINVAL},	/* outside of packet */
+	{22, 30, 0, 0, 0, 0},
+	{2000, 2004, 0, 0, 0, 0},	/* in a fragment (over Ethernet) */
+};
+
+#define CSCOUNT	ARRAY_SIZE(cstab)
+
+int TST_TOTAL = PTCOUNT + CSCOUNT;
+
+static int recvtprot(int sd, unsigned char *packet)
+{
+	struct tprot *tpt;
+	int cc;
+	unsigned int total, expected;
+	int gothead;
+
+	tpt = (struct tprot *)packet;
+	total = cc = recv(sd, packet, sizeof(struct tprot), 0);
+	expected = sizeof(struct tprot);	/* until we get tp_dlen */
+	gothead = total >= sizeof(struct tprot);
+	if (gothead)
+		expected += ntohl(tpt->tp_dlen);
+	if (cc <= 0)
+		return cc;
+	while (cc > 0 && total < expected) {
+		cc = recv(sd, &packet[total], expected - total, 0);
+		if (cc >= 0) {
+			total += cc;
+			if (!gothead && total >= sizeof(struct tprot)) {
+				gothead = 1;
+				expected += ntohl(tpt->tp_dlen);
+			}
+		} else {
+			break;
+		}
+	}
+	if (cc < 0)
+		return cc;
+	return total;
+}
+
+static unsigned short csum(unsigned short partial, unsigned char *packet,
+			   int len)
+{
+	unsigned long sum = partial;
+	unsigned short *ps;
+	int i;
+
+	ps = (unsigned short *)packet;
+	for (i = 0; i < len / 2; ++i)
+		sum += *ps++;
+	if (len & 1)
+		sum += htons(packet[len - 1] << 8);
+	sum = (sum >> 16) + (sum & 0xffff);
+	sum += (sum >> 16);
+	return ~sum;
+}
+
+static struct ph {
+	struct in6_addr ph_sa;
+	struct in6_addr ph_da;
+	uint32_t ph_len;
+	uint8_t ph_mbz[3];
+	uint8_t ph_nh;
+} ph;
+
+static int client(int sfd)
+{
+	struct tprot *pttp = (struct tprot *)tpbuf;
+	struct tprot *prtp = (struct tprot *)rpbuf;
+	struct sockaddr_in6 rsin6;
+	static int seq;
+	unsigned int i;
+	int sd, cc, cs;
+
+	memset(&rsin6, 0, sizeof(rsin6));
+	rsin6.sin6_family = AF_INET6;
+	rsin6.sin6_addr = in6addr_loopback;
+
+	memset(&ph, 0, sizeof(ph));
+	ph.ph_sa = rsin6.sin6_addr;
+	ph.ph_da = rsin6.sin6_addr;
+	ph.ph_nh = NH_TEST;
+
+	sd = SAFE_SOCKET(NULL, PF_INET6, SOCK_RAW, NH_TEST);
+
+	for (i = 0; i < CSCOUNT; ++i) {
+		int offset, len, xlen;
+		int rv;
+		unsigned char *p, *pend;
+
+		offset = sizeof(struct tprot) + cstab[i].cs_offset;
+		len = sizeof(struct tprot) + cstab[i].cs_dlen;
+
+		memset(pttp, 0, sizeof(*pttp));
+		memset(pttp->tp_dat, 0xA5, cstab[i].cs_dlen);
+
+		pttp->tp_pid = htonl(pid);
+		pttp->tp_offset = ntohl(offset);
+		pttp->tp_dlen = ntohl(cstab[i].cs_dlen);
+		pttp->tp_seq = ntohl(++seq);
+
+		TEST(setsockopt(sd, IPPROTO_IPV6, IPV6_CHECKSUM, &offset,
+				sizeof(offset)));
+		if (TEST_RETURN != cstab[i].cs_setresult) {
+			tst_resm(TFAIL | TTERRNO,
+				 "IPV6_CHECKSUM offset %d len %d "
+				 "- result %ld != %d", offset, len, TEST_RETURN,
+				 cstab[i].cs_setresult);
+			continue;
+		}
+		if (TEST_RETURN < 0) {
+			tst_resm(TPASS, "IPV6_CHECKSUM offset %d len %d",
+				 offset, len);
+			continue;
+		}
+		if (TEST_RETURN && TEST_ERRNO != cstab[i].cs_seterrno) {
+			tst_resm(TFAIL, "IPV6_CHECKSUM offset %d len %d "
+				 "- errno %d != %d", offset, len,
+				 TEST_ERRNO, cstab[i].cs_seterrno);
+			continue;
+		}
+		/* send packet */
+		TEST(sendto(sd, pttp, len, 0, (struct sockaddr *)&rsin6,
+			    sizeof(rsin6)));
+		xlen = (cstab[i].cs_sndresult < 0) ? -1 : len;
+		if (TEST_RETURN != xlen) {
+			tst_resm(TFAIL | TTERRNO,
+				 "IPV6_CHECKSUM offset %d len %d "
+				 "- sndresult %ld != %d", offset, len,
+				 TEST_RETURN, xlen);
+			continue;
+		}
+		if (TEST_RETURN < 0 && TEST_ERRNO != cstab[i].cs_snderrno) {
+			tst_resm(TFAIL, "IPV6_CHECKSUM offset %d len %d "
+				 "- snderrno %d != %d", offset, len,
+				 TEST_ERRNO, cstab[i].cs_snderrno);
+			continue;
+		}
+		if (TEST_RETURN < 0) {
+			tst_resm(TPASS, "IPV6_CHECKSUM offset %d len %d",
+				 offset, len);
+			continue;
+		}
+		while ((cc = recvtprot(sfd, rpbuf))) {
+			if (htonl(prtp->tp_pid) == (uint32_t)pid &&
+			    htonl(prtp->tp_seq) == (uint32_t)seq)
+				break;
+		}
+		rv = 1;
+		pend = rpbuf + sizeof(struct tprot) + ntohl(prtp->tp_dlen);
+		for (p = &prtp->tp_dat[0]; p < pend; ++p) {
+			if (p == &rpbuf[offset] || p == &rpbuf[offset + 1])
+				continue;
+			if (*p != 0xa5) {
+				tst_resm(TFAIL, "IPV6_CHECKSUM corrupt data "
+					 "0x%02x != 0xa5 at offset %zd in packet",
+					 *p, p - rpbuf);
+				rv = 0;
+				break;
+			}
+		}
+		if (rv == 0)
+			continue;
+		ph.ph_len = htonl(xlen);
+		cs = csum(0, (unsigned char *)&ph, sizeof(ph));
+		cs = csum(~cs, rpbuf, xlen);
+		if (!csum(0, rpbuf, xlen)) {
+			tst_resm(TFAIL, "IPV6_CHECKSUM offset %d len %d (bad "
+				 "checksum)", offset, len);
+			continue;
+		}
+		tst_resm(TPASS, "IPV6_CHECKSUM offset %d len %d", offset, len);
+	}
+	return 0;
+}
+
+static int listen_fd, connect_fd;
+
+static void *ilistener(void *arg LTP_ATTRIBUTE_UNUSED)
+{
+	connect_fd = accept(listen_fd, 0, 0);
+	close(listen_fd);
+	return NULL;
+}
+
+static void isocketpair(int pf, int type, int proto, int fd[2])
+{
+	pthread_t thid;
+	struct sockaddr_in sin4;
+	socklen_t namelen;
+
+	listen_fd = SAFE_SOCKET(NULL, pf, type, proto);
+
+	memset(&sin4, 0, sizeof(sin4));
+
+	SAFE_BIND(NULL, listen_fd, (struct sockaddr *)&sin4, sizeof(sin4));
+
+	SAFE_LISTEN(NULL, listen_fd, 10);
+
+	namelen = sizeof(sin4);
+	SAFE_GETSOCKNAME(NULL, listen_fd, (struct sockaddr *)&sin4, &namelen);
+
+	if (pthread_create(&thid, 0, ilistener, 0) < 0)
+		tst_brkm(TBROK | TERRNO, NULL, "pthread_create error");
+
+	fd[0] = SAFE_SOCKET(NULL, pf, type, proto);
+
+	sin4.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+	SAFE_CONNECT(NULL, fd[0], (struct sockaddr *)&sin4, sizeof(sin4));
+
+	pthread_join(thid, NULL);
+
+	fd[1] = connect_fd;
+}
+
+#ifndef MAX
+#define MAX(a, b) ((a) >= (b) ? (a) : (b))
+#endif /* MAX */
+
+static void csum_test(void)
+{
+	fd_set rset, rset_save;
+	int csd[2];		/* control sockets */
+	int sd, nfds, maxfd, cc;
+	struct timeval tv;
+
+	isocketpair(PF_INET, SOCK_STREAM, 0, csd);
+
+	sd = SAFE_SOCKET(NULL, PF_INET6, SOCK_RAW, NH_TEST);
+
+	FD_ZERO(&rset_save);
+	FD_SET(sd, &rset_save);
+	FD_SET(csd[1], &rset_save);
+	memcpy(&rset, &rset_save, sizeof(rset));
+	maxfd = MAX(sd, csd[1]);
+
+	/* server socket set; now start the client */
+	switch (fork()) {
+	case 0:
+		close(csd[0]);
+		break;
+	case -1:
+		tst_brkm(TBROK, NULL, "can't fork rserver");
+	default:
+		close(sd);
+		close(csd[1]);
+		client(csd[0]);
+		return;
+	}
+
+	tv.tv_sec = READ_TIMEOUT;
+	tv.tv_usec = 0;
+	while ((nfds = select(maxfd + 1, &rset, 0, 0, &tv)) >= 0) {
+		if (nfds < 0) {
+			if (errno == EINTR)
+				continue;
+			exit(0);
+		} else if (nfds == 0) {
+			fprintf(stderr, "server read timed out");
+			return;
+		}
+		if (FD_ISSET(sd, &rset)) {
+			static char packet[2048];
+
+			cc = recv(sd, packet, sizeof(packet), 0);
+			if (cc < 0) {
+				perror("server recvtprot");
+				exit(1);
+			}
+			if (cc == 0)
+				exit(0);
+			if (write(csd[1], packet, cc) < 0) {
+				perror("server write UNIX socket");
+				exit(0);
+			}
+		}
+		if (FD_ISSET(csd[1], &rset)) {
+			char buf[2048];
+
+			cc = read(csd[1], buf, sizeof(buf));
+			if (cc == 0)
+				exit(0);
+			if (cc < 0) {
+				perror("server read");
+				exit(1);
+			}
+			/* handle commands here, if any added later */
+		}
+		memcpy(&rset, &rset_save, sizeof(rset));
+		tv.tv_sec = READ_TIMEOUT;
+		tv.tv_usec = 0;
+	}
+}
+
+static void setup(void)
+{
+	TEST_PAUSE;
+
+	pid = getpid();
+}
diff --git a/testcases/network/lib6/asapi_02.c b/testcases/network/lib6/asapi_02.c
new file mode 100644
index 0000000..f8c30f1
--- /dev/null
+++ b/testcases/network/lib6/asapi_02.c
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 2015 Fujitsu Ltd.
+ * Copyright (c) International Business Machines  Corp., 2001
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: David L Stevens
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <sys/wait.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netinet/ip6.h>
+#include <netinet/icmp6.h>
+
+#include "test.h"
+#include "safe_macros.h"
+
+char *TCID = "asapi_05";
+
+static void setup(void);
+
+static void icmp6_ft(void);
+
+int main(int argc, char *argv[])
+{
+	int lc;
+
+	tst_parse_opts(argc, argv, NULL, NULL);
+
+	setup();
+
+	for (lc = 0; TEST_LOOPING(lc); ++lc)
+		icmp6_ft();
+
+	tst_exit();
+}
+
+static void setup(void)
+{
+	TEST_PAUSE;
+	tst_require_root();
+}
+
+enum tt {
+	T_WILLPASS,
+	T_WILLBLOCK,
+	T_SETPASS,
+	T_SETBLOCK,
+	T_SETPASSALL,
+	T_SETBLOCKALL
+};
+
+static struct ftent {
+	char *ft_tname;			/* test name, for logging */
+	unsigned char ft_sndtype;	/* send type field */
+	unsigned char ft_flttype;	/* filter type field */
+	enum tt ft_test;		/* what macro to test */
+	int ft_expected;		/* packet should pass? */
+} ftab[] = {
+	{"ICMP6_FILTER_SETPASS s 20 f 20", 20, 20, T_SETPASS, 1},
+	{"ICMP6_FILTER_SETPASS s 20 f 21", 20, 21, T_SETPASS, 0},
+	{"ICMP6_FILTER_SETBLOCK s 20 f 20", 20, 20, T_SETBLOCK, 0},
+	{"ICMP6_FILTER_SETBLOCK s 20 f 21", 20, 21, T_SETBLOCK, 1},
+	{"ICMP6_FILTER_PASSALL s 20", 20, 0, T_SETPASSALL, 1},
+	{"ICMP6_FILTER_PASSALL s 20", 21, 0, T_SETPASSALL, 1},
+	{"ICMP6_FILTER_BLOCKALL s 20", 20, 0, T_SETBLOCKALL, 0},
+	{"ICMP6_FILTER_BLOCKALL s 20", 21, 0, T_SETBLOCKALL, 0},
+	{"ICMP6_FILTER_WILLBLOCK s 20 f 21", 20, 21, T_WILLBLOCK, 0},
+	{"ICMP6_FILTER_WILLBLOCK s 20 f 20", 20, 20, T_WILLBLOCK, 1},
+	{"ICMP6_FILTER_WILLPASS s 20 f 21", 20, 21, T_WILLPASS, 0},
+	{"ICMP6_FILTER_WILLPASS s 22 f 22", 22, 22, T_WILLPASS, 1},
+};
+
+#define FTCOUNT	ARRAY_SIZE(ftab)
+
+static int ic6_send1(char *tname, unsigned char type)
+{
+	struct sockaddr_in6 sin6;
+	struct icmp6_hdr ic6;
+	int s;
+
+	s = SAFE_SOCKET(NULL, AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
+
+	memset(&ic6, 0, sizeof(ic6));
+	ic6.icmp6_type = type;
+	ic6.icmp6_data32[0] = htonl(getpid());
+
+	memset(&sin6, 0, sizeof(sin6));
+	sin6.sin6_family = AF_INET6;
+	sin6.sin6_addr = in6addr_loopback;
+	if (sendto(s, &ic6, sizeof(ic6), 0, (struct sockaddr *)&sin6,
+		   sizeof(sin6)) == -1) {
+		tst_resm(TBROK | TERRNO, "%s: sendto failed", tname);
+		return 1;
+	}
+	return 0;
+}
+
+static int ic6_recv1(char *tname, int sall, int sf)
+{
+	fd_set readfds, readfds_saved;
+	struct timeval tv;
+	int maxfd, nfds;
+	int gotall, gotone;
+	int cc;
+	static unsigned char rbuf[2048];
+
+	tv.tv_sec = 0;
+	tv.tv_usec = 250000;
+
+	FD_ZERO(&readfds_saved);
+	FD_SET(sall, &readfds_saved);
+	FD_SET(sf, &readfds_saved);
+	maxfd = MAX(sall, sf);
+
+	memcpy(&readfds, &readfds_saved, sizeof(readfds));
+
+	gotall = gotone = 0;
+	/*
+	 * Note: this relies on linux-specific behavior (select
+	 * updating tv with time elapsed)
+	 */
+	while (!gotall || !gotone) {
+		struct icmp6_hdr *pic6 = (struct icmp6_hdr *)rbuf;
+
+		nfds = select(maxfd + 1, &readfds, 0, 0, &tv);
+		if (nfds == 0)
+			break;	/* timed out */
+		if (nfds < 0) {
+			if (errno == EINTR)
+				continue;
+			tst_resm(TBROK | TERRNO, "%s: select failed", tname);
+		}
+		if (FD_ISSET(sall, &readfds)) {
+			cc = recv(sall, rbuf, sizeof(rbuf), 0);
+			if (cc < 0) {
+				tst_resm(TBROK | TERRNO,
+					 "%s: recv(sall, ..) failed", tname);
+				return -1;
+			}
+			/* if packet check succeeds... */
+			if (htonl(pic6->icmp6_data32[0]) == (uint32_t)getpid())
+				gotall = 1;
+		}
+		if (FD_ISSET(sf, &readfds)) {
+			cc = recv(sf, rbuf, sizeof(rbuf), 0);
+			if (cc < 0) {
+				tst_resm(TBROK | TERRNO,
+					 "%s: recv(sf, ..) failed", tname);
+				return -1;
+			}
+			/* if packet check succeeds... */
+			if (htonl(pic6->icmp6_data32[0]) == (uint32_t)getpid())
+				gotone = 1;
+		}
+		memcpy(&readfds, &readfds_saved, sizeof(readfds));
+	}
+	if (!gotall) {
+		tst_resm(TBROK, "%s: recv all timed out", tname);
+		return -1;
+	}
+	if (gotone)
+		return 1;
+	return 0;
+}
+
+/* functional tests */
+static void icmp6_ft(void)
+{
+	struct icmp6_filter i6f;
+	int sall, sf;
+	unsigned int i;
+
+	sall = SAFE_SOCKET(NULL, PF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
+
+	ICMP6_FILTER_SETPASSALL(&i6f);
+	if (setsockopt(sall, IPPROTO_ICMPV6, ICMP6_FILTER, &i6f,
+		       sizeof(i6f)) < 0) {
+		tst_resm(TBROK | TERRNO,
+			 "setsockopt pass all ICMP6_FILTER failed");
+	}
+
+	sf = SAFE_SOCKET(NULL, PF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
+
+	int rv;
+
+	for (i = 0; i < FTCOUNT; ++i) {
+
+		rv = -1;
+
+		switch (ftab[i].ft_test) {
+		case T_SETPASS:
+			ICMP6_FILTER_SETBLOCKALL(&i6f);
+			ICMP6_FILTER_SETPASS(ftab[i].ft_flttype, &i6f);
+			break;
+		case T_SETPASSALL:
+			ICMP6_FILTER_SETPASSALL(&i6f);
+			break;
+		case T_SETBLOCK:
+			ICMP6_FILTER_SETPASSALL(&i6f);
+			ICMP6_FILTER_SETBLOCK(ftab[i].ft_flttype, &i6f);
+			break;
+		case T_SETBLOCKALL:
+			ICMP6_FILTER_SETBLOCKALL(&i6f);
+			break;
+		case T_WILLBLOCK:
+			ICMP6_FILTER_SETPASSALL(&i6f);
+			ICMP6_FILTER_SETBLOCK(ftab[i].ft_flttype, &i6f);
+			rv = ICMP6_FILTER_WILLBLOCK(ftab[i].ft_sndtype, &i6f);
+			break;
+		case T_WILLPASS:
+			ICMP6_FILTER_SETBLOCKALL(&i6f);
+			ICMP6_FILTER_SETPASS(ftab[i].ft_flttype, &i6f);
+			rv = ICMP6_FILTER_WILLPASS(ftab[i].ft_sndtype, &i6f);
+			break;
+		default:
+			tst_resm(TBROK, "%s: unknown test type %d",
+				 ftab[i].ft_tname, ftab[i].ft_test);
+			continue;
+		}
+		if (ftab[i].ft_test != T_WILLBLOCK &&
+		    ftab[i].ft_test != T_WILLPASS) {
+			if (setsockopt(sf, IPPROTO_ICMPV6, ICMP6_FILTER, &i6f,
+				       sizeof(i6f)) < 0) {
+				tst_resm(TFAIL | TERRNO,
+					 "setsockopt ICMP6_FILTER");
+				continue;
+			}
+			if (ic6_send1(ftab[i].ft_tname, ftab[i].ft_sndtype))
+				continue;
+			rv = ic6_recv1(ftab[i].ft_tname, sall, sf);
+		} else {
+			rv = -1;
+		}
+
+		if (rv < 0)
+			continue;
+		if (rv != ftab[i].ft_expected)
+			tst_resm(TFAIL, "%s: rv %d != expected %d",
+				 ftab[i].ft_tname, rv, ftab[i].ft_expected);
+		else
+			tst_resm(TPASS, "%s", ftab[i].ft_tname);
+	}
+}
diff --git a/testcases/network/lib6/asapi_03.c b/testcases/network/lib6/asapi_03.c
new file mode 100644
index 0000000..c6e2c8e
--- /dev/null
+++ b/testcases/network/lib6/asapi_03.c
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2015 Fujitsu Ltd.
+ * Copyright (c) International Business Machines  Corp., 2001
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: David L Stevens
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <netdb.h>
+#include <libgen.h>
+#include <pthread.h>
+#include <semaphore.h>
+
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <netinet/ip6.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#ifdef HAVE_IFADDRS_H
+#include <ifaddrs.h>
+#endif
+#include <arpa/inet.h>
+
+#include "test.h"
+#include "safe_macros.h"
+
+char *TCID = "asapi_06";
+
+int TST_TOTAL = 1;
+
+#define READ_TIMEOUT	5	/* secs */
+
+static void do_tests(void);
+static void setup(void);
+
+int main(int argc, char *argv[])
+{
+	int lc;
+
+	tst_parse_opts(argc, argv, NULL, NULL);
+
+	setup();
+
+	for (lc = 0; TEST_LOOPING(lc); ++lc)
+		do_tests();
+
+	tst_exit();
+}
+
+#define NH_TEST	0x9f
+
+#ifndef IPV6_RECVPKTINFO
+#define IPV6_RECVPKTINFO	-1
+#endif
+#ifndef IPV6_RECVHOPLIMIT
+#define IPV6_RECVHOPLIMIT	-1
+#endif
+#ifndef IPV6_RECVRTHDR
+#define IPV6_RECVRTHDR		-1
+#endif
+#ifndef IPV6_RECVHOPOPTS
+#define IPV6_RECVHOPOPTS	-1
+#endif
+#ifndef IPV6_RECVDSTOPTS
+#define IPV6_RECVDSTOPTS	-1
+#endif
+#ifndef IPV6_RECVTCLASS
+#define IPV6_RECVTCLASS		-1
+#endif
+#ifndef IPV6_TCLASS
+#define IPV6_TCLASS		-1
+#endif
+#ifndef IPV6_2292PKTINFO
+#define	IPV6_2292PKTINFO	-1
+#endif
+#ifndef IPV6_2292HOPLIMIT
+#define	IPV6_2292HOPLIMIT	-1
+#endif
+#ifndef IPV6_2292RTHDR
+#define	IPV6_2292RTHDR		-1
+#endif
+#ifndef IPV6_2292HOPOPTS
+#define	IPV6_2292HOPOPTS	-1
+#endif
+#ifndef IPV6_2292DSTOPTS
+#define	IPV6_2292DSTOPTS	-1
+#endif
+
+union soval {
+	struct in6_pktinfo sou_pktinfo;
+	int sou_hoplimit;
+	struct sockaddr_in6 sou_nexthop;
+	struct ip6_rthdr sou_rthdr;
+	struct ip6_hbh sou_hopopts;
+	struct ip6_dest sou_dstopts;
+	struct ip6_dest sou_rthdrdstopts;
+	int sou_tclass;
+	int sou_bool;
+};
+
+/* in6_addr initializer for loopback interface */
+#define IN6_LOOP	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }
+#define IN6_ANY		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+
+/* so_clrval and so_setval members are initilized in the body */
+static struct soent {
+	char *so_tname;
+	int so_opt;
+	int so_dorecv;		/* do receive test? */
+	int so_cmtype;
+	int so_clear;		/* get fresh socket? */
+	union soval so_clrval;
+	union soval so_setval;
+	socklen_t so_valsize;
+} sotab[] = {
+	/* RFC 3542, Section 4 */
+	{"IPV6_RECVPKTINFO", IPV6_RECVPKTINFO, 1, IPV6_PKTINFO, 1,
+	 {{{{{0} } }, 0} }, {{{{{0} } }, 0} }, sizeof(int)},
+	{"IPV6_RECVHOPLIMIT", IPV6_RECVHOPLIMIT, 1, IPV6_HOPLIMIT, 1,
+	 {{{{{0} } }, 0} }, {{{{{0} } }, 0} }, sizeof(int)},
+	{"IPV6_RECVRTHDR", IPV6_RECVRTHDR, 0, IPV6_RTHDR, 1,
+	 {{{{{0} } }, 0} }, {{{{{0} } }, 0} }, sizeof(int)},
+	{"IPV6_RECVHOPOPTS", IPV6_RECVHOPOPTS, 0, IPV6_HOPOPTS, 1,
+	 {{{{{0} } }, 0} }, {{{{{0} } }, 0} }, sizeof(int)},
+	{"IPV6_RECVDSTOPTS", IPV6_RECVDSTOPTS, 0, IPV6_DSTOPTS, 1,
+	 {{{{{0} } }, 0} }, {{{{{0} } }, 0} }, sizeof(int)},
+	{"IPV6_RECVTCLASS", IPV6_RECVTCLASS, 1, IPV6_TCLASS, 1,
+	 {{{{{0} } }, 0} }, {{{{{0} } }, 0} }, sizeof(int)},
+	/* make sure TCLASS stays when setting another opt */
+	{"IPV6_RECVTCLASS (2)", IPV6_RECVHOPLIMIT, 1, IPV6_TCLASS, 0,
+	 {{{{{0} } }, 0} }, {{{{{0} } }, 0} }, sizeof(int)},
+	/* OLD values */
+	{"IPV6_2292PKTINFO", IPV6_2292PKTINFO, 1, IPV6_2292PKTINFO, 1,
+	 {{{{{0} } }, 0} }, {{{{{0} } }, 0} }, sizeof(int)},
+	{"IPV6_2292HOPLIMIT", IPV6_2292HOPLIMIT, 1, IPV6_2292HOPLIMIT, 1,
+	 {{{{{0} } }, 0} }, {{{{{0} } }, 0} }, sizeof(int)},
+	{"IPV6_2292RTHDR", IPV6_2292RTHDR, 0, IPV6_2292RTHDR, 1,
+	 {{{{{0} } }, 0} }, {{{{{0} } }, 0} }, sizeof(int)},
+	{"IPV6_2292HOPOPTS", IPV6_2292HOPOPTS, 0, IPV6_2292HOPOPTS, 1,
+	 {{{{{0} } }, 0} }, {{{{{0} } }, 0} }, sizeof(int)},
+	{"IPV6_2292DSTOPTS", IPV6_2292DSTOPTS, 0, IPV6_2292DSTOPTS, 1,
+	 {{{{{0} } }, 0} }, {{{{{0} } }, 0} }, sizeof(int)},
+};
+
+#define SOCOUNT	ARRAY_SIZE(sotab)
+
+struct soprot {
+	int sop_pid;			/* sender PID */
+	int sop_seq;			/* sequence # */
+	int sop_dlen;			/* tp_dat length */
+	unsigned char sop_dat[0];	/* user data */
+};
+
+static unsigned char tpbuf[sizeof(struct soprot) + 2048];
+static unsigned char rpbuf[sizeof(struct soprot) + 2048];
+
+static unsigned char control[2048];
+
+static int seq;
+
+static struct cme {
+	int cm_len;
+	int cm_level;
+	int cm_type;
+	union {
+		uint32_t cmu_tclass;
+		uint32_t cmu_hops;
+	} cmu;
+} cmtab[] = {
+	{sizeof(uint32_t), SOL_IPV6, IPV6_TCLASS, {0x12} },
+	{sizeof(uint32_t), SOL_IPV6, IPV6_HOPLIMIT, {0x21} },
+};
+
+#define CMCOUNT	ARRAY_SIZE(cmtab)
+
+static ssize_t sendall(int st)
+{
+	struct sockaddr_in6 sin6;
+	struct msghdr msg;
+	struct iovec iov;
+	struct soprot *psop;
+	unsigned char *pd;
+	unsigned int i;
+	int ctotal;
+
+	psop = (struct soprot *)tpbuf;
+	psop->sop_pid = htonl(getpid());
+	psop->sop_seq = ++seq;
+	psop->sop_dlen = 0;
+
+	memset(&sin6, 0, sizeof(sin6));
+	sin6.sin6_family = AF_INET6;
+	sin6.sin6_addr = in6addr_loopback;
+
+	memset(&msg, 0, sizeof(msg));
+	msg.msg_name = &sin6;
+	msg.msg_namelen = sizeof(sin6);
+	iov.iov_base = tpbuf;
+	iov.iov_len = sizeof(struct soprot) + ntohl(psop->sop_dlen);
+	msg.msg_iov = &iov;
+	msg.msg_iovlen = 1;
+
+	pd = control;
+	ctotal = 0;
+	for (i = 0; i < CMCOUNT; ++i) {
+		struct cmsghdr *pcmsg = (struct cmsghdr *)pd;
+
+		pcmsg->cmsg_len = CMSG_LEN(cmtab[i].cm_len);
+		pcmsg->cmsg_level = cmtab[i].cm_level;
+		pcmsg->cmsg_type = cmtab[i].cm_type;
+		memcpy(CMSG_DATA(pcmsg), &cmtab[i].cmu, cmtab[i].cm_len);
+		pd += CMSG_SPACE(cmtab[i].cm_len);
+		ctotal += CMSG_SPACE(cmtab[i].cm_len);
+	}
+	msg.msg_control = ctotal ? control : 0;
+	msg.msg_controllen = ctotal;
+
+	return sendmsg(st, &msg, 0);
+}
+
+static void so_test(struct soent *psoe)
+{
+	struct sockaddr_in6 sin6;
+	union soval sobuf;
+	socklen_t valsize;
+	static int sr = -1;
+	int st;
+
+	if (psoe->so_opt == -1) {
+		tst_brkm(TBROK | TERRNO, NULL, "%s not present at compile time",
+			 psoe->so_tname);
+	}
+	if (psoe->so_clear || sr < 0) {
+		if (sr < 0)
+			close(sr);
+		sr = SAFE_SOCKET(NULL, PF_INET6, SOCK_RAW, NH_TEST);
+	}
+	memset(&sin6, 0, sizeof(sin6));
+	sin6.sin6_family = AF_INET6;
+	sin6.sin6_addr = in6addr_loopback;
+
+	SAFE_BIND(NULL, sr, (struct sockaddr *)&sin6, sizeof(sin6));
+
+	if (setsockopt(sr, SOL_IPV6, psoe->so_opt, &psoe->so_clrval,
+		       psoe->so_valsize) < 0) {
+		tst_brkm(TBROK | TERRNO, NULL, "%s: setsockopt",
+			 psoe->so_tname);
+	}
+
+	TEST(setsockopt(sr, SOL_IPV6, psoe->so_opt, &psoe->so_setval,
+			psoe->so_valsize));
+	if (TEST_RETURN != 0) {
+		tst_resm(TFAIL | TERRNO, "%s set-get: setsockopt",
+			 psoe->so_tname);
+		return;
+	}
+
+	valsize = psoe->so_valsize;
+	TEST(getsockopt(sr, SOL_IPV6, psoe->so_opt, &sobuf, &valsize));
+	if (TEST_RETURN != 0) {
+		tst_brkm(TBROK | TERRNO, NULL, "%s set-get: getsockopt",
+			 psoe->so_tname);
+	} else if (memcmp(&psoe->so_setval, &sobuf, psoe->so_valsize)) {
+		tst_resm(TFAIL, "%s set-get optval != setval", psoe->so_tname);
+	} else {
+		tst_resm(TPASS, "%s set-get", psoe->so_tname);
+	}
+
+	st = SAFE_SOCKET(NULL, PF_INET6, SOCK_RAW, NH_TEST);
+
+	if (sendall(st) < 0)
+		tst_brkm(TBROK | TERRNO, NULL, "%s transmit sendto",
+			 psoe->so_tname);
+
+	close(st);
+
+	/* receiver processing */
+	{
+		fd_set rfds, rfds_saved;
+		int nfds, cc;
+		int gotone;
+		struct timeval tv;
+		struct msghdr msg;
+		unsigned char cmsg[2048];
+		struct cmsghdr *pcmsg;
+		struct iovec iov;
+
+		FD_ZERO(&rfds_saved);
+		FD_SET(sr, &rfds_saved);
+
+		tv.tv_sec = 0;
+		tv.tv_usec = 250000;
+
+		while (1) {
+			memcpy(&rfds, &rfds_saved, sizeof(rfds));
+			nfds = select(sr + 1, &rfds, 0, 0, &tv);
+			if (nfds < 0) {
+				if (errno == EINTR)
+					continue;
+				tst_brkm(TBROK | TERRNO, NULL, "%s select",
+					 psoe->so_tname);
+			}
+			if (nfds == 0) {
+				tst_brkm(TBROK, NULL, "%s recvmsg timed out",
+					 psoe->so_tname);
+				return;
+			}
+			/* else, nfds == 1 */
+			if (!FD_ISSET(sr, &rfds))
+				continue;
+
+			memset(&msg, 0, sizeof(msg));
+			iov.iov_base = rpbuf;
+			iov.iov_len = sizeof(rpbuf);
+			msg.msg_iov = &iov;
+			msg.msg_iovlen = 1;
+			msg.msg_control = cmsg;
+			msg.msg_controllen = sizeof(cmsg);
+
+			cc = recvmsg(sr, &msg, 0);
+			if (cc < 0) {
+				tst_brkm(TBROK | TERRNO, NULL, "%s recvmsg",
+					 psoe->so_tname);
+			}
+			/* check pid & seq here */
+			break;
+		}
+		gotone = 0;
+		for (pcmsg = CMSG_FIRSTHDR(&msg); pcmsg != NULL;
+		     pcmsg = CMSG_NXTHDR(&msg, pcmsg)) {
+			if (!psoe->so_dorecv)
+				break;
+			gotone = pcmsg->cmsg_level == SOL_IPV6 &&
+			    pcmsg->cmsg_type == psoe->so_cmtype;
+			if (gotone) {
+				break;
+			} else if (psoe->so_clear) {
+				tst_resm(TFAIL, "%s receive: extraneous data "
+					 "in control: level %d type %d len %zu",
+					 psoe->so_tname, pcmsg->cmsg_level,
+					 pcmsg->cmsg_type, pcmsg->cmsg_len);
+				return;
+			}
+		}
+		/* check contents here */
+		if (psoe->so_dorecv)
+			tst_resm(gotone ? TPASS : TFAIL, "%s receive",
+				 psoe->so_tname);
+	}
+}
+
+static void do_tests(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < SOCOUNT; ++i) {
+		sotab[i].so_clrval.sou_bool = 0;
+		sotab[i].so_setval.sou_bool = 1;
+		so_test(&sotab[i]);
+	}
+}
+
+static void setup(void)
+{
+	TEST_PAUSE;
+}
diff --git a/testcases/network/lib6/asapi_04.c b/testcases/network/lib6/asapi_04.c
deleted file mode 100644
index df26494..0000000
--- a/testcases/network/lib6/asapi_04.c
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
- * Copyright (c) 2015 Fujitsu Ltd.
- * Copyright (c) International Business Machines  Corp., 2001
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * Author: David L Stevens
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <netdb.h>
-#include <libgen.h>
-#include <pthread.h>
-#include <semaphore.h>
-
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-#include "test.h"
-#include "safe_macros.h"
-
-char *TCID = "asapi_04";
-
-static pid_t pid;
-
-static struct {
-	char *prt_name;
-	int prt_value;
-} ptab[] = {
-	{"hopopt", 0},
-	{"ipv6", 41},
-	{"ipv6-route", 43},
-	{"ipv6-frag", 44},
-	{"esp", 50},
-	{"ah", 51},
-	{"ipv6-icmp", 58},
-	{"ipv6-nonxt", 59},
-	{"ipv6-opts", 60},
-};
-
-#define PTCOUNT		ARRAY_SIZE(ptab)
-#define READ_TIMEOUT	5
-
-static void do_tests(void);
-static void setup(void);
-static void csum_test(void);
-
-int main(int argc, char *argv[])
-{
-	int lc;
-
-	tst_parse_opts(argc, argv, 0, 0);
-
-	setup();
-
-	for (lc = 0; TEST_LOOPING(lc); ++lc)
-		do_tests();
-
-	tst_exit();
-}
-
-static void do_tests(void)
-{
-	unsigned int i;
-
-/* RFC 3542, Section 2.3 */
-#ifndef IN6_ARE_ADDR_EQUAL
-	tst_resm(TCONF, "IN6_ARE_ADDR_EQUAL not present");
-#else /* IN6_ARE_ADDR_EQUAL */
-	/*
-	 * set each bit in an address and check for unequal; then set
-	 * in the second address and check for equal. Covers all bits, all
-	 * combinations.
-	 */
-	struct in6_addr a1, a2;
-	int word, bit;
-	int rv = 1;
-
-	memset(&a1, 0, sizeof(a1));
-	memset(&a2, 0, sizeof(a2));
-
-	rv = IN6_ARE_ADDR_EQUAL(&a1, &a2);
-
-	for (word = 0; word < 4; ++word) {
-		for (bit = 0; bit < 32; ++bit) {
-			uint32_t newbit = 1U << bit;
-
-			a1.s6_addr32[word] |= newbit;
-			rv &= !IN6_ARE_ADDR_EQUAL(&a1, &a2);
-			a2.s6_addr32[word] |= newbit;
-			rv &= IN6_ARE_ADDR_EQUAL(&a1, &a2);
-		}
-	}
-
-	tst_resm(rv ? TPASS : TFAIL, "IN6_ARE_ADDR_EQUAL");
-#endif /* IN6_ARE_ADDR_EQUAL */
-
-/* RFC 3542, Section 2.4 */
-	for (i = 0; i < PTCOUNT; ++i) {
-		struct protoent *pe;
-		int pass;
-
-		pe = getprotobyname(ptab[i].prt_name);
-		pass = pe && pe->p_proto == ptab[i].prt_value;
-		tst_resm(pass ? TPASS : TFAIL, "\"%s\" protocols entry",
-			 ptab[i].prt_name);
-	}
-/* RFC 3542, Section 3.1 */
-	csum_test();
-}
-
-/*
- * this next-header value shouldn't be a real protocol!!
- * 0x9f = 01 0 11111
- *         | |     |
- *         | |     |--- rest- ~0
- *         | |--------- chg - "no change enroute"
- *         |----------- act - "discard unknown"
- */
-#define	NH_TEST	0x9f
-
-struct tprot {
-	int tp_pid;		/* sender PID */
-	int tp_seq;		/* sequence # */
-	int tp_offset;		/* offset of cksum */
-	int tp_dlen;		/* tp_dat length */
-	unsigned char tp_dat[0];	/* user data */
-};
-
-static unsigned char tpbuf[sizeof(struct tprot) + 2048];
-static unsigned char rpbuf[sizeof(struct tprot) + 2048];
-
-static struct csent {
-	int cs_offset;
-	int cs_dlen;
-	int cs_setresult;	/* setsockopt expected result */
-	int cs_seterrno;	/* setsockopt expected errno */
-	int cs_sndresult;	/* send expected result */
-	int cs_snderrno;	/* send expected errno */
-} cstab[] = {
-	{0, 5, 0, 0, 0, 0},
-	{6, 30, 0, 0, 0, 0},
-	{3, 20, -1, EINVAL, -1, -1},	/* non-aligned offset */
-	{4, 5, 0, 0, -1, EINVAL},	/* not enough space */
-	{50, 5, 0, 0, -1, EINVAL},	/* outside of packet */
-	{22, 30, 0, 0, 0, 0},
-	{2000, 2004, 0, 0, 0, 0},	/* in a fragment (over Ethernet) */
-};
-
-#define CSCOUNT	ARRAY_SIZE(cstab)
-
-int TST_TOTAL = PTCOUNT + CSCOUNT;
-
-static int recvtprot(int sd, unsigned char *packet)
-{
-	struct tprot *tpt;
-	int cc;
-	unsigned int total, expected;
-	int gothead;
-
-	tpt = (struct tprot *)packet;
-	total = cc = recv(sd, packet, sizeof(struct tprot), 0);
-	expected = sizeof(struct tprot);	/* until we get tp_dlen */
-	gothead = total >= sizeof(struct tprot);
-	if (gothead)
-		expected += ntohl(tpt->tp_dlen);
-	if (cc <= 0)
-		return cc;
-	while (cc > 0 && total < expected) {
-		cc = recv(sd, &packet[total], expected - total, 0);
-		if (cc >= 0) {
-			total += cc;
-			if (!gothead && total >= sizeof(struct tprot)) {
-				gothead = 1;
-				expected += ntohl(tpt->tp_dlen);
-			}
-		} else {
-			break;
-		}
-	}
-	if (cc < 0)
-		return cc;
-	return total;
-}
-
-static unsigned short csum(unsigned short partial, unsigned char *packet,
-			   int len)
-{
-	unsigned long sum = partial;
-	unsigned short *ps;
-	int i;
-
-	ps = (unsigned short *)packet;
-	for (i = 0; i < len / 2; ++i)
-		sum += *ps++;
-	if (len & 1)
-		sum += htons(packet[len - 1] << 8);
-	sum = (sum >> 16) + (sum & 0xffff);
-	sum += (sum >> 16);
-	return ~sum;
-}
-
-static struct ph {
-	struct in6_addr ph_sa;
-	struct in6_addr ph_da;
-	uint32_t ph_len;
-	uint8_t ph_mbz[3];
-	uint8_t ph_nh;
-} ph;
-
-static int client(int sfd)
-{
-	struct tprot *pttp = (struct tprot *)tpbuf;
-	struct tprot *prtp = (struct tprot *)rpbuf;
-	struct sockaddr_in6 rsin6;
-	static int seq;
-	unsigned int i;
-	int sd, cc, cs;
-
-	memset(&rsin6, 0, sizeof(rsin6));
-	rsin6.sin6_family = AF_INET6;
-	rsin6.sin6_addr = in6addr_loopback;
-
-	memset(&ph, 0, sizeof(ph));
-	ph.ph_sa = rsin6.sin6_addr;
-	ph.ph_da = rsin6.sin6_addr;
-	ph.ph_nh = NH_TEST;
-
-	sd = SAFE_SOCKET(NULL, PF_INET6, SOCK_RAW, NH_TEST);
-
-	for (i = 0; i < CSCOUNT; ++i) {
-		int offset, len, xlen;
-		int rv;
-		unsigned char *p, *pend;
-
-		offset = sizeof(struct tprot) + cstab[i].cs_offset;
-		len = sizeof(struct tprot) + cstab[i].cs_dlen;
-
-		memset(pttp, 0, sizeof(*pttp));
-		memset(pttp->tp_dat, 0xA5, cstab[i].cs_dlen);
-
-		pttp->tp_pid = htonl(pid);
-		pttp->tp_offset = ntohl(offset);
-		pttp->tp_dlen = ntohl(cstab[i].cs_dlen);
-		pttp->tp_seq = ntohl(++seq);
-
-		TEST(setsockopt(sd, IPPROTO_IPV6, IPV6_CHECKSUM, &offset,
-				sizeof(offset)));
-		if (TEST_RETURN != cstab[i].cs_setresult) {
-			tst_resm(TFAIL | TTERRNO,
-				 "IPV6_CHECKSUM offset %d len %d "
-				 "- result %ld != %d", offset, len, TEST_RETURN,
-				 cstab[i].cs_setresult);
-			continue;
-		}
-		if (TEST_RETURN < 0) {
-			tst_resm(TPASS, "IPV6_CHECKSUM offset %d len %d",
-				 offset, len);
-			continue;
-		}
-		if (TEST_RETURN && TEST_ERRNO != cstab[i].cs_seterrno) {
-			tst_resm(TFAIL, "IPV6_CHECKSUM offset %d len %d "
-				 "- errno %d != %d", offset, len,
-				 TEST_ERRNO, cstab[i].cs_seterrno);
-			continue;
-		}
-		/* send packet */
-		TEST(sendto(sd, pttp, len, 0, (struct sockaddr *)&rsin6,
-			    sizeof(rsin6)));
-		xlen = (cstab[i].cs_sndresult < 0) ? -1 : len;
-		if (TEST_RETURN != xlen) {
-			tst_resm(TFAIL | TTERRNO,
-				 "IPV6_CHECKSUM offset %d len %d "
-				 "- sndresult %ld != %d", offset, len,
-				 TEST_RETURN, xlen);
-			continue;
-		}
-		if (TEST_RETURN < 0 && TEST_ERRNO != cstab[i].cs_snderrno) {
-			tst_resm(TFAIL, "IPV6_CHECKSUM offset %d len %d "
-				 "- snderrno %d != %d", offset, len,
-				 TEST_ERRNO, cstab[i].cs_snderrno);
-			continue;
-		}
-		if (TEST_RETURN < 0) {
-			tst_resm(TPASS, "IPV6_CHECKSUM offset %d len %d",
-				 offset, len);
-			continue;
-		}
-		while ((cc = recvtprot(sfd, rpbuf))) {
-			if (htonl(prtp->tp_pid) == (uint32_t)pid &&
-			    htonl(prtp->tp_seq) == (uint32_t)seq)
-				break;
-		}
-		rv = 1;
-		pend = rpbuf + sizeof(struct tprot) + ntohl(prtp->tp_dlen);
-		for (p = &prtp->tp_dat[0]; p < pend; ++p) {
-			if (p == &rpbuf[offset] || p == &rpbuf[offset + 1])
-				continue;
-			if (*p != 0xa5) {
-				tst_resm(TFAIL, "IPV6_CHECKSUM corrupt data "
-					 "0x%02x != 0xa5 at offset %zd in packet",
-					 *p, p - rpbuf);
-				rv = 0;
-				break;
-			}
-		}
-		if (rv == 0)
-			continue;
-		ph.ph_len = htonl(xlen);
-		cs = csum(0, (unsigned char *)&ph, sizeof(ph));
-		cs = csum(~cs, rpbuf, xlen);
-		if (!csum(0, rpbuf, xlen)) {
-			tst_resm(TFAIL, "IPV6_CHECKSUM offset %d len %d (bad "
-				 "checksum)", offset, len);
-			continue;
-		}
-		tst_resm(TPASS, "IPV6_CHECKSUM offset %d len %d", offset, len);
-	}
-	return 0;
-}
-
-static int listen_fd, connect_fd;
-
-static void *ilistener(void *arg LTP_ATTRIBUTE_UNUSED)
-{
-	connect_fd = accept(listen_fd, 0, 0);
-	close(listen_fd);
-	return NULL;
-}
-
-static void isocketpair(int pf, int type, int proto, int fd[2])
-{
-	pthread_t thid;
-	struct sockaddr_in sin4;
-	socklen_t namelen;
-
-	listen_fd = SAFE_SOCKET(NULL, pf, type, proto);
-
-	memset(&sin4, 0, sizeof(sin4));
-
-	SAFE_BIND(NULL, listen_fd, (struct sockaddr *)&sin4, sizeof(sin4));
-
-	SAFE_LISTEN(NULL, listen_fd, 10);
-
-	namelen = sizeof(sin4);
-	SAFE_GETSOCKNAME(NULL, listen_fd, (struct sockaddr *)&sin4, &namelen);
-
-	if (pthread_create(&thid, 0, ilistener, 0) < 0)
-		tst_brkm(TBROK | TERRNO, NULL, "pthread_create error");
-
-	fd[0] = SAFE_SOCKET(NULL, pf, type, proto);
-
-	sin4.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-
-	SAFE_CONNECT(NULL, fd[0], (struct sockaddr *)&sin4, sizeof(sin4));
-
-	pthread_join(thid, NULL);
-
-	fd[1] = connect_fd;
-}
-
-#ifndef MAX
-#define MAX(a, b) ((a) >= (b) ? (a) : (b))
-#endif /* MAX */
-
-static void csum_test(void)
-{
-	fd_set rset, rset_save;
-	int csd[2];		/* control sockets */
-	int sd, nfds, maxfd, cc;
-	struct timeval tv;
-
-	isocketpair(PF_INET, SOCK_STREAM, 0, csd);
-
-	sd = SAFE_SOCKET(NULL, PF_INET6, SOCK_RAW, NH_TEST);
-
-	FD_ZERO(&rset_save);
-	FD_SET(sd, &rset_save);
-	FD_SET(csd[1], &rset_save);
-	memcpy(&rset, &rset_save, sizeof(rset));
-	maxfd = MAX(sd, csd[1]);
-
-	/* server socket set; now start the client */
-	switch (fork()) {
-	case 0:
-		close(csd[0]);
-		break;
-	case -1:
-		tst_brkm(TBROK, NULL, "can't fork rserver");
-	default:
-		close(sd);
-		close(csd[1]);
-		client(csd[0]);
-		return;
-	}
-
-	tv.tv_sec = READ_TIMEOUT;
-	tv.tv_usec = 0;
-	while ((nfds = select(maxfd + 1, &rset, 0, 0, &tv)) >= 0) {
-		if (nfds < 0) {
-			if (errno == EINTR)
-				continue;
-			exit(0);
-		} else if (nfds == 0) {
-			fprintf(stderr, "server read timed out");
-			return;
-		}
-		if (FD_ISSET(sd, &rset)) {
-			static char packet[2048];
-
-			cc = recv(sd, packet, sizeof(packet), 0);
-			if (cc < 0) {
-				perror("server recvtprot");
-				exit(1);
-			}
-			if (cc == 0)
-				exit(0);
-			if (write(csd[1], packet, cc) < 0) {
-				perror("server write UNIX socket");
-				exit(0);
-			}
-		}
-		if (FD_ISSET(csd[1], &rset)) {
-			char buf[2048];
-
-			cc = read(csd[1], buf, sizeof(buf));
-			if (cc == 0)
-				exit(0);
-			if (cc < 0) {
-				perror("server read");
-				exit(1);
-			}
-			/* handle commands here, if any added later */
-		}
-		memcpy(&rset, &rset_save, sizeof(rset));
-		tv.tv_sec = READ_TIMEOUT;
-		tv.tv_usec = 0;
-	}
-}
-
-static void setup(void)
-{
-	TEST_PAUSE;
-
-	pid = getpid();
-}
diff --git a/testcases/network/lib6/asapi_05.c b/testcases/network/lib6/asapi_05.c
deleted file mode 100644
index f8c30f1..0000000
--- a/testcases/network/lib6/asapi_05.c
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Copyright (c) 2015 Fujitsu Ltd.
- * Copyright (c) International Business Machines  Corp., 2001
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * Author: David L Stevens
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <sys/wait.h>
-#include <sys/socket.h>
-
-#include <netinet/in.h>
-#include <netinet/ip6.h>
-#include <netinet/icmp6.h>
-
-#include "test.h"
-#include "safe_macros.h"
-
-char *TCID = "asapi_05";
-
-static void setup(void);
-
-static void icmp6_ft(void);
-
-int main(int argc, char *argv[])
-{
-	int lc;
-
-	tst_parse_opts(argc, argv, NULL, NULL);
-
-	setup();
-
-	for (lc = 0; TEST_LOOPING(lc); ++lc)
-		icmp6_ft();
-
-	tst_exit();
-}
-
-static void setup(void)
-{
-	TEST_PAUSE;
-	tst_require_root();
-}
-
-enum tt {
-	T_WILLPASS,
-	T_WILLBLOCK,
-	T_SETPASS,
-	T_SETBLOCK,
-	T_SETPASSALL,
-	T_SETBLOCKALL
-};
-
-static struct ftent {
-	char *ft_tname;			/* test name, for logging */
-	unsigned char ft_sndtype;	/* send type field */
-	unsigned char ft_flttype;	/* filter type field */
-	enum tt ft_test;		/* what macro to test */
-	int ft_expected;		/* packet should pass? */
-} ftab[] = {
-	{"ICMP6_FILTER_SETPASS s 20 f 20", 20, 20, T_SETPASS, 1},
-	{"ICMP6_FILTER_SETPASS s 20 f 21", 20, 21, T_SETPASS, 0},
-	{"ICMP6_FILTER_SETBLOCK s 20 f 20", 20, 20, T_SETBLOCK, 0},
-	{"ICMP6_FILTER_SETBLOCK s 20 f 21", 20, 21, T_SETBLOCK, 1},
-	{"ICMP6_FILTER_PASSALL s 20", 20, 0, T_SETPASSALL, 1},
-	{"ICMP6_FILTER_PASSALL s 20", 21, 0, T_SETPASSALL, 1},
-	{"ICMP6_FILTER_BLOCKALL s 20", 20, 0, T_SETBLOCKALL, 0},
-	{"ICMP6_FILTER_BLOCKALL s 20", 21, 0, T_SETBLOCKALL, 0},
-	{"ICMP6_FILTER_WILLBLOCK s 20 f 21", 20, 21, T_WILLBLOCK, 0},
-	{"ICMP6_FILTER_WILLBLOCK s 20 f 20", 20, 20, T_WILLBLOCK, 1},
-	{"ICMP6_FILTER_WILLPASS s 20 f 21", 20, 21, T_WILLPASS, 0},
-	{"ICMP6_FILTER_WILLPASS s 22 f 22", 22, 22, T_WILLPASS, 1},
-};
-
-#define FTCOUNT	ARRAY_SIZE(ftab)
-
-static int ic6_send1(char *tname, unsigned char type)
-{
-	struct sockaddr_in6 sin6;
-	struct icmp6_hdr ic6;
-	int s;
-
-	s = SAFE_SOCKET(NULL, AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
-
-	memset(&ic6, 0, sizeof(ic6));
-	ic6.icmp6_type = type;
-	ic6.icmp6_data32[0] = htonl(getpid());
-
-	memset(&sin6, 0, sizeof(sin6));
-	sin6.sin6_family = AF_INET6;
-	sin6.sin6_addr = in6addr_loopback;
-	if (sendto(s, &ic6, sizeof(ic6), 0, (struct sockaddr *)&sin6,
-		   sizeof(sin6)) == -1) {
-		tst_resm(TBROK | TERRNO, "%s: sendto failed", tname);
-		return 1;
-	}
-	return 0;
-}
-
-static int ic6_recv1(char *tname, int sall, int sf)
-{
-	fd_set readfds, readfds_saved;
-	struct timeval tv;
-	int maxfd, nfds;
-	int gotall, gotone;
-	int cc;
-	static unsigned char rbuf[2048];
-
-	tv.tv_sec = 0;
-	tv.tv_usec = 250000;
-
-	FD_ZERO(&readfds_saved);
-	FD_SET(sall, &readfds_saved);
-	FD_SET(sf, &readfds_saved);
-	maxfd = MAX(sall, sf);
-
-	memcpy(&readfds, &readfds_saved, sizeof(readfds));
-
-	gotall = gotone = 0;
-	/*
-	 * Note: this relies on linux-specific behavior (select
-	 * updating tv with time elapsed)
-	 */
-	while (!gotall || !gotone) {
-		struct icmp6_hdr *pic6 = (struct icmp6_hdr *)rbuf;
-
-		nfds = select(maxfd + 1, &readfds, 0, 0, &tv);
-		if (nfds == 0)
-			break;	/* timed out */
-		if (nfds < 0) {
-			if (errno == EINTR)
-				continue;
-			tst_resm(TBROK | TERRNO, "%s: select failed", tname);
-		}
-		if (FD_ISSET(sall, &readfds)) {
-			cc = recv(sall, rbuf, sizeof(rbuf), 0);
-			if (cc < 0) {
-				tst_resm(TBROK | TERRNO,
-					 "%s: recv(sall, ..) failed", tname);
-				return -1;
-			}
-			/* if packet check succeeds... */
-			if (htonl(pic6->icmp6_data32[0]) == (uint32_t)getpid())
-				gotall = 1;
-		}
-		if (FD_ISSET(sf, &readfds)) {
-			cc = recv(sf, rbuf, sizeof(rbuf), 0);
-			if (cc < 0) {
-				tst_resm(TBROK | TERRNO,
-					 "%s: recv(sf, ..) failed", tname);
-				return -1;
-			}
-			/* if packet check succeeds... */
-			if (htonl(pic6->icmp6_data32[0]) == (uint32_t)getpid())
-				gotone = 1;
-		}
-		memcpy(&readfds, &readfds_saved, sizeof(readfds));
-	}
-	if (!gotall) {
-		tst_resm(TBROK, "%s: recv all timed out", tname);
-		return -1;
-	}
-	if (gotone)
-		return 1;
-	return 0;
-}
-
-/* functional tests */
-static void icmp6_ft(void)
-{
-	struct icmp6_filter i6f;
-	int sall, sf;
-	unsigned int i;
-
-	sall = SAFE_SOCKET(NULL, PF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
-
-	ICMP6_FILTER_SETPASSALL(&i6f);
-	if (setsockopt(sall, IPPROTO_ICMPV6, ICMP6_FILTER, &i6f,
-		       sizeof(i6f)) < 0) {
-		tst_resm(TBROK | TERRNO,
-			 "setsockopt pass all ICMP6_FILTER failed");
-	}
-
-	sf = SAFE_SOCKET(NULL, PF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
-
-	int rv;
-
-	for (i = 0; i < FTCOUNT; ++i) {
-
-		rv = -1;
-
-		switch (ftab[i].ft_test) {
-		case T_SETPASS:
-			ICMP6_FILTER_SETBLOCKALL(&i6f);
-			ICMP6_FILTER_SETPASS(ftab[i].ft_flttype, &i6f);
-			break;
-		case T_SETPASSALL:
-			ICMP6_FILTER_SETPASSALL(&i6f);
-			break;
-		case T_SETBLOCK:
-			ICMP6_FILTER_SETPASSALL(&i6f);
-			ICMP6_FILTER_SETBLOCK(ftab[i].ft_flttype, &i6f);
-			break;
-		case T_SETBLOCKALL:
-			ICMP6_FILTER_SETBLOCKALL(&i6f);
-			break;
-		case T_WILLBLOCK:
-			ICMP6_FILTER_SETPASSALL(&i6f);
-			ICMP6_FILTER_SETBLOCK(ftab[i].ft_flttype, &i6f);
-			rv = ICMP6_FILTER_WILLBLOCK(ftab[i].ft_sndtype, &i6f);
-			break;
-		case T_WILLPASS:
-			ICMP6_FILTER_SETBLOCKALL(&i6f);
-			ICMP6_FILTER_SETPASS(ftab[i].ft_flttype, &i6f);
-			rv = ICMP6_FILTER_WILLPASS(ftab[i].ft_sndtype, &i6f);
-			break;
-		default:
-			tst_resm(TBROK, "%s: unknown test type %d",
-				 ftab[i].ft_tname, ftab[i].ft_test);
-			continue;
-		}
-		if (ftab[i].ft_test != T_WILLBLOCK &&
-		    ftab[i].ft_test != T_WILLPASS) {
-			if (setsockopt(sf, IPPROTO_ICMPV6, ICMP6_FILTER, &i6f,
-				       sizeof(i6f)) < 0) {
-				tst_resm(TFAIL | TERRNO,
-					 "setsockopt ICMP6_FILTER");
-				continue;
-			}
-			if (ic6_send1(ftab[i].ft_tname, ftab[i].ft_sndtype))
-				continue;
-			rv = ic6_recv1(ftab[i].ft_tname, sall, sf);
-		} else {
-			rv = -1;
-		}
-
-		if (rv < 0)
-			continue;
-		if (rv != ftab[i].ft_expected)
-			tst_resm(TFAIL, "%s: rv %d != expected %d",
-				 ftab[i].ft_tname, rv, ftab[i].ft_expected);
-		else
-			tst_resm(TPASS, "%s", ftab[i].ft_tname);
-	}
-}
diff --git a/testcases/network/lib6/asapi_06.c b/testcases/network/lib6/asapi_06.c
deleted file mode 100644
index c6e2c8e..0000000
--- a/testcases/network/lib6/asapi_06.c
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * Copyright (c) 2015 Fujitsu Ltd.
- * Copyright (c) International Business Machines  Corp., 2001
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * Author: David L Stevens
- */
-
-#include "config.h"
-
-#include <stdio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <netdb.h>
-#include <libgen.h>
-#include <pthread.h>
-#include <semaphore.h>
-
-#include <sys/time.h>
-#include <netinet/in.h>
-#include <netinet/ip6.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <net/if.h>
-#include <sys/ioctl.h>
-#ifdef HAVE_IFADDRS_H
-#include <ifaddrs.h>
-#endif
-#include <arpa/inet.h>
-
-#include "test.h"
-#include "safe_macros.h"
-
-char *TCID = "asapi_06";
-
-int TST_TOTAL = 1;
-
-#define READ_TIMEOUT	5	/* secs */
-
-static void do_tests(void);
-static void setup(void);
-
-int main(int argc, char *argv[])
-{
-	int lc;
-
-	tst_parse_opts(argc, argv, NULL, NULL);
-
-	setup();
-
-	for (lc = 0; TEST_LOOPING(lc); ++lc)
-		do_tests();
-
-	tst_exit();
-}
-
-#define NH_TEST	0x9f
-
-#ifndef IPV6_RECVPKTINFO
-#define IPV6_RECVPKTINFO	-1
-#endif
-#ifndef IPV6_RECVHOPLIMIT
-#define IPV6_RECVHOPLIMIT	-1
-#endif
-#ifndef IPV6_RECVRTHDR
-#define IPV6_RECVRTHDR		-1
-#endif
-#ifndef IPV6_RECVHOPOPTS
-#define IPV6_RECVHOPOPTS	-1
-#endif
-#ifndef IPV6_RECVDSTOPTS
-#define IPV6_RECVDSTOPTS	-1
-#endif
-#ifndef IPV6_RECVTCLASS
-#define IPV6_RECVTCLASS		-1
-#endif
-#ifndef IPV6_TCLASS
-#define IPV6_TCLASS		-1
-#endif
-#ifndef IPV6_2292PKTINFO
-#define	IPV6_2292PKTINFO	-1
-#endif
-#ifndef IPV6_2292HOPLIMIT
-#define	IPV6_2292HOPLIMIT	-1
-#endif
-#ifndef IPV6_2292RTHDR
-#define	IPV6_2292RTHDR		-1
-#endif
-#ifndef IPV6_2292HOPOPTS
-#define	IPV6_2292HOPOPTS	-1
-#endif
-#ifndef IPV6_2292DSTOPTS
-#define	IPV6_2292DSTOPTS	-1
-#endif
-
-union soval {
-	struct in6_pktinfo sou_pktinfo;
-	int sou_hoplimit;
-	struct sockaddr_in6 sou_nexthop;
-	struct ip6_rthdr sou_rthdr;
-	struct ip6_hbh sou_hopopts;
-	struct ip6_dest sou_dstopts;
-	struct ip6_dest sou_rthdrdstopts;
-	int sou_tclass;
-	int sou_bool;
-};
-
-/* in6_addr initializer for loopback interface */
-#define IN6_LOOP	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }
-#define IN6_ANY		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
-
-/* so_clrval and so_setval members are initilized in the body */
-static struct soent {
-	char *so_tname;
-	int so_opt;
-	int so_dorecv;		/* do receive test? */
-	int so_cmtype;
-	int so_clear;		/* get fresh socket? */
-	union soval so_clrval;
-	union soval so_setval;
-	socklen_t so_valsize;
-} sotab[] = {
-	/* RFC 3542, Section 4 */
-	{"IPV6_RECVPKTINFO", IPV6_RECVPKTINFO, 1, IPV6_PKTINFO, 1,
-	 {{{{{0} } }, 0} }, {{{{{0} } }, 0} }, sizeof(int)},
-	{"IPV6_RECVHOPLIMIT", IPV6_RECVHOPLIMIT, 1, IPV6_HOPLIMIT, 1,
-	 {{{{{0} } }, 0} }, {{{{{0} } }, 0} }, sizeof(int)},
-	{"IPV6_RECVRTHDR", IPV6_RECVRTHDR, 0, IPV6_RTHDR, 1,
-	 {{{{{0} } }, 0} }, {{{{{0} } }, 0} }, sizeof(int)},
-	{"IPV6_RECVHOPOPTS", IPV6_RECVHOPOPTS, 0, IPV6_HOPOPTS, 1,
-	 {{{{{0} } }, 0} }, {{{{{0} } }, 0} }, sizeof(int)},
-	{"IPV6_RECVDSTOPTS", IPV6_RECVDSTOPTS, 0, IPV6_DSTOPTS, 1,
-	 {{{{{0} } }, 0} }, {{{{{0} } }, 0} }, sizeof(int)},
-	{"IPV6_RECVTCLASS", IPV6_RECVTCLASS, 1, IPV6_TCLASS, 1,
-	 {{{{{0} } }, 0} }, {{{{{0} } }, 0} }, sizeof(int)},
-	/* make sure TCLASS stays when setting another opt */
-	{"IPV6_RECVTCLASS (2)", IPV6_RECVHOPLIMIT, 1, IPV6_TCLASS, 0,
-	 {{{{{0} } }, 0} }, {{{{{0} } }, 0} }, sizeof(int)},
-	/* OLD values */
-	{"IPV6_2292PKTINFO", IPV6_2292PKTINFO, 1, IPV6_2292PKTINFO, 1,
-	 {{{{{0} } }, 0} }, {{{{{0} } }, 0} }, sizeof(int)},
-	{"IPV6_2292HOPLIMIT", IPV6_2292HOPLIMIT, 1, IPV6_2292HOPLIMIT, 1,
-	 {{{{{0} } }, 0} }, {{{{{0} } }, 0} }, sizeof(int)},
-	{"IPV6_2292RTHDR", IPV6_2292RTHDR, 0, IPV6_2292RTHDR, 1,
-	 {{{{{0} } }, 0} }, {{{{{0} } }, 0} }, sizeof(int)},
-	{"IPV6_2292HOPOPTS", IPV6_2292HOPOPTS, 0, IPV6_2292HOPOPTS, 1,
-	 {{{{{0} } }, 0} }, {{{{{0} } }, 0} }, sizeof(int)},
-	{"IPV6_2292DSTOPTS", IPV6_2292DSTOPTS, 0, IPV6_2292DSTOPTS, 1,
-	 {{{{{0} } }, 0} }, {{{{{0} } }, 0} }, sizeof(int)},
-};
-
-#define SOCOUNT	ARRAY_SIZE(sotab)
-
-struct soprot {
-	int sop_pid;			/* sender PID */
-	int sop_seq;			/* sequence # */
-	int sop_dlen;			/* tp_dat length */
-	unsigned char sop_dat[0];	/* user data */
-};
-
-static unsigned char tpbuf[sizeof(struct soprot) + 2048];
-static unsigned char rpbuf[sizeof(struct soprot) + 2048];
-
-static unsigned char control[2048];
-
-static int seq;
-
-static struct cme {
-	int cm_len;
-	int cm_level;
-	int cm_type;
-	union {
-		uint32_t cmu_tclass;
-		uint32_t cmu_hops;
-	} cmu;
-} cmtab[] = {
-	{sizeof(uint32_t), SOL_IPV6, IPV6_TCLASS, {0x12} },
-	{sizeof(uint32_t), SOL_IPV6, IPV6_HOPLIMIT, {0x21} },
-};
-
-#define CMCOUNT	ARRAY_SIZE(cmtab)
-
-static ssize_t sendall(int st)
-{
-	struct sockaddr_in6 sin6;
-	struct msghdr msg;
-	struct iovec iov;
-	struct soprot *psop;
-	unsigned char *pd;
-	unsigned int i;
-	int ctotal;
-
-	psop = (struct soprot *)tpbuf;
-	psop->sop_pid = htonl(getpid());
-	psop->sop_seq = ++seq;
-	psop->sop_dlen = 0;
-
-	memset(&sin6, 0, sizeof(sin6));
-	sin6.sin6_family = AF_INET6;
-	sin6.sin6_addr = in6addr_loopback;
-
-	memset(&msg, 0, sizeof(msg));
-	msg.msg_name = &sin6;
-	msg.msg_namelen = sizeof(sin6);
-	iov.iov_base = tpbuf;
-	iov.iov_len = sizeof(struct soprot) + ntohl(psop->sop_dlen);
-	msg.msg_iov = &iov;
-	msg.msg_iovlen = 1;
-
-	pd = control;
-	ctotal = 0;
-	for (i = 0; i < CMCOUNT; ++i) {
-		struct cmsghdr *pcmsg = (struct cmsghdr *)pd;
-
-		pcmsg->cmsg_len = CMSG_LEN(cmtab[i].cm_len);
-		pcmsg->cmsg_level = cmtab[i].cm_level;
-		pcmsg->cmsg_type = cmtab[i].cm_type;
-		memcpy(CMSG_DATA(pcmsg), &cmtab[i].cmu, cmtab[i].cm_len);
-		pd += CMSG_SPACE(cmtab[i].cm_len);
-		ctotal += CMSG_SPACE(cmtab[i].cm_len);
-	}
-	msg.msg_control = ctotal ? control : 0;
-	msg.msg_controllen = ctotal;
-
-	return sendmsg(st, &msg, 0);
-}
-
-static void so_test(struct soent *psoe)
-{
-	struct sockaddr_in6 sin6;
-	union soval sobuf;
-	socklen_t valsize;
-	static int sr = -1;
-	int st;
-
-	if (psoe->so_opt == -1) {
-		tst_brkm(TBROK | TERRNO, NULL, "%s not present at compile time",
-			 psoe->so_tname);
-	}
-	if (psoe->so_clear || sr < 0) {
-		if (sr < 0)
-			close(sr);
-		sr = SAFE_SOCKET(NULL, PF_INET6, SOCK_RAW, NH_TEST);
-	}
-	memset(&sin6, 0, sizeof(sin6));
-	sin6.sin6_family = AF_INET6;
-	sin6.sin6_addr = in6addr_loopback;
-
-	SAFE_BIND(NULL, sr, (struct sockaddr *)&sin6, sizeof(sin6));
-
-	if (setsockopt(sr, SOL_IPV6, psoe->so_opt, &psoe->so_clrval,
-		       psoe->so_valsize) < 0) {
-		tst_brkm(TBROK | TERRNO, NULL, "%s: setsockopt",
-			 psoe->so_tname);
-	}
-
-	TEST(setsockopt(sr, SOL_IPV6, psoe->so_opt, &psoe->so_setval,
-			psoe->so_valsize));
-	if (TEST_RETURN != 0) {
-		tst_resm(TFAIL | TERRNO, "%s set-get: setsockopt",
-			 psoe->so_tname);
-		return;
-	}
-
-	valsize = psoe->so_valsize;
-	TEST(getsockopt(sr, SOL_IPV6, psoe->so_opt, &sobuf, &valsize));
-	if (TEST_RETURN != 0) {
-		tst_brkm(TBROK | TERRNO, NULL, "%s set-get: getsockopt",
-			 psoe->so_tname);
-	} else if (memcmp(&psoe->so_setval, &sobuf, psoe->so_valsize)) {
-		tst_resm(TFAIL, "%s set-get optval != setval", psoe->so_tname);
-	} else {
-		tst_resm(TPASS, "%s set-get", psoe->so_tname);
-	}
-
-	st = SAFE_SOCKET(NULL, PF_INET6, SOCK_RAW, NH_TEST);
-
-	if (sendall(st) < 0)
-		tst_brkm(TBROK | TERRNO, NULL, "%s transmit sendto",
-			 psoe->so_tname);
-
-	close(st);
-
-	/* receiver processing */
-	{
-		fd_set rfds, rfds_saved;
-		int nfds, cc;
-		int gotone;
-		struct timeval tv;
-		struct msghdr msg;
-		unsigned char cmsg[2048];
-		struct cmsghdr *pcmsg;
-		struct iovec iov;
-
-		FD_ZERO(&rfds_saved);
-		FD_SET(sr, &rfds_saved);
-
-		tv.tv_sec = 0;
-		tv.tv_usec = 250000;
-
-		while (1) {
-			memcpy(&rfds, &rfds_saved, sizeof(rfds));
-			nfds = select(sr + 1, &rfds, 0, 0, &tv);
-			if (nfds < 0) {
-				if (errno == EINTR)
-					continue;
-				tst_brkm(TBROK | TERRNO, NULL, "%s select",
-					 psoe->so_tname);
-			}
-			if (nfds == 0) {
-				tst_brkm(TBROK, NULL, "%s recvmsg timed out",
-					 psoe->so_tname);
-				return;
-			}
-			/* else, nfds == 1 */
-			if (!FD_ISSET(sr, &rfds))
-				continue;
-
-			memset(&msg, 0, sizeof(msg));
-			iov.iov_base = rpbuf;
-			iov.iov_len = sizeof(rpbuf);
-			msg.msg_iov = &iov;
-			msg.msg_iovlen = 1;
-			msg.msg_control = cmsg;
-			msg.msg_controllen = sizeof(cmsg);
-
-			cc = recvmsg(sr, &msg, 0);
-			if (cc < 0) {
-				tst_brkm(TBROK | TERRNO, NULL, "%s recvmsg",
-					 psoe->so_tname);
-			}
-			/* check pid & seq here */
-			break;
-		}
-		gotone = 0;
-		for (pcmsg = CMSG_FIRSTHDR(&msg); pcmsg != NULL;
-		     pcmsg = CMSG_NXTHDR(&msg, pcmsg)) {
-			if (!psoe->so_dorecv)
-				break;
-			gotone = pcmsg->cmsg_level == SOL_IPV6 &&
-			    pcmsg->cmsg_type == psoe->so_cmtype;
-			if (gotone) {
-				break;
-			} else if (psoe->so_clear) {
-				tst_resm(TFAIL, "%s receive: extraneous data "
-					 "in control: level %d type %d len %zu",
-					 psoe->so_tname, pcmsg->cmsg_level,
-					 pcmsg->cmsg_type, pcmsg->cmsg_len);
-				return;
-			}
-		}
-		/* check contents here */
-		if (psoe->so_dorecv)
-			tst_resm(gotone ? TPASS : TFAIL, "%s receive",
-				 psoe->so_tname);
-	}
-}
-
-static void do_tests(void)
-{
-	unsigned int i;
-
-	for (i = 0; i < SOCOUNT; ++i) {
-		sotab[i].so_clrval.sou_bool = 0;
-		sotab[i].so_setval.sou_bool = 1;
-		so_test(&sotab[i]);
-	}
-}
-
-static void setup(void)
-{
-	TEST_PAUSE;
-}
-- 
1.9.3



More information about the Ltp mailing list