setup.c revision 71076533ea2d32b0573b30b6f9507b88cd3a95f3
1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <stdio.h> 18#include <stdlib.h> 19#include <string.h> 20#include <unistd.h> 21#include <sys/param.h> 22#include <sys/types.h> 23#include <sys/socket.h> 24#include <netinet/in.h> 25#include <netinet/ip.h> 26#include <netdb.h> 27#include <fcntl.h> 28 29#include "config.h" 30#include "gcmalloc.h" 31#include "libpfkey.h" 32#include "var.h" 33#include "isakmp_var.h" 34#include "isakmp.h" 35#include "isakmp_xauth.h" 36#include "vmbuf.h" 37#include "crypto_openssl.h" 38#include "oakley.h" 39#include "ipsec_doi.h" 40#include "algorithm.h" 41#include "vendorid.h" 42#include "schedule.h" 43#include "pfkey.h" 44#include "nattraversal.h" 45#include "proposal.h" 46#include "sainfo.h" 47#include "localconf.h" 48#include "remoteconf.h" 49#include "sockmisc.h" 50#include "grabmyaddr.h" 51#include "plog.h" 52#include "admin.h" 53#include "privsep.h" 54#include "throttle.h" 55#include "misc.h" 56 57static struct localconf localconf; 58static struct sainfo sainfo; 59static char *pre_shared_key; 60 61static char *interface; 62static struct sockaddr *targets[2]; 63static struct { 64 struct sockaddr *addr; 65 int fd; 66} sources[2]; 67 68struct localconf *lcconf = &localconf; 69char *script_names[SCRIPT_MAX + 1]; 70int f_local = 0; 71 72/*****************************************************************************/ 73 74static void add_sainfo_algorithm(int class, int algorithm, int length) 75{ 76 struct sainfoalg *p = calloc(1, sizeof(struct sainfoalg)); 77 p->alg = algorithm; 78 p->encklen = length; 79 80 if (!sainfo.algs[class]) { 81 sainfo.algs[class] = p; 82 } else { 83 struct sainfoalg *q = sainfo.algs[class]; 84 while (q->next) { 85 q = q->next; 86 } 87 q->next = p; 88 } 89} 90 91static void set_globals(char *interfaze, char *server) 92{ 93 struct addrinfo hints = { 94 .ai_flags = AI_NUMERICSERV, 95#ifndef INET6 96 .ai_family = AF_INET, 97#else 98 .ai_family = AF_UNSPEC, 99#endif 100 .ai_socktype = SOCK_DGRAM, 101 }; 102 struct addrinfo *info; 103 104 if (getaddrinfo(server, "500", &hints, &info) != 0) { 105 do_plog(LLV_ERROR, "Cannot resolve address: %s\n", server); 106 exit(1); 107 } 108 if (info->ai_next) { 109 do_plog(LLV_WARNING, "Found multiple addresses. Use the first one.\n"); 110 } 111 targets[0] = dupsaddr(info->ai_addr); 112 freeaddrinfo(info); 113 114 interface = interfaze; 115 sources[0].addr = getlocaladdr(targets[0]); 116 if (!sources[0].addr) { 117 do_plog(LLV_ERROR, "Cannot get local address\n"); 118 exit(1); 119 } 120 set_port(targets[0], 0); 121 set_port(sources[0].addr, 0); 122 sources[0].fd = -1; 123 sources[1].addr = dupsaddr(sources[0].addr); 124 sources[1].fd = -1; 125 126 localconf.port_isakmp = PORT_ISAKMP; 127 localconf.port_isakmp_natt = PORT_ISAKMP_NATT; 128 localconf.default_af = AF_INET; 129 localconf.pathinfo[LC_PATHTYPE_CERT] = "./"; 130 localconf.pad_random = LC_DEFAULT_PAD_RANDOM; 131 localconf.pad_randomlen = LC_DEFAULT_PAD_RANDOM; 132 localconf.pad_strict = LC_DEFAULT_PAD_STRICT; 133 localconf.pad_excltail = LC_DEFAULT_PAD_EXCLTAIL; 134 localconf.retry_counter = 10; 135 localconf.retry_interval = 3; 136 localconf.count_persend = LC_DEFAULT_COUNT_PERSEND; 137 localconf.secret_size = LC_DEFAULT_SECRETSIZE; 138 localconf.retry_checkph1 = LC_DEFAULT_RETRY_CHECKPH1; 139 localconf.wait_ph2complete = LC_DEFAULT_WAIT_PH2COMPLETE; 140 localconf.natt_ka_interval = LC_DEFAULT_NATT_KA_INTERVAL; 141 142 sainfo.lifetime = IPSECDOI_ATTR_SA_LD_SEC_DEFAULT; 143 sainfo.lifebyte = IPSECDOI_ATTR_SA_LD_KB_MAX; 144 add_sainfo_algorithm(algclass_ipsec_auth, IPSECDOI_ATTR_AUTH_HMAC_SHA1, 0); 145 add_sainfo_algorithm(algclass_ipsec_auth, IPSECDOI_ATTR_AUTH_HMAC_MD5, 0); 146 add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_AES, 256); 147 add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_AES, 128); 148 add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_3DES, 0); 149 add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_DES, 0); 150} 151 152/*****************************************************************************/ 153 154static int policy_match(struct sadb_address *address) 155{ 156 if (address) { 157 struct sockaddr *addr = PFKEY_ADDR_SADDR(address); 158 return cmpsaddr(addr, targets[0]) < CMPSADDR_MISMATCH || 159 cmpsaddr(addr, targets[1]) < CMPSADDR_MISMATCH; 160 } 161 return 0; 162} 163 164/* flush; spdflush; */ 165static void flush() 166{ 167 struct sadb_msg *p; 168 int replies = 0; 169 int key = pfkey_open(); 170 171 if (pfkey_send_dump(key, SADB_SATYPE_UNSPEC) <= 0 || 172 pfkey_send_spddump(key) <= 0) { 173 do_plog(LLV_ERROR, "Cannot dump SAD and SPD\n"); 174 exit(1); 175 } 176 177 for (p = NULL; replies < 2 && (p = pfkey_recv(key)) != NULL; free(p)) { 178 caddr_t q[SADB_EXT_MAX + 1]; 179 180 if (p->sadb_msg_type != SADB_DUMP && 181 p->sadb_msg_type != SADB_X_SPDDUMP) { 182 continue; 183 } 184 replies += !p->sadb_msg_seq; 185 186 if (p->sadb_msg_errno || pfkey_align(p, q) || pfkey_check(q)) { 187 continue; 188 } 189 if (policy_match((struct sadb_address *)q[SADB_EXT_ADDRESS_SRC]) || 190 policy_match((struct sadb_address *)q[SADB_EXT_ADDRESS_DST])) { 191 p->sadb_msg_type = (p->sadb_msg_type == SADB_DUMP) ? 192 SADB_DELETE : SADB_X_SPDDELETE; 193 p->sadb_msg_reserved = 0; 194 p->sadb_msg_seq = 0; 195 pfkey_send(key, p, PFKEY_UNUNIT64(p->sadb_msg_len)); 196 } 197 } 198 199 pfkey_close(key); 200} 201 202/* flush; spdflush; 203 * spdadd src dst protocol -P out ipsec esp/transport//require; OR 204 * spdadd src any protocol -P out ipsec esp/tunnel/local-remote/require; */ 205static void spdadd(struct sockaddr *src, struct sockaddr *dst, 206 int protocol, struct sockaddr *local, struct sockaddr *remote) 207{ 208 struct __attribute__((packed)) { 209 struct sadb_x_policy p; 210 struct sadb_x_ipsecrequest q; 211 char addresses[sizeof(struct sockaddr_storage) * 2]; 212 } policy; 213 214 struct sockaddr_storage any = { 215#ifndef __linux__ 216 .ss_len = src->sa_len, 217#endif 218 .ss_family = src->sa_family, 219 }; 220 221 int src_prefix = (src->sa_family == AF_INET) ? 32 : 128; 222 int dst_prefix = src_prefix; 223 int length = 0; 224 int key; 225 226 /* Fill default values. */ 227 memset(&policy, 0, sizeof(policy)); 228 policy.p.sadb_x_policy_exttype = SADB_X_EXT_POLICY; 229 policy.p.sadb_x_policy_type = IPSEC_POLICY_IPSEC; 230 policy.p.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND; 231#ifdef HAVE_PFKEY_POLICY_PRIORITY 232 policy.p.sadb_x_policy_priority = PRIORITY_DEFAULT; 233#endif 234 policy.q.sadb_x_ipsecrequest_proto = IPPROTO_ESP; 235 policy.q.sadb_x_ipsecrequest_mode = IPSEC_MODE_TRANSPORT; 236 policy.q.sadb_x_ipsecrequest_level = IPSEC_LEVEL_REQUIRE; 237 238 /* Deal with tunnel mode. */ 239 if (!dst) { 240 policy.q.sadb_x_ipsecrequest_mode = IPSEC_MODE_TUNNEL; 241 dst = (struct sockaddr *)&any; 242 dst_prefix = 0; 243 244 length = sysdep_sa_len(local); 245 memcpy(policy.addresses, local, length); 246 memcpy(&policy.addresses[length], remote, length); 247 length += length; 248 249 /* Also use the source address to filter policies. */ 250 targets[1] = dupsaddr(src); 251 } 252 253 /* Fix lengths. */ 254 length += sizeof(policy.q); 255 policy.q.sadb_x_ipsecrequest_len = length; 256 length += sizeof(policy.p); 257 policy.p.sadb_x_policy_len = PFKEY_UNIT64(length); 258 259 /* Always do a flush before adding the new policy. */ 260 flush(); 261 key = pfkey_open(); 262 if (pfkey_send_spdadd(key, src, src_prefix, dst, dst_prefix, protocol, 263 (caddr_t)&policy, length, 0) <= 0) { 264 do_plog(LLV_ERROR, "Cannot initialize SAD and SPD\n"); 265 exit(1); 266 } 267 pfkey_close(key); 268 atexit(flush); 269} 270 271/*****************************************************************************/ 272 273static void add_proposal(struct remoteconf *remoteconf, 274 int auth, int hash, int encryption, int length) 275{ 276 struct isakmpsa *p = racoon_calloc(1, sizeof(struct isakmpsa)); 277 p->prop_no = 1; 278 p->lifetime = OAKLEY_ATTR_SA_LD_SEC_DEFAULT; 279 p->enctype = encryption; 280 p->encklen = length; 281 p->authmethod = auth; 282 p->hashtype = hash; 283 p->dh_group = OAKLEY_ATTR_GRP_DESC_MODP1024; 284 p->vendorid = VENDORID_UNKNOWN; 285 286 if (!remoteconf->proposal) { 287 p->trns_no = 1; 288 remoteconf->proposal = p; 289 } else { 290 struct isakmpsa *q = remoteconf->proposal; 291 while (q->next) { 292 q = q->next; 293 } 294 p->trns_no = q->trns_no + 1; 295 q->next = p; 296 } 297} 298 299static vchar_t *strtovchar(char *string) 300{ 301 vchar_t *vchar = string ? vmalloc(strlen(string) + 1) : NULL; 302 if (vchar) { 303 memcpy(vchar->v, string, vchar->l); 304 } 305 return vchar; 306} 307 308static void set_pre_shared_key(struct remoteconf *remoteconf, 309 char *identifier, char *key) 310{ 311 pre_shared_key = key; 312 if (identifier[0]) { 313 remoteconf->idv = strtovchar(identifier); 314 remoteconf->idv->l -= 1; 315 remoteconf->etypes->type = ISAKMP_ETYPE_AGG; 316 317 remoteconf->idvtype = IDTYPE_KEYID; 318 if (strchr(identifier, '.')) { 319 remoteconf->idvtype = IDTYPE_FQDN; 320 if (strchr(identifier, '@')) { 321 remoteconf->idvtype = IDTYPE_USERFQDN; 322 } 323 } 324 } 325} 326 327static vchar_t *get_certificate(char *type, char *file) 328{ 329 char path[PATH_MAX + 1]; 330 vchar_t *certificate = NULL; 331 332 getpathname(path, sizeof(path), LC_PATHTYPE_CERT, file); 333 certificate = eay_get_x509cert(path); 334 if (!certificate) { 335 do_plog(LLV_ERROR, "Cannot load %s certificate\n", type); 336 exit(1); 337 } 338 return certificate; 339} 340 341static void set_certificates(struct remoteconf *remoteconf, 342 char *user_private_key, char *user_certificate, char *ca_certificate) 343{ 344 remoteconf->myprivfile = user_private_key; 345 remoteconf->mycertfile = user_certificate; 346 if (user_certificate) { 347 remoteconf->idvtype = IDTYPE_ASN1DN; 348 remoteconf->mycert = get_certificate("user", user_certificate); 349 } 350 if (!ca_certificate[0]) { 351 remoteconf->verify_cert = FALSE; 352 } else { 353 remoteconf->cacertfile = ca_certificate; 354 remoteconf->cacert = get_certificate("CA", ca_certificate); 355 } 356} 357 358#ifdef ENABLE_HYBRID 359 360static void set_xauth_and_more(struct remoteconf *remoteconf, 361 char *username, char *password, char *phase1_up, char *script_arg) 362{ 363 struct xauth_rmconf *xauth = racoon_calloc(1, sizeof(struct xauth_rmconf)); 364 xauth->login = strtovchar(username); 365 xauth->pass = strtovchar(password); 366 remoteconf->xauth = xauth; 367 remoteconf->mode_cfg = TRUE; 368 remoteconf->script[SCRIPT_PHASE1_UP] = strtovchar(phase1_up); 369 script_names[SCRIPT_PHASE1_UP] = script_arg; 370} 371 372#endif 373 374void setup(int argc, char **argv) 375{ 376 struct remoteconf *remoteconf = NULL; 377 int auth; 378 379 if (argc > 2) { 380 set_globals(argv[1], argv[2]); 381 382 /* Initialize everything else. */ 383 eay_init(); 384 initrmconf(); 385 oakley_dhinit(); 386 compute_vendorids(); 387 sched_init(); 388 if (pfkey_init() < 0 || isakmp_init() < 0) { 389 exit(1); 390 } 391#ifdef ENABLE_NATT 392 natt_keepalive_init(); 393#endif 394 395 /* Create remote configuration. */ 396 remoteconf = newrmconf(); 397 remoteconf->etypes = racoon_calloc(1, sizeof(struct etypes)); 398 remoteconf->etypes->type = ISAKMP_ETYPE_IDENT; 399 remoteconf->idvtype = IDTYPE_ADDRESS; 400 remoteconf->ike_frag = TRUE; 401 remoteconf->pcheck_level = PROP_CHECK_CLAIM; 402 remoteconf->gen_policy = TRUE; 403 remoteconf->nat_traversal = TRUE; 404 remoteconf->dh_group = OAKLEY_ATTR_GRP_DESC_MODP1024; 405 oakley_setdhgroup(remoteconf->dh_group, &remoteconf->dhgrp); 406 remoteconf->remote = dupsaddr(targets[0]); 407 set_port(remoteconf->remote, localconf.port_isakmp); 408 } 409 410 /* Set authentication method and credentials. */ 411 if (argc == 7 && !strcmp(argv[3], "udppsk")) { 412 set_pre_shared_key(remoteconf, argv[4], argv[5]); 413 auth = OAKLEY_ATTR_AUTH_METHOD_PSKEY; 414 415 set_port(targets[0], atoi(argv[6])); 416 spdadd(sources[0].addr, targets[0], IPPROTO_UDP, NULL, NULL); 417 } else if (argc == 8 && !strcmp(argv[3], "udprsa")) { 418 set_certificates(remoteconf, argv[4], argv[5], argv[6]); 419 auth = OAKLEY_ATTR_AUTH_METHOD_RSASIG; 420 421 set_port(targets[0], atoi(argv[7])); 422 spdadd(sources[0].addr, targets[0], IPPROTO_UDP, NULL, NULL); 423#ifdef ENABLE_HYBRID 424 } else if (argc == 10 && !strcmp(argv[3], "xauthpsk")) { 425 set_pre_shared_key(remoteconf, argv[4], argv[5]); 426 set_xauth_and_more(remoteconf, argv[6], argv[7], argv[8], argv[9]); 427 auth = OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I; 428 } else if (argc == 11 && !strcmp(argv[3], "xauthrsa")) { 429 set_certificates(remoteconf, argv[4], argv[5], argv[6]); 430 set_xauth_and_more(remoteconf, argv[7], argv[8], argv[9], argv[10]); 431 auth = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I; 432 } else if (argc == 9 && !strcmp(argv[3], "hybridrsa")) { 433 set_certificates(remoteconf, NULL, NULL, argv[4]); 434 set_xauth_and_more(remoteconf, argv[5], argv[6], argv[7], argv[8]); 435 auth = OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I; 436#endif 437 } else { 438 printf("Usage: %s <interface> <server> [...], where [...] can be:\n" 439 " udppsk <identifier> <pre-shared-key> <port>\n" 440 " udprsa <user-private-key> <user-cert> <ca-cert> <port>\n" 441#ifdef ENABLE_HYBRID 442 " xauthpsk <identifier> <pre-shared-key>" 443 " <username> <password> <phase1-up> <script-arg>\n" 444 " xauthrsa <user-private-key> <user-cert> <ca-cert>" 445 " <username> <password> <phase1-up> <script-arg>\n" 446 " hybridrsa <ca-cert>" 447 " <username> <password> <phase1-up> <script-arg>\n" 448#endif 449 "", argv[0]); 450 exit(0); 451 } 452 453 /* Add proposals. */ 454 add_proposal(remoteconf, auth, 455 OAKLEY_ATTR_HASH_ALG_SHA, OAKLEY_ATTR_ENC_ALG_AES, 256); 456 add_proposal(remoteconf, auth, 457 OAKLEY_ATTR_HASH_ALG_MD5, OAKLEY_ATTR_ENC_ALG_AES, 256); 458 add_proposal(remoteconf, auth, 459 OAKLEY_ATTR_HASH_ALG_SHA, OAKLEY_ATTR_ENC_ALG_AES, 128); 460 add_proposal(remoteconf, auth, 461 OAKLEY_ATTR_HASH_ALG_MD5, OAKLEY_ATTR_ENC_ALG_AES, 128); 462 add_proposal(remoteconf, auth, 463 OAKLEY_ATTR_HASH_ALG_SHA, OAKLEY_ATTR_ENC_ALG_3DES, 0); 464 add_proposal(remoteconf, auth, 465 OAKLEY_ATTR_HASH_ALG_MD5, OAKLEY_ATTR_ENC_ALG_3DES, 0); 466 add_proposal(remoteconf, auth, 467 OAKLEY_ATTR_HASH_ALG_SHA, OAKLEY_ATTR_ENC_ALG_DES, 0); 468 add_proposal(remoteconf, auth, 469 OAKLEY_ATTR_HASH_ALG_MD5, OAKLEY_ATTR_ENC_ALG_DES, 0); 470 471 /* Install remote configuration. */ 472 insrmconf(remoteconf); 473 474 /* Create ISAKMP sockets. */ 475 set_port(sources[0].addr, localconf.port_isakmp); 476 sources[0].fd = isakmp_open(sources[0].addr, FALSE); 477 if (sources[0].fd == -1) { 478 do_plog(LLV_ERROR, "Cannot create ISAKMP socket\n"); 479 exit(1); 480 } 481#ifdef ENABLE_NATT 482 set_port(sources[1].addr, localconf.port_isakmp_natt); 483 sources[1].fd = isakmp_open(sources[1].addr, TRUE); 484 if (sources[1].fd == -1) { 485 do_plog(LLV_WARNING, "Cannot create ISAKMP socket for NAT-T\n"); 486 } 487#endif 488 489 /* Start phase 1 negotiation for xauth. */ 490 if (remoteconf->xauth) { 491 isakmp_ph1begin_i(remoteconf, remoteconf->remote, sources[0].addr); 492 } 493} 494 495/*****************************************************************************/ 496 497/* localconf.h */ 498 499vchar_t *getpskbyaddr(struct sockaddr *addr) 500{ 501 return strtovchar(pre_shared_key); 502} 503 504vchar_t *getpskbyname(vchar_t *name) 505{ 506 return NULL; 507} 508 509void getpathname(char *path, int length, int type, const char *name) 510{ 511 if (pname) { 512 snprintf(path, length, pname, name); 513 } else { 514 strncpy(path, name, length); 515 } 516 path[length - 1] = '\0'; 517} 518 519/* grabmyaddr.h */ 520 521int myaddr_getsport(struct sockaddr *addr) 522{ 523 return 0; 524} 525 526int myaddr_getfd(struct sockaddr *addr) 527{ 528#ifdef ENABLE_NATT 529 if (sources[1].fd != -1 && 530 cmpsaddr(addr, sources[1].addr) == CMPSADDR_MATCH) { 531 return sources[1].fd; 532 } 533#endif 534 if (cmpsaddr(addr, sources[0].addr) < CMPSADDR_MISMATCH) { 535 return sources[0].fd; 536 } 537 return -1; 538} 539 540/* privsep.h */ 541 542int privsep_socket(int domain, int type, int protocol) 543{ 544 int fd = socket(domain, type, protocol); 545 if ((domain == AF_INET || domain == AF_INET6) && setsockopt( 546 fd, SOL_SOCKET, SO_BINDTODEVICE, interface, strlen(interface))) { 547 do_plog(LLV_WARNING, "Cannot bind socket to %s\n", interface); 548 } 549 return fd; 550} 551 552int privsep_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) 553{ 554 return bind(fd, addr, addrlen); 555} 556 557vchar_t *privsep_eay_get_pkcs1privkey(char *file) 558{ 559 return eay_get_pkcs1privkey(file); 560} 561 562static char *get_env(char * const *envp, char *key) 563{ 564 int length = strlen(key); 565 while (*envp && (strncmp(*envp, key, length) || (*envp)[length] != '=')) { 566 ++envp; 567 } 568 return *envp ? &(*envp)[length + 1] : ""; 569} 570 571static int skip_script = 0; 572extern const char *android_hook(char **envp); 573 574int privsep_script_exec(char *script, int name, char * const *envp) 575{ 576 if (skip_script) { 577 do_plog(LLV_WARNING, 578 "Phase 1 is up again. This time skip executing the script.\n"); 579 } else { 580 /* Racoon ignores INTERNAL_IP6_ADDRESS, so we only do IPv4. */ 581 struct sockaddr *addr4 = str2saddr(get_env(envp, "INTERNAL_ADDR4"), 582 NULL); 583 struct sockaddr *local = str2saddr(get_env(envp, "LOCAL_ADDR"), 584 get_env(envp, "LOCAL_PORT")); 585 struct sockaddr *remote = str2saddr(get_env(envp, "REMOTE_ADDR"), 586 get_env(envp, "REMOTE_PORT")); 587 588 if (addr4 && local && remote) { 589#ifdef ANDROID_CHANGES 590 if (pname) { 591 script = (char *)android_hook((char **)envp); 592 } 593#endif 594 spdadd(addr4, NULL, IPPROTO_IP, local, remote); 595 } else { 596 do_plog(LLV_ERROR, "Cannot get parameters for SPD policy.\n"); 597 exit(1); 598 } 599 600 skip_script = 1; 601 racoon_free(addr4); 602 racoon_free(local); 603 racoon_free(remote); 604 return script_exec(script, name, envp); 605 } 606 return 0; 607} 608 609int privsep_accounting_system(int port, struct sockaddr *addr, 610 char *user, int status) 611{ 612 return 0; 613} 614 615int privsep_xauth_login_system(char *user, char *password) 616{ 617 return -1; 618} 619 620/* misc.h */ 621 622int racoon_hexdump(void *data, size_t length) 623{ 624 return 0; 625} 626 627void close_on_exec(int fd) 628{ 629 fcntl(fd, F_SETFD, FD_CLOEXEC); 630} 631 632/* sainfo.h */ 633 634struct sainfo *getsainfo(const vchar_t *src, const vchar_t *dst, 635 const vchar_t *peer, const vchar_t *client, uint32_t remoteid) 636{ 637 return &sainfo; 638} 639 640const char *sainfo2str(const struct sainfo *si) 641{ 642 return "*"; 643} 644 645/* throttle.h */ 646 647int throttle_host(struct sockaddr *addr, int fail) 648{ 649 return 0; 650} 651