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
dump_packet(net_buffer * packet,const char * direction)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
IPCP(KPPPInterface & interface,driver_parameter * settings)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
~IPCP()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
Uninit()128 IPCP::Uninit()
129 {
130 RemoveRoutes();
131 }
132
133
134 status_t
StackControl(uint32 op,void * data)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
Up()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
Down()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
Send(net_buffer * packet,uint16 protocolNumber)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
Receive(net_buffer * packet,uint16 protocolNumber)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
ReceiveIPPacket(net_buffer * packet,uint16 protocolNumber)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
Pulse()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
ParseSideRequests(const driver_parameter * requests,ppp_side side)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 *
get_interface_by_name(net_domain * domain,const char * name)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
set_interface_address(net_domain * domain,struct ifaliasreq * inreq)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
UpdateAddresses()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
RemoveRoutes()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
NextID()649 IPCP::NextID()
650 {
651 return (uint8) atomic_add(&fID, 1);
652 }
653
654
655 void
NewState(ppp_state next)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
TOGoodEvent()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
TOBadEvent()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
RCREvent(net_buffer * packet)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
RCRGoodEvent(net_buffer * packet)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
RCRBadEvent(net_buffer * nak,net_buffer * reject)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
RCAEvent(net_buffer * packet)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
RCNEvent(net_buffer * packet)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
RTREvent(net_buffer * packet)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
RTAEvent(net_buffer * packet)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
RUCEvent(net_buffer * packet)1242 IPCP::RUCEvent(net_buffer *packet)
1243 {
1244 TRACE("IPCP: RUCEvent() state=%d\n", State());
1245
1246 SendCodeReject(packet);
1247 }
1248
1249
1250 void
RXJBadEvent(net_buffer * packet)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
IllegalEvent(ppp_event event)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
ReportUpFailedEvent()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
ReportUpEvent()1309 IPCP::ReportUpEvent()
1310 {
1311 UpdateAddresses();
1312
1313 UpEvent();
1314 }
1315
1316
1317 void
ReportDownEvent()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
InitializeRestartCount()1333 IPCP::InitializeRestartCount()
1334 {
1335 fRequestCounter = fMaxRequest;
1336 fTerminateCounter = fMaxTerminate;
1337 fNakCounter = fMaxNak;
1338 }
1339
1340
1341 void
ResetRestartCount()1342 IPCP::ResetRestartCount()
1343 {
1344 fRequestCounter = 0;
1345 fTerminateCounter = 0;
1346 fNakCounter = 0;
1347 }
1348
1349
1350 bool
SendConfigureRequest()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
SendConfigureAck(net_buffer * packet)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
SendConfigureNak(net_buffer * packet)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
SendTerminateRequest()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
SendTerminateAck(net_buffer * request)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
SendCodeReject(net_buffer * packet)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