xref: /freebsd/tools/regression/priv/priv_netinet_ipsec.c (revision f3d220fb9ed2980f805567fbad3a3a3d0cb77f73)
16007da5fSBjoern A. Zeeb /*-
26007da5fSBjoern A. Zeeb  * Copyright (c) 2007 Bjoern A. Zeeb
36007da5fSBjoern A. Zeeb  * All rights reserved.
46007da5fSBjoern A. Zeeb  *
56007da5fSBjoern A. Zeeb  * Redistribution and use in source and binary forms, with or without
66007da5fSBjoern A. Zeeb  * modification, are permitted provided that the following conditions
76007da5fSBjoern A. Zeeb  * are met:
86007da5fSBjoern A. Zeeb  * 1. Redistributions of source code must retain the above copyright
96007da5fSBjoern A. Zeeb  *    notice, this list of conditions and the following disclaimer.
106007da5fSBjoern A. Zeeb  * 2. Redistributions in binary form must reproduce the above copyright
116007da5fSBjoern A. Zeeb  *    notice, this list of conditions and the following disclaimer in the
126007da5fSBjoern A. Zeeb  *    documentation and/or other materials provided with the distribution.
136007da5fSBjoern A. Zeeb  *
146007da5fSBjoern A. Zeeb  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
156007da5fSBjoern A. Zeeb  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
166007da5fSBjoern A. Zeeb  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
176007da5fSBjoern A. Zeeb  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR, NCIRCLE NETWORK SECURITY,
186007da5fSBjoern A. Zeeb  * INC., OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
196007da5fSBjoern A. Zeeb  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
206007da5fSBjoern A. Zeeb  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
216007da5fSBjoern A. Zeeb  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
226007da5fSBjoern A. Zeeb  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
236007da5fSBjoern A. Zeeb  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
246007da5fSBjoern A. Zeeb  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
256007da5fSBjoern A. Zeeb  *
266007da5fSBjoern A. Zeeb  * $FreeBSD$
276007da5fSBjoern A. Zeeb  */
286007da5fSBjoern A. Zeeb 
296007da5fSBjoern A. Zeeb /*
306007da5fSBjoern A. Zeeb  * Confirm that privilege is required to open a pfkey socket, and that this
316007da5fSBjoern A. Zeeb  * is not allowed in jail.
326007da5fSBjoern A. Zeeb  */
336007da5fSBjoern A. Zeeb 
346007da5fSBjoern A. Zeeb #include <sys/types.h>
356007da5fSBjoern A. Zeeb #include <sys/socket.h>
366007da5fSBjoern A. Zeeb #include <net/pfkeyv2.h>
37f3d220fbSBjoern A. Zeeb #include <netinet/in.h>
38f3d220fbSBjoern A. Zeeb #include <netipsec/ipsec.h>
396007da5fSBjoern A. Zeeb 
40f3d220fbSBjoern A. Zeeb #include <err.h>
416007da5fSBjoern A. Zeeb #include <errno.h>
42f3d220fbSBjoern A. Zeeb #include <stdlib.h>
436007da5fSBjoern A. Zeeb #include <unistd.h>
446007da5fSBjoern A. Zeeb 
456007da5fSBjoern A. Zeeb #include "main.h"
466007da5fSBjoern A. Zeeb 
47f3d220fbSBjoern A. Zeeb static char	policy_bypass[]	= "in bypass";
48f3d220fbSBjoern A. Zeeb static char	policy_entrust[] = "in entrust";
49f3d220fbSBjoern A. Zeeb static char	*bypassbuf = NULL;
50f3d220fbSBjoern A. Zeeb static char	*entrustbuf = NULL;
51f3d220fbSBjoern A. Zeeb static int	sd = -1;
52f3d220fbSBjoern A. Zeeb 
53f3d220fbSBjoern A. Zeeb 
54f3d220fbSBjoern A. Zeeb static int
55f3d220fbSBjoern A. Zeeb priv_netinet_ipsec_policy_bypass_setup_af(int asroot, int injail,
56f3d220fbSBjoern A. Zeeb     struct test *test, int af)
576007da5fSBjoern A. Zeeb {
586007da5fSBjoern A. Zeeb 
59f3d220fbSBjoern A. Zeeb 	bypassbuf = ipsec_set_policy(policy_bypass, sizeof(policy_bypass) - 1);
60f3d220fbSBjoern A. Zeeb 	if (bypassbuf == NULL) {
61f3d220fbSBjoern A. Zeeb 		warn("%s: ipsec_set_policy(NULL)", __func__);
62f3d220fbSBjoern A. Zeeb 		return (-1);
63f3d220fbSBjoern A. Zeeb 	}
64f3d220fbSBjoern A. Zeeb 	switch (af) {
65f3d220fbSBjoern A. Zeeb 	case AF_INET:
66f3d220fbSBjoern A. Zeeb 		sd = socket(AF_INET, SOCK_DGRAM, 0);
67f3d220fbSBjoern A. Zeeb 		if (sd < 0) {
68f3d220fbSBjoern A. Zeeb 			warn("%s: socket4", __func__);
69f3d220fbSBjoern A. Zeeb 			return (-1);
70f3d220fbSBjoern A. Zeeb 		}
71f3d220fbSBjoern A. Zeeb 		break;
72f3d220fbSBjoern A. Zeeb 	case AF_INET6:
73f3d220fbSBjoern A. Zeeb 		sd = socket(AF_INET6, SOCK_DGRAM, 0);
74f3d220fbSBjoern A. Zeeb 		if (sd < 0) {
75f3d220fbSBjoern A. Zeeb 			warn("%s: socket6", __func__);
76f3d220fbSBjoern A. Zeeb 			return (-1);
77f3d220fbSBjoern A. Zeeb 		}
78f3d220fbSBjoern A. Zeeb 		break;
79f3d220fbSBjoern A. Zeeb 	default:
80f3d220fbSBjoern A. Zeeb 		warnx("%s: unexpected address family", __func__);
81f3d220fbSBjoern A. Zeeb 		return (-1);
82f3d220fbSBjoern A. Zeeb 	}
836007da5fSBjoern A. Zeeb 	return (0);
846007da5fSBjoern A. Zeeb }
856007da5fSBjoern A. Zeeb 
86f3d220fbSBjoern A. Zeeb int
87f3d220fbSBjoern A. Zeeb priv_netinet_ipsec_policy4_bypass_setup(int asroot, int injail,
88f3d220fbSBjoern A. Zeeb     struct test *test)
89f3d220fbSBjoern A. Zeeb {
90f3d220fbSBjoern A. Zeeb 
91f3d220fbSBjoern A. Zeeb 	return (priv_netinet_ipsec_policy_bypass_setup_af(asroot, injail, test,
92f3d220fbSBjoern A. Zeeb 	    AF_INET));
93f3d220fbSBjoern A. Zeeb }
94f3d220fbSBjoern A. Zeeb 
95f3d220fbSBjoern A. Zeeb int
96f3d220fbSBjoern A. Zeeb priv_netinet_ipsec_policy6_bypass_setup(int asroot, int injail,
97f3d220fbSBjoern A. Zeeb     struct test *test)
98f3d220fbSBjoern A. Zeeb {
99f3d220fbSBjoern A. Zeeb 
100f3d220fbSBjoern A. Zeeb 	return (priv_netinet_ipsec_policy_bypass_setup_af(asroot, injail, test,
101f3d220fbSBjoern A. Zeeb 	    AF_INET6));
102f3d220fbSBjoern A. Zeeb }
103f3d220fbSBjoern A. Zeeb 
104f3d220fbSBjoern A. Zeeb 
105f3d220fbSBjoern A. Zeeb 
106f3d220fbSBjoern A. Zeeb static int
107f3d220fbSBjoern A. Zeeb priv_netinet_ipsec_policy_entrust_setup_af(int asroot, int injail,
108f3d220fbSBjoern A. Zeeb     struct test *test, int af)
109f3d220fbSBjoern A. Zeeb {
110f3d220fbSBjoern A. Zeeb 
111f3d220fbSBjoern A. Zeeb 	entrustbuf = ipsec_set_policy(policy_entrust, sizeof(policy_entrust)-1);
112f3d220fbSBjoern A. Zeeb 	if (entrustbuf == NULL) {
113f3d220fbSBjoern A. Zeeb 		warn("%s: ipsec_set_policy(NULL)", __func__);
114f3d220fbSBjoern A. Zeeb 		return (-1);
115f3d220fbSBjoern A. Zeeb 	}
116f3d220fbSBjoern A. Zeeb 	switch (af) {
117f3d220fbSBjoern A. Zeeb 	case AF_INET:
118f3d220fbSBjoern A. Zeeb 		sd = socket(AF_INET, SOCK_DGRAM, 0);
119f3d220fbSBjoern A. Zeeb 		if (sd < 0) {
120f3d220fbSBjoern A. Zeeb 			warn("%s: socket4", __func__);
121f3d220fbSBjoern A. Zeeb 			return (-1);
122f3d220fbSBjoern A. Zeeb 		}
123f3d220fbSBjoern A. Zeeb 		break;
124f3d220fbSBjoern A. Zeeb 	case AF_INET6:
125f3d220fbSBjoern A. Zeeb 		sd = socket(AF_INET6, SOCK_DGRAM, 0);
126f3d220fbSBjoern A. Zeeb 		if (sd < 0) {
127f3d220fbSBjoern A. Zeeb 			warn("%s: socket6", __func__);
128f3d220fbSBjoern A. Zeeb 			return (-1);
129f3d220fbSBjoern A. Zeeb 		}
130f3d220fbSBjoern A. Zeeb 		break;
131f3d220fbSBjoern A. Zeeb 	default:
132f3d220fbSBjoern A. Zeeb 		warnx("%s: unexpected address family", __func__);
133f3d220fbSBjoern A. Zeeb 		return (-1);
134f3d220fbSBjoern A. Zeeb 	}
135f3d220fbSBjoern A. Zeeb 	return (0);
136f3d220fbSBjoern A. Zeeb }
137f3d220fbSBjoern A. Zeeb 
138f3d220fbSBjoern A. Zeeb int
139f3d220fbSBjoern A. Zeeb priv_netinet_ipsec_policy4_entrust_setup(int asroot, int injail,
140f3d220fbSBjoern A. Zeeb     struct test *test)
141f3d220fbSBjoern A. Zeeb {
142f3d220fbSBjoern A. Zeeb 
143f3d220fbSBjoern A. Zeeb 	return (priv_netinet_ipsec_policy_entrust_setup_af(asroot, injail, test,
144f3d220fbSBjoern A. Zeeb 	    AF_INET));
145f3d220fbSBjoern A. Zeeb }
146f3d220fbSBjoern A. Zeeb 
147f3d220fbSBjoern A. Zeeb int
148f3d220fbSBjoern A. Zeeb priv_netinet_ipsec_policy6_entrust_setup(int asroot, int injail,
149f3d220fbSBjoern A. Zeeb     struct test *test)
150f3d220fbSBjoern A. Zeeb {
151f3d220fbSBjoern A. Zeeb 
152f3d220fbSBjoern A. Zeeb 	return (priv_netinet_ipsec_policy_entrust_setup_af(asroot, injail, test,
153f3d220fbSBjoern A. Zeeb 	    AF_INET6));
154f3d220fbSBjoern A. Zeeb }
155f3d220fbSBjoern A. Zeeb 
156f3d220fbSBjoern A. Zeeb 
1576007da5fSBjoern A. Zeeb void
1586007da5fSBjoern A. Zeeb priv_netinet_ipsec_pfkey(int asroot, int injail, struct test *test)
1596007da5fSBjoern A. Zeeb {
1606007da5fSBjoern A. Zeeb 	int error, fd;
1616007da5fSBjoern A. Zeeb 
1626007da5fSBjoern A. Zeeb 	fd = socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
1636007da5fSBjoern A. Zeeb 	if (fd < 0)
1646007da5fSBjoern A. Zeeb 		error = -1;
1656007da5fSBjoern A. Zeeb 	else
1666007da5fSBjoern A. Zeeb 		error = 0;
1676007da5fSBjoern A. Zeeb 	/*
1686007da5fSBjoern A. Zeeb 	 * The injail checks are not really priv checks but making sure
1696007da5fSBjoern A. Zeeb 	 * sys/kern/uipc_socket.c:socreate cred checks are working correctly.
1706007da5fSBjoern A. Zeeb 	 */
1716007da5fSBjoern A. Zeeb 	if (asroot && injail)
1726007da5fSBjoern A. Zeeb 		expect("priv_netinet_ipsec_pfkey(asroot, injail)", error,
1736007da5fSBjoern A. Zeeb 		    -1, EPROTONOSUPPORT);
1746007da5fSBjoern A. Zeeb 	if (asroot && !injail)
1756007da5fSBjoern A. Zeeb 		expect("priv_netinet_ipsec_pfkey(asroot, !injail)", error,
1766007da5fSBjoern A. Zeeb 		    0, 0);
1776007da5fSBjoern A. Zeeb 	if (!asroot && injail)
1786007da5fSBjoern A. Zeeb 		expect("priv_netinet_ipsec_pfkey(!asroot, injail)", error,
1796007da5fSBjoern A. Zeeb 		    -1, EPROTONOSUPPORT);
1806007da5fSBjoern A. Zeeb 	if (!asroot && !injail)
1816007da5fSBjoern A. Zeeb 		expect("priv_netinet_ipsec_pfkey(!asroot, !injail)", error,
1826007da5fSBjoern A. Zeeb 		    -1, EPERM);
1836007da5fSBjoern A. Zeeb 	if (fd >= 0)
1846007da5fSBjoern A. Zeeb 		(void)close(fd);
1856007da5fSBjoern A. Zeeb }
1866007da5fSBjoern A. Zeeb 
187f3d220fbSBjoern A. Zeeb 
188f3d220fbSBjoern A. Zeeb static void
189f3d220fbSBjoern A. Zeeb priv_netinet_ipsec_policy_bypass_af(int asroot, int injail, struct test *test,
190f3d220fbSBjoern A. Zeeb     int af)
191f3d220fbSBjoern A. Zeeb {
192f3d220fbSBjoern A. Zeeb 	int error, level, optname;
193f3d220fbSBjoern A. Zeeb 
194f3d220fbSBjoern A. Zeeb 	switch (af) {
195f3d220fbSBjoern A. Zeeb 	case AF_INET:
196f3d220fbSBjoern A. Zeeb 		level = IPPROTO_IP;
197f3d220fbSBjoern A. Zeeb 		optname = IP_IPSEC_POLICY;
198f3d220fbSBjoern A. Zeeb 		break;
199f3d220fbSBjoern A. Zeeb 	case AF_INET6:
200f3d220fbSBjoern A. Zeeb 		level = IPPROTO_IPV6;
201f3d220fbSBjoern A. Zeeb 		optname = IPV6_IPSEC_POLICY;
202f3d220fbSBjoern A. Zeeb 		break;
203f3d220fbSBjoern A. Zeeb 	default:
204f3d220fbSBjoern A. Zeeb 		warnx("%s: unexpected address family", __func__);
205f3d220fbSBjoern A. Zeeb 		return;
206f3d220fbSBjoern A. Zeeb 	}
207f3d220fbSBjoern A. Zeeb 	error = setsockopt(sd, level, optname,
208f3d220fbSBjoern A. Zeeb 	    bypassbuf, ipsec_get_policylen(bypassbuf));
209f3d220fbSBjoern A. Zeeb 	if (asroot && injail)
210f3d220fbSBjoern A. Zeeb 		expect("priv_netinet_ipsec_policy_bypass(asroot, injail)",
211f3d220fbSBjoern A. Zeeb 		    error, -1, EACCES); /* see ipsec_set_policy */
212f3d220fbSBjoern A. Zeeb 	if (asroot && !injail)
213f3d220fbSBjoern A. Zeeb 		expect("priv_netinet_ipsec_policy_bypass(asroot, !injail)",
214f3d220fbSBjoern A. Zeeb 		    error, 0, 0);
215f3d220fbSBjoern A. Zeeb 	if (!asroot && injail)
216f3d220fbSBjoern A. Zeeb 		expect("priv_netinet_ipsec_policy_bypass(!asroot, injail)",
217f3d220fbSBjoern A. Zeeb 		    error, -1, EACCES); /* see ipsec_set_policy */
218f3d220fbSBjoern A. Zeeb 	if (!asroot && !injail)
219f3d220fbSBjoern A. Zeeb 		expect("priv_netinet_ipsec_policy_bypass(!asroot, !injail)",
220f3d220fbSBjoern A. Zeeb 		    error, -1, EACCES); /* see ipsec_set_policy */
221f3d220fbSBjoern A. Zeeb }
222f3d220fbSBjoern A. Zeeb 
2236007da5fSBjoern A. Zeeb void
224f3d220fbSBjoern A. Zeeb priv_netinet_ipsec_policy4_bypass(int asroot, int injail, struct test *test)
2256007da5fSBjoern A. Zeeb {
2266007da5fSBjoern A. Zeeb 
227f3d220fbSBjoern A. Zeeb 	priv_netinet_ipsec_policy_bypass_af(asroot, injail, test, AF_INET);
228f3d220fbSBjoern A. Zeeb }
229f3d220fbSBjoern A. Zeeb 
230f3d220fbSBjoern A. Zeeb void
231f3d220fbSBjoern A. Zeeb priv_netinet_ipsec_policy6_bypass(int asroot, int injail, struct test *test)
232f3d220fbSBjoern A. Zeeb {
233f3d220fbSBjoern A. Zeeb 
234f3d220fbSBjoern A. Zeeb 	priv_netinet_ipsec_policy_bypass_af(asroot, injail, test, AF_INET6);
235f3d220fbSBjoern A. Zeeb }
236f3d220fbSBjoern A. Zeeb 
237f3d220fbSBjoern A. Zeeb 
238f3d220fbSBjoern A. Zeeb static void
239f3d220fbSBjoern A. Zeeb priv_netinet_ipsec_policy_entrust_af(int asroot, int injail, struct test *test,
240f3d220fbSBjoern A. Zeeb     int af)
241f3d220fbSBjoern A. Zeeb {
242f3d220fbSBjoern A. Zeeb 	int error, level, optname;
243f3d220fbSBjoern A. Zeeb 
244f3d220fbSBjoern A. Zeeb 	switch (af) {
245f3d220fbSBjoern A. Zeeb 	case AF_INET:
246f3d220fbSBjoern A. Zeeb 		level = IPPROTO_IP;
247f3d220fbSBjoern A. Zeeb 		optname = IP_IPSEC_POLICY;
248f3d220fbSBjoern A. Zeeb 		break;
249f3d220fbSBjoern A. Zeeb 	case AF_INET6:
250f3d220fbSBjoern A. Zeeb 		level = IPPROTO_IPV6;
251f3d220fbSBjoern A. Zeeb 		optname = IPV6_IPSEC_POLICY;
252f3d220fbSBjoern A. Zeeb 		break;
253f3d220fbSBjoern A. Zeeb 	default:
254f3d220fbSBjoern A. Zeeb 		warnx("%s: unexpected address family", __func__);
255f3d220fbSBjoern A. Zeeb 		return;
256f3d220fbSBjoern A. Zeeb 	}
257f3d220fbSBjoern A. Zeeb 	error = setsockopt(sd, level, optname,
258f3d220fbSBjoern A. Zeeb 	    entrustbuf, ipsec_get_policylen(entrustbuf));
259f3d220fbSBjoern A. Zeeb 	if (asroot && injail)
260f3d220fbSBjoern A. Zeeb 		expect("priv_netinet_ipsec_policy_entrust(asroot, injail)",
261f3d220fbSBjoern A. Zeeb 		    error, 0, 0); /* XXX ipsec_set_policy */
262f3d220fbSBjoern A. Zeeb 	if (asroot && !injail)
263f3d220fbSBjoern A. Zeeb 		expect("priv_netinet_ipsec_policy_entrust(asroot, !injail)",
264f3d220fbSBjoern A. Zeeb 		    error, 0, 0);
265f3d220fbSBjoern A. Zeeb 	if (!asroot && injail)
266f3d220fbSBjoern A. Zeeb 		expect("priv_netinet_ipsec_policy_entrust(!asroot, injail)",
267f3d220fbSBjoern A. Zeeb 		    error, 0, 0); /* XXX ipsec_set_policy */
268f3d220fbSBjoern A. Zeeb 	if (!asroot && !injail)
269f3d220fbSBjoern A. Zeeb 		expect("priv_netinet_ipsec_policy_entrust(!asroot, !injail)",
270f3d220fbSBjoern A. Zeeb 		    error, 0, 0); /* XXX ipsec_set_policy */
271f3d220fbSBjoern A. Zeeb }
272f3d220fbSBjoern A. Zeeb 
273f3d220fbSBjoern A. Zeeb void
274f3d220fbSBjoern A. Zeeb priv_netinet_ipsec_policy4_entrust(int asroot, int injail, struct test *test)
275f3d220fbSBjoern A. Zeeb {
276f3d220fbSBjoern A. Zeeb 
277f3d220fbSBjoern A. Zeeb 	priv_netinet_ipsec_policy_entrust_af(asroot, injail, test, AF_INET);
278f3d220fbSBjoern A. Zeeb }
279f3d220fbSBjoern A. Zeeb 
280f3d220fbSBjoern A. Zeeb void
281f3d220fbSBjoern A. Zeeb priv_netinet_ipsec_policy6_entrust(int asroot, int injail, struct test *test)
282f3d220fbSBjoern A. Zeeb {
283f3d220fbSBjoern A. Zeeb 
284f3d220fbSBjoern A. Zeeb 	priv_netinet_ipsec_policy_entrust_af(asroot, injail, test, AF_INET6);
285f3d220fbSBjoern A. Zeeb }
286f3d220fbSBjoern A. Zeeb 
287f3d220fbSBjoern A. Zeeb 
288f3d220fbSBjoern A. Zeeb void
289f3d220fbSBjoern A. Zeeb priv_netinet_ipsec_policy_bypass_cleanup(int asroot, int injail,
290f3d220fbSBjoern A. Zeeb     struct test *test)
291f3d220fbSBjoern A. Zeeb {
292f3d220fbSBjoern A. Zeeb 
293f3d220fbSBjoern A. Zeeb 	if (bypassbuf != NULL) {
294f3d220fbSBjoern A. Zeeb 		free(bypassbuf);
295f3d220fbSBjoern A. Zeeb 		bypassbuf = NULL;
296f3d220fbSBjoern A. Zeeb 	}
297f3d220fbSBjoern A. Zeeb 	if (sd >= 0) {
298f3d220fbSBjoern A. Zeeb 		close(sd);
299f3d220fbSBjoern A. Zeeb 		sd = -1;
300f3d220fbSBjoern A. Zeeb 	}
301f3d220fbSBjoern A. Zeeb }
302f3d220fbSBjoern A. Zeeb 
303f3d220fbSBjoern A. Zeeb void
304f3d220fbSBjoern A. Zeeb priv_netinet_ipsec_policy_entrust_cleanup(int asroot, int injail,
305f3d220fbSBjoern A. Zeeb     struct test *test)
306f3d220fbSBjoern A. Zeeb {
307f3d220fbSBjoern A. Zeeb 
308f3d220fbSBjoern A. Zeeb 	if (entrustbuf != NULL) {
309f3d220fbSBjoern A. Zeeb 		free(entrustbuf);
310f3d220fbSBjoern A. Zeeb 		entrustbuf = NULL;
311f3d220fbSBjoern A. Zeeb 	}
312f3d220fbSBjoern A. Zeeb 	if (sd >= 0) {
313f3d220fbSBjoern A. Zeeb 		close(sd);
314f3d220fbSBjoern A. Zeeb 		sd = -1;
315f3d220fbSBjoern A. Zeeb 	}
3166007da5fSBjoern A. Zeeb }
3176007da5fSBjoern A. Zeeb 
318