1 /*	$OpenBSD: pfkdump.c,v 1.5 2005/07/09 21:54:12 hshoexer Exp $	*/
2 
3 /*
4  * Copyright (c) 2003 Markus Friedl.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 #include <sys/param.h>
27 #include <sys/socket.h>
28 #include <sys/errno.h>
29 #include <sys/time.h>
30 #include <sys/sysctl.h>
31 #include <net/pfkeyv2.h>
32 #include <netinet/ip_ipsp.h>
33 #include <netdb.h>
34 #include <string.h>
35 #include <unistd.h>
36 #include <stdlib.h>
37 #include <stdio.h>
38 #include <err.h>
39 
40 #include "ipsecctl.h"
41 #include "pfkey.h"
42 
43 static void	print_sa(struct sadb_ext *, struct sadb_msg *);
44 static void	print_addr(struct sadb_ext *, struct sadb_msg *);
45 static void	print_key(struct sadb_ext *, struct sadb_msg *);
46 static void	print_life(struct sadb_ext *, struct sadb_msg *);
47 static void	print_ident(struct sadb_ext *, struct sadb_msg *);
48 static void	print_auth(struct sadb_ext *, struct sadb_msg *);
49 static void	print_cred(struct sadb_ext *, struct sadb_msg *);
50 static void	print_udpenc(struct sadb_ext *, struct sadb_msg *);
51 
52 static struct idname *lookup(struct idname [], u_int8_t);
53 static char    *lookup_name(struct idname [], u_int8_t);
54 static void	print_ext(struct sadb_ext *, struct sadb_msg *, int);
55 
56 void		pfkey_print_sa(struct sadb_msg *, int);
57 
58 struct sadb_ext *extensions[SADB_EXT_MAX];
59 
60 struct idname {
61 	u_int8_t id;
62 	char *name;
63 	void (*func)(struct sadb_ext *, struct sadb_msg *);
64 };
65 
66 struct idname ext_types[] = {
67 	{ SADB_EXT_RESERVED,		"reserved",		NULL },
68 	{ SADB_EXT_SA,			"sa",			print_sa},
69 	{ SADB_EXT_LIFETIME_CURRENT,	"lifetime_cur",		print_life },
70 	{ SADB_EXT_LIFETIME_HARD,	"lifetime_hard",	print_life },
71 	{ SADB_EXT_LIFETIME_SOFT,	"lifetime_soft",	print_life },
72 	{ SADB_EXT_ADDRESS_SRC,		"address_src",		print_addr},
73 	{ SADB_EXT_ADDRESS_DST,		"address_dst",		print_addr},
74 	{ SADB_EXT_KEY_AUTH,		"key_auth",		print_key},
75 	{ SADB_EXT_KEY_ENCRYPT,		"key_encrypt",		print_key},
76 	{ SADB_EXT_IDENTITY_SRC,	"identity_src",		print_ident },
77 	{ SADB_EXT_IDENTITY_DST,	"identity_dst",		print_ident },
78 	{ SADB_X_EXT_REMOTE_AUTH,	"remote_auth",		print_auth },
79 	{ SADB_X_EXT_LOCAL_CREDENTIALS, "local_cred",		print_cred },
80 	{ SADB_X_EXT_REMOTE_CREDENTIALS,"remote_cred",		print_cred },
81 	{ SADB_X_EXT_UDPENCAP,		"udpencap",		print_udpenc },
82 #ifdef SADB_X_EXT_LIFETIME_LASTUSE
83 	{ SADB_X_EXT_LIFETIME_LASTUSE,	"lifetime_lastuse",	print_life },
84 #endif
85 	{ 0,				NULL,			NULL }
86 };
87 
88 struct idname sa_types[] = {
89 	{ SADB_SATYPE_UNSPEC,		"unspec",		NULL },
90 	{ SADB_SATYPE_AH,		"ah",			NULL },
91 	{ SADB_SATYPE_ESP,		"esp",			NULL },
92 	{ SADB_SATYPE_RSVP,		"rsvp",			NULL },
93 	{ SADB_SATYPE_OSPFV2,		"ospfv2",		NULL },
94 	{ SADB_SATYPE_RIPV2,		"ripv2",		NULL },
95 	{ SADB_SATYPE_MIP,		"mip",			NULL },
96 	{ SADB_X_SATYPE_IPIP,		"ipip",			NULL },
97 	{ SADB_X_SATYPE_TCPSIGNATURE,	"tcpmd5",		NULL },
98 	{ SADB_X_SATYPE_IPCOMP,		"ipcomp",		NULL },
99 	{ 0,				NULL,			NULL }
100 };
101 
102 struct idname auth_types[] = {
103 	{ SADB_AALG_NONE,		"none",			NULL },
104 	{ SADB_X_AALG_DES,		"des",			NULL },
105 	{ SADB_AALG_MD5HMAC,		"hmac-md5",		NULL },
106 	{ SADB_X_AALG_RIPEMD160HMAC,	"hmac-ripemd160",	NULL },
107 	{ SADB_AALG_SHA1HMAC,		"hmac-sha1",		NULL },
108 	{ SADB_X_AALG_SHA2_256,		"hmac-sha2-256",	NULL },
109 	{ SADB_X_AALG_SHA2_384,		"hmac-sha2-384",	NULL },
110 	{ SADB_X_AALG_SHA2_512,		"hmac-sha2-512",	NULL },
111 	{ SADB_X_AALG_MD5,		"md5",			NULL },
112 	{ SADB_X_AALG_SHA1,		"sha1",			NULL },
113 	{ 0,				NULL,			NULL }
114 };
115 
116 struct idname cred_types[] = {
117 	{ SADB_X_CREDTYPE_X509,		"x509-asn1",		NULL },
118 	{ SADB_X_CREDTYPE_KEYNOTE,	"keynote",		NULL },
119 	{ 0,				NULL,			NULL }
120 };
121 
122 struct idname enc_types[] = {
123 	{ SADB_EALG_NONE,		"none",			NULL },
124 	{ SADB_EALG_3DESCBC,		"3des-cbc",		NULL },
125 	{ SADB_EALG_DESCBC,		"des-cbc",		NULL },
126 	{ SADB_X_EALG_3IDEA,		"idea3",		NULL },
127 	{ SADB_X_EALG_AES,		"aes",			NULL },
128 #ifdef SADB_X_EALG_AESCTR
129 	{ SADB_X_EALG_AESCTR,		"aesctr",		NULL },
130 #endif
131 	{ SADB_X_EALG_BLF,		"blowfish",		NULL },
132 	{ SADB_X_EALG_CAST,		"cast128",		NULL },
133 	{ SADB_X_EALG_DES_IV32,		"des-iv32",		NULL },
134 	{ SADB_X_EALG_DES_IV64,		"des-iv64",		NULL },
135 	{ SADB_X_EALG_IDEA,		"idea",			NULL },
136 	{ SADB_EALG_NULL,		"null",			NULL },
137 	{ SADB_X_EALG_RC4,		"rc4",			NULL },
138 	{ SADB_X_EALG_RC5,		"rc5",			NULL },
139 	{ SADB_X_EALG_SKIPJACK,		"skipjack",		NULL },
140 	{ 0,				NULL,			NULL }
141 };
142 
143 struct idname comp_types[] = {
144 	{ SADB_X_CALG_NONE,		"none",			NULL },
145 	{ SADB_X_CALG_OUI,		"oui",			NULL },
146 	{ SADB_X_CALG_DEFLATE,		"deflate",		NULL },
147 	{ SADB_X_CALG_LZS,		"lzs",			NULL },
148 	{ 0,				NULL,			NULL }
149 };
150 
151 struct idname xauth_types[] = {
152 	{ SADB_X_AUTHTYPE_NONE,		"none",			NULL },
153 	{ SADB_X_AUTHTYPE_PASSPHRASE,	"passphrase",		NULL },
154 	{ SADB_X_AUTHTYPE_RSA,		"rsa",			NULL },
155 	{ 0,				NULL,			NULL }
156 };
157 
158 struct idname identity_types[] = {
159 	{ SADB_IDENTTYPE_RESERVED,	"reserved",		NULL },
160 	{ SADB_IDENTTYPE_PREFIX,	"prefix",		NULL },
161 	{ SADB_IDENTTYPE_FQDN,		"fqdn",			NULL },
162 	{ SADB_IDENTTYPE_USERFQDN,	"ufqdn",		NULL },
163 	{ SADB_X_IDENTTYPE_CONNECTION,	"x_connection",		NULL },
164 	{ 0,				NULL,			NULL }
165 };
166 
167 static struct idname *
lookup(struct idname tab[],u_int8_t id)168 lookup(struct idname tab[], u_int8_t id)
169 {
170 	struct idname *entry;
171 
172 	for (entry = tab; entry->name; entry++)
173 		if (entry->id == id)
174 			return (entry);
175 	return (NULL);
176 }
177 
178 static char *
lookup_name(struct idname tab[],u_int8_t id)179 lookup_name(struct idname tab[], u_int8_t id)
180 {
181 	struct idname *entry;
182 
183 	entry = lookup(tab, id);
184 	return (entry ? entry->name : "unknown");
185 }
186 
187 static void
print_ext(struct sadb_ext * ext,struct sadb_msg * msg,int opts)188 print_ext(struct sadb_ext *ext, struct sadb_msg *msg, int opts)
189 {
190 	struct idname *entry;
191 
192 	if (ext->sadb_ext_type == SADB_EXT_ADDRESS_SRC ||
193 	    ext->sadb_ext_type == SADB_EXT_ADDRESS_DST)
194 		return;
195 
196 	if ((entry = lookup(ext_types, ext->sadb_ext_type)) == NULL) {
197 		printf("unknown ext: type %u len %u\n",
198 		    ext->sadb_ext_type, ext->sadb_ext_len);
199 		return;
200 	}
201 
202 	if (!(opts & IPSECCTL_OPT_VERBOSE) && (entry->id != SADB_EXT_SA))
203 		return;
204 	if (entry->id != SADB_EXT_SA)
205 		printf("\t%s: ", entry->name);
206 	if (entry->func != NULL)
207 		(*entry->func)(ext, msg);
208 	else
209 		printf("type %u len %u\n",
210 		    ext->sadb_ext_type, ext->sadb_ext_len);
211 }
212 
213 static void
print_sa(struct sadb_ext * ext,struct sadb_msg * msg)214 print_sa(struct sadb_ext *ext, struct sadb_msg *msg)
215 {
216 	struct sadb_sa *sa = (struct sadb_sa *)ext;
217 
218 	if (extensions[SADB_EXT_ADDRESS_SRC]) {
219 		printf("from ");
220 		print_addr(extensions[SADB_EXT_ADDRESS_SRC], msg);
221 	}
222 	if (extensions[SADB_EXT_ADDRESS_DST]) {
223 		printf(" to ");
224 		print_addr(extensions[SADB_EXT_ADDRESS_DST], msg);
225 	}
226 	if (msg->sadb_msg_satype == SADB_X_SATYPE_IPCOMP)
227 		printf("cpi 0x%8.8x %s",
228 		    ntohl(sa->sadb_sa_spi),
229 		    lookup_name(comp_types, sa->sadb_sa_encrypt));
230 	else {
231 		printf(" spi 0x%8.8x", ntohl(sa->sadb_sa_spi));
232 		if (sa->sadb_sa_encrypt)
233 			printf(" %s",
234 			    lookup_name(enc_types, sa->sadb_sa_encrypt));
235 		if (sa->sadb_sa_auth)
236 			printf(" %s",
237 			    lookup_name(auth_types, sa->sadb_sa_auth));
238 	}
239 	if (sa->sadb_sa_flags & SADB_X_SAFLAGS_TUNNEL)
240 		printf(" tunnel");
241 	printf("\n");
242 }
243 
244 static void
print_addr(struct sadb_ext * ext,struct sadb_msg * msg)245 print_addr(struct sadb_ext *ext, struct sadb_msg *msg)
246 {
247 	struct sadb_address *addr = (struct sadb_address *)ext;
248 	struct sockaddr *sa;
249 	struct sockaddr_in *sin4;
250 	struct sockaddr_in6 *sin6;
251 	char hbuf[NI_MAXHOST];
252 
253 	sa = (struct sockaddr *)(addr + 1);
254 	if (sa->sa_family == 0)
255 		printf("<any>");
256 	else if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), NULL, 0,
257 	    NI_NUMERICHOST))
258 		printf("<could not get numeric hostname>");
259 	else
260 		printf("%s", hbuf);
261 	switch (sa->sa_family) {
262 	case AF_INET:
263 		sin4 = (struct sockaddr_in *)sa;
264 		if (sin4->sin_port)
265 			printf(" port %u", ntohs(sin4->sin_port));
266 		break;
267 	case AF_INET6:
268 		sin6 = (struct sockaddr_in6 *)sa;
269 		if (sin6->sin6_port)
270 			printf(" port %u", ntohs(sin6->sin6_port));
271 		break;
272 	}
273 }
274 
275 static void
print_key(struct sadb_ext * ext,struct sadb_msg * msg)276 print_key(struct sadb_ext *ext, struct sadb_msg *msg)
277 {
278 	struct sadb_key *key = (struct sadb_key *)ext;
279 	u_int8_t *data;
280 	int i;
281 
282 	printf("bits %u: ", key->sadb_key_bits);
283 	data = (u_int8_t *)(key + 1);
284 	for (i = 0; i < key->sadb_key_bits / 8; i++) {
285 		printf("%2.2x", data[i]);
286 		data[i] = 0x00;		/* clear sensitive data */
287 	}
288 	printf("\n");
289 }
290 
291 static void
print_life(struct sadb_ext * ext,struct sadb_msg * msg)292 print_life(struct sadb_ext *ext, struct sadb_msg *msg)
293 {
294 	struct sadb_lifetime *life = (struct sadb_lifetime *)ext;
295 
296 	printf("alloc %u bytes %llu add %llu first %llu\n",
297 	    life->sadb_lifetime_allocations,
298 	    life->sadb_lifetime_bytes,
299 	    life->sadb_lifetime_addtime,
300 	    life->sadb_lifetime_usetime);
301 }
302 
303 static void
print_ident(struct sadb_ext * ext,struct sadb_msg * msg)304 print_ident(struct sadb_ext *ext, struct sadb_msg *msg)
305 {
306 	struct sadb_ident *ident = (struct sadb_ident *)ext;
307 
308 	printf("type %s id %llu: %s\n",
309 	    lookup_name(identity_types, ident->sadb_ident_type),
310 	    ident->sadb_ident_id, (char *)(ident + 1));
311 }
312 
313 static void
print_auth(struct sadb_ext * ext,struct sadb_msg * msg)314 print_auth(struct sadb_ext *ext, struct sadb_msg *msg)
315 {
316 	struct sadb_x_cred *x_cred = (struct sadb_x_cred *)ext;
317 
318 	printf("type %s\n",
319 	    lookup_name(xauth_types, x_cred->sadb_x_cred_type));
320 }
321 
322 static void
print_cred(struct sadb_ext * ext,struct sadb_msg * msg)323 print_cred(struct sadb_ext *ext, struct sadb_msg *msg)
324 {
325 	struct sadb_x_cred *x_cred = (struct sadb_x_cred *)ext;
326 	printf("type %s\n",
327 	    lookup_name(cred_types, x_cred->sadb_x_cred_type));
328 }
329 
330 static void
print_udpenc(struct sadb_ext * ext,struct sadb_msg * msg)331 print_udpenc(struct sadb_ext *ext, struct sadb_msg *msg)
332 {
333 	struct sadb_x_udpencap *x_udpencap = (struct sadb_x_udpencap *)ext;
334 
335 	printf("udpencap port %u\n", ntohs(x_udpencap->sadb_x_udpencap_port));
336 }
337 
338 void
pfkey_print_sa(struct sadb_msg * msg,int opts)339 pfkey_print_sa(struct sadb_msg *msg, int opts)
340 {
341 	struct sadb_ext *ext;
342 	int		 i;
343 
344 	bzero(extensions, sizeof(extensions));
345 
346 	printf("%s ", lookup_name(sa_types, msg->sadb_msg_satype));
347 	for (ext = (struct sadb_ext *)(msg + 1);
348 	    (size_t)((u_int8_t *)ext - (u_int8_t *)msg) <
349 	    msg->sadb_msg_len * PFKEYV2_CHUNK && ext->sadb_ext_len > 0;
350 	    ext = (struct sadb_ext *)((u_int8_t *)ext +
351 	    ext->sadb_ext_len * PFKEYV2_CHUNK))
352 		extensions[ext->sadb_ext_type] = ext;
353 
354 	for (i = 0; i < SADB_EXT_MAX; i++)
355 		if (extensions[i])
356 			print_ext(extensions[i], msg, opts);
357 	fflush(stdout);
358 }
359