1/* 2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24/* ----------------------------------------------------------------------------- 25 * 26 * Theory of operation : 27 * 28 * plugin to add PPTP client support to pppd. 29 * 30----------------------------------------------------------------------------- */ 31 32 33/* ----------------------------------------------------------------------------- 34 Includes 35----------------------------------------------------------------------------- */ 36 37#include <stdio.h> 38#include <ctype.h> 39#include <stdlib.h> 40#include <string.h> 41#include <unistd.h> 42#include <signal.h> 43#include <errno.h> 44#include <fcntl.h> 45#include <syslog.h> 46#include <netdb.h> 47#include <pwd.h> 48#include <setjmp.h> 49#include <sys/param.h> 50#include <sys/types.h> 51#include <sys/wait.h> 52#include <sys/time.h> 53#include <sys/resource.h> 54#include <sys/socket.h> 55#include <sys/stat.h> 56#include <sys/socket.h> 57#include <sys/sysctl.h> 58#include <netinet/in.h> 59#include <arpa/inet.h> 60#include <syslog.h> 61#include <sys/ioctl.h> 62#include <net/if.h> 63#include <net/if_media.h> 64#include <net/route.h> 65#include <pthread.h> 66#include <sys/kern_event.h> 67#include <netinet/in_var.h> 68#include <netinet/tcp.h> 69#include <net/if_dl.h> 70#include <ifaddrs.h> 71 72#include <CoreFoundation/CFNumber.h> 73#include <CoreFoundation/CFBundle.h> 74#include <SystemConfiguration/SystemConfiguration.h> 75 76#define APPLE 1 77 78#include "../../../Controller/ppp_msg.h" 79#include "../../../Family/ppp_defs.h" 80#include "../../../Family/if_ppp.h" 81#include "../../../Family/ppp_domain.h" 82#include "../PPTP-extension/PPTP.h" 83#include "../../../Helpers/pppd/pppd.h" 84#include "../../../Helpers/pppd/fsm.h" 85#include "../../../Helpers/pppd/lcp.h" 86#include "pptp.h" 87 88#if TARGET_OS_EMBEDDED 89#include <CoreTelephony/CTServerConnectionPriv.h> 90#endif 91 92/* ----------------------------------------------------------------------------- 93 Definitions 94----------------------------------------------------------------------------- */ 95 96#define MODE_CONNECT "connect" 97#define MODE_LISTEN "listen" 98#define MODE_ANSWER "answer" 99 100#define PPTP_MIN_HDR_SIZE 44 /* IPHdr(20) + GRE(16) + PPP/MPPE(8) */ 101 102#define PPTP_RETRY_CONNECT_CODE 1 103 104#define PPTP_DEFAULT_WAIT_IF_TIMEOUT 20 /* seconds */ 105 106#define MAX_CONNECT_RETRIES 10 107 108/* ----------------------------------------------------------------------------- 109 Forward declarations 110----------------------------------------------------------------------------- */ 111 112void pptp_process_extra_options(); 113void pptp_check_options(); 114int pptp_pre_start_link_check(); 115int pptp_connect(int *errorcode); 116void pptp_disconnect(); 117void pptp_close(); 118void pptp_cleanup(); 119int pptp_establish_ppp(int); 120void pptp_wait_input(); 121void pptp_disestablish_ppp(int); 122void pptp_link_down(void *arg, uintptr_t p); 123 124static void pptp_echo_check(); 125static void pptp_stop_echo_check(); 126static void pptp_echo_timeout(void *arg); 127static void pptp_send_echo_request(); 128static void pptp_link_failure(); 129static void closeall(); 130static u_long load_kext(char *kext, int byBundleID); 131static boolean_t host_gateway(int cmd, struct in_addr host, struct in_addr gateway, char *ifname, int isnet); 132static int pptp_set_peer_route(); 133static int pptp_clean_peer_route(); 134static void pptp_ip_up(void *arg, uintptr_t p); 135u_int32_t pptp_get_if_baudrate(char *if_name); 136u_int32_t pptp_get_if_media(char *if_name); 137u_int32_t pptp_get_if_mtu(char *if_name); 138static void pptp_start_wait_interface (); 139static void pptp_stop_wait_interface (); 140static void pptp_wait_interface_timeout (void *arg); 141static void enable_keepalive (int fd); 142 143 144/* ----------------------------------------------------------------------------- 145 PPP globals 146----------------------------------------------------------------------------- */ 147 148int interface_media = 0; 149 150static int ctrlsockfd = -1; /* control socket (TCP) file descriptor */ 151static int datasockfd = -1; /* data socket (GRE) file descriptor */ 152static int eventsockfd = -1; /* event socket to detect interface change */ 153static CFBundleRef bundle = 0; /* our bundle ref */ 154 155/* option variables */ 156static char *mode = MODE_CONNECT; /* connect mode by default */ 157static bool noload = 0; /* don't load the kernel extension */ 158 159static u_int16_t our_call_id = 0; /* pptp call id */ 160static u_int16_t peer_call_id = 0; /* pptp peer's calld id */ 161static u_int16_t our_window = PPTP_RECEIVE_WINDOW;/* our receive window size */ 162static u_int16_t peer_ppd = 0; /* peer packet processing delay */ 163static u_int16_t our_ppd = 0; /* our packet processing delay */ 164static u_int16_t peer_window = 0; /* peer's receive window size */ 165static u_int16_t maxtimeout = 64; /* Maximum adaptative timeout (in seconds) */ 166static struct in_addr peeraddress; /* the other side IP address */ 167static int num_alt_peer_address = 0; 168static struct in_addr alt_peer_address[MAX_CONNECT_RETRIES]; /* the other side IP address */ 169static struct sockaddr_in ouraddress; /* our side IP address */ 170static struct in_addr ip_zeros = { 0 }; 171static u_int8_t routeraddress[16]; 172static u_int8_t interface[17]; 173static pthread_t resolverthread = 0; 174static int resolverfds[2]; 175#if TARGET_OS_EMBEDDED 176static pthread_t edgethread = 0; 177static int edgefds[2]; 178#endif 179static bool linkdown = 0; /* flag set when we receive link down event */ 180static int peer_route_set = 0; /* has a route to the peer been set ? */ 181static int transport_up = 1; 182static int wait_interface_timer_running = 0; 183 184/* 185Fast echo request procedure is run when a networking change is detected 186Echos are sent every 5 seconds for 30 seconds, or until a reply is received 187If the network is detected dead, the the tunnel is disconnected. 188Echos are not sent during normal operation. 189*/ 190static int echo_interval = 5; /* Interval between echo-requests */ 191static int echo_fails = 6; /* Tolerance to unanswered echo-requests */ 192static int echo_timer_running = 0; 193static int echos_pending = 0; 194static int echo_identifier = 0; 195static int echo_active = 0; 196static int tcp_keepalive = 0; 197static int wait_if_timeout = PPTP_DEFAULT_WAIT_IF_TIMEOUT; 198static int scaled_wait_if_timeout = PPTP_DEFAULT_WAIT_IF_TIMEOUT; 199 200extern int kill_link; 201extern CFStringRef serviceidRef; /* from pppd/sys_MacOSX.c */ 202extern SCDynamicStoreRef cfgCache; /* from pppd/sys_MacOSX.c */ 203 204/* option descriptors */ 205option_t pptp_options[] = { 206 { "nopptpload", o_bool, &noload, 207 "Don't try to load the PPTP kernel extension", 1 }, 208 { "pptpmode", o_string, &mode, 209 "Configure configuration mode [connect, listen, answer]" }, 210 { "pptpmaxtimeout", o_int, &maxtimeout, 211 "Maximum adaptative timeout" }, 212 { "pptp-fast-echo-interval", o_int, &echo_interval, 213 "Fast echo interval to reassert link" }, 214 { "pptp-fast-echo-failure", o_int, &echo_fails, 215 "Fast echo failure to reassert link" }, 216 { "pptp-tcp-keepalive", o_int, &tcp_keepalive, 217 "TCP keepalive interval" }, 218 { "pptpwaitiftimeout", o_int, &wait_if_timeout, 219 "How long do we wait for our transport interface to come back after interface events" }, 220 { NULL } 221}; 222 223 224void pptp_init_session __P((char *, u_int32_t, struct in_addr *, link_failure_func)); 225 226static ppp_session_t pptp_session = PPP_SESSION_INITIALIZER(); 227 228/* ----------------------------------------------------------------------------- 229plugin entry point, called by pppd 230----------------------------------------------------------------------------- */ 231int start(CFBundleRef ref) 232{ 233 234 bundle = ref; 235 CFRetain(bundle); 236 237 // hookup our socket handlers 238 bzero(the_channel, sizeof(struct channel)); 239 the_channel->options = pptp_options; 240 the_channel->process_extra_options = pptp_process_extra_options; 241 the_channel->wait_input = pptp_wait_input; 242 the_channel->check_options = pptp_check_options; 243 the_channel->pre_start_link_check = pptp_pre_start_link_check; 244 the_channel->connect = pptp_connect; 245 the_channel->disconnect = pptp_disconnect; 246 the_channel->cleanup = pptp_cleanup; 247 the_channel->close = pptp_close; 248 the_channel->establish_ppp = pptp_establish_ppp; 249 the_channel->disestablish_ppp = pptp_disestablish_ppp; 250 // use the default config functions 251 the_channel->send_config = generic_send_config; 252 the_channel->recv_config = generic_recv_config; 253 254 add_notifier(&link_down_notifier, pptp_link_down, 0); 255 add_notifier(&ip_up_notify, pptp_ip_up, 0); 256 257 return 0; 258} 259 260/* ----------------------------------------------------------------------------- 261----------------------------------------------------------------------------- */ 262void pptp_process_extra_options() 263{ 264 if (!strcmp(mode, MODE_ANSWER)) { 265 // make sure we get a file descriptor > 2 so that pppd can detach and close 0,1,2 266 ctrlsockfd = dup(0); 267 } 268} 269 270/* ----------------------------------------------------------------------------- 271do consistency checks on the options we were given 272----------------------------------------------------------------------------- */ 273void pptp_check_options() 274{ 275 if (strcmp(mode, MODE_CONNECT) 276 && strcmp(mode, MODE_LISTEN) 277 && strcmp(mode, MODE_ANSWER)) { 278 error("PPTP incorrect mode : '%s'", mode ? mode : ""); 279 mode = MODE_CONNECT; 280 } 281 282 /* 283 reuse pppd redial functionality to retry connection 284 retry every 3 seconds for the duration of the extra time 285 do not report busy state 286 */ 287 if (extraconnecttime) { 288 busycode = PPTP_RETRY_CONNECT_CODE; 289 redialtimer = 3 ; 290 redialcount = extraconnecttime / redialtimer; 291 hasbusystate = 0; 292 } 293 294} 295 296/* ----------------------------------------------------------------------------- 297----------------------------------------------------------------------------- */ 298void pptp_link_down(void *arg, uintptr_t p) 299{ 300 linkdown = 1; 301} 302 303/* ----------------------------------------------------------------------------- 304----------------------------------------------------------------------------- */ 305static void pptp_start_wait_interface () 306{ 307 int timeout_scale_factor = 0; 308 309 if (!wait_underlying_interface_up && lcp_echo_interval) { 310 wait_underlying_interface_up = 1; 311 } 312 // the interface timer takes priority over the mapping timer 313 ppp_block_public_nat_port_mapping_timer(); 314 315 if (wait_interface_timer_running != 0) 316 return; 317 318#if !TARGET_OS_EMBEDDED 319 // increase the timeout if we're waiting for a wireless interface 320 if (IFM_TYPE(interface_media) == IFM_IEEE80211) { 321 timeout_scale_factor = 2; 322 } 323#endif /* !iPhone */ 324 scaled_wait_if_timeout = (wait_if_timeout << timeout_scale_factor); 325 notice("starting wait-interface timer for pptp: %d secs", scaled_wait_if_timeout); 326 TIMEOUT (pptp_wait_interface_timeout, 0, scaled_wait_if_timeout); 327 wait_interface_timer_running = 1; 328} 329 330/* ----------------------------------------------------------------------------- 331----------------------------------------------------------------------------- */ 332static void pptp_stop_wait_interface () 333{ 334 ppp_variable_echo_start(); 335 336 if (wait_interface_timer_running) { 337 UNTIMEOUT (pptp_wait_interface_timeout, 0); 338 wait_interface_timer_running = 0; 339 } 340 ppp_unblock_public_nat_port_mapping_timer(); 341} 342 343/* ----------------------------------------------------------------------------- 344----------------------------------------------------------------------------- */ 345static void pptp_wait_interface_timeout (void *arg) 346{ 347 if (wait_interface_timer_running != 0) { 348 wait_interface_timer_running = 0; 349 log_vpn_interface_address_event(__FUNCTION__, NULL, scaled_wait_if_timeout, interface, &ouraddress.sin_addr); 350 // our transport interface didn't come back, take down the connection 351 pptp_link_failure(); 352 } 353} 354 355/* ----------------------------------------------------------------------------- 356called back everytime we go out of select, and data needs to be read 357the hook is called and has a chance to get data out of its file descriptor 358in the case of PPTP, we get control data on the socket 359or get awaken when connection is closed 360----------------------------------------------------------------------------- */ 361void pptp_wait_input() 362{ 363 int err, found; 364 struct ifaddrs *ifap = NULL; 365 366#if 0 367 // Code removed. See radar 9129161 368 if (linkdown && !hungup) { 369 notice("PPTP linkdown"); 370 pptp_link_failure(); 371 return; 372 } 373#endif 374 375 if (eventsockfd != -1 && is_ready_fd(eventsockfd)) { 376 377 char buf[256] __attribute__ ((aligned(4))); // Wcast-align fix - force alignment 378 char ev_if[32]; 379 struct kern_event_msg *ev_msg; 380 struct kev_in_data *inetdata; 381 382 if (recv(eventsockfd, &buf, sizeof(buf), 0) != -1) { 383 ev_msg = ALIGNED_CAST(struct kern_event_msg *) &buf; 384 inetdata = (struct kev_in_data *) &ev_msg->event_data[0]; 385 log_vpn_interface_address_event(__FUNCTION__, ev_msg, wait_if_timeout, interface, &ouraddress.sin_addr); 386 switch (ev_msg->event_code) { 387 case KEV_INET_NEW_ADDR: 388 case KEV_INET_CHANGED_ADDR: 389 case KEV_INET_ADDR_DELETED: 390 snprintf(ev_if, sizeof(ev_if), "%s%d", inetdata->link_data.if_name, inetdata->link_data.if_unit); 391 // check if changes occured on the interface we are using 392 if (!strncmp(ev_if, (char*)interface, sizeof(interface))) { 393 if (inetdata->link_data.if_family == APPLE_IF_FAM_PPP 394 || echo_interval == 0 395 || echo_fails == 0) { 396 // disconnect immediatly 397 pptp_link_failure(); 398 } 399 else { 400 401 /* check if address still exist */ 402 found = 0; 403 if (getifaddrs(&ifap) == 0) { 404 struct ifaddrs *ifa; 405 for (ifa = ifap; ifa && !found ; ifa = ifa->ifa_next) { 406 found = (ifa->ifa_name 407 && ifa->ifa_addr 408 && !strncmp(ifa->ifa_name, (char*)interface, sizeof(interface)) 409 && ifa->ifa_addr->sa_family == AF_INET 410 && (ALIGNED_CAST(struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == ouraddress.sin_addr.s_addr); 411 } 412 freeifaddrs(ifap); 413 } 414 415 if (found) { 416 417 // no meaningful change, or address came back. Cancel timer if it was on. 418 if (transport_up == 0) { 419 420 /* 421 Our transport interface comes back with the same address. 422 Stop waiting for interface. 423 A smarter algorithm should be implemented here. 424 */ 425 transport_up = 1; 426 if (phase == PHASE_WAITING) 427 new_phase(PHASE_RUNNING); 428 pptp_stop_wait_interface(); 429 430 // give time to check for connectivity 431 /* Clear the parameters for generating echo frames */ 432 echos_pending = 0; 433 echo_active = 1; 434 435 /* If a timeout interval is specified then start the timer */ 436 if (echo_interval != 0) 437 pptp_echo_check(); 438 } 439 } 440 else { 441 // quick exit if there has been an unrecoverable change in interface/service 442 if (check_vpn_interface_or_service_unrecoverable(cfgCache, 443 __FUNCTION__, 444 ev_msg, 445 (char*)interface)) { 446 error("PPTP: the underlying interface/service has changed unrecoverably\n"); 447 transport_up = 0; 448 pptp_link_failure(); 449 break; 450 } 451 452 if (transport_up == 1) { 453 transport_up = 0; 454 if (phase == PHASE_RUNNING) 455 new_phase(PHASE_WAITING); 456 pptp_start_wait_interface(); 457 } else { 458 // transport is still down: check if there was a valid address change 459 if (check_vpn_interface_address_change(wait_interface_timer_running /* && !transport_up */, 460 ev_msg, 461 (char*)interface, 462 interface_media, 463 &ouraddress.sin_addr)) { 464 error("PPTP: the underlying interface %s address changed\n", 465 interface); 466 // disconnect immediately 467 pptp_link_failure(); 468 } 469 } 470 } 471 472 } 473 } else { 474 /* if transport is still down: ignore deletes, and check if this alternative interface has a valid address */ 475 if (check_vpn_interface_alternate((!transport_up && wait_interface_timer_running), 476 ev_msg, 477 (char*)interface)) { 478 error("PPTP: an alternative interface %s was detected while the underlying interface %s was down\n", 479 ev_if, interface); 480 // disconnect immediately 481 pptp_link_failure(); 482 } 483 } 484 break; 485 } 486 } 487 } 488 489 if (ctrlsockfd != -1 && is_ready_fd(ctrlsockfd)) { 490 491 err = pptp_data_in(ctrlsockfd); 492 if (err < 0) { 493 // looks like we have been disconnected... 494 // the status is updated only if link is not already down 495 if (linkdown == 0) { 496 notice("PPTP hangup"); 497 status = EXIT_HANGUP; 498 } 499 remove_fd(ctrlsockfd); 500 remove_fd(eventsockfd); 501 hungup = 1; 502 lcp_lowerdown(0); /* PPTP link is no longer available */ 503 link_terminated(0); 504 ppp_auxiliary_probe_stop(); 505 pptp_clear_nat_port_mapping(); 506 ppp_session_clear(&pptp_session); 507 session = NULL; 508 } 509 } 510 511 ppp_process_nat_port_mapping_events(); 512 ppp_process_auxiliary_probe_input(); 513} 514 515/* ----------------------------------------------------------------------------- 516----------------------------------------------------------------------------- */ 517void *pptp_resolver_thread(void *arg) 518{ 519 struct hostent *host; 520 char result = -1; 521 int count, fd; 522 u_int8_t rd8; 523 524 if (pthread_detach(pthread_self()) == 0) { 525 526 // try to resolve the name 527 if ((host = gethostbyname(remoteaddress))) { 528 529 for (count = 0; host->h_addr_list[count]; count++); 530 531 rd8 = 0; 532 fd = open("/dev/random", O_RDONLY); 533 if (fd) { 534 read(fd, &rd8, sizeof(rd8)); 535 close(fd); 536 } 537 538 bzero(&peeraddress, sizeof(peeraddress)); 539 if (count) 540 peeraddress = *ALIGNED_CAST(struct in_addr*)host->h_addr_list[rd8 % count]; 541 bzero(alt_peer_address, sizeof(alt_peer_address)); 542 num_alt_peer_address = 0; 543 if (count > 1) { 544 while (num_alt_peer_address < (count - 1) && 545 num_alt_peer_address < MAX_CONNECT_RETRIES) { 546 alt_peer_address[num_alt_peer_address] = *ALIGNED_CAST(struct in_addr*)host->h_addr_list[(rd8 + num_alt_peer_address + 1)% count]; 547 num_alt_peer_address++; 548 } 549 } 550 result = 0; 551 } 552 } 553 554 write(resolverfds[1], &result, 1); 555 return 0; 556} 557 558#if TARGET_OS_EMBEDDED 559static 560void callbackEDGE(CTServerConnectionRef connection, CFStringRef notification, CFDictionaryRef notificationInfo, void* info) { 561 562 /* not used */ 563} 564 565/* ----------------------------------------------------------------------------- 566 ----------------------------------------------------------------------------- */ 567void *pptp_edge_thread(void *arg) 568{ 569 char result = -1; 570 int count; 571 CTServerConnectionRef edgeConnection; 572 _CTServerConnectionContext ctxt = { 0, NULL, NULL, NULL, NULL }; 573 Boolean active = FALSE; 574 CTError cterror = { kCTErrorDomainNoError, 0 }; 575 576 if (pthread_detach(pthread_self()) == 0) { 577 578 edgeConnection = _CTServerConnectionCreate(kCFAllocatorDefault, callbackEDGE, &ctxt); 579 if (edgeConnection) { 580 _CTServerConnectionSetPacketContextActiveByServiceType(edgeConnection, kCTDataConnectionServiceTypeInternet, TRUE); 581 582 count = PPPD_WWAN_INTERFACE_TIMEOUT; 583 cterror = _CTServerConnectionGetPacketContextActive(edgeConnection, 0, &active); 584 while (!cterror.error && !active && count--) { 585 sleep(1); 586 cterror = _CTServerConnectionGetPacketContextActive(edgeConnection, 0, &active); 587 } 588 CFRelease(edgeConnection); 589 590 if (active) { 591 sleep(2); // additionnal 2 seconds for DNS information to be installed 592 result = 0; 593 } 594 } 595 } 596 597 598 write(edgefds[1], &result, 1); 599 return 0; 600} 601#endif 602 603int pptp_pre_start_link_check() 604{ 605 int reachable = FALSE; 606 SCNetworkReachabilityRef ref; 607 SCNetworkConnectionFlags flags; 608 609 ref = SCNetworkReachabilityCreateWithName(NULL, remoteaddress); 610 if (ref) { 611 if (SCNetworkReachabilityGetFlags(ref, &flags)) { 612 if (REACHABLE_NOW || REACHABLE_AUTOMATICALLY_WITHOUT_USER) { 613 reachable = TRUE; 614 } 615 } 616 CFRelease(ref); 617 } 618 619 if (reachable) { 620 return 0; 621 } 622 return -1; 623} 624 625/* ----------------------------------------------------------------------------- 626get the socket ready to start doing PPP. 627That is, open the socket and start the PPTP dialog 628----------------------------------------------------------------------------- */ 629int pptp_connect(int *errorcode) 630{ 631 char dev[32], name[MAXPATHLEN], c; 632 int err = 0, fd, val; 633 uint32_t len; 634 CFURLRef url; 635 CFDictionaryRef dict; 636 CFStringRef string, key; 637 struct sockaddr_in addr; 638 struct kev_request kev_req; 639 u_int32_t baudrate; 640 int num_connect_retries = 0; 641 int connect_timeout = 15; 642 643 *errorcode = 0; 644 645 if (cfgCache == NULL || serviceidRef == NULL) { 646 goto fail; 647 } 648 649 snprintf(dev, sizeof(dev), "socket[%d:%d]", PF_PPP, PPPPROTO_PPTP); 650 strlcpy(ppp_devnam, dev, sizeof(ppp_devnam)); 651 652 hungup = 0; 653 kill_link = 0; 654 linkdown = 0; 655 our_call_id = getpid(); 656 routeraddress[0] = 0; 657 interface[0] = 0; 658 659 key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetIPv4); 660 if (key) { 661 dict = SCDynamicStoreCopyValue(cfgCache, key); 662 CFRelease(key); 663 if (dict) { 664 if ((string = CFDictionaryGetValue(dict, kSCPropNetIPv4Router))) 665 CFStringGetCString(string, (char*)routeraddress, sizeof(routeraddress), kCFStringEncodingUTF8); 666 if ((string = CFDictionaryGetValue(dict, kSCDynamicStorePropNetPrimaryInterface))) 667 CFStringGetCString(string, (char*)interface, sizeof(interface), kCFStringEncodingUTF8); 668 CFRelease(dict); 669 } 670 } 671 672 /* now that we know our interface, adjust the MTU if necessary */ 673 if (interface[0]) { 674 int min_mtu = pptp_get_if_mtu((char*)interface) - PPTP_MIN_HDR_SIZE; 675 if (lcp_allowoptions[0].mru > min_mtu) /* defines out mtu */ 676 lcp_allowoptions[0].mru = min_mtu; 677 678 /* Don't adjust MRU, radar 3974763 */ 679#if 0 680 if (lcp_wantoptions[0].mru > min_mtu) /* defines out mru */ 681 lcp_wantoptions[0].mru = min_mtu; 682 if (lcp_wantoptions[0].neg_mru > min_mtu) /* defines our mru */ 683 lcp_wantoptions[0].neg_mru = min_mtu; 684#endif 685 } 686 687#if !TARGET_OS_EMBEDDED 688 interface_media = pptp_get_if_media((char*)interface); 689#endif /* !iPhone */ 690 691 // check to see if interface is captive: if so, bail if the interface is not ready. 692 if (check_vpn_interface_captive_and_not_ready(cfgCache, (char *)interface)) { 693 // TODO: perhaps we should wait for a few seconds? 694 goto fail; 695 } 696 697 /* let's say our underlying transport is up */ 698 transport_up = 1; 699 wait_interface_timer_running = 0; 700 wait_underlying_interface_up = 0; 701 ppp_session_clear(&pptp_session); 702 session = NULL; 703 704 eventsockfd = socket(PF_SYSTEM, SOCK_RAW, SYSPROTO_EVENT); 705 if (eventsockfd != -1) { 706 // PPTP can survive without event socket anyway 707 kev_req.vendor_code = KEV_VENDOR_APPLE; 708 kev_req.kev_class = KEV_NETWORK_CLASS; 709 kev_req.kev_subclass = KEV_INET_SUBCLASS; 710 ioctl(eventsockfd, SIOCSKEVFILT, &kev_req); 711 } 712 713 /* -------------------------------------------------------------*/ 714 /* connect mode : we need a valid remote address or name */ 715 if (!strcmp(mode, MODE_CONNECT)) { 716 if (remoteaddress == 0) { 717 error("PPTP: No remote address supplied...\n"); 718 devstatus = EXIT_PPTP_NOSERVER; 719 goto fail; 720 } 721 722 set_network_signature("VPN.RemoteAddress", remoteaddress, 0, 0); 723 724#if TARGET_OS_EMBEDDED 725 { 726 /* first, bring up EDGE */ 727 int need_edge = FALSE; 728 SCNetworkReachabilityRef ref = NULL; 729 SCNetworkConnectionFlags flags; 730 731 ref = SCNetworkReachabilityCreateWithName(NULL, remoteaddress); 732 if (ref) { 733 734 if (SCNetworkReachabilityGetFlags(ref, &flags)) { 735 if ((flags & kSCNetworkReachabilityFlagsReachable) && 736 (flags & kSCNetworkReachabilityFlagsConnectionRequired) && 737 (flags & kSCNetworkReachabilityFlagsIsWWAN)) { 738 need_edge = TRUE; 739 } 740 } 741 CFRelease(ref); 742 } 743 744 if (need_edge) { 745 746 if (pipe(edgefds) < 0) { 747 error("PPTP: failed to create pipe for starting edge...\n"); 748 goto fail; 749 } 750 751 if (pthread_create(&edgethread, NULL, pptp_edge_thread, NULL)) { 752 error("PPTP: failed to create thread for starting edge...\n"); 753 close(edgefds[0]); 754 close(edgefds[1]); 755 goto fail; 756 } 757 758 while (read(edgefds[0], &c, 1) != 1) { 759 if (kill_link) { 760 pthread_cancel(edgethread); 761 break; 762 } 763 } 764 765 close(edgefds[0]); 766 close(edgefds[1]); 767 768 if (kill_link) 769 goto fail1; 770 771 if (c) { 772 error("PPTP: Cannot start EDGE connection...\n"); 773 *errorcode = PPTP_RETRY_CONNECT_CODE; /* wait and retry if necessary */ 774 devstatus = EXIT_PPTP_NOEDGE; 775 goto fail; 776 } 777 778 } 779 780 } 781#endif 782 783 if (inet_aton(remoteaddress, &peeraddress) == 0) { 784 785 if (pipe(resolverfds) < 0) { 786 error("PPTP: failed to create pipe for gethostbyname...\n"); 787 goto fail; 788 } 789 790 if (pthread_create(&resolverthread, NULL, pptp_resolver_thread, NULL)) { 791 error("PPTP: failed to create thread for gethostbyname...\n"); 792 close(resolverfds[0]); 793 close(resolverfds[1]); 794 goto fail; 795 } 796 797 while (read(resolverfds[0], &c, 1) != 1) { 798 if (kill_link) { 799 pthread_cancel(resolverthread); 800 break; 801 } 802 } 803 804 close(resolverfds[0]); 805 close(resolverfds[1]); 806 807 if (kill_link) 808 goto fail1; 809 810 if (c) { 811 error("PPTP: Host '%s' not found...\n", remoteaddress); 812 *errorcode = PPTP_RETRY_CONNECT_CODE; /* wait and retry if necessary */ 813 devstatus = EXIT_PPTP_NOSERVER; 814 goto fail; 815 } 816 } 817 818 notice("PPTP connecting to server '%s' (%s)...\n", remoteaddress, inet_ntoa(peeraddress)); 819 820 set_server_peer(peeraddress); 821 822 if ((ctrlsockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { 823 error("PPTP can't create control socket...\n"); 824 goto fail; 825 } 826 // TODO: make connection_timeout configurable 827 if (setsockopt(ctrlsockfd, IPPROTO_TCP, TCP_CONNECTIONTIMEOUT, &connect_timeout, sizeof(connect_timeout))) { 828 error("PPTP can't set control socket's maximum timeout ...\n"); 829 // prevent retries since the default 90 sec is *too* long 830 num_alt_peer_address = 0; 831 } 832 833 /* connect to the pptp server */ 834 bzero(&addr, sizeof(addr)); 835 addr.sin_len = sizeof(addr); 836 addr.sin_family = AF_INET; 837 addr.sin_port = htons(PPTP_TCP_PORT); 838 addr.sin_addr = peeraddress; 839 840 while (connect(ctrlsockfd, (struct sockaddr *)&addr, sizeof(addr))) { 841 if (errno != EINTR) { 842 error("PPTP connect errno = %d %m\n", errno); 843 if ((errno == ETIMEDOUT || errno == ECONNREFUSED) && 844 num_connect_retries < num_alt_peer_address) { 845 peeraddress = alt_peer_address[num_connect_retries]; 846 notice("PPTP connecting to alternate server '%s' (%s)...\n", remoteaddress, inet_ntoa(peeraddress)); 847 set_server_peer(peeraddress); 848 addr.sin_addr = peeraddress; 849 num_connect_retries++; 850 continue; 851 } 852 *errorcode = PPTP_RETRY_CONNECT_CODE; /* wait and retry if necessary */ 853 devstatus = EXIT_PPTP_NOANSWER; 854 goto fail; 855 } 856 if (kill_link) 857 goto fail1; 858 } 859 860 /* enable keepalive on control connection. need to be done before sending data */ 861 enable_keepalive(ctrlsockfd); 862 863 err = pptp_outgoing_call(ctrlsockfd, 864 our_call_id, our_window, our_ppd, &peer_call_id, &peer_window, &peer_ppd); 865 866 /* setup the specific route */ 867 pptp_set_peer_route(); 868 } 869 /* -------------------------------------------------------------*/ 870 /* answer mode : we need a valid remote address or name */ 871 else if (!strcmp(mode, MODE_ANSWER)) { 872 len = sizeof(addr); 873 if (getpeername(ctrlsockfd, (struct sockaddr *)&addr, &len) < 0) { 874 error("PPTP: cannot get client address... %m\n"); 875 //devstatus = EXIT_PPTP_NOSERVER; 876 goto fail; 877 } 878 peeraddress = addr.sin_addr; 879 remoteaddress = inet_ntoa(peeraddress); 880 881 notice("PPTP incoming call in progress from '%s'...", remoteaddress); 882 883 /* enable keepalive on control connection. need to be done before sending data */ 884 enable_keepalive(ctrlsockfd); 885 886 err = pptp_incoming_call(ctrlsockfd, 887 our_call_id, our_window, our_ppd, &peer_call_id, &peer_window, &peer_ppd); 888 } 889 /* -------------------------------------------------------------*/ 890 else if (!strcmp(mode, MODE_LISTEN)) { 891 892 notice("PPTP listening...\n"); 893 894 if ((fd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { 895 error("PPTP can't create listening socket...\n"); 896 goto fail; 897 } 898 899 val = 1; 900 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); 901 902 bzero(&addr, sizeof(addr)); 903 addr.sin_len = sizeof(addr); 904 addr.sin_family = AF_INET; 905 addr.sin_port = htons(PPTP_TCP_PORT); 906 addr.sin_addr.s_addr = INADDR_ANY; 907 if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 908 error("PPTP bind failed, %m"); 909 goto fail; 910 } 911 912 if (listen(fd, 10) < 0) { 913 error("PPTP listen failed, %m"); 914 return errno; 915 } 916 917 len = sizeof(addr); 918 ctrlsockfd = accept(fd, (struct sockaddr *)&addr, &len); 919 close(fd); // close the socket used for listening 920 if (ctrlsockfd < 0) { 921 error("PPTP accept failed, %m"); 922 goto fail; 923 } 924 925 peeraddress = addr.sin_addr; 926 remoteaddress = inet_ntoa(peeraddress); 927 928 notice("PPTP incoming call in progress from '%s'...", remoteaddress); 929 930 /* enable keepalive on control connection. need to be done before sending data */ 931 enable_keepalive(ctrlsockfd); 932 933 err = pptp_incoming_call(ctrlsockfd, 934 our_call_id, our_window, our_ppd, &peer_call_id, &peer_window, &peer_ppd); 935 } 936 937 if (err) { 938 if (err != -2) { 939 if (err != -1) 940 devstatus = err; 941 goto fail; 942 } 943 goto fail1; 944 } 945 946 notice("PPTP connection established."); 947 948 bzero(&ouraddress, sizeof(ouraddress)); 949 len = sizeof(ouraddress); 950 getsockname(ctrlsockfd, (struct sockaddr *)&ouraddress, &len); 951 952 /* get reachability flags of peer */ 953 bzero(&addr, sizeof(addr)); 954 addr.sin_len = sizeof(addr); 955 addr.sin_family = AF_INET; 956 addr.sin_port = htons(PPTP_TCP_PORT); 957 addr.sin_addr = peeraddress; 958 959 /* open the data socket */ 960 datasockfd = socket(PF_PPP, SOCK_DGRAM, PPPPROTO_PPTP); 961 if (datasockfd < 0) { 962 if (!noload) { 963 if ((url = CFBundleCopyBundleURL(bundle))) { 964 name[0] = 0; 965 CFURLGetFileSystemRepresentation(url, 0, (UInt8 *)name, MAXPATHLEN - 1); 966 CFRelease(url); 967 strlcat(name, "/", sizeof(name)); 968 if ((url = CFBundleCopyBuiltInPlugInsURL(bundle))) { 969 CFURLGetFileSystemRepresentation(url, 0, (UInt8 *)(name + strlen(name)), 970 MAXPATHLEN - strlen(name) - strlen(PPTP_NKE) - 1); 971 CFRelease(url); 972 strlcat(name, "/", sizeof(name)); 973 strlcat(name, PPTP_NKE, sizeof(name)); 974#if !TARGET_OS_EMBEDDED 975 if (!load_kext(name, 0)) 976#else 977 if (!load_kext(PPTP_NKE_ID, 1)) 978#endif 979 datasockfd = socket(PF_PPP, SOCK_DGRAM, PPPPROTO_PPTP); 980 } 981 } 982 } 983 if (datasockfd < 0) { 984 error("Failed to open PPTP socket: %m"); 985 goto fail; 986 } 987 } 988 989 if (kdebugflag & 1) { 990 u_int32_t flags; 991 flags = debug ? PPTP_FLAG_DEBUG : 0; 992 if (setsockopt(datasockfd, PPPPROTO_PPTP, PPTP_OPT_FLAGS, &flags, 4)) { 993 error("PPTP can't set PPTP flags...\n"); 994 goto fail; 995 } 996 } 997 998 len = sizeof(addr); 999 if (getsockname(ctrlsockfd, (struct sockaddr *)&addr, &len) < 0) { 1000 error("PPTP: cannot get our address... %m\n"); 1001 goto fail; 1002 } 1003 if (setsockopt(datasockfd, PPPPROTO_PPTP, PPTP_OPT_OURADDRESS, &addr.sin_addr.s_addr, 4)) { 1004 error("PPTP can't set our PPTP address...\n"); 1005 goto fail; 1006 } 1007 if (setsockopt(datasockfd, PPPPROTO_PPTP, PPTP_OPT_PEERADDRESS, &peeraddress.s_addr, 4)) { 1008 error("PPTP can't set PPTP server address...\n"); 1009 goto fail; 1010 } 1011 1012 baudrate = pptp_get_if_baudrate((char*)interface); 1013 if (setsockopt(datasockfd, PPPPROTO_PPTP, PPTP_OPT_BAUDRATE, &baudrate, 4)) { 1014 error("PPTP can't set our baudrate...\n"); 1015 goto fail; 1016 } 1017 1018 if (setsockopt(datasockfd, PPPPROTO_PPTP, PPTP_OPT_CALL_ID, &our_call_id, 2)) { 1019 error("PPTP can't set our call id...\n"); 1020 goto fail; 1021 } 1022 1023 if (setsockopt(datasockfd, PPPPROTO_PPTP, PPTP_OPT_PEER_CALL_ID, &peer_call_id, 2)) { 1024 error("PPTP can't set peer call id...\n"); 1025 goto fail; 1026 } 1027 if (setsockopt(datasockfd, PPPPROTO_PPTP, PPTP_OPT_WINDOW, &our_window, 2)) { 1028 error("PPTP can't set our receive window size...\n"); 1029 goto fail; 1030 } 1031 if (setsockopt(datasockfd, PPPPROTO_PPTP, PPTP_OPT_PEER_WINDOW, &peer_window, 2)) { 1032 error("PPTP can't set peer receive window size...\n"); 1033 goto fail; 1034 } 1035 if (setsockopt(datasockfd, PPPPROTO_PPTP, PPTP_OPT_PEER_PPD, &peer_ppd, 2)) { 1036 error("PPTP can't set peer packet processing delay ...\n"); 1037 goto fail; 1038 } 1039 if (setsockopt(datasockfd, PPPPROTO_PPTP, PPTP_OPT_MAXTIMEOUT, &maxtimeout, 2)) { 1040 error("PPTP can't set adaptative maximum timeout ...\n"); 1041 goto fail; 1042 } 1043 1044 if (!strcmp(mode, MODE_CONNECT)) { 1045 pptp_init_session((char *)interface, sizeof(interface), &ouraddress.sin_addr, ppp_variable_echo_start); 1046 pptp_set_nat_port_mapping(); 1047 } 1048 1049 return datasockfd; 1050 1051fail: 1052 status = EXIT_CONNECT_FAILED; 1053fail1: 1054 if (eventsockfd != -1) { 1055 close(eventsockfd); 1056 eventsockfd = -1; 1057 } 1058 if (ctrlsockfd != -1) { 1059 close(ctrlsockfd); 1060 ctrlsockfd = -1; 1061 } 1062 return -1; 1063} 1064 1065/* ----------------------------------------------------------------------------- 1066run the disconnector 1067----------------------------------------------------------------------------- */ 1068void pptp_disconnect() 1069{ 1070 notice("PPTP disconnecting...\n"); 1071 1072 if (eventsockfd != -1) { 1073 close(eventsockfd); 1074 eventsockfd = -1; 1075 } 1076 if (ctrlsockfd >= 0) { 1077 close(ctrlsockfd); 1078 ctrlsockfd = -1; 1079 } 1080 1081 ppp_auxiliary_probe_stop(); 1082 pptp_clear_nat_port_mapping(); 1083 ppp_session_clear(&pptp_session); 1084 session = NULL; 1085 1086 notice("PPTP disconnected\n"); 1087} 1088 1089/* ----------------------------------------------------------------------------- 1090close the socket descriptors 1091----------------------------------------------------------------------------- */ 1092void pptp_close() 1093{ 1094 1095 pptp_stop_echo_check(); 1096 1097 if (eventsockfd != -1) { 1098 close(eventsockfd); 1099 eventsockfd = -1; 1100 } 1101 if (datasockfd >= 0) { 1102 close(datasockfd); 1103 datasockfd = -1; 1104 } 1105 if (ctrlsockfd >= 0) { 1106 close(ctrlsockfd); 1107 ctrlsockfd = -1; 1108 } 1109} 1110 1111/* ----------------------------------------------------------------------------- 1112clean up before quitting 1113----------------------------------------------------------------------------- */ 1114void pptp_cleanup() 1115{ 1116 pptp_close(); 1117 pptp_clean_peer_route(); 1118} 1119 1120/* ----------------------------------------------------------------------------- 1121establish the socket as a ppp link 1122----------------------------------------------------------------------------- */ 1123int pptp_establish_ppp(int fd) 1124{ 1125 int x, new_fd; 1126 1127 if (ioctl(fd, PPPIOCATTACH, &x) < 0) { 1128 error("Couldn't attach socket to the link layer: %m"); 1129 return -1; 1130 } 1131 1132 new_fd = generic_establish_ppp(fd, interface); 1133 if (new_fd == -1) 1134 return -1; 1135 1136 // add just the control socket to the select 1137 // the data socket is just for moving data in the kernel 1138 add_fd(ctrlsockfd); 1139 add_fd(eventsockfd); 1140 return new_fd; 1141} 1142 1143/* ----------------------------------------------------------------------------- 1144disestablish the socket as a ppp link 1145----------------------------------------------------------------------------- */ 1146void pptp_disestablish_ppp(int fd) 1147{ 1148 int x; 1149 1150 remove_fd(ctrlsockfd); 1151 remove_fd(eventsockfd); 1152 1153 if (ioctl(fd, PPPIOCDETACH, &x) < 0) 1154 error("Couldn't detach socket from link layer: %m"); 1155 1156 generic_disestablish_ppp(fd); 1157} 1158 1159/* ----------------------------------------------------------------------------- 1160----------------------------------------------------------------------------- */ 1161void closeall() 1162{ 1163 int i; 1164 1165 for (i = getdtablesize() - 1; i >= 0; i--) close(i); 1166 open("/dev/null", O_RDWR, 0); 1167 dup(0); 1168 dup(0); 1169 return; 1170} 1171 1172/* ----------------------------------------------------------------------------- 1173----------------------------------------------------------------------------- */ 1174u_long load_kext(char *kext, int byBundleID) 1175{ 1176 int pid; 1177 1178 if ((pid = fork()) < 0) 1179 return 1; 1180 1181 if (pid == 0) { 1182 closeall(); 1183 // PPP kernel extension not loaded, try load it... 1184 if (byBundleID) 1185 execle("/sbin/kextload", "kextload", "-b", kext, (char *)0, (char *)0); 1186 else 1187 execle("/sbin/kextload", "kextload", kext, (char *)0, (char *)0); 1188 exit(1); 1189 } 1190 1191 while (waitpid(pid, 0, 0) < 0) { 1192 if (errno == EINTR) 1193 continue; 1194 return 1; 1195 } 1196 return 0; 1197} 1198 1199/* ----------------------------------------------------------------------------- 1200get the MTU on the network interface 1201----------------------------------------------------------------------------- */ 1202u_int32_t 1203pptp_get_if_mtu(char *if_name) 1204{ 1205 struct ifreq ifr; 1206 int s, err; 1207 1208 ifr.ifr_mtu = 1500; 1209 1210 s = socket(AF_INET, SOCK_DGRAM, 0); 1211 if (s >= 0) { 1212 strlcpy(ifr.ifr_name, if_name, sizeof (ifr.ifr_name)); 1213 if ((err = ioctl(s, SIOCGIFMTU, (caddr_t) &ifr)) < 0) 1214 error("PPTP: can't get interface '%s' mtu, err %d (%m)", if_name, err); 1215 close(s); 1216 } 1217 return ifr.ifr_mtu; 1218} 1219 1220/* ----------------------------------------------------------------------------- 1221 Get the media of an interface. 1222 1223 Parameters: 1224 if_name: interface we want information about. 1225 1226 Return code: 1227 media for the interface. 1228 ----------------------------------------------------------------------------- */ 1229u_int32_t 1230pptp_get_if_media(char *if_name) 1231{ 1232 struct ifmediareq ifr; 1233 int s, err; 1234 1235 if (!if_name || !if_name[0]) { 1236 return 0; 1237 } 1238 1239 bzero(&ifr, sizeof(ifr)); 1240 1241 s = socket(AF_INET, SOCK_DGRAM, 0); 1242 if (s >= 0) { 1243 strlcpy(ifr.ifm_name, if_name, sizeof (ifr.ifm_name)); 1244 if ((err = ioctl(s, SIOCGIFMEDIA, (caddr_t) &ifr)) < 0) { 1245 error("PPTP: can't get interface '%s' media, err %d (%m)", if_name, err); 1246 } 1247 close(s); 1248 } 1249 return ifr.ifm_current; 1250} 1251 1252/* ----------------------------------------------------------------------------- 1253----------------------------------------------------------------------------- */ 1254u_int32_t 1255pptp_get_if_baudrate(char *if_name) 1256{ 1257 char * buf = NULL; 1258 size_t buf_len = 0; 1259 struct if_msghdr * ifm; 1260 unsigned int if_index; 1261 u_int32_t baudrate = 0; 1262 int mib[6]; 1263 1264 /* get the interface index */ 1265 1266 if_index = if_nametoindex(if_name); 1267 if (if_index == 0) { 1268 goto done; // if unknown interface 1269 } 1270 1271 /* get information for the specified device */ 1272 1273 mib[0] = CTL_NET; 1274 mib[1] = PF_ROUTE; 1275 mib[2] = 0; 1276 mib[3] = AF_LINK; 1277 mib[4] = NET_RT_IFLIST; 1278 mib[5] = if_index; /* ask for exactly one interface */ 1279 1280 if (sysctl(mib, 6, NULL, &buf_len, NULL, 0) < 0) { 1281 goto done; 1282 } 1283 buf = malloc(buf_len); 1284 if (sysctl(mib, 6, buf, &buf_len, NULL, 0) < 0) { 1285 goto done; 1286 } 1287 1288 /* get the baudrate for the interface */ 1289 1290 ifm = ALIGNED_CAST(struct if_msghdr *)buf; 1291 switch (ifm->ifm_type) { 1292 case RTM_IFINFO : { 1293 baudrate = ifm->ifm_data.ifi_baudrate; 1294 break; 1295 } 1296 } 1297 1298done : 1299 1300 if (buf != NULL) 1301 free(buf); 1302 1303 return baudrate; 1304} 1305 1306/* ----------------------------------------------------------------------------- 1307----------------------------------------------------------------------------- */ 1308int pptp_set_peer_route() 1309{ 1310 SCNetworkReachabilityRef ref; 1311 SCNetworkConnectionFlags flags; 1312 bool is_peer_local; 1313 struct in_addr gateway; 1314 struct sockaddr_in addr; 1315 1316 if (peeraddress.s_addr == 0) 1317 return -1; 1318 1319 /* check if is peer on our local subnet */ 1320 bzero(&addr, sizeof(addr)); 1321 addr.sin_len = sizeof(addr); 1322 addr.sin_family = AF_INET; 1323 addr.sin_port = htons(PPTP_TCP_PORT); 1324 addr.sin_addr = peeraddress; 1325 ref = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&addr); 1326 is_peer_local = SCNetworkReachabilityGetFlags(ref, &flags) && (flags & kSCNetworkFlagsIsDirect); 1327 CFRelease(ref); 1328 1329 host_gateway(RTM_DELETE, peeraddress, ip_zeros, 0, 0); 1330 1331 if (is_peer_local 1332 || routeraddress[0] == 0 1333 || inet_aton((char*)routeraddress, &gateway) != 1) { 1334 1335 if (interface[0]) { 1336 bzero(&gateway, sizeof(gateway)); 1337 /* subnet route */ 1338 host_gateway(RTM_ADD, peeraddress, gateway, (char*)interface, 1); 1339 peer_route_set = 2; 1340 } 1341 } 1342 else { 1343 /* host route */ 1344 host_gateway(RTM_ADD, peeraddress, gateway, 0, 0); 1345 peer_route_set = 1; 1346 } 1347 1348 return 0; 1349} 1350 1351/* ----------------------------------------------------------------------------- 1352----------------------------------------------------------------------------- */ 1353int pptp_clean_peer_route() 1354{ 1355 1356 if (peeraddress.s_addr == 0) 1357 return -1; 1358 1359 if (peer_route_set) { 1360 host_gateway(RTM_DELETE, peeraddress, ip_zeros, 0, peer_route_set == 1 ? 0 : 1); 1361 peer_route_set = 0; 1362 } 1363 1364 return 0; 1365} 1366 1367/* ----------------------------------------------------------------------------- 1368----------------------------------------------------------------------------- */ 1369void pptp_ip_up(void *arg, uintptr_t p) 1370{ 1371 1372 if (peer_route_set == 2) { 1373 /* in the link local case, delete the route to the server, 1374 in case it conflicts with the one from the ppp interface */ 1375 host_gateway(RTM_DELETE, peeraddress, ip_zeros, 0, 0); 1376 } 1377} 1378 1379/* ----------------------------------------------------------------------------- 1380add/remove a host route 1381----------------------------------------------------------------------------- */ 1382static boolean_t 1383host_gateway(int cmd, struct in_addr host, struct in_addr gateway, char *ifname, int isnet) 1384{ 1385 int len; 1386 int rtm_seq = 0; 1387 struct { 1388 struct rt_msghdr hdr; 1389 struct sockaddr_in dst; 1390 struct sockaddr_in gway; 1391 struct sockaddr_in mask; 1392 struct sockaddr_dl link; 1393 } rtmsg; 1394 int sockfd = -1; 1395 1396 if ((sockfd = socket(PF_ROUTE, SOCK_RAW, PF_ROUTE)) < 0) { 1397 syslog(LOG_INFO, "host_gateway: open routing socket failed, %s", 1398 strerror(errno)); 1399 return (FALSE); 1400 } 1401 1402 memset(&rtmsg, 0, sizeof(rtmsg)); 1403 rtmsg.hdr.rtm_type = cmd; 1404 rtmsg.hdr.rtm_flags = RTF_UP | RTF_STATIC; 1405 if (isnet) 1406 rtmsg.hdr.rtm_flags |= RTF_CLONING; 1407 else 1408 rtmsg.hdr.rtm_flags |= RTF_HOST; 1409 if (gateway.s_addr) 1410 rtmsg.hdr.rtm_flags |= RTF_GATEWAY; 1411 rtmsg.hdr.rtm_version = RTM_VERSION; 1412 rtmsg.hdr.rtm_seq = ++rtm_seq; 1413 rtmsg.hdr.rtm_addrs = RTA_DST | RTA_NETMASK; 1414 rtmsg.dst.sin_len = sizeof(rtmsg.dst); 1415 rtmsg.dst.sin_family = AF_INET; 1416 rtmsg.dst.sin_addr = host; 1417 rtmsg.hdr.rtm_addrs |= RTA_GATEWAY; 1418 rtmsg.gway.sin_len = sizeof(rtmsg.gway); 1419 rtmsg.gway.sin_family = AF_INET; 1420 rtmsg.gway.sin_addr = gateway; 1421 rtmsg.mask.sin_len = sizeof(rtmsg.mask); 1422 rtmsg.mask.sin_family = AF_INET; 1423 rtmsg.mask.sin_addr.s_addr = 0xFFFFFFFF; 1424 1425 len = sizeof(rtmsg); 1426 if (ifname) { 1427 rtmsg.link.sdl_len = sizeof(rtmsg.link); 1428 rtmsg.link.sdl_family = AF_LINK; 1429 rtmsg.link.sdl_nlen = MIN(strlen(ifname), sizeof(rtmsg.link.sdl_data)); 1430 rtmsg.hdr.rtm_addrs |= RTA_IFP; 1431 bcopy(ifname, rtmsg.link.sdl_data, rtmsg.link.sdl_nlen); 1432 } 1433 else { 1434 /* no link information */ 1435 len -= sizeof(rtmsg.link); 1436 } 1437 rtmsg.hdr.rtm_msglen = len; 1438 if (write(sockfd, &rtmsg, len) < 0) { 1439 syslog(LOG_DEBUG, "host_gateway: write routing socket failed, %s", 1440 strerror(errno)); 1441 close(sockfd); 1442 return (FALSE); 1443 } 1444 1445 close(sockfd); 1446 return (TRUE); 1447} 1448 1449/* ----------------------------------------------------------------------------- 1450----------------------------------------------------------------------------- */ 1451static void pptp_echo_check () 1452{ 1453 if (echo_active == 0 || echo_timer_running != 0) 1454 return; 1455 1456 pptp_send_echo_request (); 1457 1458 TIMEOUT (pptp_echo_timeout, 0, echo_interval); 1459 echo_timer_running = 1; 1460} 1461 1462/* ----------------------------------------------------------------------------- 1463----------------------------------------------------------------------------- */ 1464static void pptp_stop_echo_check () 1465{ 1466 echo_active = 0; 1467 if (echo_timer_running) { 1468 UNTIMEOUT (pptp_echo_timeout, 0); 1469 echo_timer_running = 0; 1470 } 1471} 1472 1473/* ----------------------------------------------------------------------------- 1474----------------------------------------------------------------------------- */ 1475static void pptp_echo_timeout (void *arg) 1476{ 1477 if (echo_timer_running != 0) { 1478 echo_timer_running = 0; 1479 pptp_echo_check (); 1480 } 1481} 1482 1483/* ----------------------------------------------------------------------------- 1484----------------------------------------------------------------------------- */ 1485void pptp_received_echo_reply(u_int32_t identifier, u_int8_t result, u_int8_t error) 1486{ 1487 // not really interested in the content 1488 // we just know our link is still alive 1489 dbglog("PPTP received Echo Reply, id = %d", identifier); 1490 /* Reset the number of outstanding echo frames */ 1491 echos_pending = 0; 1492 echo_active = 0; 1493} 1494 1495/* ----------------------------------------------------------------------------- 1496----------------------------------------------------------------------------- */ 1497static void pptp_link_failure () 1498{ 1499 // major change happen on the interface we are using. 1500 // disconnect PPTP 1501 // Enhancement : should check if link is still usable 1502 notice("PPTP has detected change in the network and lost connection with the server."); 1503 devstatus = EXIT_PPTP_NETWORKCHANGED; 1504 status = EXIT_HANGUP; 1505 remove_fd(ctrlsockfd); 1506 remove_fd(eventsockfd); 1507 hungup = 1; 1508 lcp_lowerdown(0); /* PPTP link is no longer available */ 1509 link_terminated(0); 1510 ppp_auxiliary_probe_stop(); 1511 pptp_clear_nat_port_mapping(); 1512 ppp_session_clear(&pptp_session); 1513 session = NULL; 1514} 1515 1516/* ----------------------------------------------------------------------------- 1517----------------------------------------------------------------------------- */ 1518static void pptp_send_echo_request () 1519{ 1520 /* 1521 * Detect the failure of the peer at this point. 1522 */ 1523 if (echo_fails != 0) { 1524 if (echos_pending >= echo_fails) { 1525 pptp_link_failure(); 1526 echos_pending = 0; 1527 } 1528 } 1529 1530 /* 1531 * Make and send the echo request frame. 1532 */ 1533 dbglog("PPTP sent Echo Request, id = %d", echo_identifier); 1534 if (pptp_echo(ctrlsockfd, echo_identifier++) == -1) 1535 pptp_link_failure(); 1536 echos_pending++; 1537} 1538 1539/* ----------------------------------------------------------------------------- 1540----------------------------------------------------------------------------- */ 1541static void enable_keepalive (int fd) 1542{ 1543 int val; 1544 1545 if (tcp_keepalive) { 1546 val = 1; 1547 setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)); 1548 setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &tcp_keepalive, sizeof(tcp_keepalive)); 1549 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)); 1550 } 1551} 1552 1553/* ----------------------------------------------------------------------------- 1554 ----------------------------------------------------------------------------- */ 1555int 1556pptp_ip_probe_init (struct sockaddr_in *probe_addrs, 1557 int *probe_fds, 1558 int num) 1559{ 1560 int scope; 1561 1562 if (!probe_addrs || !probe_fds || num < 3) { 1563 return -1; 1564 } 1565 1566 scope = if_nametoindex((char *)interface); 1567 1568 bzero(probe_addrs, (sizeof(*probe_addrs) * num)); 1569 probe_addrs[GOOG_DNS_PROBE].sin_len = sizeof(struct in_addr); 1570 probe_addrs[GOOG_DNS_PROBE].sin_family = AF_INET; 1571 probe_addrs[GOOG_DNS_PROBE].sin_port = 0; 1572 probe_addrs[GOOG_DNS_PROBE].sin_addr.s_addr = GOOG_DNS_PROBE_ADDR_A; // google-public-dns-a.google.com 1573 if (peeraddress.s_addr) { 1574 probe_addrs[PEER_ADDR_PROBE].sin_len = sizeof(peeraddress); 1575 probe_addrs[PEER_ADDR_PROBE].sin_family = AF_INET; 1576 probe_addrs[PEER_ADDR_PROBE].sin_port = 0; 1577 probe_addrs[PEER_ADDR_PROBE].sin_addr = peeraddress; 1578 if (num_alt_peer_address) { 1579 probe_addrs[ALT_PEER_ADDR_PROBE].sin_len = sizeof(peeraddress); 1580 probe_addrs[ALT_PEER_ADDR_PROBE].sin_family = AF_INET; 1581 probe_addrs[ALT_PEER_ADDR_PROBE].sin_port = 0; 1582 probe_addrs[ALT_PEER_ADDR_PROBE].sin_addr = alt_peer_address[(arc4random() % num_alt_peer_address)]; 1583 } 1584 } 1585 probe_fds[GOOG_DNS_PROBE] = -1; 1586 probe_fds[PEER_ADDR_PROBE] = -1; 1587 probe_fds[ALT_PEER_ADDR_PROBE] = -1; 1588 return 0; 1589} 1590 1591static char *pptp_sd_name = "PPTP"; 1592void 1593pptp_init_session (char *interface_name, 1594 u_int32_t interface_name_siz, 1595 struct in_addr *addr, 1596 link_failure_func func) 1597{ 1598 ppp_session_clear(&pptp_session); 1599 pptp_session.sd_name = pptp_sd_name; 1600 pptp_session.interface_name = interface_name; 1601 pptp_session.interface_name_siz = interface_name_siz; 1602 pptp_session.interface_address.s_addr = addr->s_addr; 1603 pptp_session.failure_func = func; 1604 //sess->probe_timer_running = 0; 1605 pptp_ip_probe_init(pptp_session.probe_addrs, pptp_session.probe_fds, MAX_PROBE_ADDRS); 1606 pptp_session.valid = 1; 1607 session = &pptp_session; 1608} 1609