1 /* 2 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the project nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $FreeBSD$ 30 */ 31 32 #include <sys/types.h> 33 #include <sys/param.h> 34 #include <sys/socket.h> 35 #include <netinet6/ipsec.h> 36 #include <net/pfkeyv2.h> 37 #include <netkey/key_var.h> 38 #include <netkey/key_debug.h> 39 40 #include <netinet/in.h> 41 #include <netinet6/ipsec.h> 42 #ifdef INET6 43 #include <netinet6/in6.h> 44 #endif 45 #include <arpa/inet.h> 46 47 #include <stdlib.h> 48 #include <unistd.h> 49 #include <stdio.h> 50 #include <string.h> 51 #include <time.h> 52 53 #include "ipsec_strerror.h" 54 55 #define GETMSGSTR(str, num) \ 56 { \ 57 if (sizeof((str)[0]) == 0 \ 58 || num >= sizeof(str)/sizeof((str)[0])) \ 59 printf("%d ", (num)); \ 60 else if (strlen((str)[(num)]) == 0) \ 61 printf("%d ", (num)); \ 62 else \ 63 printf("%s ", (str)[(num)]); \ 64 } 65 66 #define GETAF(p) \ 67 (((struct sockaddr *)(p))->sa_family) 68 69 static char *_str_ipaddr __P((u_int family, caddr_t addr)); 70 static char *_str_prefport __P((u_int family, u_int pref, u_int port)); 71 static char *_str_time __P((time_t t)); 72 static void _str_lifetime_byte __P((struct sadb_lifetime *x, char *str)); 73 74 /* 75 * Must to be re-written about following strings. 76 */ 77 static char *_str_satype[] = { 78 "unspec", 79 "unknown", 80 "ah", 81 "esp", 82 "unknown", 83 "rsvp", 84 "ospfv2", 85 "ripv2", 86 "mip", 87 "ipcomp", 88 }; 89 90 static char *_str_mode[] = { 91 "any", 92 "transport", 93 "tunnel", 94 }; 95 96 static char *_str_upper[] = { 97 /*0*/ "ip", "icmp", "igmp", "ggp", "ip4", 98 "", "tcp", "", "egp", "", 99 /*10*/ "", "", "", "", "", 100 "", "", "udp", "", "", 101 /*20*/ "", "", "idp", "", "", 102 "", "", "", "", "tp", 103 /*30*/ "", "", "", "", "", 104 "", "", "", "", "", 105 /*40*/ "", "ip6", "", "rt6", "frag6", 106 "", "rsvp", "gre", "", "", 107 /*50*/ "esp", "ah", "", "", "", 108 "", "", "", "icmp6", "none", 109 /*60*/ "dst6", 110 }; 111 112 static char *_str_state[] = { 113 "larval", 114 "mature", 115 "dying", 116 "dead", 117 }; 118 119 static char *_str_alg_auth[] = { 120 "none", 121 "hmac-md5", 122 "hmac-sha1", 123 "md5", 124 "sha", 125 "null", 126 }; 127 128 static char *_str_alg_enc[] = { 129 "none", 130 "des-cbc", 131 "3des-cbc", 132 "null", 133 "blowfish-cbc", 134 "cast128-cbc", 135 "rc5-cbc", 136 }; 137 138 static char *_str_alg_comp[] = { 139 "none", 140 "oui", 141 "deflate", 142 "lzs", 143 }; 144 145 /* 146 * dump SADB_MSG formated. For debugging, you should use kdebug_sadb(). 147 */ 148 void 149 pfkey_sadump(m) 150 struct sadb_msg *m; 151 { 152 caddr_t mhp[SADB_EXT_MAX + 1]; 153 struct sadb_sa *m_sa; 154 struct sadb_lifetime *m_lftc, *m_lfth, *m_lfts; 155 struct sadb_address *m_saddr, *m_daddr, *m_paddr; 156 struct sadb_key *m_auth, *m_enc; 157 struct sadb_ident *m_sid, *m_did; 158 struct sadb_sens *m_sens; 159 160 /* check pfkey message. */ 161 if (pfkey_align(m, mhp)) { 162 printf("%s\n", ipsec_strerror()); 163 return; 164 } 165 if (pfkey_check(mhp)) { 166 printf("%s\n", ipsec_strerror()); 167 return; 168 } 169 170 m_sa = (struct sadb_sa *)mhp[SADB_EXT_SA]; 171 m_lftc = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_CURRENT]; 172 m_lfth = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_HARD]; 173 m_lfts = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_SOFT]; 174 m_saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; 175 m_daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]; 176 m_paddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_PROXY]; 177 m_auth = (struct sadb_key *)mhp[SADB_EXT_KEY_AUTH]; 178 m_enc = (struct sadb_key *)mhp[SADB_EXT_KEY_ENCRYPT]; 179 m_sid = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_SRC]; 180 m_did = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_SRC]; 181 m_sens = (struct sadb_sens *)mhp[SADB_EXT_SENSITIVITY]; 182 183 /* source address */ 184 if (m_saddr == NULL) { 185 printf("no ADDRESS_SRC extension.\n"); 186 return; 187 } 188 printf("%s ", 189 _str_ipaddr(GETAF(m_saddr + 1), _INADDRBYSA(m_saddr + 1))); 190 191 /* destination address */ 192 if (m_daddr == NULL) { 193 printf("no ADDRESS_DST extension.\n"); 194 return; 195 } 196 printf("%s ", 197 _str_ipaddr(GETAF(m_daddr + 1), _INADDRBYSA(m_daddr + 1))); 198 199 /* SA type */ 200 if (m_sa == NULL) { 201 printf("no SA extension.\n"); 202 return; 203 } 204 printf("\n\t"); 205 206 GETMSGSTR(_str_satype, m->sadb_msg_satype); 207 208 printf("mode="); 209 GETMSGSTR(_str_mode, m->sadb_msg_mode); 210 211 printf("spi=%u(0x%08x) replay=%u flags=0x%08x\n", 212 (u_int32_t)ntohl(m_sa->sadb_sa_spi), 213 (u_int32_t)ntohl(m_sa->sadb_sa_spi), 214 m_sa->sadb_sa_replay, 215 m_sa->sadb_sa_flags); 216 217 /* encryption key */ 218 if (m->sadb_msg_satype == SADB_X_SATYPE_IPCOMP) { 219 printf("\tC: "); 220 GETMSGSTR(_str_alg_comp, m_sa->sadb_sa_encrypt); 221 } else if (m->sadb_msg_satype == SADB_SATYPE_ESP) { 222 if (m_enc != NULL) { 223 printf("\tE: "); 224 GETMSGSTR(_str_alg_enc, m_sa->sadb_sa_encrypt); 225 ipsec_hexdump((caddr_t)m_enc + sizeof(*m_enc), 226 m_enc->sadb_key_bits / 8); 227 printf("\n"); 228 } 229 } 230 231 /* authentication key */ 232 if (m_auth != NULL) { 233 printf("\tA: "); 234 GETMSGSTR(_str_alg_auth, m_sa->sadb_sa_auth); 235 ipsec_hexdump((caddr_t)m_auth + sizeof(*m_auth), 236 m_auth->sadb_key_bits / 8); 237 printf("\n"); 238 } 239 240 /* state */ 241 printf("\tstate="); 242 GETMSGSTR(_str_state, m_sa->sadb_sa_state); 243 244 printf("seq=%lu pid=%lu\n", 245 (u_long)m->sadb_msg_seq, 246 (u_long)m->sadb_msg_pid); 247 248 /* lifetime */ 249 if (m_lftc != NULL) { 250 time_t tmp_time = time(0); 251 252 printf("\tcreated: %s", 253 _str_time(m_lftc->sadb_lifetime_addtime)); 254 printf("\tcurrent: %s\n", _str_time(tmp_time)); 255 printf("\tdiff: %lu(s)", 256 (u_long)(m_lftc->sadb_lifetime_addtime == 0 ? 257 0 : (tmp_time - m_lftc->sadb_lifetime_addtime))); 258 259 printf("\thard: %lu(s)", 260 (u_long)(m_lfth == NULL ? 261 0 : m_lfth->sadb_lifetime_addtime)); 262 printf("\tsoft: %lu(s)\n", 263 (u_long)(m_lfts == NULL ? 264 0 : m_lfts->sadb_lifetime_addtime)); 265 266 printf("\tlast: %s", 267 _str_time(m_lftc->sadb_lifetime_usetime)); 268 printf("\thard: %lu(s)", 269 (u_long)(m_lfth == NULL ? 270 0 : m_lfth->sadb_lifetime_usetime)); 271 printf("\tsoft: %lu(s)\n", 272 (u_long)(m_lfts == NULL ? 273 0 : m_lfts->sadb_lifetime_usetime)); 274 275 _str_lifetime_byte(m_lftc, "current"); 276 _str_lifetime_byte(m_lfth, "hard"); 277 _str_lifetime_byte(m_lfts, "soft"); 278 printf("\n"); 279 280 printf("\tallocated: %lu", 281 (unsigned long)m_lftc->sadb_lifetime_allocations); 282 printf("\thard: %lu", 283 (u_long)(m_lfth == NULL ? 284 0 : m_lfth->sadb_lifetime_allocations)); 285 printf("\tsoft: %lu\n", 286 (u_long)(m_lfts == NULL ? 287 0 : m_lfts->sadb_lifetime_allocations)); 288 } 289 290 /* XXX DEBUG */ 291 printf("\trefcnt=%d\n", m->sadb_msg_reserved); 292 293 return; 294 } 295 296 void 297 pfkey_spdump(m) 298 struct sadb_msg *m; 299 { 300 caddr_t mhp[SADB_EXT_MAX + 1]; 301 struct sadb_address *m_saddr, *m_daddr; 302 struct sadb_x_policy *m_xpl; 303 304 /* check pfkey message. */ 305 if (pfkey_align(m, mhp)) { 306 printf("%s\n", ipsec_strerror()); 307 return; 308 } 309 if (pfkey_check(mhp)) { 310 printf("%s\n", ipsec_strerror()); 311 return; 312 } 313 314 m_saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; 315 m_daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]; 316 m_xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY]; 317 318 /* source address */ 319 if (m_saddr == NULL) { 320 printf("no ADDRESS_SRC extension.\n"); 321 return; 322 } 323 printf("%s%s ", 324 _str_ipaddr(GETAF(m_saddr + 1), _INADDRBYSA(m_saddr + 1)), 325 _str_prefport(GETAF(m_saddr + 1), 326 m_saddr->sadb_address_prefixlen, 327 _INPORTBYSA(m_saddr + 1))); 328 329 /* destination address */ 330 if (m_daddr == NULL) { 331 printf("no ADDRESS_DST extension.\n"); 332 return; 333 } 334 printf("%s%s ", 335 _str_ipaddr(GETAF(m_daddr + 1), _INADDRBYSA(m_daddr + 1)), 336 _str_prefport(GETAF(m_daddr + 1), 337 m_daddr->sadb_address_prefixlen, 338 _INPORTBYSA(m_daddr + 1))); 339 340 /* upper layer protocol */ 341 if (m_saddr->sadb_address_proto != m_saddr->sadb_address_proto) { 342 printf("upper layer protocol mismatched.\n"); 343 return; 344 } 345 if (m_saddr->sadb_address_proto == IPSEC_ULPROTO_ANY) 346 printf("any"); 347 else 348 GETMSGSTR(_str_upper, m_saddr->sadb_address_proto); 349 350 /* policy */ 351 { 352 char *d_xpl; 353 354 if (m_xpl == NULL) { 355 printf("no X_POLICY extension.\n"); 356 return; 357 } 358 d_xpl = ipsec_dump_policy((char *)m_xpl, "\n\t"); 359 360 /* dump SPD */ 361 printf("\n\t%s\n", d_xpl); 362 free(d_xpl); 363 } 364 365 printf("\tseq=%ld pid=%ld\n", 366 (u_long)m->sadb_msg_seq, 367 (u_long)m->sadb_msg_pid); 368 369 /* XXX TEST */ 370 printf("\trefcnt=%d\n", m->sadb_msg_reserved); 371 372 return; 373 } 374 375 /* 376 * set "ipaddress" to buffer. 377 */ 378 static char * 379 _str_ipaddr(family, addr) 380 u_int family; 381 caddr_t addr; 382 { 383 static char buf[128]; 384 char addrbuf[128]; 385 386 if (addr == NULL) 387 return ""; 388 389 inet_ntop(family, addr, addrbuf, sizeof(addrbuf)); 390 391 snprintf(buf, sizeof(buf), "%s", addrbuf); 392 393 return buf; 394 } 395 396 /* 397 * set "/prefix[port number]" to buffer. 398 */ 399 static char * 400 _str_prefport(family, pref, port) 401 u_int family, pref, port; 402 { 403 static char buf[128]; 404 char prefbuf[10]; 405 char portbuf[10]; 406 407 if (pref == (_INALENBYAF(family) << 3)) 408 prefbuf[0] = '\0'; 409 else 410 snprintf(prefbuf, sizeof(prefbuf), "/%u", pref); 411 412 if (port == IPSEC_PORT_ANY) 413 snprintf(portbuf, sizeof(portbuf), "[%s]", "any"); 414 else 415 snprintf(portbuf, sizeof(portbuf), "[%u]", ntohs(port)); 416 417 snprintf(buf, sizeof(buf), "%s%s", prefbuf, portbuf); 418 419 return buf; 420 } 421 422 /* 423 * set "Mon Day Time Year" to buffer 424 */ 425 static char * 426 _str_time(t) 427 time_t t; 428 { 429 static char buf[128]; 430 431 if (t == 0) { 432 int i = 0; 433 for (;i < 20;) buf[i++] = ' '; 434 } else { 435 char *t0; 436 t0 = ctime(&t); 437 memcpy(buf, t0 + 4, 20); 438 } 439 440 buf[20] = '\0'; 441 442 return(buf); 443 } 444 445 static void 446 _str_lifetime_byte(x, str) 447 struct sadb_lifetime *x; 448 char *str; 449 { 450 double y; 451 char *unit; 452 int w; 453 454 if (x == NULL) { 455 printf("\t%s: 0(bytes)", str); 456 return; 457 } 458 459 y = (x->sadb_lifetime_bytes) * 1.0; 460 unit = ""; 461 w = 0; 462 printf("\t%s: %.*f(%sbytes)", str, w, y, unit); 463 } 464