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