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