1 /* 2 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the project nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $FreeBSD$ 30 */ 31 32 #include <sys/types.h> 33 #include <sys/param.h> 34 #include <sys/socket.h> 35 36 #include <netinet/in.h> 37 #include <netinet6/in6.h> 38 #include <net/pfkeyv2.h> 39 #include <netkey/key_debug.h> 40 #include <netinet6/ipsec.h> 41 42 #include <stdio.h> 43 #include <stdlib.h> 44 #include <unistd.h> 45 #include <string.h> 46 #include <err.h> 47 48 char *requests[] = { 49 "must_error", /* error */ 50 "in ipsec must_error", /* error */ 51 "out ipsec esp/must_error", /* error */ 52 "out discard", 53 "out none", 54 "in entrust", 55 "out entrust", 56 "in bypass", /* may be error */ 57 "out ipsec esp", /* error */ 58 "in ipsec ah/transport", 59 "in ipsec ah/tunnel", /* error */ 60 "out ipsec ah/transport/", 61 "out ipsec ah/tunnel/", /* error */ 62 "in ipsec esp / transport / 10.0.0.1-10.0.0.2", 63 "in ipsec esp/tunnel/::1-::2", 64 "in ipsec esp/tunnel/10.0.0.1-::2", /* error */ 65 "in ipsec esp/tunnel/::1-::2/require", 66 "out ipsec ah/transport//use", 67 "out ipsec ah/transport esp/use", 68 "in ipsec ah/transport esp/tunnel", /* error */ 69 "in ipsec 70 ah / transport 71 esp / tunnel / ::1-::2", 72 " 73 out ipsec 74 ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require 75 ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require 76 ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require 77 ", 78 "out ipsec esp/transport/fec0::10-fec0::11/use", 79 }; 80 81 int test(char *buf, int family); 82 83 int 84 main(ac, av) 85 int ac; 86 char **av; 87 { 88 int do_setsockopt; 89 char *buf; 90 int i; 91 92 if (ac != 1) 93 do_setsockopt = 1; 94 else 95 do_setsockopt = 0; 96 97 for (i = 0; i < sizeof(requests)/sizeof(requests[0]); i++) { 98 printf("*** requests ***\n"); 99 printf("\t[%s]\n", requests[i]); 100 101 buf = ipsec_set_policy(requests[i], strlen(requests[i])); 102 if (buf == NULL) { 103 printf("ipsec_set_policy: %s\n", ipsec_strerror()); 104 continue; 105 } 106 107 printf("\tsetlen:%d\n", ipsec_get_policylen(buf)); 108 109 if (do_setsockopt) { 110 printf("\tPF_INET:\n"); 111 test(buf, PF_INET); 112 113 printf("\tPF_INET6:\n"); 114 test(buf, PF_INET6); 115 } else { 116 kdebug_sadb_x_policy((struct sadb_ext *)buf); 117 } 118 free(buf); 119 } 120 121 return 0; 122 } 123 124 int 125 test(policy, family) 126 char *policy; 127 int family; 128 { 129 int so, proto, optname; 130 int len; 131 char getbuf[1024]; 132 133 switch (family) { 134 case PF_INET: 135 proto = IPPROTO_IP; 136 optname = IP_IPSEC_POLICY; 137 break; 138 case PF_INET6: 139 proto = IPPROTO_IPV6; 140 optname = IPV6_IPSEC_POLICY; 141 break; 142 } 143 144 if ((so = socket(family, SOCK_DGRAM, 0)) < 0) 145 err(1, "socket"); 146 147 len = ipsec_get_policylen(policy); 148 if (setsockopt(so, proto, optname, policy, len) < 0) { 149 printf("error on setsockopt"); 150 goto end; 151 } 152 153 len = sizeof(getbuf); 154 memset(getbuf, 0, sizeof(getbuf)); 155 if (getsockopt(so, proto, optname, getbuf, &len) < 0) { 156 printf("error on getsockopt"); 157 goto end; 158 } 159 160 { 161 char *buf = NULL; 162 163 printf("\tgetlen:%d\n", len); 164 165 if ((buf = ipsec_dump_policy(getbuf, NULL)) == NULL) { 166 printf("%s\n", ipsec_strerror()); 167 goto end; 168 } else { 169 printf("\t[%s]\n", buf); 170 free(buf); 171 } 172 } 173 174 end: 175 close (so); 176 177 return 0; 178 } 179 180