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