1331722Seadler/*
255505Sshin * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
355505Sshin * All rights reserved.
455505Sshin *
555505Sshin * Redistribution and use in source and binary forms, with or without
655505Sshin * modification, are permitted provided that the following conditions
755505Sshin * are met:
855505Sshin * 1. Redistributions of source code must retain the above copyright
955505Sshin *    notice, this list of conditions and the following disclaimer.
1055505Sshin * 2. Redistributions in binary form must reproduce the above copyright
1155505Sshin *    notice, this list of conditions and the following disclaimer in the
1255505Sshin *    documentation and/or other materials provided with the distribution.
1355505Sshin * 3. Neither the name of the project nor the names of its contributors
1455505Sshin *    may be used to endorse or promote products derived from this software
1555505Sshin *    without specific prior written permission.
1655505Sshin *
1755505Sshin * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
1855505Sshin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1955505Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2055505Sshin * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
2155505Sshin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2255505Sshin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2355505Sshin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2455505Sshin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2555505Sshin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2655505Sshin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2755505Sshin * SUCH DAMAGE.
2855505Sshin *
2955505Sshin * $FreeBSD$
3055505Sshin */
3155505Sshin
3255505Sshin#include <sys/types.h>
3355505Sshin#include <sys/param.h>
3455505Sshin#include <sys/socket.h>
3555505Sshin#include <netinet/in.h>
3655505Sshin#include <netinet6/in6.h>
37171135Sgnn#include <netipsec/ipsec.h>
3855505Sshin#include <stdlib.h>
3955505Sshin#include <string.h>
4055505Sshin
4155505Sshin
4255505Sshinchar *requests[] = {
4355505Sshin"must_error",		/* must be error */
4455505Sshin"ipsec must_error",	/* must be error */
4555505Sshin"ipsec esp/must_error",	/* must be error */
4655505Sshin"discard",
4755505Sshin"none",
4855505Sshin"entrust",
4955505Sshin"bypass",		/* may be error */
5055505Sshin"ipsec esp",		/* must be error */
5155505Sshin"ipsec ah/require",
5255505Sshin"ipsec ah/use/",
5355505Sshin"ipsec esp/require ah/default/203.178.141.194",
5455505Sshin"ipsec ah/use/203.178.141.195 esp/use/203.178.141.194",
5555505Sshin"ipsec esp/elf.wide.ydc.co.jp esp/www.wide.ydc.co.jp"
5655505Sshin"
5755505Sshinipsec esp/require ah/use esp/require/10.0.0.1
5855505Sshinah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1
5955505Sshinah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1
6055505Sshinah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1
6155505Sshinah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1
6255505Sshinah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1
6355505Sshinah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1
6455505Sshinah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1
6555505Sshinah/use/3ffe:501:481d::1  ah/use/3ffe:501:481d::1ah/use/3ffe:501:481d::1
6655505Sshin",
6755505Sshin};
6855505Sshin
6955505Sshinu_char	*p_secpolicy;
7055505Sshin
7155505Sshinint	test(char *buf, int family);
7255505Sshinchar	*setpolicy(char *req);
7355505Sshin
7455505Sshinmain()
7555505Sshin{
7655505Sshin	int i;
7755505Sshin	char *buf;
7855505Sshin
79298261Saraujo	for (i = 0; i < nitems(requests); i++) {
8055505Sshin		printf("* requests:[%s]\n", requests[i]);
8155505Sshin		if ((buf = setpolicy(requests[i])) == NULL)
8255505Sshin			continue;
8355505Sshin		printf("\tsetlen:%d\n", PFKEY_EXTLEN(buf));
8455505Sshin
8555505Sshin		printf("\tPF_INET:\n");
8655505Sshin		test(buf, PF_INET);
8755505Sshin
8855505Sshin		printf("\tPF_INET6:\n");
8955505Sshin		test(buf, PF_INET6);
9055505Sshin		free(buf);
9155505Sshin	}
9255505Sshin}
9355505Sshin
9455505Sshinint test(char *policy, int family)
9555505Sshin{
9655505Sshin	int so, proto, optname;
9755505Sshin	int len;
9855505Sshin	char getbuf[1024];
9955505Sshin
10055505Sshin	switch (family) {
10155505Sshin	case PF_INET:
10255505Sshin		proto = IPPROTO_IP;
10355505Sshin		optname = IP_IPSEC_POLICY;
10455505Sshin		break;
10555505Sshin	case PF_INET6:
10655505Sshin		proto = IPPROTO_IPV6;
10755505Sshin		optname = IPV6_IPSEC_POLICY;
10855505Sshin		break;
10955505Sshin	}
11055505Sshin
11155505Sshin	if ((so = socket(family, SOCK_DGRAM, 0)) < 0)
11255505Sshin		perror("socket");
11355505Sshin
11455505Sshin	if (setsockopt(so, proto, optname, policy, PFKEY_EXTLEN(policy)) < 0)
11555505Sshin		perror("setsockopt");
11655505Sshin
11755505Sshin	len = sizeof(getbuf);
11855505Sshin	memset(getbuf, 0, sizeof(getbuf));
11955505Sshin	if (getsockopt(so, proto, optname, getbuf, &len) < 0)
12055505Sshin		perror("getsockopt");
12155505Sshin
12255505Sshin    {
12355505Sshin	char *buf = NULL;
12455505Sshin
12555505Sshin	printf("\tgetlen:%d\n", len);
12655505Sshin
12755505Sshin	if ((buf = ipsec_dump_policy(getbuf, NULL)) == NULL)
12855505Sshin		ipsec_strerror();
12955505Sshin	else
13055505Sshin		printf("\t[%s]\n", buf);
13155505Sshin
13255505Sshin	free(buf);
13355505Sshin    }
13455505Sshin
13555505Sshin	close (so);
13655505Sshin}
13755505Sshin
13855505Sshinchar *setpolicy(char *req)
13955505Sshin{
14055505Sshin	int len;
14155505Sshin	char *buf;
14255505Sshin
14355505Sshin	if ((len = ipsec_get_policylen(req)) < 0) {
14455505Sshin		printf("ipsec_get_policylen: %s\n", ipsec_strerror());
14555505Sshin		return NULL;
14655505Sshin	}
14755505Sshin
14855505Sshin	if ((buf = malloc(len)) == NULL) {
14955505Sshin		perror("malloc");
15055505Sshin		return NULL;
15155505Sshin	}
15255505Sshin
15355505Sshin	if ((len = ipsec_set_policy(buf, len, req)) < 0) {
15455505Sshin		printf("ipsec_set_policy: %s\n", ipsec_strerror());
15555505Sshin		free(buf);
15655505Sshin		return NULL;
15755505Sshin	}
15855505Sshin
15955505Sshin	return buf;
16055505Sshin}
161