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