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 { 320 #if DEBUG 321 dump_packet(packet, "incoming"); 322 #endif 323 Interface().UpdateIdleSince(); 324 325 TRACE("We got 1 IP packet from %s::%s\n", __FILE__, __func__); 326 gBufferModule->free(packet); 327 return B_OK; 328 } else { 329 ERROR("IPCP: Error: Could not find input function for IP!\n"); 330 gBufferModule->free(packet); 331 return B_ERROR; 332 } 333 } 334 335 336 void 337 IPCP::Pulse() 338 { 339 if (fNextTimeout == 0 || fNextTimeout > system_time()) 340 return; 341 fNextTimeout = 0; 342 343 switch (State()) { 344 case PPP_CLOSING_STATE: 345 if (fTerminateCounter <= 0) 346 TOBadEvent(); 347 else 348 TOGoodEvent(); 349 break; 350 351 case PPP_REQ_SENT_STATE: 352 case PPP_ACK_RCVD_STATE: 353 case PPP_ACK_SENT_STATE: 354 if (fRequestCounter <= 0) 355 TOBadEvent(); 356 else 357 TOGoodEvent(); 358 break; 359 360 default: 361 ; 362 } 363 } 364 365 366 bool 367 IPCP::ParseSideRequests(const driver_parameter *requests, ppp_side side) 368 { 369 if (!requests) 370 return false; 371 372 ipcp_requests *selectedRequests; 373 374 if (side == PPP_LOCAL_SIDE) { 375 selectedRequests = &fLocalRequests; 376 fRequestPrimaryDNS = fRequestSecondaryDNS = false; 377 } else 378 selectedRequests = &fPeerRequests; 379 380 memset(selectedRequests, 0, sizeof(ipcp_requests)); 381 // reset current requests 382 383 // The following values are allowed: 384 // "Address" the ip address that will be suggested 385 // "Netmask" the netmask that should be used 386 // "PrimaryDNS" primary DNS server 387 // "SecondaryDNS" secondary DNS server 388 // Setting any value to 0.0.0.0 or "auto" means it should be chosen automatically. 389 390 in_addr_t address = INADDR_ANY; 391 for (int32 index = 0; index < requests->parameter_count; index++) { 392 if (requests->parameters[index].value_count == 0) 393 continue; 394 395 // all values are IP addresses, so parse the address here 396 if (strcasecmp(requests->parameters[index].values[0], "auto")) { 397 address = inet_addr(requests->parameters[index].values[0]); 398 // address = INADDR_ANY; 399 if (address == INADDR_NONE) 400 continue; 401 } 402 403 if (!strcasecmp(requests->parameters[index].name, IPCP_IP_ADDRESS_KEY)) 404 selectedRequests->address = address; 405 else if (!strcasecmp(requests->parameters[index].name, IPCP_NETMASK_KEY)) 406 selectedRequests->netmask = address; 407 else if (!strcasecmp(requests->parameters[index].name, IPCP_PRIMARY_DNS_KEY)) { 408 selectedRequests->primaryDNS = address; 409 if (side == PPP_LOCAL_SIDE) 410 fRequestPrimaryDNS = true; 411 } else if (!strcasecmp(requests->parameters[index].name, 412 IPCP_SECONDARY_DNS_KEY)) { 413 selectedRequests->secondaryDNS = address; 414 if (side == PPP_LOCAL_SIDE) 415 fRequestSecondaryDNS = true; 416 } 417 } 418 419 return true; 420 } 421 422 423 net_interface * 424 get_interface_by_name(net_domain *domain, const char *name) 425 { 426 ifreq request; 427 memset(&request, 0, sizeof(request)); 428 size_t size = sizeof(request); 429 430 strlcpy(request.ifr_name, name, IF_NAMESIZE); 431 432 if (sDatalinkModule->control(domain, SIOCGIFINDEX, &request, &size) != B_OK) { 433 TRACE("sDatalinkModule->control failure\n"); 434 return NULL; 435 } 436 return sDatalinkModule->get_interface(domain, request.ifr_index); 437 } 438 439 440 status_t 441 set_interface_address(net_domain* domain, struct ifaliasreq* inreq) 442 { 443 size_t size = sizeof(struct ifaliasreq); 444 return sDatalinkModule->control(domain, B_SOCKET_SET_ALIAS, inreq, &size); 445 } 446 447 448 void 449 IPCP::UpdateAddresses() 450 { 451 TRACE("%s::%s: entering UpdateAddresses\n", __FILE__, __func__); 452 RemoveRoutes(); 453 454 if (State() != PPP_OPENED_STATE && !Interface().DoesConnectOnDemand()) 455 return; 456 457 TRACE("%s::%s: entering ChangeAddress\n", __FILE__, __func__); 458 if (sDatalinkModule == NULL) { 459 TRACE("%s::%s: some module not found!\n", __FILE__, __func__); 460 return; 461 } 462 463 464 struct sockaddr newAddr = {6, AF_INET, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; 465 struct sockaddr netmask = {6, AF_INET, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; 466 struct sockaddr broadaddr = {6, AF_INET, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; 467 468 if (fLocalRequests.address != INADDR_ANY) 469 memcpy(newAddr.sa_data + 2, &fLocalRequests.address, sizeof(in_addr_t)); 470 else if (fLocalConfiguration.address == INADDR_ANY) { 471 in_addr_t inaddrBroadcast = 0x010F0F0F; // was: INADDR_BROADCAST 472 memcpy(newAddr.sa_data + 2, &inaddrBroadcast, sizeof(in_addr_t)); 473 } else 474 memcpy(newAddr.sa_data + 2, &fLocalConfiguration.address, sizeof(in_addr_t)); 475 476 struct ifaliasreq inreq; 477 memset(&inreq, 0, sizeof(struct ifaliasreq)); 478 memcpy(inreq.ifra_name, Interface().Name(), IF_NAMESIZE); 479 memcpy(&inreq.ifra_addr, &newAddr, sizeof(struct sockaddr)); 480 memcpy(&inreq.ifra_mask, &netmask, sizeof(struct sockaddr)); 481 memcpy(&inreq.ifra_broadaddr, &broadaddr, sizeof(struct sockaddr)); 482 inreq.ifra_index = -1; 483 // create a new interface address 484 // Is it OK when we already have one? 485 // test case: ifconfig ppp up 486 // ifconfig ppp down 487 // ifconfig ppp up 488 // check if some weird things happen 489 490 net_domain* domain = sStackModule->get_domain(AF_INET); 491 status_t status = set_interface_address(domain, &inreq); 492 493 if (status != B_OK) { 494 TRACE("%s:%s: set_interface_address Fail!!!!\n", __FILE__, __func__); 495 return; 496 } 497 TRACE("%s:%s: set_interface_address fine\n", __FILE__, __func__); 498 499 500 net_interface* pppInterface = get_interface_by_name(domain, Interface().Name()); 501 if (pppInterface == NULL) { 502 TRACE("%s::%s: pppInterface not found!\n", __FILE__, __func__); 503 return; 504 } 505 506 net_interface_address* pppInterfaceAddress = NULL; 507 while (sDatalinkModule->get_next_interface_address(pppInterface, 508 &pppInterfaceAddress)) { 509 if (pppInterfaceAddress->domain->family != AF_INET) 510 continue; 511 break; 512 } 513 514 // add default/subnet route 515 if (Side() == PPP_LOCAL_SIDE && pppInterfaceAddress != NULL) { 516 struct sockaddr addrGateway = {8, AF_INET, {0x00, 0x00, 0x00, 0x00, 517 0x00, 0x00} }; 518 519 // create destination address 520 if (fPeerRequests.address != INADDR_ANY) 521 memcpy(addrGateway.sa_data + 2, &fPeerRequests.address, 522 sizeof(in_addr_t)); 523 else if (fPeerConfiguration.address == INADDR_ANY) { 524 in_addr_t gateway = 0x020F0F0F; 525 memcpy(addrGateway.sa_data + 2, &gateway, sizeof(in_addr_t)); 526 // was: INADDR_BROADCAST 527 } else 528 memcpy(addrGateway.sa_data + 2, &fPeerConfiguration.address, 529 sizeof(in_addr_t)); 530 531 net_route defaultRoute; 532 defaultRoute.destination = NULL; 533 defaultRoute.mask = NULL; 534 defaultRoute.gateway = &addrGateway; 535 defaultRoute.flags = RTF_DEFAULT | RTF_GATEWAY; 536 defaultRoute.interface_address = pppInterfaceAddress; 537 // route->interface_address; 538 539 status_t status = sDatalinkModule->add_route(domain, &defaultRoute); 540 if (status == B_OK) 541 dprintf("%s::%s: add route default OK!\n", __FILE__, __func__); 542 else 543 dprintf("%s::%s: add route default Fail!\n", __FILE__, __func__); 544 545 sDatalinkModule->put_interface_address(pppInterfaceAddress); 546 } 547 548 if (Side() == PPP_LOCAL_SIDE) { 549 int file; 550 int primary_dns, secondary_dns; 551 char buf[256]; 552 553 file = open(RESOLV_CONF_FILE, O_RDWR); 554 555 primary_dns = ntohl(fLocalConfiguration.primaryDNS); 556 secondary_dns = ntohl(fLocalConfiguration.secondaryDNS); 557 558 sprintf(buf, "%s\t%d.%d.%d.%d\n%s\t%d.%d.%d.%d\n", 559 "nameserver", 560 (primary_dns & 0xff000000) >> 24, 561 (primary_dns & 0x00ff0000) >> 16, 562 (primary_dns & 0x0000ff00) >> 8, 563 (primary_dns & 0x000000ff), 564 "nameserver", 565 (secondary_dns & 0xff000000) >> 24, 566 (secondary_dns & 0x00ff0000) >> 16, 567 (secondary_dns & 0x0000ff00) >> 8, 568 (secondary_dns & 0x000000ff)); 569 570 write(file, buf, strlen(buf)); 571 close(file); 572 } 573 } 574 575 576 void 577 IPCP::RemoveRoutes() 578 { 579 // note: 580 // haiku supports multi default route. But for Desktop, ppp is generally 581 // the only default route. So is it necessary to remove other default 582 // route? 583 TRACE("%s::%s: entering RemoveRoutes!\n", __FILE__, __func__); 584 585 char *ethernetName = NULL; 586 PPPoEDevice* pppoeDevice = (PPPoEDevice *)Interface().Device(); 587 if (pppoeDevice == NULL) 588 return; 589 ethernetName = pppoeDevice->EthernetIfnet()->name; 590 if (ethernetName == NULL) 591 return; 592 593 net_domain* domain = sStackModule->get_domain(AF_INET); 594 net_interface* pppInterface = get_interface_by_name(domain, ethernetName); 595 596 if (pppInterface == NULL) { 597 TRACE("%s::%s: pppInterface not found!\n", __FILE__, __func__); 598 return; 599 } 600 601 net_interface_address* pppInterfaceAddress = NULL; 602 603 while (sDatalinkModule->get_next_interface_address(pppInterface, 604 &pppInterfaceAddress)) { 605 if (pppInterfaceAddress->domain->family != AF_INET) 606 continue; 607 608 net_route oldDefaultRoute; 609 oldDefaultRoute.destination = NULL; 610 oldDefaultRoute.mask = NULL; 611 oldDefaultRoute.gateway = NULL; 612 oldDefaultRoute.flags= RTF_DEFAULT; 613 oldDefaultRoute.interface_address = pppInterfaceAddress; 614 615 status_t status = sDatalinkModule->remove_route(domain, &oldDefaultRoute); 616 // current: can not get the system default route so we fake 617 // one default route for delete 618 // Todo: save the oldDefaultRoute to fDefaultRoute 619 // restore the fDefaultRoute when ppp is down 620 621 sDatalinkModule->put_interface_address(pppInterfaceAddress); 622 623 if (status == B_OK) 624 dprintf("IPCP::RemoveRoutes: remove old default route OK!\n"); 625 else 626 dprintf("IPCP::RemoveRoutes: remove old default route Fail!\n"); 627 628 break; 629 } 630 631 if (fDefaultRoute) { 632 struct sockaddr_in netmask; 633 memset(&netmask, 0, sizeof(struct sockaddr_in)); 634 635 netmask.sin_family = AF_INET; 636 netmask.sin_addr.s_addr = fLocalRequests.netmask; 637 netmask.sin_len = sizeof(struct sockaddr_in); 638 639 // if (rtrequest(RTM_DELETE, (struct sockaddr*) &netmask, 640 // (struct sockaddr*) &fGateway, (struct sockaddr*) &netmask, 641 // RTF_UP | RTF_GATEWAY, &fDefaultRoute) != B_OK) 642 ERROR("IPCP: RemoveRoutes(): could not remove default/subnet route!\n"); 643 644 fDefaultRoute = NULL; 645 } 646 } 647 648 649 uint8 650 IPCP::NextID() 651 { 652 return (uint8) atomic_add(&fID, 1); 653 } 654 655 656 void 657 IPCP::NewState(ppp_state next) 658 { 659 TRACE("IPCP: NewState(%d) state=%d\n", next, State()); 660 661 // report state changes 662 if (State() == PPP_INITIAL_STATE && next != State()) 663 UpStarted(); 664 else if (State() == PPP_OPENED_STATE && next != State()) 665 DownStarted(); 666 667 // maybe we do not need the timer anymore 668 if (next < PPP_CLOSING_STATE || next == PPP_OPENED_STATE) 669 fNextTimeout = 0; 670 671 fState = next; 672 } 673 674 675 void 676 IPCP::TOGoodEvent() 677 { 678 #if DEBUG 679 printf("IPCP: TOGoodEvent() state=%d\n", State()); 680 #endif 681 682 switch (State()) { 683 case PPP_CLOSING_STATE: 684 SendTerminateRequest(); 685 break; 686 687 case PPP_ACK_RCVD_STATE: 688 NewState(PPP_REQ_SENT_STATE); 689 690 case PPP_REQ_SENT_STATE: 691 case PPP_ACK_SENT_STATE: 692 SendConfigureRequest(); 693 break; 694 695 default: 696 IllegalEvent(PPP_TO_GOOD_EVENT); 697 } 698 } 699 700 701 void 702 IPCP::TOBadEvent() 703 { 704 TRACE("IPCP: TOBadEvent() state=%d\n", State()); 705 706 switch (State()) { 707 case PPP_CLOSING_STATE: 708 NewState(PPP_INITIAL_STATE); 709 ReportDownEvent(); 710 break; 711 712 case PPP_REQ_SENT_STATE: 713 case PPP_ACK_RCVD_STATE: 714 case PPP_ACK_SENT_STATE: 715 NewState(PPP_INITIAL_STATE); 716 ReportUpFailedEvent(); 717 break; 718 719 default: 720 IllegalEvent(PPP_TO_BAD_EVENT); 721 } 722 } 723 724 725 void 726 IPCP::RCREvent(net_buffer *packet) 727 { 728 TRACE("IPCP: RCREvent() state=%d\n", State()); 729 730 KPPPConfigurePacket request(packet); 731 KPPPConfigurePacket nak(PPP_CONFIGURE_NAK); 732 KPPPConfigurePacket reject(PPP_CONFIGURE_REJECT); 733 734 NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet); 735 if (bufferheader.Status() != B_OK) 736 return; 737 ppp_lcp_packet &lcpHeader = bufferheader.Data(); 738 739 // we should not use the same id as the peer 740 if (fID == lcpHeader.id) 741 fID -= 128; 742 743 nak.SetID(request.ID()); 744 reject.SetID(request.ID()); 745 746 // parse each item 747 ppp_configure_item *item; 748 in_addr_t *requestedAddress, *wishedAddress = NULL; 749 for (int32 index = 0; index < request.CountItems(); index++) { 750 item = request.ItemAt(index); 751 if (!item) 752 continue; 753 754 // addresses have special handling to reduce code size 755 switch (item->type) { 756 case IPCP_ADDRESSES: 757 // abandoned by the standard 758 case IPCP_ADDRESS: 759 wishedAddress = &fPeerRequests.address; 760 break; 761 762 case IPCP_PRIMARY_DNS: 763 wishedAddress = &fPeerRequests.primaryDNS; 764 break; 765 766 case IPCP_SECONDARY_DNS: 767 wishedAddress = &fPeerRequests.secondaryDNS; 768 break; 769 } 770 771 // now parse item 772 switch (item->type) { 773 case IPCP_ADDRESSES: 774 // abandoned by the standard 775 case IPCP_ADDRESS: 776 case IPCP_PRIMARY_DNS: 777 case IPCP_SECONDARY_DNS: 778 if (item->length != 6) { 779 // the packet is invalid 780 gBufferModule->free(packet); 781 NewState(PPP_INITIAL_STATE); 782 ReportUpFailedEvent(); 783 return; 784 } 785 786 requestedAddress = (in_addr_t*) item->data; 787 if (*wishedAddress == INADDR_ANY) { 788 if (*requestedAddress == INADDR_ANY) { 789 // we do not have an address for you 790 gBufferModule->free(packet); 791 NewState(PPP_INITIAL_STATE); 792 ReportUpFailedEvent(); 793 return; 794 } 795 } else if (*requestedAddress != *wishedAddress) { 796 // we do not want this address 797 ip_item ipItem; 798 ipItem.type = item->type; 799 ipItem.length = 6; 800 ipItem.address = *wishedAddress; 801 nak.AddItem((ppp_configure_item*) &ipItem); 802 } 803 break; 804 805 // case IPCP_COMPRESSION_PROTOCOL: 806 // TODO: implement me! 807 // break; 808 809 default: 810 reject.AddItem(item); 811 } 812 } 813 814 // append additional values to the nak 815 if (!request.ItemWithType(IPCP_ADDRESS) && fPeerRequests.address == INADDR_ANY) { 816 // The peer did not provide us his address. Tell him to do so. 817 ip_item ipItem; 818 ipItem.type = IPCP_ADDRESS; 819 ipItem.length = 6; 820 ipItem.address = INADDR_ANY; 821 nak.AddItem((ppp_configure_item*) &ipItem); 822 } 823 824 if (nak.CountItems() > 0) { 825 RCRBadEvent(nak.ToNetBuffer(Interface().MRU()), NULL); 826 gBufferModule->free(packet); 827 } else if (reject.CountItems() > 0) { 828 RCRBadEvent(NULL, reject.ToNetBuffer(Interface().MRU())); 829 gBufferModule->free(packet); 830 } else 831 RCRGoodEvent(packet); 832 } 833 834 835 void 836 IPCP::RCRGoodEvent(net_buffer *packet) 837 { 838 TRACE("IPCP: RCRGoodEvent() state=%d\n", State()); 839 840 switch (State()) { 841 case PPP_INITIAL_STATE: 842 NewState(PPP_ACK_SENT_STATE); 843 InitializeRestartCount(); 844 SendConfigureRequest(); 845 SendConfigureAck(packet); 846 break; 847 848 case PPP_REQ_SENT_STATE: 849 NewState(PPP_ACK_SENT_STATE); 850 851 case PPP_ACK_SENT_STATE: 852 SendConfigureAck(packet); 853 break; 854 855 case PPP_ACK_RCVD_STATE: 856 NewState(PPP_OPENED_STATE); 857 SendConfigureAck(packet); 858 ReportUpEvent(); 859 break; 860 861 case PPP_OPENED_STATE: 862 NewState(PPP_ACK_SENT_STATE); 863 SendConfigureRequest(); 864 SendConfigureAck(packet); 865 break; 866 867 default: 868 gBufferModule->free(packet); 869 } 870 } 871 872 873 void 874 IPCP::RCRBadEvent(net_buffer *nak, net_buffer *reject) 875 { 876 TRACE("IPCP: RCRBadEvent() state=%d\n", State()); 877 878 uint16 lcpHdrRejectLength = 0; 879 uint16 lcpHdrNakLength = 0; 880 881 if (nak) { 882 NetBufferHeaderReader<ppp_lcp_packet> nakBufferHeaderReader(nak); 883 if (nakBufferHeaderReader.Status() != B_OK) 884 return; 885 ppp_lcp_packet &lcpNakPacket = nakBufferHeaderReader.Data(); 886 lcpHdrNakLength = lcpNakPacket.length; 887 } 888 889 890 if (reject) { 891 NetBufferHeaderReader<ppp_lcp_packet> rejectBufferHeaderReader(reject); 892 if (rejectBufferHeaderReader.Status() != B_OK) 893 return; 894 ppp_lcp_packet &lcpRejectPacket = rejectBufferHeaderReader.Data(); 895 lcpHdrRejectLength = lcpRejectPacket.length; 896 } 897 898 switch (State()) { 899 case PPP_OPENED_STATE: 900 NewState(PPP_REQ_SENT_STATE); 901 SendConfigureRequest(); 902 903 case PPP_ACK_SENT_STATE: 904 if (State() == PPP_ACK_SENT_STATE) 905 NewState(PPP_REQ_SENT_STATE); 906 // OPENED_STATE might have set this already 907 908 case PPP_INITIAL_STATE: 909 case PPP_REQ_SENT_STATE: 910 case PPP_ACK_RCVD_STATE: 911 if (nak && ntohs(lcpHdrNakLength) > 3) 912 SendConfigureNak(nak); 913 else if (reject && ntohs(lcpHdrRejectLength) > 3) 914 SendConfigureNak(reject); 915 return; 916 // prevents the nak/reject from being m_freem()'d 917 918 default: 919 ; 920 } 921 922 if (nak) 923 gBufferModule->free(nak); 924 if (reject) 925 gBufferModule->free(reject); 926 } 927 928 929 void 930 IPCP::RCAEvent(net_buffer *packet) 931 { 932 ERROR("IPCP: RCAEvent() state=%d\n", State()); 933 934 NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet); 935 if (bufferheader.Status() != B_OK) 936 return; 937 ppp_lcp_packet &lcpHeader = bufferheader.Data(); 938 if (fRequestID != lcpHeader.id) { 939 // this packet is not a reply to our request 940 941 // TODO: log this event 942 gBufferModule->free(packet); 943 return; 944 } 945 946 // parse this ack 947 KPPPConfigurePacket ack(packet); 948 ppp_configure_item *item; 949 in_addr_t *requestedAddress, *wishedAddress = NULL, *configuredAddress = NULL; 950 for (int32 index = 0; index < ack.CountItems(); index++) { 951 item = ack.ItemAt(index); 952 if (!item) 953 continue; 954 955 // addresses have special handling to reduce code size 956 switch (item->type) { 957 case IPCP_ADDRESSES: 958 // abandoned by the standard 959 case IPCP_ADDRESS: 960 wishedAddress = &fLocalRequests.address; 961 configuredAddress = &fLocalConfiguration.address; 962 break; 963 964 case IPCP_PRIMARY_DNS: 965 wishedAddress = &fLocalRequests.primaryDNS; 966 configuredAddress = &fLocalConfiguration.primaryDNS; 967 break; 968 969 case IPCP_SECONDARY_DNS: 970 wishedAddress = &fLocalRequests.secondaryDNS; 971 configuredAddress = &fLocalConfiguration.secondaryDNS; 972 break; 973 } 974 975 // now parse item 976 switch (item->type) { 977 case IPCP_ADDRESSES: 978 // abandoned by the standard 979 case IPCP_ADDRESS: 980 case IPCP_PRIMARY_DNS: 981 case IPCP_SECONDARY_DNS: 982 requestedAddress = (in_addr_t*) item->data; 983 if ((*wishedAddress == INADDR_ANY && *requestedAddress != INADDR_ANY) 984 || *wishedAddress == *requestedAddress) 985 *configuredAddress = *requestedAddress; 986 break; 987 988 // case IPCP_COMPRESSION_PROTOCOL: 989 // TODO: implement me 990 // break; 991 992 default: 993 ; 994 } 995 } 996 997 // if address was not specified we should select the given one 998 if (!ack.ItemWithType(IPCP_ADDRESS)) 999 fLocalConfiguration.address = fLocalRequests.address; 1000 1001 1002 switch (State()) { 1003 case PPP_INITIAL_STATE: 1004 IllegalEvent(PPP_RCA_EVENT); 1005 break; 1006 1007 case PPP_REQ_SENT_STATE: 1008 NewState(PPP_ACK_RCVD_STATE); 1009 InitializeRestartCount(); 1010 break; 1011 1012 case PPP_ACK_RCVD_STATE: 1013 NewState(PPP_REQ_SENT_STATE); 1014 SendConfigureRequest(); 1015 break; 1016 1017 case PPP_ACK_SENT_STATE: 1018 NewState(PPP_OPENED_STATE); 1019 InitializeRestartCount(); 1020 ReportUpEvent(); 1021 break; 1022 1023 case PPP_OPENED_STATE: 1024 NewState(PPP_REQ_SENT_STATE); 1025 SendConfigureRequest(); 1026 break; 1027 1028 default: 1029 ; 1030 } 1031 1032 gBufferModule->free(packet); 1033 } 1034 1035 1036 void 1037 IPCP::RCNEvent(net_buffer *packet) 1038 { 1039 TRACE("IPCP: RCNEvent() state=%d\n", State()); 1040 1041 NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet); 1042 if (bufferheader.Status() != B_OK) 1043 return; 1044 ppp_lcp_packet &lcpHeader = bufferheader.Data(); 1045 1046 if (fRequestID != lcpHeader.id) { 1047 // this packet is not a reply to our request 1048 1049 // TODO: log this event 1050 gBufferModule->free(packet); 1051 return; 1052 } 1053 1054 // parse this nak/reject 1055 KPPPConfigurePacket nak_reject(packet); 1056 ppp_configure_item *item; 1057 in_addr_t *requestedAddress; 1058 if (nak_reject.Code() == PPP_CONFIGURE_NAK) 1059 for (int32 index = 0; index < nak_reject.CountItems(); index++) { 1060 item = nak_reject.ItemAt(index); 1061 if (!item) 1062 continue; 1063 1064 switch (item->type) { 1065 case IPCP_ADDRESSES: 1066 // abandoned by the standard 1067 case IPCP_ADDRESS: 1068 if (item->length != 6) 1069 continue; 1070 1071 requestedAddress = (in_addr_t*) item->data; 1072 if (fLocalRequests.address == INADDR_ANY 1073 && *requestedAddress != INADDR_ANY) 1074 fLocalConfiguration.address = *requestedAddress; 1075 // this will be used in our next request 1076 break; 1077 1078 // case IPCP_COMPRESSION_PROTOCOL: 1079 // TODO: implement me! 1080 // break; 1081 1082 case IPCP_PRIMARY_DNS: 1083 if (item->length != 6) 1084 continue; 1085 1086 requestedAddress = (in_addr_t*) item->data; 1087 if (fRequestPrimaryDNS 1088 && fLocalRequests.primaryDNS == INADDR_ANY 1089 && *requestedAddress != INADDR_ANY) 1090 fLocalConfiguration.primaryDNS = *requestedAddress; 1091 // this will be used in our next request 1092 break; 1093 1094 case IPCP_SECONDARY_DNS: 1095 if (item->length != 6) 1096 continue; 1097 1098 requestedAddress = (in_addr_t*) item->data; 1099 if (fRequestSecondaryDNS 1100 && fLocalRequests.secondaryDNS == INADDR_ANY 1101 && *requestedAddress != INADDR_ANY) 1102 fLocalConfiguration.secondaryDNS = *requestedAddress; 1103 // this will be used in our next request 1104 break; 1105 1106 default: 1107 ; 1108 } 1109 } 1110 else if (nak_reject.Code() == PPP_CONFIGURE_REJECT) 1111 for (int32 index = 0; index < nak_reject.CountItems(); index++) { 1112 item = nak_reject.ItemAt(index); 1113 if (!item) 1114 continue; 1115 1116 switch (item->type) { 1117 // case IPCP_COMPRESSION_PROTOCOL: 1118 // TODO: implement me! 1119 // break; 1120 1121 default: 1122 // DNS and addresses must be supported if we set them to auto 1123 gBufferModule->free(packet); 1124 NewState(PPP_INITIAL_STATE); 1125 ReportUpFailedEvent(); 1126 return; 1127 } 1128 } 1129 1130 switch (State()) { 1131 case PPP_INITIAL_STATE: 1132 IllegalEvent(PPP_RCN_EVENT); 1133 break; 1134 1135 case PPP_REQ_SENT_STATE: 1136 case PPP_ACK_SENT_STATE: 1137 InitializeRestartCount(); 1138 1139 case PPP_ACK_RCVD_STATE: 1140 case PPP_OPENED_STATE: 1141 if (State() == PPP_ACK_RCVD_STATE || State() == PPP_OPENED_STATE) 1142 NewState(PPP_REQ_SENT_STATE); 1143 SendConfigureRequest(); 1144 break; 1145 1146 default: 1147 ; 1148 } 1149 1150 gBufferModule->free(packet); 1151 } 1152 1153 1154 void 1155 IPCP::RTREvent(net_buffer *packet) 1156 { 1157 TRACE("IPCP: RTREvent() state=%d\n", State()); 1158 1159 NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet); 1160 if (bufferheader.Status() != B_OK) 1161 return; 1162 ppp_lcp_packet &lcpHeader = bufferheader.Data(); 1163 1164 // we should not use the same ID as the peer 1165 if (fID == lcpHeader.id) 1166 fID -= 128; 1167 1168 switch (State()) { 1169 case PPP_INITIAL_STATE: 1170 IllegalEvent(PPP_RTR_EVENT); 1171 break; 1172 1173 case PPP_ACK_RCVD_STATE: 1174 case PPP_ACK_SENT_STATE: 1175 NewState(PPP_REQ_SENT_STATE); 1176 1177 case PPP_CLOSING_STATE: 1178 case PPP_REQ_SENT_STATE: 1179 SendTerminateAck(packet); 1180 return; 1181 // do not free packet 1182 1183 case PPP_OPENED_STATE: 1184 NewState(PPP_CLOSING_STATE); 1185 ResetRestartCount(); 1186 SendTerminateAck(packet); 1187 return; 1188 // do not free packet 1189 1190 default: 1191 ; 1192 } 1193 1194 gBufferModule->free(packet); 1195 } 1196 1197 1198 void 1199 IPCP::RTAEvent(net_buffer *packet) 1200 { 1201 TRACE("IPCP: RTAEvent() state=%d\n", State()); 1202 1203 NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet); 1204 if (bufferheader.Status() != B_OK) 1205 return; 1206 ppp_lcp_packet &lcpHeader = bufferheader.Data(); 1207 if (fTerminateID != lcpHeader.id) { 1208 // this packet is not a reply to our request 1209 1210 // TODO: log this event 1211 gBufferModule->free(packet); 1212 return; 1213 } 1214 1215 switch (State()) { 1216 case PPP_INITIAL_STATE: 1217 IllegalEvent(PPP_RTA_EVENT); 1218 break; 1219 1220 case PPP_CLOSING_STATE: 1221 NewState(PPP_INITIAL_STATE); 1222 ReportDownEvent(); 1223 break; 1224 1225 case PPP_ACK_RCVD_STATE: 1226 NewState(PPP_REQ_SENT_STATE); 1227 break; 1228 1229 case PPP_OPENED_STATE: 1230 NewState(PPP_REQ_SENT_STATE); 1231 SendConfigureRequest(); 1232 break; 1233 1234 default: 1235 ; 1236 } 1237 1238 gBufferModule->free(packet); 1239 } 1240 1241 1242 void 1243 IPCP::RUCEvent(net_buffer *packet) 1244 { 1245 TRACE("IPCP: RUCEvent() state=%d\n", State()); 1246 1247 SendCodeReject(packet); 1248 } 1249 1250 1251 void 1252 IPCP::RXJBadEvent(net_buffer *packet) 1253 { 1254 TRACE("IPCP: RXJBadEvent() state=%d\n", State()); 1255 1256 switch (State()) { 1257 case PPP_INITIAL_STATE: 1258 IllegalEvent(PPP_RXJ_BAD_EVENT); 1259 break; 1260 1261 case PPP_CLOSING_STATE: 1262 NewState(PPP_INITIAL_STATE); 1263 ReportDownEvent(); 1264 break; 1265 1266 case PPP_REQ_SENT_STATE: 1267 case PPP_ACK_RCVD_STATE: 1268 case PPP_ACK_SENT_STATE: 1269 NewState(PPP_INITIAL_STATE); 1270 ReportUpFailedEvent(); 1271 break; 1272 1273 case PPP_OPENED_STATE: 1274 NewState(PPP_CLOSING_STATE); 1275 InitializeRestartCount(); 1276 SendTerminateRequest(); 1277 break; 1278 1279 default: 1280 ; 1281 } 1282 1283 gBufferModule->free(packet); 1284 } 1285 1286 1287 // actions 1288 void 1289 IPCP::IllegalEvent(ppp_event event) 1290 { 1291 // TODO: update error statistics 1292 ERROR("IPCP: IllegalEvent(event=%d) state=%d\n", event, State()); 1293 } 1294 1295 1296 void 1297 IPCP::ReportUpFailedEvent() 1298 { 1299 // reset configurations 1300 memset(&fLocalConfiguration, 0, sizeof(ipcp_configuration)); 1301 memset(&fPeerConfiguration, 0, sizeof(ipcp_configuration)); 1302 1303 UpdateAddresses(); 1304 1305 UpFailedEvent(); 1306 } 1307 1308 1309 void 1310 IPCP::ReportUpEvent() 1311 { 1312 UpdateAddresses(); 1313 1314 UpEvent(); 1315 } 1316 1317 1318 void 1319 IPCP::ReportDownEvent() 1320 { 1321 // reset configurations 1322 memset(&fLocalConfiguration, 0, sizeof(ipcp_configuration)); 1323 memset(&fPeerConfiguration, 0, sizeof(ipcp_configuration)); 1324 1325 // don't update address if connect on demand is enabled 1326 dprintf("ppp down, and leaving old address and rotues\n"); 1327 // UpdateAddresses(); 1328 1329 DownEvent(); 1330 } 1331 1332 1333 void 1334 IPCP::InitializeRestartCount() 1335 { 1336 fRequestCounter = fMaxRequest; 1337 fTerminateCounter = fMaxTerminate; 1338 fNakCounter = fMaxNak; 1339 } 1340 1341 1342 void 1343 IPCP::ResetRestartCount() 1344 { 1345 fRequestCounter = 0; 1346 fTerminateCounter = 0; 1347 fNakCounter = 0; 1348 } 1349 1350 1351 bool 1352 IPCP::SendConfigureRequest() 1353 { 1354 TRACE("IPCP: SendConfigureRequest() state=%d\n", State()); 1355 1356 --fRequestCounter; 1357 fNextTimeout = system_time() + kIPCPStateMachineTimeout; 1358 1359 KPPPConfigurePacket request(PPP_CONFIGURE_REQUEST); 1360 request.SetID(NextID()); 1361 fRequestID = request.ID(); 1362 ip_item ipItem; 1363 ipItem.length = 6; 1364 1365 // add address 1366 ipItem.type = IPCP_ADDRESS; 1367 if (fLocalRequests.address == INADDR_ANY) 1368 ipItem.address = (fLocalConfiguration.address); 1369 else 1370 ipItem.address =(fLocalRequests.address); 1371 request.AddItem((ppp_configure_item*) &ipItem); 1372 1373 TRACE("IPCP: SCR: confaddr=%X; reqaddr=%X; addr=%X\n", 1374 fLocalConfiguration.address, fLocalRequests.address, 1375 ((ip_item*)request.ItemAt(0))->address); 1376 1377 // add primary DNS (if needed) 1378 if (fRequestPrimaryDNS && fLocalRequests.primaryDNS == INADDR_ANY) { 1379 ipItem.type = IPCP_PRIMARY_DNS; 1380 ipItem.address = fLocalConfiguration.primaryDNS; 1381 // at first this is 0.0.0.0, but a nak might have set it to a correct value 1382 request.AddItem((ppp_configure_item*) &ipItem); 1383 } 1384 1385 // add secondary DNS (if needed) 1386 if (fRequestSecondaryDNS && fLocalRequests.primaryDNS == INADDR_ANY) { 1387 ipItem.type = IPCP_SECONDARY_DNS; 1388 ipItem.address = fLocalConfiguration.secondaryDNS; 1389 // at first this is 0.0.0.0, but a nak might have set it to a correct value 1390 request.AddItem((ppp_configure_item*) &ipItem); 1391 } 1392 1393 // TODO: add VJC support 1394 1395 return Send(request.ToNetBuffer(Interface().MRU())) == B_OK; 1396 } 1397 1398 1399 bool 1400 IPCP::SendConfigureAck(net_buffer *packet) 1401 { 1402 TRACE("IPCP: SendConfigureAck() state=%d\n", State()); 1403 1404 if (!packet) 1405 return false; 1406 1407 NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet); 1408 if (bufferheader.Status() != B_OK) 1409 return false; 1410 ppp_lcp_packet &lcpheader = bufferheader.Data(); 1411 lcpheader.code = PPP_CONFIGURE_ACK; 1412 1413 bufferheader.Sync(); 1414 1415 KPPPConfigurePacket ack(packet); 1416 1417 // verify items 1418 ppp_configure_item *item; 1419 in_addr_t *requestedAddress, *wishedAddress = NULL, *configuredAddress = NULL; 1420 for (int32 index = 0; index < ack.CountItems(); index++) { 1421 item = ack.ItemAt(index); 1422 if (!item) 1423 continue; 1424 1425 // addresses have special handling to reduce code size 1426 switch (item->type) { 1427 case IPCP_ADDRESSES: 1428 // abandoned by the standard 1429 case IPCP_ADDRESS: 1430 wishedAddress = &fPeerRequests.address; 1431 configuredAddress = &fPeerConfiguration.address; 1432 break; 1433 1434 case IPCP_PRIMARY_DNS: 1435 wishedAddress = &fPeerRequests.primaryDNS; 1436 configuredAddress = &fPeerConfiguration.primaryDNS; 1437 break; 1438 1439 case IPCP_SECONDARY_DNS: 1440 wishedAddress = &fPeerRequests.secondaryDNS; 1441 configuredAddress = &fPeerConfiguration.secondaryDNS; 1442 break; 1443 } 1444 1445 // now parse item 1446 switch (item->type) { 1447 case IPCP_ADDRESSES: 1448 // abandoned by the standard 1449 case IPCP_ADDRESS: 1450 case IPCP_PRIMARY_DNS: 1451 case IPCP_SECONDARY_DNS: 1452 requestedAddress = (in_addr_t*) item->data; 1453 if ((*wishedAddress == INADDR_ANY && *requestedAddress != INADDR_ANY) 1454 || *wishedAddress == *requestedAddress) 1455 *configuredAddress = *requestedAddress; 1456 break; 1457 1458 // case IPCP_COMPRESSION_PROTOCOL: 1459 // TODO: implement me! 1460 // break; 1461 1462 default: 1463 ; 1464 } 1465 } 1466 1467 // if address was not specified we should select the given one 1468 if (!ack.ItemWithType(IPCP_ADDRESS)) 1469 fPeerConfiguration.address = fPeerRequests.address; 1470 1471 return Send(packet) == B_OK; 1472 } 1473 1474 1475 bool 1476 IPCP::SendConfigureNak(net_buffer *packet) 1477 { 1478 TRACE("IPCP: SendConfigureNak() state=%d\n", State()); 1479 1480 if (!packet) 1481 return false; 1482 1483 NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet); 1484 if (bufferheader.Status() != B_OK) 1485 return false; 1486 1487 ppp_lcp_packet &nak = bufferheader.Data(); 1488 1489 if (nak.code == PPP_CONFIGURE_NAK) { 1490 if (fNakCounter == 0) { 1491 // We sent enough naks. Let's try a reject. 1492 nak.code = PPP_CONFIGURE_REJECT; 1493 } else 1494 --fNakCounter; 1495 } 1496 1497 bufferheader.Sync(); 1498 1499 return Send(packet) == B_OK; 1500 } 1501 1502 1503 bool 1504 IPCP::SendTerminateRequest() 1505 { 1506 TRACE("IPCP: SendTerminateRequest() state=%d\n", State()); 1507 1508 --fTerminateCounter; 1509 fNextTimeout = system_time() + kIPCPStateMachineTimeout; 1510 1511 net_buffer *packet = gBufferModule->create(256); 1512 if (!packet) 1513 return false; 1514 1515 ppp_lcp_packet *request; 1516 status_t status = gBufferModule->append_size(packet, 1492, (void **)(&request)); 1517 if (status != B_OK) 1518 return false; 1519 1520 request->code = PPP_TERMINATE_REQUEST; 1521 request->id = fTerminateID = NextID(); 1522 request->length = htons(4); 1523 1524 status = gBufferModule->trim(packet, 4); 1525 if (status != B_OK) 1526 return false; 1527 1528 return Send(packet) == B_OK; 1529 } 1530 1531 1532 bool 1533 IPCP::SendTerminateAck(net_buffer *request) 1534 { 1535 TRACE("IPCP: SendTerminateAck() state=%d\n", State()); 1536 1537 net_buffer *reply = request; 1538 1539 if (!reply) { 1540 reply = gBufferModule->create(256); 1541 ppp_lcp_packet *ack; 1542 status_t status = gBufferModule->append_size(reply, 1492, (void **)(&ack)); 1543 if (status != B_OK) { 1544 gBufferModule->free(reply); 1545 return false; 1546 } 1547 ack->id = NextID(); 1548 ack->code = PPP_TERMINATE_ACK; 1549 ack->length = htons(4); 1550 gBufferModule->trim(reply, 4); 1551 } else { 1552 NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(reply); 1553 if (bufferHeader.Status() < B_OK) 1554 return false; 1555 ppp_lcp_packet &ack = bufferHeader.Data(); 1556 ack.code = PPP_TERMINATE_ACK; 1557 ack.length = htons(4); 1558 } 1559 1560 return Send(reply) == B_OK; 1561 } 1562 1563 1564 bool 1565 IPCP::SendCodeReject(net_buffer *packet) 1566 { 1567 TRACE("IPCP: SendCodeReject() state=%d\n", State()); 1568 1569 if (!packet) 1570 return false; 1571 1572 NetBufferPrepend<ppp_lcp_packet> bufferHeader(packet); 1573 if (bufferHeader.Status() != B_OK) 1574 return false; 1575 1576 ppp_lcp_packet &reject = bufferHeader.Data(); 1577 1578 reject.code = PPP_CODE_REJECT; 1579 reject.id = NextID(); 1580 reject.length = htons(packet->size); 1581 1582 bufferHeader.Sync(); 1583 1584 return Send(packet) == B_OK; 1585 } 1586