1 /* 2 * Copyright 2003-2006, Waldemar Kornewald <wkornew@gmx.net> 3 * Distributed under the terms of the MIT License. 4 */ 5 6 #if DEBUG 7 #include <cstdio> 8 #endif 9 10 #include "Protocol.h" 11 #include "IPCP.h" 12 #include <KPPPConfigurePacket.h> 13 #include <KPPPInterface.h> 14 #include <settings_tools.h> 15 16 #include <PPPoEDevice.h> 17 18 #include <cstring> 19 20 #include <arpa/inet.h> 21 #include <net_buffer.h> 22 #include <net_stack.h> 23 #include <net/route.h> 24 #include <sys/sockio.h> 25 26 // For updating resolv.conf 27 #include <ctype.h> 28 #include <fcntl.h> 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <string.h> 32 #include <unistd.h> 33 34 #define RESOLV_CONF_FILE "/boot/system/settings/network/resolv.conf" 35 36 extern net_buffer_module_info *gBufferModule; 37 static struct net_datalink_module_info *sDatalinkModule; 38 static struct net_stack_module_info *sStackModule; 39 40 #if DEBUG 41 #include <unistd.h> 42 43 static int sFD; 44 // the file descriptor for debug output 45 static char sDigits[] = "0123456789ABCDEF"; 46 void 47 dump_packet(net_buffer *packet, const char *direction) 48 { 49 if (!packet) 50 return; 51 52 uint8 *data = mtod(packet, uint8*); 53 uint8 buffer[128]; 54 uint8 bufferIndex = 0; 55 56 sprintf((char*) buffer, "Dumping %s packet;len=%ld;pkthdr.len=%d\n", direction, 57 packet->m_len, packet->m_flags & M_PKTHDR ? packet->m_pkthdr.len : -1); 58 write(sFD, buffer, strlen((char*) buffer)); 59 60 for (uint32 index = 0; index < packet->m_len; index++) { 61 buffer[bufferIndex++] = sDigits[data[index] >> 4]; 62 buffer[bufferIndex++] = sDigits[data[index] & 0x0F]; 63 if (bufferIndex == 32 || index == packet->m_len - 1) { 64 buffer[bufferIndex++] = '\n'; 65 buffer[bufferIndex] = 0; 66 write(sFD, buffer, strlen((char*) buffer)); 67 bufferIndex = 0; 68 } 69 } 70 } 71 #endif 72 73 74 static const bigtime_t kIPCPStateMachineTimeout = 3000000; 75 // 3 seconds 76 77 78 IPCP::IPCP(KPPPInterface& interface, driver_parameter *settings) 79 : KPPPProtocol("IPCP", PPP_NCP_PHASE, IPCP_PROTOCOL, PPP_PROTOCOL_LEVEL, 80 AF_INET, 0, interface, settings, PPP_INCLUDES_NCP), 81 fDefaultRoute(NULL), 82 fRequestPrimaryDNS(false), 83 fRequestSecondaryDNS(false), 84 fState(PPP_INITIAL_STATE), 85 fID(system_time() & 0xFF), 86 fMaxRequest(10), 87 fMaxTerminate(2), 88 fMaxNak(5), 89 fRequestID(0), 90 fTerminateID(0), 91 fNextTimeout(0) 92 { 93 // reset configurations 94 memset(&fLocalConfiguration, 0, sizeof(ipcp_configuration)); 95 memset(&fPeerConfiguration, 0, sizeof(ipcp_configuration)); 96 97 // reset requests 98 memset(&fLocalRequests, 0, sizeof(ipcp_requests)); 99 memset(&fPeerRequests, 0, sizeof(ipcp_requests)); 100 101 // Parse settings: 102 // "Local" and "Peer" describe each side's settings 103 ParseSideRequests(get_parameter_with_name(IPCP_LOCAL_SIDE_KEY, Settings()), 104 PPP_LOCAL_SIDE); 105 ParseSideRequests(get_parameter_with_name(IPCP_PEER_SIDE_KEY, Settings()), 106 PPP_PEER_SIDE); 107 108 get_module(NET_STACK_MODULE_NAME, (module_info **)&sStackModule); 109 get_module(NET_DATALINK_MODULE_NAME, (module_info **)&sDatalinkModule); 110 #if DEBUG 111 sFD = open("/boot/home/ipcpdebug", O_WRONLY | O_CREAT | O_TRUNC); 112 #endif 113 } 114 115 116 IPCP::~IPCP() 117 { 118 119 put_module(NET_DATALINK_MODULE_NAME); 120 put_module(NET_STACK_MODULE_NAME); 121 #if DEBUG 122 close(sFD); 123 #endif 124 } 125 126 127 void 128 IPCP::Uninit() 129 { 130 RemoveRoutes(); 131 } 132 133 134 status_t 135 IPCP::StackControl(uint32 op, void *data) 136 { 137 TRACE("IPCP: StackControl(op=%ld)\n", op); 138 139 // TODO: 140 // check values 141 142 switch (op) { 143 case SIOCSIFADDR: 144 break; 145 146 case SIOCSIFFLAGS: 147 break; 148 149 case SIOCSIFDSTADDR: 150 break; 151 152 case SIOCSIFNETMASK: 153 break; 154 155 default: 156 ERROR("IPCP: Unknown ioctl: %" B_PRIu32 "\n", op); 157 return KPPPProtocol::StackControl(op, data); 158 } 159 160 return B_OK; 161 } 162 163 164 bool 165 IPCP::Up() 166 { 167 TRACE("IPCP: Up() state=%d\n", State()); 168 169 // Servers do not send a configure-request when Up() is called. They wait until 170 // the client requests this protocol. 171 if (Interface().Mode() == PPP_SERVER_MODE) 172 return true; 173 174 switch (State()) { 175 case PPP_INITIAL_STATE: 176 NewState(PPP_REQ_SENT_STATE); 177 InitializeRestartCount(); 178 SendConfigureRequest(); 179 break; 180 181 default: 182 ; 183 } 184 185 return true; 186 } 187 188 189 bool 190 IPCP::Down() 191 { 192 TRACE("IPCP: Down() state=%d\n", State()); 193 194 switch (Interface().Phase()) { 195 case PPP_DOWN_PHASE: 196 // interface finished terminating 197 NewState(PPP_INITIAL_STATE); 198 ReportDownEvent(); 199 // this will also reset and update addresses 200 break; 201 202 /* case PPP_TERMINATION_PHASE: 203 // interface is terminating 204 break; 205 206 case PPP_ESTABLISHMENT_PHASE: 207 // interface is reconfiguring 208 break; 209 */ 210 case PPP_ESTABLISHED_PHASE: 211 // terminate this NCP individually (block until we finished terminating) 212 if (State() != PPP_INITIAL_STATE && State() != PPP_CLOSING_STATE) { 213 NewState(PPP_CLOSING_STATE); 214 InitializeRestartCount(); 215 SendTerminateRequest(); 216 } 217 218 while (State() == PPP_CLOSING_STATE) 219 snooze(50000); 220 break; 221 222 default: 223 ; 224 } 225 226 return true; 227 } 228 229 230 status_t 231 IPCP::Send(net_buffer *packet, uint16 protocolNumber) 232 { 233 TRACE("IPCP: Send(0x%X)\n", protocolNumber); 234 235 if ((protocolNumber == IP_PROTOCOL && State() == PPP_OPENED_STATE) 236 || protocolNumber == IPCP_PROTOCOL) { 237 #if DEBUG 238 dump_packet(packet, "outgoing"); 239 #endif 240 Interface().UpdateIdleSince(); 241 return SendToNext(packet, protocolNumber); 242 } 243 244 ERROR("IPCP: Send() failed because of wrong state or protocol number!\n"); 245 246 gBufferModule->free(packet); 247 return B_ERROR; 248 } 249 250 251 status_t 252 IPCP::Receive(net_buffer *packet, uint16 protocolNumber) 253 { 254 TRACE("IPCP: Receive(0x%X)\n", protocolNumber); 255 256 if (!packet) 257 return B_ERROR; 258 259 if (protocolNumber == IP_PROTOCOL) 260 return ReceiveIPPacket(packet, protocolNumber); 261 262 if (protocolNumber != IPCP_PROTOCOL) 263 return PPP_UNHANDLED; 264 265 NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet); 266 if (bufferheader.Status() != B_OK) 267 return B_ERROR; 268 ppp_lcp_packet &data = bufferheader.Data(); 269 270 if (ntohs(data.length) < 4) 271 return B_ERROR; 272 273 // packet is freed by event methods 274 switch (data.code) { 275 case PPP_CONFIGURE_REQUEST: 276 RCREvent(packet); 277 break; 278 279 case PPP_CONFIGURE_ACK: 280 RCAEvent(packet); 281 break; 282 283 case PPP_CONFIGURE_NAK: 284 case PPP_CONFIGURE_REJECT: 285 RCNEvent(packet); 286 break; 287 288 case PPP_TERMINATE_REQUEST: 289 RTREvent(packet); 290 break; 291 292 case PPP_TERMINATE_ACK: 293 RTAEvent(packet); 294 break; 295 296 case PPP_CODE_REJECT: 297 RXJBadEvent(packet); 298 // we implemented the minimum requirements 299 break; 300 301 default: 302 RUCEvent(packet); 303 return PPP_REJECTED; 304 } 305 306 return B_OK; 307 } 308 309 310 status_t 311 IPCP::ReceiveIPPacket(net_buffer *packet, uint16 protocolNumber) 312 { 313 if (protocolNumber != IP_PROTOCOL || State() != PPP_OPENED_STATE) 314 return PPP_UNHANDLED; 315 316 // TODO: add VJC support (the packet would be decoded here) 317 318 if (packet) { 319 #if DEBUG 320 dump_packet(packet, "incoming"); 321 #endif 322 Interface().UpdateIdleSince(); 323 324 TRACE("We got 1 IP packet from %s::%s\n", __FILE__, __func__); 325 gBufferModule->free(packet); 326 return B_OK; 327 } else { 328 ERROR("IPCP: Error: Could not find input function for IP!\n"); 329 gBufferModule->free(packet); 330 return B_ERROR; 331 } 332 } 333 334 335 void 336 IPCP::Pulse() 337 { 338 if (fNextTimeout == 0 || fNextTimeout > system_time()) 339 return; 340 fNextTimeout = 0; 341 342 switch (State()) { 343 case PPP_CLOSING_STATE: 344 if (fTerminateCounter <= 0) 345 TOBadEvent(); 346 else 347 TOGoodEvent(); 348 break; 349 350 case PPP_REQ_SENT_STATE: 351 case PPP_ACK_RCVD_STATE: 352 case PPP_ACK_SENT_STATE: 353 if (fRequestCounter <= 0) 354 TOBadEvent(); 355 else 356 TOGoodEvent(); 357 break; 358 359 default: 360 ; 361 } 362 } 363 364 365 bool 366 IPCP::ParseSideRequests(const driver_parameter *requests, ppp_side side) 367 { 368 if (!requests) 369 return false; 370 371 ipcp_requests *selectedRequests; 372 373 if (side == PPP_LOCAL_SIDE) { 374 selectedRequests = &fLocalRequests; 375 fRequestPrimaryDNS = fRequestSecondaryDNS = false; 376 } else 377 selectedRequests = &fPeerRequests; 378 379 memset(selectedRequests, 0, sizeof(ipcp_requests)); 380 // reset current requests 381 382 // The following values are allowed: 383 // "Address" the ip address that will be suggested 384 // "Netmask" the netmask that should be used 385 // "PrimaryDNS" primary DNS server 386 // "SecondaryDNS" secondary DNS server 387 // Setting any value to 0.0.0.0 or "auto" means it should be chosen automatically. 388 389 in_addr_t address = INADDR_ANY; 390 for (int32 index = 0; index < requests->parameter_count; index++) { 391 if (requests->parameters[index].value_count == 0) 392 continue; 393 394 // all values are IP addresses, so parse the address here 395 if (strcasecmp(requests->parameters[index].values[0], "auto")) { 396 address = inet_addr(requests->parameters[index].values[0]); 397 // address = INADDR_ANY; 398 if (address == INADDR_NONE) 399 continue; 400 } 401 402 if (!strcasecmp(requests->parameters[index].name, IPCP_IP_ADDRESS_KEY)) 403 selectedRequests->address = address; 404 else if (!strcasecmp(requests->parameters[index].name, IPCP_NETMASK_KEY)) 405 selectedRequests->netmask = address; 406 else if (!strcasecmp(requests->parameters[index].name, IPCP_PRIMARY_DNS_KEY)) { 407 selectedRequests->primaryDNS = address; 408 if (side == PPP_LOCAL_SIDE) 409 fRequestPrimaryDNS = true; 410 } else if (!strcasecmp(requests->parameters[index].name, 411 IPCP_SECONDARY_DNS_KEY)) { 412 selectedRequests->secondaryDNS = address; 413 if (side == PPP_LOCAL_SIDE) 414 fRequestSecondaryDNS = true; 415 } 416 } 417 418 return true; 419 } 420 421 422 net_interface * 423 get_interface_by_name(net_domain *domain, const char *name) 424 { 425 ifreq request; 426 memset(&request, 0, sizeof(request)); 427 size_t size = sizeof(request); 428 429 strlcpy(request.ifr_name, name, IF_NAMESIZE); 430 431 if (sDatalinkModule->control(domain, SIOCGIFINDEX, &request, &size) != B_OK) { 432 TRACE("sDatalinkModule->control failure\n"); 433 return NULL; 434 } 435 return sDatalinkModule->get_interface(domain, request.ifr_index); 436 } 437 438 439 status_t 440 set_interface_address(net_domain* domain, struct ifaliasreq* inreq) 441 { 442 size_t size = sizeof(struct ifaliasreq); 443 return sDatalinkModule->control(domain, B_SOCKET_SET_ALIAS, inreq, &size); 444 } 445 446 447 void 448 IPCP::UpdateAddresses() 449 { 450 TRACE("%s::%s: entering UpdateAddresses\n", __FILE__, __func__); 451 RemoveRoutes(); 452 453 if (State() != PPP_OPENED_STATE && !Interface().DoesConnectOnDemand()) 454 return; 455 456 TRACE("%s::%s: entering ChangeAddress\n", __FILE__, __func__); 457 if (sDatalinkModule == NULL) { 458 TRACE("%s::%s: some module not found!\n", __FILE__, __func__); 459 return; 460 } 461 462 463 struct sockaddr newAddr = {6, AF_INET, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; 464 struct sockaddr netmask = {6, AF_INET, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; 465 struct sockaddr broadaddr = {6, AF_INET, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; 466 467 if (fLocalRequests.address != INADDR_ANY) 468 memcpy(newAddr.sa_data + 2, &fLocalRequests.address, sizeof(in_addr_t)); 469 else if (fLocalConfiguration.address == INADDR_ANY) { 470 in_addr_t inaddrBroadcast = 0x010F0F0F; // was: INADDR_BROADCAST 471 memcpy(newAddr.sa_data + 2, &inaddrBroadcast, sizeof(in_addr_t)); 472 } else 473 memcpy(newAddr.sa_data + 2, &fLocalConfiguration.address, sizeof(in_addr_t)); 474 475 struct ifaliasreq inreq; 476 memset(&inreq, 0, sizeof(struct ifaliasreq)); 477 memcpy(inreq.ifra_name, Interface().Name(), IF_NAMESIZE); 478 memcpy(&inreq.ifra_addr, &newAddr, sizeof(struct sockaddr)); 479 memcpy(&inreq.ifra_mask, &netmask, sizeof(struct sockaddr)); 480 memcpy(&inreq.ifra_broadaddr, &broadaddr, sizeof(struct sockaddr)); 481 inreq.ifra_index = -1; 482 // create a new interface address 483 // Is it OK when we already have one? 484 // test case: ifconfig ppp up 485 // ifconfig ppp down 486 // ifconfig ppp up 487 // check if some weird things happen 488 489 net_domain* domain = sStackModule->get_domain(AF_INET); 490 status_t status = set_interface_address(domain, &inreq); 491 492 if (status != B_OK) { 493 TRACE("%s:%s: set_interface_address Fail!!!!\n", __FILE__, __func__); 494 return; 495 } 496 TRACE("%s:%s: set_interface_address fine\n", __FILE__, __func__); 497 498 499 net_interface* pppInterface = get_interface_by_name(domain, Interface().Name()); 500 if (pppInterface == NULL) { 501 TRACE("%s::%s: pppInterface not found!\n", __FILE__, __func__); 502 return; 503 } 504 505 net_interface_address* pppInterfaceAddress = NULL; 506 while (sDatalinkModule->get_next_interface_address(pppInterface, 507 &pppInterfaceAddress)) { 508 if (pppInterfaceAddress->domain->family != AF_INET) 509 continue; 510 break; 511 } 512 513 // add default/subnet route 514 if (Side() == PPP_LOCAL_SIDE && pppInterfaceAddress != NULL) { 515 struct sockaddr addrGateway = {8, AF_INET, {0x00, 0x00, 0x00, 0x00, 516 0x00, 0x00} }; 517 518 // create destination address 519 if (fPeerRequests.address != INADDR_ANY) 520 memcpy(addrGateway.sa_data + 2, &fPeerRequests.address, 521 sizeof(in_addr_t)); 522 else if (fPeerConfiguration.address == INADDR_ANY) { 523 in_addr_t gateway = 0x020F0F0F; 524 memcpy(addrGateway.sa_data + 2, &gateway, sizeof(in_addr_t)); 525 // was: INADDR_BROADCAST 526 } else 527 memcpy(addrGateway.sa_data + 2, &fPeerConfiguration.address, 528 sizeof(in_addr_t)); 529 530 net_route defaultRoute; 531 defaultRoute.destination = NULL; 532 defaultRoute.mask = NULL; 533 defaultRoute.gateway = &addrGateway; 534 defaultRoute.flags = RTF_DEFAULT | RTF_GATEWAY; 535 defaultRoute.interface_address = pppInterfaceAddress; 536 // route->interface_address; 537 538 status_t status = sDatalinkModule->add_route(domain, &defaultRoute); 539 if (status == B_OK) 540 dprintf("%s::%s: add route default OK!\n", __FILE__, __func__); 541 else 542 dprintf("%s::%s: add route default Fail!\n", __FILE__, __func__); 543 544 sDatalinkModule->put_interface_address(pppInterfaceAddress); 545 } 546 547 if (Side() == PPP_LOCAL_SIDE) { 548 int file; 549 int primary_dns, secondary_dns; 550 char buf[256]; 551 552 file = open(RESOLV_CONF_FILE, O_RDWR); 553 554 primary_dns = ntohl(fLocalConfiguration.primaryDNS); 555 secondary_dns = ntohl(fLocalConfiguration.secondaryDNS); 556 557 sprintf(buf, "%s\t%d.%d.%d.%d\n%s\t%d.%d.%d.%d\n", 558 "nameserver", 559 (primary_dns & 0xff000000) >> 24, 560 (primary_dns & 0x00ff0000) >> 16, 561 (primary_dns & 0x0000ff00) >> 8, 562 (primary_dns & 0x000000ff), 563 "nameserver", 564 (secondary_dns & 0xff000000) >> 24, 565 (secondary_dns & 0x00ff0000) >> 16, 566 (secondary_dns & 0x0000ff00) >> 8, 567 (secondary_dns & 0x000000ff)); 568 569 write(file, buf, strlen(buf)); 570 close(file); 571 } 572 } 573 574 575 void 576 IPCP::RemoveRoutes() 577 { 578 // note: 579 // haiku supports multi default route. But for Desktop, ppp is generally 580 // the only default route. So is it necessary to remove other default 581 // route? 582 TRACE("%s::%s: entering RemoveRoutes!\n", __FILE__, __func__); 583 584 char *ethernetName = NULL; 585 PPPoEDevice* pppoeDevice = (PPPoEDevice *)Interface().Device(); 586 if (pppoeDevice == NULL) 587 return; 588 ethernetName = pppoeDevice->EthernetIfnet()->name; 589 if (ethernetName == NULL) 590 return; 591 592 net_domain* domain = sStackModule->get_domain(AF_INET); 593 net_interface* pppInterface = get_interface_by_name(domain, ethernetName); 594 595 if (pppInterface == NULL) { 596 TRACE("%s::%s: pppInterface not found!\n", __FILE__, __func__); 597 return; 598 } 599 600 net_interface_address* pppInterfaceAddress = NULL; 601 602 while (sDatalinkModule->get_next_interface_address(pppInterface, 603 &pppInterfaceAddress)) { 604 if (pppInterfaceAddress->domain->family != AF_INET) 605 continue; 606 607 net_route oldDefaultRoute; 608 oldDefaultRoute.destination = NULL; 609 oldDefaultRoute.mask = NULL; 610 oldDefaultRoute.gateway = NULL; 611 oldDefaultRoute.flags= RTF_DEFAULT; 612 oldDefaultRoute.interface_address = pppInterfaceAddress; 613 614 status_t status = sDatalinkModule->remove_route(domain, &oldDefaultRoute); 615 // current: can not get the system default route so we fake 616 // one default route for delete 617 // Todo: save the oldDefaultRoute to fDefaultRoute 618 // restore the fDefaultRoute when ppp is down 619 620 sDatalinkModule->put_interface_address(pppInterfaceAddress); 621 622 if (status == B_OK) 623 dprintf("IPCP::RemoveRoutes: remove old default route OK!\n"); 624 else 625 dprintf("IPCP::RemoveRoutes: remove old default route Fail!\n"); 626 627 break; 628 } 629 630 if (fDefaultRoute) { 631 struct sockaddr_in netmask; 632 memset(&netmask, 0, sizeof(struct sockaddr_in)); 633 634 netmask.sin_family = AF_INET; 635 netmask.sin_addr.s_addr = fLocalRequests.netmask; 636 netmask.sin_len = sizeof(struct sockaddr_in); 637 638 // if (rtrequest(RTM_DELETE, (struct sockaddr*) &netmask, 639 // (struct sockaddr*) &fGateway, (struct sockaddr*) &netmask, 640 // RTF_UP | RTF_GATEWAY, &fDefaultRoute) != B_OK) 641 ERROR("IPCP: RemoveRoutes(): could not remove default/subnet route!\n"); 642 643 fDefaultRoute = NULL; 644 } 645 } 646 647 648 uint8 649 IPCP::NextID() 650 { 651 return (uint8) atomic_add(&fID, 1); 652 } 653 654 655 void 656 IPCP::NewState(ppp_state next) 657 { 658 TRACE("IPCP: NewState(%d) state=%d\n", next, State()); 659 660 // report state changes 661 if (State() == PPP_INITIAL_STATE && next != State()) 662 UpStarted(); 663 else if (State() == PPP_OPENED_STATE && next != State()) 664 DownStarted(); 665 666 // maybe we do not need the timer anymore 667 if (next < PPP_CLOSING_STATE || next == PPP_OPENED_STATE) 668 fNextTimeout = 0; 669 670 fState = next; 671 } 672 673 674 void 675 IPCP::TOGoodEvent() 676 { 677 #if DEBUG 678 printf("IPCP: TOGoodEvent() state=%d\n", State()); 679 #endif 680 681 switch (State()) { 682 case PPP_CLOSING_STATE: 683 SendTerminateRequest(); 684 break; 685 686 case PPP_ACK_RCVD_STATE: 687 NewState(PPP_REQ_SENT_STATE); 688 689 case PPP_REQ_SENT_STATE: 690 case PPP_ACK_SENT_STATE: 691 SendConfigureRequest(); 692 break; 693 694 default: 695 IllegalEvent(PPP_TO_GOOD_EVENT); 696 } 697 } 698 699 700 void 701 IPCP::TOBadEvent() 702 { 703 TRACE("IPCP: TOBadEvent() state=%d\n", State()); 704 705 switch (State()) { 706 case PPP_CLOSING_STATE: 707 NewState(PPP_INITIAL_STATE); 708 ReportDownEvent(); 709 break; 710 711 case PPP_REQ_SENT_STATE: 712 case PPP_ACK_RCVD_STATE: 713 case PPP_ACK_SENT_STATE: 714 NewState(PPP_INITIAL_STATE); 715 ReportUpFailedEvent(); 716 break; 717 718 default: 719 IllegalEvent(PPP_TO_BAD_EVENT); 720 } 721 } 722 723 724 void 725 IPCP::RCREvent(net_buffer *packet) 726 { 727 TRACE("IPCP: RCREvent() state=%d\n", State()); 728 729 KPPPConfigurePacket request(packet); 730 KPPPConfigurePacket nak(PPP_CONFIGURE_NAK); 731 KPPPConfigurePacket reject(PPP_CONFIGURE_REJECT); 732 733 NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet); 734 if (bufferheader.Status() != B_OK) 735 return; 736 ppp_lcp_packet &lcpHeader = bufferheader.Data(); 737 738 // we should not use the same id as the peer 739 if (fID == lcpHeader.id) 740 fID -= 128; 741 742 nak.SetID(request.ID()); 743 reject.SetID(request.ID()); 744 745 // parse each item 746 ppp_configure_item *item; 747 in_addr_t *requestedAddress, *wishedAddress = NULL; 748 for (int32 index = 0; index < request.CountItems(); index++) { 749 item = request.ItemAt(index); 750 if (!item) 751 continue; 752 753 // addresses have special handling to reduce code size 754 switch (item->type) { 755 case IPCP_ADDRESSES: 756 // abandoned by the standard 757 case IPCP_ADDRESS: 758 wishedAddress = &fPeerRequests.address; 759 break; 760 761 case IPCP_PRIMARY_DNS: 762 wishedAddress = &fPeerRequests.primaryDNS; 763 break; 764 765 case IPCP_SECONDARY_DNS: 766 wishedAddress = &fPeerRequests.secondaryDNS; 767 break; 768 } 769 770 // now parse item 771 switch (item->type) { 772 case IPCP_ADDRESSES: 773 // abandoned by the standard 774 case IPCP_ADDRESS: 775 case IPCP_PRIMARY_DNS: 776 case IPCP_SECONDARY_DNS: 777 if (item->length != 6) { 778 // the packet is invalid 779 gBufferModule->free(packet); 780 NewState(PPP_INITIAL_STATE); 781 ReportUpFailedEvent(); 782 return; 783 } 784 785 requestedAddress = (in_addr_t*) item->data; 786 if (*wishedAddress == INADDR_ANY) { 787 if (*requestedAddress == INADDR_ANY) { 788 // we do not have an address for you 789 gBufferModule->free(packet); 790 NewState(PPP_INITIAL_STATE); 791 ReportUpFailedEvent(); 792 return; 793 } 794 } else if (*requestedAddress != *wishedAddress) { 795 // we do not want this address 796 ip_item ipItem; 797 ipItem.type = item->type; 798 ipItem.length = 6; 799 ipItem.address = *wishedAddress; 800 nak.AddItem((ppp_configure_item*) &ipItem); 801 } 802 break; 803 804 // case IPCP_COMPRESSION_PROTOCOL: 805 // TODO: implement me! 806 // break; 807 808 default: 809 reject.AddItem(item); 810 } 811 } 812 813 // append additional values to the nak 814 if (!request.ItemWithType(IPCP_ADDRESS) && fPeerRequests.address == INADDR_ANY) { 815 // The peer did not provide us his address. Tell him to do so. 816 ip_item ipItem; 817 ipItem.type = IPCP_ADDRESS; 818 ipItem.length = 6; 819 ipItem.address = INADDR_ANY; 820 nak.AddItem((ppp_configure_item*) &ipItem); 821 } 822 823 if (nak.CountItems() > 0) { 824 RCRBadEvent(nak.ToNetBuffer(Interface().MRU()), NULL); 825 gBufferModule->free(packet); 826 } else if (reject.CountItems() > 0) { 827 RCRBadEvent(NULL, reject.ToNetBuffer(Interface().MRU())); 828 gBufferModule->free(packet); 829 } else 830 RCRGoodEvent(packet); 831 } 832 833 834 void 835 IPCP::RCRGoodEvent(net_buffer *packet) 836 { 837 TRACE("IPCP: RCRGoodEvent() state=%d\n", State()); 838 839 switch (State()) { 840 case PPP_INITIAL_STATE: 841 NewState(PPP_ACK_SENT_STATE); 842 InitializeRestartCount(); 843 SendConfigureRequest(); 844 SendConfigureAck(packet); 845 break; 846 847 case PPP_REQ_SENT_STATE: 848 NewState(PPP_ACK_SENT_STATE); 849 850 case PPP_ACK_SENT_STATE: 851 SendConfigureAck(packet); 852 break; 853 854 case PPP_ACK_RCVD_STATE: 855 NewState(PPP_OPENED_STATE); 856 SendConfigureAck(packet); 857 ReportUpEvent(); 858 break; 859 860 case PPP_OPENED_STATE: 861 NewState(PPP_ACK_SENT_STATE); 862 SendConfigureRequest(); 863 SendConfigureAck(packet); 864 break; 865 866 default: 867 gBufferModule->free(packet); 868 } 869 } 870 871 872 void 873 IPCP::RCRBadEvent(net_buffer *nak, net_buffer *reject) 874 { 875 TRACE("IPCP: RCRBadEvent() state=%d\n", State()); 876 877 uint16 lcpHdrRejectLength = 0; 878 uint16 lcpHdrNakLength = 0; 879 880 if (nak) { 881 NetBufferHeaderReader<ppp_lcp_packet> nakBufferHeaderReader(nak); 882 if (nakBufferHeaderReader.Status() != B_OK) 883 return; 884 ppp_lcp_packet &lcpNakPacket = nakBufferHeaderReader.Data(); 885 lcpHdrNakLength = lcpNakPacket.length; 886 } 887 888 889 if (reject) { 890 NetBufferHeaderReader<ppp_lcp_packet> rejectBufferHeaderReader(reject); 891 if (rejectBufferHeaderReader.Status() != B_OK) 892 return; 893 ppp_lcp_packet &lcpRejectPacket = rejectBufferHeaderReader.Data(); 894 lcpHdrRejectLength = lcpRejectPacket.length; 895 } 896 897 switch (State()) { 898 case PPP_OPENED_STATE: 899 NewState(PPP_REQ_SENT_STATE); 900 SendConfigureRequest(); 901 902 case PPP_ACK_SENT_STATE: 903 if (State() == PPP_ACK_SENT_STATE) 904 NewState(PPP_REQ_SENT_STATE); 905 // OPENED_STATE might have set this already 906 907 case PPP_INITIAL_STATE: 908 case PPP_REQ_SENT_STATE: 909 case PPP_ACK_RCVD_STATE: 910 if (nak && ntohs(lcpHdrNakLength) > 3) 911 SendConfigureNak(nak); 912 else if (reject && ntohs(lcpHdrRejectLength) > 3) 913 SendConfigureNak(reject); 914 return; 915 // prevents the nak/reject from being m_freem()'d 916 917 default: 918 ; 919 } 920 921 if (nak) 922 gBufferModule->free(nak); 923 if (reject) 924 gBufferModule->free(reject); 925 } 926 927 928 void 929 IPCP::RCAEvent(net_buffer *packet) 930 { 931 ERROR("IPCP: RCAEvent() state=%d\n", State()); 932 933 NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet); 934 if (bufferheader.Status() != B_OK) 935 return; 936 ppp_lcp_packet &lcpHeader = bufferheader.Data(); 937 if (fRequestID != lcpHeader.id) { 938 // this packet is not a reply to our request 939 940 // TODO: log this event 941 gBufferModule->free(packet); 942 return; 943 } 944 945 // parse this ack 946 KPPPConfigurePacket ack(packet); 947 ppp_configure_item *item; 948 in_addr_t *requestedAddress, *wishedAddress = NULL, *configuredAddress = NULL; 949 for (int32 index = 0; index < ack.CountItems(); index++) { 950 item = ack.ItemAt(index); 951 if (!item) 952 continue; 953 954 // addresses have special handling to reduce code size 955 switch (item->type) { 956 case IPCP_ADDRESSES: 957 // abandoned by the standard 958 case IPCP_ADDRESS: 959 wishedAddress = &fLocalRequests.address; 960 configuredAddress = &fLocalConfiguration.address; 961 break; 962 963 case IPCP_PRIMARY_DNS: 964 wishedAddress = &fLocalRequests.primaryDNS; 965 configuredAddress = &fLocalConfiguration.primaryDNS; 966 break; 967 968 case IPCP_SECONDARY_DNS: 969 wishedAddress = &fLocalRequests.secondaryDNS; 970 configuredAddress = &fLocalConfiguration.secondaryDNS; 971 break; 972 } 973 974 // now parse item 975 switch (item->type) { 976 case IPCP_ADDRESSES: 977 // abandoned by the standard 978 case IPCP_ADDRESS: 979 case IPCP_PRIMARY_DNS: 980 case IPCP_SECONDARY_DNS: 981 requestedAddress = (in_addr_t*) item->data; 982 if ((*wishedAddress == INADDR_ANY && *requestedAddress != INADDR_ANY) 983 || *wishedAddress == *requestedAddress) 984 *configuredAddress = *requestedAddress; 985 break; 986 987 // case IPCP_COMPRESSION_PROTOCOL: 988 // TODO: implement me 989 // break; 990 991 default: 992 ; 993 } 994 } 995 996 // if address was not specified we should select the given one 997 if (!ack.ItemWithType(IPCP_ADDRESS)) 998 fLocalConfiguration.address = fLocalRequests.address; 999 1000 1001 switch (State()) { 1002 case PPP_INITIAL_STATE: 1003 IllegalEvent(PPP_RCA_EVENT); 1004 break; 1005 1006 case PPP_REQ_SENT_STATE: 1007 NewState(PPP_ACK_RCVD_STATE); 1008 InitializeRestartCount(); 1009 break; 1010 1011 case PPP_ACK_RCVD_STATE: 1012 NewState(PPP_REQ_SENT_STATE); 1013 SendConfigureRequest(); 1014 break; 1015 1016 case PPP_ACK_SENT_STATE: 1017 NewState(PPP_OPENED_STATE); 1018 InitializeRestartCount(); 1019 ReportUpEvent(); 1020 break; 1021 1022 case PPP_OPENED_STATE: 1023 NewState(PPP_REQ_SENT_STATE); 1024 SendConfigureRequest(); 1025 break; 1026 1027 default: 1028 ; 1029 } 1030 1031 gBufferModule->free(packet); 1032 } 1033 1034 1035 void 1036 IPCP::RCNEvent(net_buffer *packet) 1037 { 1038 TRACE("IPCP: RCNEvent() state=%d\n", State()); 1039 1040 NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet); 1041 if (bufferheader.Status() != B_OK) 1042 return; 1043 ppp_lcp_packet &lcpHeader = bufferheader.Data(); 1044 1045 if (fRequestID != lcpHeader.id) { 1046 // this packet is not a reply to our request 1047 1048 // TODO: log this event 1049 gBufferModule->free(packet); 1050 return; 1051 } 1052 1053 // parse this nak/reject 1054 KPPPConfigurePacket nak_reject(packet); 1055 ppp_configure_item *item; 1056 in_addr_t *requestedAddress; 1057 if (nak_reject.Code() == PPP_CONFIGURE_NAK) 1058 for (int32 index = 0; index < nak_reject.CountItems(); index++) { 1059 item = nak_reject.ItemAt(index); 1060 if (!item) 1061 continue; 1062 1063 switch (item->type) { 1064 case IPCP_ADDRESSES: 1065 // abandoned by the standard 1066 case IPCP_ADDRESS: 1067 if (item->length != 6) 1068 continue; 1069 1070 requestedAddress = (in_addr_t*) item->data; 1071 if (fLocalRequests.address == INADDR_ANY 1072 && *requestedAddress != INADDR_ANY) 1073 fLocalConfiguration.address = *requestedAddress; 1074 // this will be used in our next request 1075 break; 1076 1077 // case IPCP_COMPRESSION_PROTOCOL: 1078 // TODO: implement me! 1079 // break; 1080 1081 case IPCP_PRIMARY_DNS: 1082 if (item->length != 6) 1083 continue; 1084 1085 requestedAddress = (in_addr_t*) item->data; 1086 if (fRequestPrimaryDNS 1087 && fLocalRequests.primaryDNS == INADDR_ANY 1088 && *requestedAddress != INADDR_ANY) 1089 fLocalConfiguration.primaryDNS = *requestedAddress; 1090 // this will be used in our next request 1091 break; 1092 1093 case IPCP_SECONDARY_DNS: 1094 if (item->length != 6) 1095 continue; 1096 1097 requestedAddress = (in_addr_t*) item->data; 1098 if (fRequestSecondaryDNS 1099 && fLocalRequests.secondaryDNS == INADDR_ANY 1100 && *requestedAddress != INADDR_ANY) 1101 fLocalConfiguration.secondaryDNS = *requestedAddress; 1102 // this will be used in our next request 1103 break; 1104 1105 default: 1106 ; 1107 } 1108 } 1109 else if (nak_reject.Code() == PPP_CONFIGURE_REJECT) 1110 for (int32 index = 0; index < nak_reject.CountItems(); index++) { 1111 item = nak_reject.ItemAt(index); 1112 if (!item) 1113 continue; 1114 1115 switch (item->type) { 1116 // case IPCP_COMPRESSION_PROTOCOL: 1117 // TODO: implement me! 1118 // break; 1119 1120 default: 1121 // DNS and addresses must be supported if we set them to auto 1122 gBufferModule->free(packet); 1123 NewState(PPP_INITIAL_STATE); 1124 ReportUpFailedEvent(); 1125 return; 1126 } 1127 } 1128 1129 switch (State()) { 1130 case PPP_INITIAL_STATE: 1131 IllegalEvent(PPP_RCN_EVENT); 1132 break; 1133 1134 case PPP_REQ_SENT_STATE: 1135 case PPP_ACK_SENT_STATE: 1136 InitializeRestartCount(); 1137 1138 case PPP_ACK_RCVD_STATE: 1139 case PPP_OPENED_STATE: 1140 if (State() == PPP_ACK_RCVD_STATE || State() == PPP_OPENED_STATE) 1141 NewState(PPP_REQ_SENT_STATE); 1142 SendConfigureRequest(); 1143 break; 1144 1145 default: 1146 ; 1147 } 1148 1149 gBufferModule->free(packet); 1150 } 1151 1152 1153 void 1154 IPCP::RTREvent(net_buffer *packet) 1155 { 1156 TRACE("IPCP: RTREvent() state=%d\n", State()); 1157 1158 NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet); 1159 if (bufferheader.Status() != B_OK) 1160 return; 1161 ppp_lcp_packet &lcpHeader = bufferheader.Data(); 1162 1163 // we should not use the same ID as the peer 1164 if (fID == lcpHeader.id) 1165 fID -= 128; 1166 1167 switch (State()) { 1168 case PPP_INITIAL_STATE: 1169 IllegalEvent(PPP_RTR_EVENT); 1170 break; 1171 1172 case PPP_ACK_RCVD_STATE: 1173 case PPP_ACK_SENT_STATE: 1174 NewState(PPP_REQ_SENT_STATE); 1175 1176 case PPP_CLOSING_STATE: 1177 case PPP_REQ_SENT_STATE: 1178 SendTerminateAck(packet); 1179 return; 1180 // do not free packet 1181 1182 case PPP_OPENED_STATE: 1183 NewState(PPP_CLOSING_STATE); 1184 ResetRestartCount(); 1185 SendTerminateAck(packet); 1186 return; 1187 // do not free packet 1188 1189 default: 1190 ; 1191 } 1192 1193 gBufferModule->free(packet); 1194 } 1195 1196 1197 void 1198 IPCP::RTAEvent(net_buffer *packet) 1199 { 1200 TRACE("IPCP: RTAEvent() state=%d\n", State()); 1201 1202 NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet); 1203 if (bufferheader.Status() != B_OK) 1204 return; 1205 ppp_lcp_packet &lcpHeader = bufferheader.Data(); 1206 if (fTerminateID != lcpHeader.id) { 1207 // this packet is not a reply to our request 1208 1209 // TODO: log this event 1210 gBufferModule->free(packet); 1211 return; 1212 } 1213 1214 switch (State()) { 1215 case PPP_INITIAL_STATE: 1216 IllegalEvent(PPP_RTA_EVENT); 1217 break; 1218 1219 case PPP_CLOSING_STATE: 1220 NewState(PPP_INITIAL_STATE); 1221 ReportDownEvent(); 1222 break; 1223 1224 case PPP_ACK_RCVD_STATE: 1225 NewState(PPP_REQ_SENT_STATE); 1226 break; 1227 1228 case PPP_OPENED_STATE: 1229 NewState(PPP_REQ_SENT_STATE); 1230 SendConfigureRequest(); 1231 break; 1232 1233 default: 1234 ; 1235 } 1236 1237 gBufferModule->free(packet); 1238 } 1239 1240 1241 void 1242 IPCP::RUCEvent(net_buffer *packet) 1243 { 1244 TRACE("IPCP: RUCEvent() state=%d\n", State()); 1245 1246 SendCodeReject(packet); 1247 } 1248 1249 1250 void 1251 IPCP::RXJBadEvent(net_buffer *packet) 1252 { 1253 TRACE("IPCP: RXJBadEvent() state=%d\n", State()); 1254 1255 switch (State()) { 1256 case PPP_INITIAL_STATE: 1257 IllegalEvent(PPP_RXJ_BAD_EVENT); 1258 break; 1259 1260 case PPP_CLOSING_STATE: 1261 NewState(PPP_INITIAL_STATE); 1262 ReportDownEvent(); 1263 break; 1264 1265 case PPP_REQ_SENT_STATE: 1266 case PPP_ACK_RCVD_STATE: 1267 case PPP_ACK_SENT_STATE: 1268 NewState(PPP_INITIAL_STATE); 1269 ReportUpFailedEvent(); 1270 break; 1271 1272 case PPP_OPENED_STATE: 1273 NewState(PPP_CLOSING_STATE); 1274 InitializeRestartCount(); 1275 SendTerminateRequest(); 1276 break; 1277 1278 default: 1279 ; 1280 } 1281 1282 gBufferModule->free(packet); 1283 } 1284 1285 1286 // actions 1287 void 1288 IPCP::IllegalEvent(ppp_event event) 1289 { 1290 // TODO: update error statistics 1291 ERROR("IPCP: IllegalEvent(event=%d) state=%d\n", event, State()); 1292 } 1293 1294 1295 void 1296 IPCP::ReportUpFailedEvent() 1297 { 1298 // reset configurations 1299 memset(&fLocalConfiguration, 0, sizeof(ipcp_configuration)); 1300 memset(&fPeerConfiguration, 0, sizeof(ipcp_configuration)); 1301 1302 UpdateAddresses(); 1303 1304 UpFailedEvent(); 1305 } 1306 1307 1308 void 1309 IPCP::ReportUpEvent() 1310 { 1311 UpdateAddresses(); 1312 1313 UpEvent(); 1314 } 1315 1316 1317 void 1318 IPCP::ReportDownEvent() 1319 { 1320 // reset configurations 1321 memset(&fLocalConfiguration, 0, sizeof(ipcp_configuration)); 1322 memset(&fPeerConfiguration, 0, sizeof(ipcp_configuration)); 1323 1324 // don't update address if connect on demand is enabled 1325 dprintf("ppp down, and leaving old address and rotues\n"); 1326 // UpdateAddresses(); 1327 1328 DownEvent(); 1329 } 1330 1331 1332 void 1333 IPCP::InitializeRestartCount() 1334 { 1335 fRequestCounter = fMaxRequest; 1336 fTerminateCounter = fMaxTerminate; 1337 fNakCounter = fMaxNak; 1338 } 1339 1340 1341 void 1342 IPCP::ResetRestartCount() 1343 { 1344 fRequestCounter = 0; 1345 fTerminateCounter = 0; 1346 fNakCounter = 0; 1347 } 1348 1349 1350 bool 1351 IPCP::SendConfigureRequest() 1352 { 1353 TRACE("IPCP: SendConfigureRequest() state=%d\n", State()); 1354 1355 --fRequestCounter; 1356 fNextTimeout = system_time() + kIPCPStateMachineTimeout; 1357 1358 KPPPConfigurePacket request(PPP_CONFIGURE_REQUEST); 1359 request.SetID(NextID()); 1360 fRequestID = request.ID(); 1361 ip_item ipItem; 1362 ipItem.length = 6; 1363 1364 // add address 1365 ipItem.type = IPCP_ADDRESS; 1366 if (fLocalRequests.address == INADDR_ANY) 1367 ipItem.address = (fLocalConfiguration.address); 1368 else 1369 ipItem.address =(fLocalRequests.address); 1370 request.AddItem((ppp_configure_item*) &ipItem); 1371 1372 TRACE("IPCP: SCR: confaddr=%X; reqaddr=%X; addr=%X\n", 1373 fLocalConfiguration.address, fLocalRequests.address, 1374 ((ip_item*)request.ItemAt(0))->address); 1375 1376 // add primary DNS (if needed) 1377 if (fRequestPrimaryDNS && fLocalRequests.primaryDNS == INADDR_ANY) { 1378 ipItem.type = IPCP_PRIMARY_DNS; 1379 ipItem.address = fLocalConfiguration.primaryDNS; 1380 // at first this is 0.0.0.0, but a nak might have set it to a correct value 1381 request.AddItem((ppp_configure_item*) &ipItem); 1382 } 1383 1384 // add secondary DNS (if needed) 1385 if (fRequestSecondaryDNS && fLocalRequests.primaryDNS == INADDR_ANY) { 1386 ipItem.type = IPCP_SECONDARY_DNS; 1387 ipItem.address = fLocalConfiguration.secondaryDNS; 1388 // at first this is 0.0.0.0, but a nak might have set it to a correct value 1389 request.AddItem((ppp_configure_item*) &ipItem); 1390 } 1391 1392 // TODO: add VJC support 1393 1394 return Send(request.ToNetBuffer(Interface().MRU())) == B_OK; 1395 } 1396 1397 1398 bool 1399 IPCP::SendConfigureAck(net_buffer *packet) 1400 { 1401 TRACE("IPCP: SendConfigureAck() state=%d\n", State()); 1402 1403 if (!packet) 1404 return false; 1405 1406 NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet); 1407 if (bufferheader.Status() != B_OK) 1408 return false; 1409 ppp_lcp_packet &lcpheader = bufferheader.Data(); 1410 lcpheader.code = PPP_CONFIGURE_ACK; 1411 1412 bufferheader.Sync(); 1413 1414 KPPPConfigurePacket ack(packet); 1415 1416 // verify items 1417 ppp_configure_item *item; 1418 in_addr_t *requestedAddress, *wishedAddress = NULL, *configuredAddress = NULL; 1419 for (int32 index = 0; index < ack.CountItems(); index++) { 1420 item = ack.ItemAt(index); 1421 if (!item) 1422 continue; 1423 1424 // addresses have special handling to reduce code size 1425 switch (item->type) { 1426 case IPCP_ADDRESSES: 1427 // abandoned by the standard 1428 case IPCP_ADDRESS: 1429 wishedAddress = &fPeerRequests.address; 1430 configuredAddress = &fPeerConfiguration.address; 1431 break; 1432 1433 case IPCP_PRIMARY_DNS: 1434 wishedAddress = &fPeerRequests.primaryDNS; 1435 configuredAddress = &fPeerConfiguration.primaryDNS; 1436 break; 1437 1438 case IPCP_SECONDARY_DNS: 1439 wishedAddress = &fPeerRequests.secondaryDNS; 1440 configuredAddress = &fPeerConfiguration.secondaryDNS; 1441 break; 1442 } 1443 1444 // now parse item 1445 switch (item->type) { 1446 case IPCP_ADDRESSES: 1447 // abandoned by the standard 1448 case IPCP_ADDRESS: 1449 case IPCP_PRIMARY_DNS: 1450 case IPCP_SECONDARY_DNS: 1451 requestedAddress = (in_addr_t*) item->data; 1452 if ((*wishedAddress == INADDR_ANY && *requestedAddress != INADDR_ANY) 1453 || *wishedAddress == *requestedAddress) 1454 *configuredAddress = *requestedAddress; 1455 break; 1456 1457 // case IPCP_COMPRESSION_PROTOCOL: 1458 // TODO: implement me! 1459 // break; 1460 1461 default: 1462 ; 1463 } 1464 } 1465 1466 // if address was not specified we should select the given one 1467 if (!ack.ItemWithType(IPCP_ADDRESS)) 1468 fPeerConfiguration.address = fPeerRequests.address; 1469 1470 return Send(packet) == B_OK; 1471 } 1472 1473 1474 bool 1475 IPCP::SendConfigureNak(net_buffer *packet) 1476 { 1477 TRACE("IPCP: SendConfigureNak() state=%d\n", State()); 1478 1479 if (!packet) 1480 return false; 1481 1482 NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet); 1483 if (bufferheader.Status() != B_OK) 1484 return false; 1485 1486 ppp_lcp_packet &nak = bufferheader.Data(); 1487 1488 if (nak.code == PPP_CONFIGURE_NAK) { 1489 if (fNakCounter == 0) { 1490 // We sent enough naks. Let's try a reject. 1491 nak.code = PPP_CONFIGURE_REJECT; 1492 } else 1493 --fNakCounter; 1494 } 1495 1496 bufferheader.Sync(); 1497 1498 return Send(packet) == B_OK; 1499 } 1500 1501 1502 bool 1503 IPCP::SendTerminateRequest() 1504 { 1505 TRACE("IPCP: SendTerminateRequest() state=%d\n", State()); 1506 1507 --fTerminateCounter; 1508 fNextTimeout = system_time() + kIPCPStateMachineTimeout; 1509 1510 net_buffer *packet = gBufferModule->create(256); 1511 if (!packet) 1512 return false; 1513 1514 ppp_lcp_packet *request; 1515 status_t status = gBufferModule->append_size(packet, 1492, (void **)(&request)); 1516 if (status != B_OK) 1517 return false; 1518 1519 request->code = PPP_TERMINATE_REQUEST; 1520 request->id = fTerminateID = NextID(); 1521 request->length = htons(4); 1522 1523 status = gBufferModule->trim(packet, 4); 1524 if (status != B_OK) 1525 return false; 1526 1527 return Send(packet) == B_OK; 1528 } 1529 1530 1531 bool 1532 IPCP::SendTerminateAck(net_buffer *request) 1533 { 1534 TRACE("IPCP: SendTerminateAck() state=%d\n", State()); 1535 1536 net_buffer *reply = request; 1537 1538 if (!reply) { 1539 reply = gBufferModule->create(256); 1540 ppp_lcp_packet *ack; 1541 status_t status = gBufferModule->append_size(reply, 1492, (void **)(&ack)); 1542 if (status != B_OK) { 1543 gBufferModule->free(reply); 1544 return false; 1545 } 1546 ack->id = NextID(); 1547 ack->code = PPP_TERMINATE_ACK; 1548 ack->length = htons(4); 1549 gBufferModule->trim(reply, 4); 1550 } else { 1551 NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(reply); 1552 if (bufferHeader.Status() < B_OK) 1553 return false; 1554 ppp_lcp_packet &ack = bufferHeader.Data(); 1555 ack.code = PPP_TERMINATE_ACK; 1556 ack.length = htons(4); 1557 } 1558 1559 return Send(reply) == B_OK; 1560 } 1561 1562 1563 bool 1564 IPCP::SendCodeReject(net_buffer *packet) 1565 { 1566 TRACE("IPCP: SendCodeReject() state=%d\n", State()); 1567 1568 if (!packet) 1569 return false; 1570 1571 NetBufferPrepend<ppp_lcp_packet> bufferHeader(packet); 1572 if (bufferHeader.Status() != B_OK) 1573 return false; 1574 1575 ppp_lcp_packet &reject = bufferHeader.Data(); 1576 1577 reject.code = PPP_CODE_REJECT; 1578 reject.id = NextID(); 1579 reject.length = htons(packet->size); 1580 1581 bufferHeader.Sync(); 1582 1583 return Send(packet) == B_OK; 1584 } 1585