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