summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbluhm <bluhm@openbsd.org>2018-05-19 10:50:57 +0000
committerbluhm <bluhm@openbsd.org>2018-05-19 10:50:57 +0000
commitecef606853b080cc7c8470cc8793cf6c081ce676 (patch)
treebe6ae9d24e81cefa6bfc03473e1211145c14cd30
parentAdd a const qualifier to the aint argument of X509V3_add_value_int() (diff)
downloadwireguard-openbsd-ecef606853b080cc7c8470cc8793cf6c081ce676.tar.xz
wireguard-openbsd-ecef606853b080cc7c8470cc8793cf6c081ce676.zip
Additionally send no next header protocol 59 packets through the
IPsec test. They consist solely of an IPv6 header chain and trigger edge cases. Deactivate for now until the raw IP reflector can be build and started reliably on remote machine.
-rw-r--r--regress/sys/netinet/ipsec/Makefile72
-rw-r--r--regress/sys/netinet/ipsec/nonxt-reflect.c104
-rw-r--r--regress/sys/netinet/ipsec/nonxt-sendrecv.c123
3 files changed, 285 insertions, 14 deletions
diff --git a/regress/sys/netinet/ipsec/Makefile b/regress/sys/netinet/ipsec/Makefile
index 02ec8f89e66..84aac1596a6 100644
--- a/regress/sys/netinet/ipsec/Makefile
+++ b/regress/sys/netinet/ipsec/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.19 2018/05/15 14:10:16 mpi Exp $
+# $OpenBSD: Makefile,v 1.20 2018/05/19 10:50:57 bluhm Exp $
# This test needs a manual setup of four machines, the make
# target create-setup can be used to distribute the configuration.
@@ -149,6 +149,8 @@ RT_IN_IF ?= vio1
RT_OUT_IF ?= vio2
ECO_IN_IF ?= vio1
+PROGS = nonxt-sendrecv nonxt-reflect
+
.MAIN: all
.if empty (IPS_SSH) || empty (RT_SSH) || empty (ECO_SSH)
@@ -257,9 +259,11 @@ stamp-drop:
run-regress-pflog-ping-IPS_AH_TRANSP_IPV4 \
run-regress-pflog-udp-IPS_AH_TRANSP_IPV4 \
run-regress-pflog-tcp-IPS_AH_TRANSP_IPV4 \
+ run-regress-pflog-nonxt-IPS_AH_TRANSP_IPV4 \
run-regress-pflog-ping-IPS_AH_TRANSP_IPV6 \
run-regress-pflog-udp-IPS_AH_TRANSP_IPV6 \
- run-regress-pflog-tcp-IPS_AH_TRANSP_IPV6:
+ run-regress-pflog-tcp-IPS_AH_TRANSP_IPV6 \
+ run-regress-pflog-nonxt-IPS_AH_TRANSP_IPV6:
@echo '\n======== $@ ========'
@echo IPv6 AH packets are treated as their payload protocol by pf.
@echo So they match the floating state on the physical interface
@@ -321,6 +325,7 @@ run-regress-send-ping-${len}-${host}_${sec}_${mode}_${ipv}:
.for host mode in IPS TRANSP IPS TUNNEL4 IPS TUNNEL6 \
ECO TUNNEL4 ECO TUNNEL6
.for ipv in IPV4 IPV6
+
TARGETS += udp-${host}_${sec}_${mode}_${ipv}
udp ${host:L} ${sec:L} ${mode:L} ${ipv:L}:\
run-regress-send-udp-${host}_${sec}_${mode}_${ipv}
@@ -356,6 +361,39 @@ run-regress-send-tcp-${host}_${sec}_${mode}_${ipv}:
echo $$$$ | nc -n -N -w 3 ${${host}_${sec}_${mode}_${ipv}} 7 |\
fgrep $$$$
+# Send no next header protocol 59 packets through the IPsec test.
+# They consist solely of an IPv6 header chain and trigger edge cases.
+
+# Deactivate for now until the raw IP reflector can be build and
+# started reliably on remote machine. Manually run make nonxt.
+# XXX TARGETS += nonxt-${host}_${sec}_${mode}_${ipv}
+nonxt ${host:L} ${sec:L} ${mode:L} ${ipv:L}:\
+ run-regress-send-nonxt-${host}_${sec}_${mode}_${ipv}
+run-regress-send-nonxt-${host}_${sec}_${mode}_${ipv}: nonxt-sendrecv
+ @echo '\n======== $@ ========'
+ netstat -s -p ${sec:L:S/ipip/ipencap/:S/bundle/esp/} |\
+ awk '/input ${sec:S/BUNDLE/ESP/} /{print $$1}' >pkt.in
+ netstat -s -p ${sec:L:S/ipip/ipencap/:S/bundle/esp/} |\
+ awk '/output ${sec:S/BUNDLE/ESP/} /{print $$1}' >pkt.out
+ ssh ${${host}_SSH} ${SUDO}\
+ ./nonxt-reflect ${${host}_${sec}_${mode}_${ipv}}
+ ${SUDO} ./nonxt-sendrecv ${${host}_${sec}_${mode}_${ipv}}
+.if "${sec}" == IPCOMP
+ netstat -s -p ${sec:L:S/ipip/ipencap/:S/bundle/esp/} |\
+ awk '/input ${sec:S/BUNDLE/ESP/} /{print $$1}' |\
+ diff pkt.in -
+ netstat -s -p ${sec:L:S/ipip/ipencap/:S/bundle/esp/} |\
+ awk '/output ${sec:S/BUNDLE/ESP/} /{print $$1}' |\
+ diff pkt.out -
+.else
+ netstat -s -p ${sec:L:S/ipip/ipencap/:S/bundle/esp/} |\
+ awk '/input ${sec:S/BUNDLE/ESP/} /{print $$1-1}' |\
+ diff pkt.in -
+ netstat -s -p ${sec:L:S/ipip/ipencap/:S/bundle/esp/} |\
+ awk '/output ${sec:S/BUNDLE/ESP/} /{print $$1-1}' |\
+ diff pkt.out -
+.endif
+
.endfor
.endfor
@@ -363,9 +401,9 @@ run-regress-send-tcp-${host}_${sec}_${mode}_${ipv}:
# Check bpf has dumped all IPsec packets to enc0 on IPS
-REGEX_ESP= (authentic,confidential): SPI 0x[0-9a-f]*:
-REGEX_AH= (authentic): SPI 0x[0-9a-f]*:
-REGEX_IPCOMP= (unprotected): SPI 0x[0-9a-f]*:
+REGEX_ESP= \(authentic,confidential\): SPI 0x[0-9a-f]*:
+REGEX_AH= \(authentic\): SPI 0x[0-9a-f]*:
+REGEX_IPCOMP= \(unprotected\): SPI 0x[0-9a-f]*:
REGEX_REQ_TRANSP= *
REGEX_REQ_TUNNEL4= ${SRC_OUT_IPV4} > ${IPS_IN_IPV4}:
@@ -375,13 +413,15 @@ REGEX_RPL_TRANSP= *
REGEX_RPL_TUNNEL4= ${IPS_IN_IPV4} > ${SRC_OUT_IPV4}:
REGEX_RPL_TUNNEL6= ${IPS_IN_IPV6} > ${SRC_OUT_IPV6}:
-REGEX_REQ_PING= icmp6*: echo request
+REGEX_REQ_PING= icmp6?: echo request
REGEX_REQ_UDP= .* udp
REGEX_REQ_TCP= S
+REGEX_REQ_NONXT=(ip-proto-59|no next header)
REGEX_RPL_PING= icmp6*: echo reply
REGEX_RPL_UDP= .* udp
REGEX_RPL_TCP= S .* ack
+REGEX_RPL_NONXT=(ip-proto-59|no next header)
.for host in IPS ECO
.for sec in ESP AH IPIP IPCOMP BUNDLE
@@ -396,6 +436,8 @@ REGEX_REQ_${host}_${sec}_${mode}_${ipv}_UDP=\
${${host}_${sec}_${mode}_${ipv}}\.7:
REGEX_REQ_${host}_${sec}_${mode}_${ipv}_TCP=\
${REGEX_REQ_${host}_${sec}_${mode}_${ipv}_UDP}
+REGEX_REQ_${host}_${sec}_${mode}_${ipv}_NONXT=\
+ ${REGEX_REQ_${host}_${sec}_${mode}_${ipv}_PING}
REGEX_RPL_${host}_${sec}_${mode}_${ipv}_PING=\
${${host}_${sec}_${mode}_${ipv}} >\
@@ -405,17 +447,19 @@ REGEX_RPL_${host}_${sec}_${mode}_${ipv}_UDP=\
${SRC_${sec}_${mode:C/[46]$//}_${ipv}}\.[0-9][0-9]*:
REGEX_RPL_${host}_${sec}_${mode}_${ipv}_TCP=\
${REGEX_RPL_${host}_${sec}_${mode}_${ipv}_UDP}
+REGEX_RPL_${host}_${sec}_${mode}_${ipv}_NONXT=\
+ ${REGEX_RPL_${host}_${sec}_${mode}_${ipv}_PING}
-.for proto in PING UDP TCP
+.for proto in PING UDP TCP NONXT
run-regress-bpf-${proto:L}-${host}_${sec}_${mode}_${ipv}: stamp-stop
@echo '\n======== $@ ========'
- grep -q '\
+ egrep -q '\
${REGEX_${sec}}\
${REGEX_REQ_${mode}}\
${REGEX_REQ_${host}_${sec}_${mode}_${ipv}_${proto}}\
${REGEX_REQ_${proto}} ' enc0.tcpdump
- grep -q '\
+ egrep -q '\
${REGEX_${sec}}\
${REGEX_RPL_${mode}}\
${REGEX_RPL_${host}_${sec}_${mode}_${ipv}_${proto}}\
@@ -423,13 +467,13 @@ run-regress-bpf-${proto:L}-${host}_${sec}_${mode}_${ipv}: stamp-stop
run-regress-pflog-${proto:L}-${host}_${sec}_${mode}_${ipv}: stamp-stop
@echo '\n======== $@ ========'
- grep -q '\
- rule .*regress.0/(match) .*\
+ egrep -q '\
+ rule .*regress.0/\(match\) .*\
pass in on enc0:.*\
${REGEX_REQ_${host}_${sec}_${mode}_${ipv}_${proto}}\
${REGEX_REQ_${proto}} ' pflog0.tcpdump
- grep -q '\
- rule .*/(match) .*\
+ egrep -q '\
+ rule .*/\(match\) .*\
pass out on enc0:.*\
${REGEX_RPL_${host}_${sec}_${mode}_${ipv}_${proto}}\
${REGEX_RPL_${proto}} ' pflog0.tcpdump
@@ -441,7 +485,7 @@ run-regress-pflog-${proto:L}-${host}_${sec}_${mode}_${ipv}: stamp-stop
.endfor
REGRESS_TARGETS = ${TARGETS:S/^/run-regress-send-/} \
- ${TARGETS:N*_IPIP_*:N*_BUNDLE_*:N*_IN_*:N*_OUT_*:N*-SRC_*:Nudp-*_IPCOMP_*:Ntcp-*_IPCOMP_*:N*-small-*:S/-big-/-/:S/^/run-regress-bpf-/} \
+ ${TARGETS:N*_IPIP_*:N*_BUNDLE_*:N*_IN_*:N*_OUT_*:N*-SRC_*:Nudp-*_IPCOMP_*:Ntcp-*_IPCOMP_*:N*-small-*:Nnonxt-*_IPCOMP_*:S/-big-/-/:S/^/run-regress-bpf-/} \
${TARGETS:N*_IPIP_*:N*_IPCOMP_*:N*_IN_*:N*_OUT_*:N*-SRC_*:N*-small-*:S/-big-/-/:S/^/run-regress-pflog-/}
${REGRESS_TARGETS:Mrun-regress-send-*}: \
stamp-ipsec stamp-bpf stamp-pflog stamp-drop
diff --git a/regress/sys/netinet/ipsec/nonxt-reflect.c b/regress/sys/netinet/ipsec/nonxt-reflect.c
new file mode 100644
index 00000000000..6aafe7e8ebb
--- /dev/null
+++ b/regress/sys/netinet/ipsec/nonxt-reflect.c
@@ -0,0 +1,104 @@
+/* $OpenBSD: nonxt-reflect.c,v 1.1 2018/05/19 10:50:57 bluhm Exp $ */
+/*
+ * Copyright (c) Alexander Bluhm <bluhm@genua.de>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netdb.h>
+
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+void __dead usage(void);
+
+void
+usage(void)
+{
+ fprintf(stderr, "usage: nonxt-reflect [localaddr]\n"
+ "Wait for protocol 59 packet in background and send answer.\n");
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct addrinfo hints, *res, *res0;
+ struct sockaddr_storage ss;
+ const char *cause = NULL, *local;
+ socklen_t slen;
+ int error;
+ int save_errno;
+ int s;
+ char buf[1024];
+
+ switch (argc) {
+ case 1:
+ local = NULL;
+ break;
+ case 2:
+ local = argv[1];
+ break;
+ default:
+ usage();
+ }
+
+ /* Create socket and bind it to local address. */
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_RAW;
+ hints.ai_protocol = IPPROTO_NONE;
+ hints.ai_flags = AI_PASSIVE;
+ error = getaddrinfo(local, NULL, &hints, &res0);
+ if (error)
+ errx(1, "getaddrinfo local: %s", gai_strerror(error));
+ for (res = res0; res; res = res->ai_next) {
+ s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (s == -1) {
+ cause = "socket";
+ continue;
+ }
+ if (bind(s, res->ai_addr, res->ai_addrlen) == -1) {
+ cause = "bind";
+ save_errno = errno;
+ close(s);
+ errno = save_errno;
+ continue;
+ }
+ break;
+ }
+ if (res == NULL)
+ err(1, "%s", cause);
+ freeaddrinfo(res0);
+
+ /* Scoket is ready to receive, test may proceed. */
+ daemon(0, 0);
+
+ /* Receive a protocol 59 packet. */
+ slen = sizeof(ss);
+ if (recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr *)&ss, &slen)
+ == -1)
+ err(1, "recv");
+ /* Send back a reply packet. */
+ if (sendto(s, buf, 0, 0, (struct sockaddr *)&ss, slen) == -1)
+ err(1, "send");
+
+ return 0;
+}
diff --git a/regress/sys/netinet/ipsec/nonxt-sendrecv.c b/regress/sys/netinet/ipsec/nonxt-sendrecv.c
new file mode 100644
index 00000000000..68170eb40b1
--- /dev/null
+++ b/regress/sys/netinet/ipsec/nonxt-sendrecv.c
@@ -0,0 +1,123 @@
+/* $OpenBSD: nonxt-sendrecv.c,v 1.1 2018/05/19 10:50:57 bluhm Exp $ */
+/*
+ * Copyright (c) Alexander Bluhm <bluhm@genua.de>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netdb.h>
+
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+void __dead usage(void);
+
+void
+usage(void)
+{
+ fprintf(stderr, "usage: nonxt-sendrecv [localaddr] remoteaddr\n"
+ "Send empty protocol 59 packet and wait for answer.\n");
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct addrinfo hints, *res, *res0;
+ struct timeval to;
+ const char *cause = NULL, *local, *remote;
+ int error;
+ int save_errno;
+ int s;
+ char buf[1024];
+
+ switch (argc) {
+ case 2:
+ local = NULL;
+ remote = argv[1];
+ break;
+ case 3:
+ local = argv[1];
+ remote = argv[2];
+ break;
+ default:
+ usage();
+ }
+
+ /* Create socket and connect it to remote address. */
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_RAW;
+ hints.ai_protocol = IPPROTO_NONE;
+ error = getaddrinfo(remote, NULL, &hints, &res0);
+ if (error)
+ errx(1, "getaddrinfo remote: %s", gai_strerror(error));
+ for (res = res0; res; res = res->ai_next) {
+ s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (s == -1) {
+ cause = "socket";
+ continue;
+ }
+ if (connect(s, res->ai_addr, res->ai_addrlen) == -1) {
+ cause = "connect";
+ save_errno = errno;
+ close(s);
+ errno = save_errno;
+ continue;
+ }
+ break;
+ }
+ if (res == NULL)
+ err(1, "%s", cause);
+
+ /* Optionally bind the socket to local address. */
+ if (local != NULL) {
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = res->ai_family;
+ hints.ai_socktype = SOCK_RAW;
+ hints.ai_protocol = IPPROTO_NONE;
+ hints.ai_flags = AI_PASSIVE;
+ freeaddrinfo(res0);
+ error = getaddrinfo(local, NULL, &hints, &res0);
+ if (error)
+ errx(1, "getaddrinfo local: %s", gai_strerror(error));
+ for (res = res0; res; res = res->ai_next) {
+ if (bind(s, res->ai_addr, res->ai_addrlen) == -1)
+ continue;
+ break;
+ }
+ if (res == NULL)
+ err(1, "bind");
+ }
+ freeaddrinfo(res0);
+
+ /* Send a protocol 59 packet. */
+ if (send(s, buf, 0, 0) == -1)
+ err(1, "send");
+ /* Wait for up to 3 seconds to receive a reply packet. */
+ to.tv_sec = 3;
+ to.tv_usec = 0;
+ if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &to, sizeof(to)) == -1)
+ err(1, "setsockopt");
+ if (recv(s, buf, sizeof(buf), 0) == -1)
+ err(1, "recv");
+
+ return 0;
+}