1/*	$KAME: test-pfkey.c,v 1.4 2000/06/07 00:29:14 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#include <net/route.h>
36#include <netinet/in.h>
37#include <net/pfkeyv2.h>
38#include <System/netkey/keydb.h>
39#include <System/netkey/key_var.h>
40#include <System/netkey/key_debug.h>
41
42#include <stdio.h>
43#include <stdlib.h>
44#include <limits.h>
45#include <string.h>
46#include <ctype.h>
47#include <unistd.h>
48#include <errno.h>
49#include <netdb.h>
50
51u_char m_buf[BUFSIZ];
52u_int m_len;
53char *pname;
54
55void Usage (void);
56int sendkeymsg (void);
57void key_setsadbmsg (u_int);
58void key_setsadbsens (void);
59void key_setsadbprop (void);
60void key_setsadbid (u_int, caddr_t);
61void key_setsadblft (u_int, u_int);
62void key_setspirange (void);
63void key_setsadbkey (u_int, caddr_t);
64void key_setsadbsa (void);
65void key_setsadbaddr (u_int, u_int, caddr_t);
66void key_setsadbextbuf (caddr_t, int, caddr_t, int, caddr_t, int);
67
68void
69Usage()
70{
71	printf("Usage:\t%s number\n", pname);
72	exit(0);
73}
74
75int
76main(ac, av)
77	int ac;
78	char **av;
79{
80	pname = *av;
81
82	if (ac == 1) Usage();
83
84	key_setsadbmsg(atoi(*(av+1)));
85	sendkeymsg();
86
87	exit(0);
88}
89
90/* %%% */
91int
92sendkeymsg()
93{
94	u_char rbuf[1024 * 32];	/* XXX: Enough ? Should I do MSG_PEEK ? */
95	int so, len;
96
97	if ((so = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) {
98		perror("socket(PF_KEY)");
99		goto end;
100	}
101#if 0
102    {
103#include <sys/time.h>
104	struct timeval tv;
105	tv.tv_sec = 1;
106	tv.tv_usec = 0;
107	if (setsockopt(so, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
108		perror("setsockopt");
109		goto end;
110	}
111    }
112#endif
113
114	pfkey_sadump((struct sadb_msg *)m_buf);
115
116	if ((len = send(so, m_buf, m_len, 0)) < 0) {
117		perror("send");
118		goto end;
119	}
120
121	if ((len = recv(so, rbuf, sizeof(rbuf), 0)) < 0) {
122		perror("recv");
123		goto end;
124	}
125
126	pfkey_sadump((struct sadb_msg *)rbuf);
127
128end:
129	(void)close(so);
130	return(0);
131}
132
133void
134key_setsadbmsg(type)
135	u_int type;
136{
137	struct sadb_msg m_msg;
138
139	memset(&m_msg, 0, sizeof(m_msg));
140	m_msg.sadb_msg_version = PF_KEY_V2;
141	m_msg.sadb_msg_type = type;
142	m_msg.sadb_msg_errno = 0;
143	m_msg.sadb_msg_satype = SADB_SATYPE_ESP;
144#if 0
145	m_msg.sadb_msg_reserved = 0;
146#endif
147	m_msg.sadb_msg_seq = 0;
148	m_msg.sadb_msg_pid = getpid();
149
150	m_len = sizeof(struct sadb_msg);
151	memcpy(m_buf, &m_msg, m_len);
152
153	switch (type) {
154	case SADB_GETSPI:
155		/*<base, address(SD), SPI range>*/
156		key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "10.0.3.4");
157		key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "127.0.0.1");
158		key_setspirange();
159		/*<base, SA(*), address(SD)>*/
160		break;
161
162	case SADB_ADD:
163		/* <base, SA, (lifetime(HSC),) address(SD), (address(P),)
164		   key(AE), (identity(SD),) (sensitivity)> */
165		key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1");
166	case SADB_UPDATE:
167		key_setsadbsa();
168		key_setsadblft(SADB_EXT_LIFETIME_HARD, 10);
169		key_setsadblft(SADB_EXT_LIFETIME_SOFT, 5);
170		key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1");
171		key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4");
172		/* XXX key_setsadbkey(SADB_EXT_KEY_AUTH, "abcde"); */
173		key_setsadbkey(SADB_EXT_KEY_AUTH, "1234567812345678");
174		key_setsadbkey(SADB_EXT_KEY_ENCRYPT, "12345678");
175		key_setsadbid(SADB_EXT_IDENTITY_SRC, "hoge1234@hoge.com");
176		key_setsadbid(SADB_EXT_IDENTITY_DST, "hage5678@hage.net");
177		key_setsadbsens();
178		/* <base, SA, (lifetime(HSC),) address(SD), (address(P),)
179		  (identity(SD),) (sensitivity)> */
180		break;
181
182	case SADB_DELETE:
183		/* <base, SA(*), address(SDP)> */
184		key_setsadbsa();
185		key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1");
186		key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4");
187		key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1");
188		/* <base, SA(*), address(SDP)> */
189		break;
190
191	case SADB_GET:
192		/* <base, SA(*), address(SDP)> */
193		key_setsadbsa();
194		key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1");
195		key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4");
196		key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1");
197		/* <base, SA, (lifetime(HSC),) address(SD), (address(P),)
198		   key(AE), (identity(SD),) (sensitivity)> */
199		break;
200
201	case SADB_ACQUIRE:
202		/* <base, address(SD), (address(P),) (identity(SD),)
203		   (sensitivity,) proposal> */
204		key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1");
205		key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4");
206		key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1");
207		key_setsadbid(SADB_EXT_IDENTITY_SRC, "hoge1234@hoge.com");
208		key_setsadbid(SADB_EXT_IDENTITY_DST, "hage5678@hage.net");
209		key_setsadbsens();
210		key_setsadbprop();
211		/* <base, address(SD), (address(P),) (identity(SD),)
212		   (sensitivity,) proposal> */
213		break;
214
215	case SADB_REGISTER:
216		/* <base> */
217		/* <base, supported> */
218		break;
219
220	case SADB_EXPIRE:
221	case SADB_FLUSH:
222		break;
223
224	case SADB_DUMP:
225		break;
226
227	case SADB_X_PROMISC:
228		/* <base> */
229		/* <base, base(, others)> */
230		break;
231
232	case SADB_X_PCHANGE:
233		break;
234
235	/* for SPD management */
236	case SADB_X_SPDFLUSH:
237	case SADB_X_SPDDUMP:
238		break;
239
240	case SADB_X_SPDADD:
241#if 0
242	    {
243		struct sadb_x_policy m_policy;
244
245		m_policy.sadb_x_policy_len = PFKEY_UNIT64(sizeof(m_policy));
246		m_policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
247		m_policy.sadb_x_policy_type = SADB_X_PL_IPSEC;
248		m_policy.sadb_x_policy_esp_trans = 1;
249		m_policy.sadb_x_policy_ah_trans = 2;
250		m_policy.sadb_x_policy_esp_network = 3;
251		m_policy.sadb_x_policy_ah_network = 4;
252		m_policy.sadb_x_policy_reserved = 0;
253
254		memcpy(m_buf + m_len, &m_policy, sizeof(struct sadb_x_policy));
255		m_len += sizeof(struct sadb_x_policy);
256	    }
257#endif
258
259	case SADB_X_SPDDELETE:
260		key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1");
261		key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4");
262		break;
263	}
264
265	((struct sadb_msg *)m_buf)->sadb_msg_len = PFKEY_UNIT64(m_len);
266
267	return;
268}
269
270void
271key_setsadbsens()
272{
273	struct sadb_sens m_sens;
274	u_char buf[64];
275	u_int s, i, slen, ilen, len;
276
277	/* make sens & integ */
278	s = htonl(0x01234567);
279	i = htonl(0x89abcdef);
280	slen = sizeof(s);
281	ilen = sizeof(i);
282	memcpy(buf, &s, slen);
283	memcpy(buf + slen, &i, ilen);
284
285	len = sizeof(m_sens) + PFKEY_ALIGN8(slen) + PFKEY_ALIGN8(ilen);
286	m_sens.sadb_sens_len = PFKEY_UNIT64(len);
287	m_sens.sadb_sens_exttype = SADB_EXT_SENSITIVITY;
288	m_sens.sadb_sens_dpd = 1;
289	m_sens.sadb_sens_sens_level = 2;
290	m_sens.sadb_sens_sens_len = PFKEY_ALIGN8(slen);
291	m_sens.sadb_sens_integ_level = 3;
292	m_sens.sadb_sens_integ_len = PFKEY_ALIGN8(ilen);
293	m_sens.sadb_sens_reserved = 0;
294
295	key_setsadbextbuf(m_buf, m_len,
296			(caddr_t)&m_sens, sizeof(struct sadb_sens),
297			buf, slen + ilen);
298	m_len += len;
299
300	return;
301}
302
303void
304key_setsadbprop()
305{
306	struct sadb_prop m_prop;
307	struct sadb_comb *m_comb;
308	u_char buf[256];
309#if defined(SADB_X_EALG_AESCBC) && defined(SADB_X_AALG_SHA2_256)
310	u_int len = sizeof(m_prop) + sizeof(m_comb) * 3;
311#else
312	u_int len = sizeof(m_prop) + sizeof(m_comb) * 2;
313#endif
314
315	/* make prop & comb */
316	m_prop.sadb_prop_len = PFKEY_UNIT64(len);
317	m_prop.sadb_prop_exttype = SADB_EXT_PROPOSAL;
318	m_prop.sadb_prop_replay = 0;
319	m_prop.sadb_prop_reserved[0] = 0;
320	m_prop.sadb_prop_reserved[1] = 0;
321	m_prop.sadb_prop_reserved[2] = 0;
322
323	/* the 1st is ESP DES-CBC HMAC-MD5 */
324	m_comb = (struct sadb_comb *)buf;
325	m_comb->sadb_comb_auth = SADB_AALG_MD5HMAC;
326	m_comb->sadb_comb_encrypt = SADB_EALG_DESCBC;
327	m_comb->sadb_comb_flags = 0;
328	m_comb->sadb_comb_auth_minbits = 8;
329	m_comb->sadb_comb_auth_maxbits = 96;
330	m_comb->sadb_comb_encrypt_minbits = 64;
331	m_comb->sadb_comb_encrypt_maxbits = 64;
332	m_comb->sadb_comb_reserved = 0;
333	m_comb->sadb_comb_soft_allocations = 0;
334	m_comb->sadb_comb_hard_allocations = 0;
335	m_comb->sadb_comb_soft_bytes = 0;
336	m_comb->sadb_comb_hard_bytes = 0;
337	m_comb->sadb_comb_soft_addtime = 0;
338	m_comb->sadb_comb_hard_addtime = 0;
339	m_comb->sadb_comb_soft_usetime = 0;
340	m_comb->sadb_comb_hard_usetime = 0;
341
342	/* the 2st is ESP 3DES-CBC and AH HMAC-SHA1 */
343	m_comb = (struct sadb_comb *)(buf + sizeof(*m_comb));
344	m_comb->sadb_comb_auth = SADB_AALG_SHA1HMAC;
345	m_comb->sadb_comb_encrypt = SADB_EALG_3DESCBC;
346	m_comb->sadb_comb_flags = 0;
347	m_comb->sadb_comb_auth_minbits = 8;
348	m_comb->sadb_comb_auth_maxbits = 96;
349	m_comb->sadb_comb_encrypt_minbits = 64;
350	m_comb->sadb_comb_encrypt_maxbits = 64;
351	m_comb->sadb_comb_reserved = 0;
352	m_comb->sadb_comb_soft_allocations = 0;
353	m_comb->sadb_comb_hard_allocations = 0;
354	m_comb->sadb_comb_soft_bytes = 0;
355	m_comb->sadb_comb_hard_bytes = 0;
356	m_comb->sadb_comb_soft_addtime = 0;
357	m_comb->sadb_comb_hard_addtime = 0;
358	m_comb->sadb_comb_soft_usetime = 0;
359	m_comb->sadb_comb_hard_usetime = 0;
360
361	key_setsadbextbuf(m_buf, m_len,
362			(caddr_t)&m_prop, sizeof(struct sadb_prop),
363			buf, sizeof(*m_comb) * 2);
364	m_len += len;
365
366 #if defined(SADB_X_EALG_AESCBC) && defined(SADB_X_AALG_SHA2_256)
367 	/* the 3rd is ESP AES-CBC and AH HMAC-SHA256 */
368 	m_comb = (struct sadb_comb *)(buf + sizeof(*m_comb));
369 	m_comb->sadb_comb_auth = SADB_X_AALG_SHA2_256;
370 	m_comb->sadb_comb_encrypt = SADB_X_EALG_AESCBC;
371 	m_comb->sadb_comb_flags = 0;
372 	m_comb->sadb_comb_auth_minbits = 8;
373 	m_comb->sadb_comb_auth_maxbits = 96;
374 	m_comb->sadb_comb_encrypt_minbits = 128;
375 	m_comb->sadb_comb_encrypt_maxbits = 128;
376 	m_comb->sadb_comb_reserved = 0;
377 	m_comb->sadb_comb_soft_allocations = 0;
378 	m_comb->sadb_comb_hard_allocations = 0;
379 	m_comb->sadb_comb_soft_bytes = 0;
380 	m_comb->sadb_comb_hard_bytes = 0;
381 	m_comb->sadb_comb_soft_addtime = 0;
382 	m_comb->sadb_comb_hard_addtime = 0;
383 	m_comb->sadb_comb_soft_usetime = 0;
384 	m_comb->sadb_comb_hard_usetime = 0;
385
386 	key_setsadbextbuf(m_buf, m_len,
387 			(caddr_t)&m_prop, sizeof(struct sadb_prop),
388 			buf, sizeof(*m_comb) * 3);
389 	m_len += len;
390#else
391	key_setsadbextbuf(m_buf, m_len,
392			(caddr_t)&m_prop, sizeof(struct sadb_prop),
393			buf, sizeof(*m_comb) * 2);
394 	m_len += len;
395#endif
396	return;
397}
398
399void
400key_setsadbid(ext, str)
401	u_int ext;
402	caddr_t str;
403{
404	struct sadb_ident m_id;
405	u_int idlen = strlen(str), len;
406
407	len = sizeof(m_id) + PFKEY_ALIGN8(idlen);
408	m_id.sadb_ident_len = PFKEY_UNIT64(len);
409	m_id.sadb_ident_exttype = ext;
410	m_id.sadb_ident_type = SADB_IDENTTYPE_USERFQDN;
411	m_id.sadb_ident_reserved = 0;
412	m_id.sadb_ident_id = getpid();
413
414	key_setsadbextbuf(m_buf, m_len,
415			(caddr_t)&m_id, sizeof(struct sadb_ident),
416			str, idlen);
417	m_len += len;
418
419	return;
420}
421
422void
423key_setsadblft(ext, time)
424	u_int ext, time;
425{
426	struct sadb_lifetime m_lft;
427
428	m_lft.sadb_lifetime_len = PFKEY_UNIT64(sizeof(m_lft));
429	m_lft.sadb_lifetime_exttype = ext;
430	m_lft.sadb_lifetime_allocations = 0x2;
431	m_lft.sadb_lifetime_bytes = 0x1000;
432	m_lft.sadb_lifetime_addtime = time;
433	m_lft.sadb_lifetime_usetime = 0x0020;
434
435	memcpy(m_buf + m_len, &m_lft, sizeof(struct sadb_lifetime));
436	m_len += sizeof(struct sadb_lifetime);
437
438	return;
439}
440
441void
442key_setspirange()
443{
444	struct sadb_spirange m_spi;
445
446	m_spi.sadb_spirange_len = PFKEY_UNIT64(sizeof(m_spi));
447	m_spi.sadb_spirange_exttype = SADB_EXT_SPIRANGE;
448	m_spi.sadb_spirange_min = 0x00001000;
449	m_spi.sadb_spirange_max = 0x00002000;
450	m_spi.sadb_spirange_reserved = 0;
451
452	memcpy(m_buf + m_len, &m_spi, sizeof(struct sadb_spirange));
453	m_len += sizeof(struct sadb_spirange);
454
455	return;
456}
457
458void
459key_setsadbkey(ext, str)
460	u_int ext;
461	caddr_t str;
462{
463	struct sadb_key m_key;
464	u_int keylen = strlen(str);
465	u_int len;
466
467	len = sizeof(struct sadb_key) + PFKEY_ALIGN8(keylen);
468	m_key.sadb_key_len = PFKEY_UNIT64(len);
469	m_key.sadb_key_exttype = ext;
470	m_key.sadb_key_bits = keylen * 8;
471	m_key.sadb_key_reserved = 0;
472
473	key_setsadbextbuf(m_buf, m_len,
474			(caddr_t)&m_key, sizeof(struct sadb_key),
475			str, keylen);
476	m_len += len;
477
478	return;
479}
480
481void
482key_setsadbsa()
483{
484	struct sadb_sa m_sa;
485
486	m_sa.sadb_sa_len = PFKEY_UNIT64(sizeof(struct sadb_sa));
487	m_sa.sadb_sa_exttype = SADB_EXT_SA;
488	m_sa.sadb_sa_spi = htonl(0x12345678);
489	m_sa.sadb_sa_replay = 4;
490	m_sa.sadb_sa_state = 0;
491	m_sa.sadb_sa_auth = SADB_AALG_MD5HMAC;
492	m_sa.sadb_sa_encrypt = SADB_EALG_DESCBC;
493	m_sa.sadb_sa_flags = 0;
494
495	memcpy(m_buf + m_len, &m_sa, sizeof(struct sadb_sa));
496	m_len += sizeof(struct sadb_sa);
497
498	return;
499}
500
501void
502key_setsadbaddr(ext, af, str)
503	u_int ext, af;
504	caddr_t str;
505{
506	struct sadb_address m_addr;
507	u_int len;
508	struct addrinfo hints, *res;
509	const char *serv;
510	int plen;
511
512	switch (af) {
513	case AF_INET:
514		plen = sizeof(struct in_addr) << 3;
515		break;
516	case AF_INET6:
517		plen = sizeof(struct in6_addr) << 3;
518		break;
519	default:
520		/* XXX bark */
521		exit(1);
522	}
523
524	/* make sockaddr buffer */
525	memset(&hints, 0, sizeof(hints));
526	hints.ai_family = af;
527	hints.ai_socktype = SOCK_DGRAM;	/*dummy*/
528	hints.ai_flags = AI_NUMERICHOST;
529	serv = (ext == SADB_EXT_ADDRESS_PROXY ? "0" : "4660");	/*0x1234*/
530	if (getaddrinfo(str, serv, &hints, &res) != 0 || res->ai_next) {
531		/* XXX bark */
532		exit(1);
533	}
534
535	len = sizeof(struct sadb_address) + PFKEY_ALIGN8(res->ai_addrlen);
536	m_addr.sadb_address_len = PFKEY_UNIT64(len);
537	m_addr.sadb_address_exttype = ext;
538	m_addr.sadb_address_proto =
539		(ext == SADB_EXT_ADDRESS_PROXY ? 0 : IPPROTO_TCP);
540	m_addr.sadb_address_prefixlen = plen;
541	m_addr.sadb_address_reserved = 0;
542
543	key_setsadbextbuf(m_buf, m_len,
544			(caddr_t)&m_addr, sizeof(struct sadb_address),
545			(caddr_t)res->ai_addr, res->ai_addrlen);
546	m_len += len;
547
548	freeaddrinfo(res);
549
550	return;
551}
552
553void
554key_setsadbextbuf(dst, off, ebuf, elen, vbuf, vlen)
555	caddr_t dst, ebuf, vbuf;
556	int off, elen, vlen;
557{
558	memset(dst + off, 0, elen + vlen);
559	memcpy(dst + off, (caddr_t)ebuf, elen);
560	memcpy(dst + off + elen, vbuf, vlen);
561
562	return;
563}
564
565