http://downloads.netgear.com/files/GPL/GPL_Source_V361j_DM111PSP_series_consumer_rele...
[bcm963xx.git] / userapps / opensource / ipsec-tools / src / libipsec / test-policy.c
1 /*      $KAME: test-policy.c,v 1.16 2003/08/26 03:24:08 itojun Exp $    */
2
3 /*
4  * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the project nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
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 <net/pfkeyv2.h>
38 #include <netinet/ipsec.h>
39
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <unistd.h>
43 #include <string.h>
44 #include <errno.h>
45 #include <err.h>
46
47 #include "libpfkey.h"
48
49 struct req_t {
50         int result;     /* expected result; 0:ok 1:ng */
51         char *str;
52 } reqs[] = {
53 { 0, "out ipsec" },
54 { 1, "must_error" },
55 { 1, "in ipsec must_error" },
56 { 1, "out ipsec esp/must_error" },
57 { 1, "out discard" },
58 { 1, "out none" },
59 { 0, "in entrust" },
60 { 0, "out entrust" },
61 { 1, "out ipsec esp" },
62 { 0, "in ipsec ah/transport" },
63 { 1, "in ipsec ah/tunnel" },
64 { 0, "out ipsec ah/transport/" },
65 { 1, "out ipsec ah/tunnel/" },
66 { 0, "in ipsec esp / transport / 10.0.0.1-10.0.0.2" },
67 { 0, "in ipsec esp/tunnel/::1-::2" },
68 { 1, "in ipsec esp/tunnel/10.0.0.1-::2" },
69 { 0, "in ipsec esp/tunnel/::1-::2/require" },
70 { 0, "out ipsec ah/transport//use" },
71 { 1, "out ipsec ah/transport esp/use" },
72 { 1, "in ipsec ah/transport esp/tunnel" },
73 { 0, "in ipsec ah/transport esp/tunnel/::1-::1" },
74 { 0, "in ipsec
75         ah / transport
76         esp / tunnel / ::1-::2" },
77 { 0, "out ipsec
78         ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require
79         ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require
80         ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require
81         " },
82 { 0, "out ipsec esp/transport/fec0::10-fec0::11/use" },
83 };
84
85 int test1 __P((void));
86 int test1sub1 __P((struct req_t *));
87 int test1sub2 __P((char *, int));
88 int test2 __P((void));
89 int test2sub __P((int));
90
91 int
92 main(ac, av)
93         int ac;
94         char **av;
95 {
96         test1();
97         test2();
98
99         exit(0);
100 }
101
102 int
103 test1()
104 {
105         int i;
106         int result;
107
108         printf("TEST1\n");
109         for (i = 0; i < sizeof(reqs)/sizeof(reqs[0]); i++) {
110                 printf("#%d [%s]\n", i + 1, reqs[i].str);
111
112                 result = test1sub1(&reqs[i]);
113                 if (result == 0 && reqs[i].result == 1) {
114                         warnx("ERROR: expecting failure.");
115                 } else if (result == 1 && reqs[i].result == 0) {
116                         warnx("ERROR: expecting success.");
117                 }
118         }
119
120         return 0;
121 }
122
123 int
124 test1sub1(req)
125         struct req_t *req;
126 {
127         char *buf;
128
129         buf = ipsec_set_policy(req->str, strlen(req->str));
130         if (buf == NULL) {
131                 printf("ipsec_set_policy: %s\n", ipsec_strerror());
132                 return 1;
133         }
134
135         if (test1sub2(buf, PF_INET) != 0
136          || test1sub2(buf, PF_INET6) != 0) {
137                 free(buf);
138                 return 1;
139         }
140 #if 0
141         kdebug_sadb_x_policy((struct sadb_ext *)buf);
142 #endif
143
144         free(buf);
145         return 0;
146 }
147
148 int
149 test1sub2(policy, family)
150         char *policy;
151         int family;
152 {
153         int so;
154         int proto = 0, optname = 0;
155         int len;
156         char getbuf[1024];
157
158         switch (family) {
159         case PF_INET:
160                 proto = IPPROTO_IP;
161                 optname = IP_IPSEC_POLICY;
162                 break;
163         case PF_INET6:
164                 proto = IPPROTO_IPV6;
165                 optname = IPV6_IPSEC_POLICY;
166                 break;
167         }
168
169         if ((so = socket(family, SOCK_DGRAM, 0)) < 0)
170                 err(1, "socket");
171
172         len = ipsec_get_policylen(policy);
173 #if 0
174         printf("\tsetlen:%d\n", len);
175 #endif
176
177         if (setsockopt(so, proto, optname, policy, len) < 0) {
178                 printf("fail to set sockopt; %s\n", strerror(errno));
179                 close(so);
180                 return 1;
181         }
182
183         memset(getbuf, 0, sizeof(getbuf));
184         memcpy(getbuf, policy, sizeof(struct sadb_x_policy));
185         if (getsockopt(so, proto, optname, getbuf, &len) < 0) {
186                 printf("fail to get sockopt; %s\n", strerror(errno));
187                 close(so);
188                 return 1;
189         }
190
191     {
192         char *buf = NULL;
193
194 #if 0
195         printf("\tgetlen:%d\n", len);
196 #endif
197
198         if ((buf = ipsec_dump_policy(getbuf, NULL)) == NULL) {
199                 printf("%s\n", ipsec_strerror());
200                 close(so);
201                 return 1;
202         }
203 #if 0
204         printf("\t[%s]\n", buf);
205 #endif
206         free(buf);
207     }
208
209         close (so);
210         return 0;
211 }
212
213 char addr[] = {
214         28, 28, 0, 0,
215         0, 0, 0, 0,
216         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
217         0, 0, 0, 0,
218 };
219
220 int
221 test2()
222 {
223         int so;
224         char *pol1 = "out ipsec";
225         char *pol2 = "out ipsec ah/transport//use";
226         char *sp1, *sp2;
227         int splen1, splen2;
228         int spid;
229         struct sadb_msg *m;
230
231         printf("TEST2\n");
232         if (getuid() != 0)
233                 errx(1, "root privilege required.");
234
235         sp1 = ipsec_set_policy(pol1, strlen(pol1));
236         splen1 = ipsec_get_policylen(sp1);
237         sp2 = ipsec_set_policy(pol2, strlen(pol2));
238         splen2 = ipsec_get_policylen(sp2);
239
240         if ((so = pfkey_open()) < 0)
241                 errx(1, "ERROR: %s", ipsec_strerror());
242
243         printf("spdflush()\n");
244         if (pfkey_send_spdflush(so) < 0)
245                 errx(1, "ERROR: %s", ipsec_strerror());
246         m = pfkey_recv(so);
247         free(m);
248
249         printf("spdsetidx()\n");
250         if (pfkey_send_spdsetidx(so, (struct sockaddr *)addr, 128,
251                                 (struct sockaddr *)addr, 128,
252                                 255, sp1, splen1, 0) < 0)
253                 errx(1, "ERROR: %s", ipsec_strerror());
254         m = pfkey_recv(so);
255         free(m);
256         
257         printf("spdupdate()\n");
258         if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128,
259                                 (struct sockaddr *)addr, 128,
260                                 255, sp2, splen2, 0) < 0)
261                 errx(1, "ERROR: %s", ipsec_strerror());
262         m = pfkey_recv(so);
263         free(m);
264
265         printf("sleep(4)\n");
266         sleep(4);
267
268         printf("spddelete()\n");
269         if (pfkey_send_spddelete(so, (struct sockaddr *)addr, 128,
270                                 (struct sockaddr *)addr, 128,
271                                 255, sp1, splen1, 0) < 0)
272                 errx(1, "ERROR: %s", ipsec_strerror());
273         m = pfkey_recv(so);
274         free(m);
275
276         printf("spdadd()\n");
277         if (pfkey_send_spdadd(so, (struct sockaddr *)addr, 128,
278                                 (struct sockaddr *)addr, 128,
279                                 255, sp2, splen2, 0) < 0)
280                 errx(1, "ERROR: %s", ipsec_strerror());
281         spid = test2sub(so);
282
283         printf("spdget(%u)\n", spid);
284         if (pfkey_send_spdget(so, spid) < 0)
285                 errx(1, "ERROR: %s", ipsec_strerror());
286         m = pfkey_recv(so);
287         free(m);
288
289         printf("sleep(4)\n");
290         sleep(4);
291
292         printf("spddelete2()\n");
293         if (pfkey_send_spddelete2(so, spid) < 0)
294                 errx(1, "ERROR: %s", ipsec_strerror());
295         m = pfkey_recv(so);
296         free(m);
297
298         printf("spdadd() with lifetime's 10(s)\n");
299         if (pfkey_send_spdadd2(so, (struct sockaddr *)addr, 128,
300                                 (struct sockaddr *)addr, 128,
301                                 255, 0, 10, sp2, splen2, 0) < 0)
302                 errx(1, "ERROR: %s", ipsec_strerror());
303         spid = test2sub(so);
304
305         /* expecting failure */
306         printf("spdupdate()\n");
307         if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128,
308                                 (struct sockaddr *)addr, 128,
309                                 255, sp2, splen2, 0) == 0) {
310                 warnx("ERROR: expecting failure.");
311         }
312
313         return 0;
314 }
315
316 int
317 test2sub(so)
318         int so;
319 {
320         struct sadb_msg *msg;
321         caddr_t mhp[SADB_EXT_MAX + 1];
322
323         if ((msg = pfkey_recv(so)) == NULL)
324                 errx(1, "ERROR: pfkey_recv failure.");
325         if (pfkey_align(msg, mhp) < 0)
326                 errx(1, "ERROR: pfkey_align failure.");
327
328         return ((struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY])->sadb_x_policy_id;
329 }
330