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