1 /*
2 * Copyright 2003-2007, Waldemar Kornewald <wkornew@gmx.net>
3 * Distributed under the terms of the MIT License.
4 */
5
6 /*! \class KPPPInterface
7 \brief The kernel representation of a PPP interface.
8
9 This class is never created by the programmer directly. Instead, the PPP manager
10 kernel module should be used. \n
11 KPPPInterface handles all interface-specific commands from userspace and it
12 passes packets to their receiver or sends them to the device. Additionally,
13 it contains the KPPPLCP object with represents the LCP protocol and the
14 KPPPStateMachine object which represents the state machine. \n
15 All PPP modules are loaded from here. \n
16 Protocols and encapsulators should be added to this class. LCP-specific extensions
17 belong to the KPPPLCP object. \n
18 Multilink support is distributed between KPPPInterface and KPPPStateMachine.
19 */
20
21 // cstdio must be included before KPPPModule.h/KPPPManager.h because
22 // dprintf is defined twice with different return values, once with
23 // void (KernelExport.h) and once with int (stdio.h).
24 #include <cstdio>
25 #include <cstring>
26 #include <arpa/inet.h>
27
28 #include <ByteOrder.h>
29 #include <net_buffer.h>
30 #include <net_stack.h>
31 #include <ppp_device.h>
32
33 // now our headers...
34 #include <KPPPInterface.h>
35
36 // our other classes
37 #include <PPPControl.h>
38 #include <KPPPDevice.h>
39 #include <KPPPLCPExtension.h>
40 #include <KPPPOptionHandler.h>
41 #include <KPPPModule.h>
42 #include <KPPPManager.h>
43 #include <KPPPUtils.h>
44
45 // general helper classes not only belonging to us
46 // #include <lock.h>
47 // #include <util/AutoLock.h>
48
49 // tools only for us :)
50 #include "settings_tools.h"
51
52 // internal modules
53 #include "_KPPPMRUHandler.h"
54 #include "_KPPPAuthenticationHandler.h"
55 #include "_KPPPPFCHandler.h"
56
57
58 // TODO:
59 // - implement timers with support for setting next event instead of receiving timer
60 // events periodically
61 // - add missing settings support (ConnectRetryDelay, etc.)
62
63
64 //! Private structure needed for reconnecting.
65 typedef struct reconnect_info {
66 KPPPInterface *interface;
67 thread_id *thread;
68 uint32 delay;
69 } reconnect_info;
70
71 extern net_buffer_module_info *gBufferModule;
72 extern net_stack_module_info *gStackModule;
73
74 status_t reconnect_thread(void *data);
75
76 // other functions
77 status_t interface_deleter_thread(void *data);
78
79
80 /*! \brief Creates a new interface.
81
82 \param name Name of the PPP interface description file.
83 \param entry The PPP manager passes an internal structure to the constructor.
84 \param ID The interface's ID.
85 \param settings (Optional): If no name is given you must pass the settings here.
86 \param parent (Optional): Interface's parent (only used for multilink interfaces).
87 */
KPPPInterface(const char * name,ppp_interface_entry * entry,ppp_interface_id ID,const driver_settings * settings,KPPPInterface * parent)88 KPPPInterface::KPPPInterface(const char *name, ppp_interface_entry *entry,
89 ppp_interface_id ID, const driver_settings *settings, KPPPInterface *parent)
90 :
91 KPPPLayer(name, PPP_INTERFACE_LEVEL, 2),
92 fID(ID),
93 fSettings(NULL),
94 fIfnet(NULL),
95 fReconnectThread(-1),
96 fConnectAttempt(1),
97 fConnectRetriesLimit(0),
98 fManager(NULL),
99 fConnectedSince(0),
100 fIdleSince(0),
101 fMRU(1500),
102 fInterfaceMTU(1498),
103 fHeaderLength(2),
104 fParent(NULL),
105 fIsMultilink(false),
106 fAutoReconnect(false),
107 fConnectOnDemand(true),
108 fAskBeforeConnecting(false),
109 fMode(PPP_CLIENT_MODE),
110 fLocalPFCState(PPP_PFC_DISABLED),
111 fPeerPFCState(PPP_PFC_DISABLED),
112 fPFCOptions(0),
113 fDevice(NULL),
114 fFirstProtocol(NULL),
115 fStateMachine(*this),
116 fLCP(*this),
117 fReportManager(StateMachine().fLock),
118 fLock(StateMachine().fLock),
119 fDeleteCounter(0)
120 {
121 entry->interface = this;
122
123 if (name) {
124 // load settings from description file
125 char path[B_PATH_NAME_LENGTH];
126 sprintf(path, "ptpnet/%s", name);
127
128 void *handle = load_driver_settings(path);
129 if (!handle) {
130 ERROR("KPPPInterface: Unable to load %s PPP driver settings!\n", path);
131 fInitStatus = B_ERROR;
132 return;
133 }
134
135 fSettings = dup_driver_settings(get_driver_settings(handle));
136 unload_driver_settings(handle);
137 } else
138 fSettings = dup_driver_settings(settings);
139 // use the given settings
140
141 if (!fSettings) {
142 ERROR("KPPPInterface: No fSettings!\n");
143 fInitStatus = B_ERROR;
144 return;
145 }
146
147 // add internal modules
148 // LCP
149 if (!AddProtocol(&LCP())) {
150 ERROR("KPPPInterface: Could not add LCP protocol!\n");
151 fInitStatus = B_ERROR;
152 return;
153 }
154 // MRU
155 _KPPPMRUHandler *mruHandler =
156 new _KPPPMRUHandler(*this);
157 if (!LCP().AddOptionHandler(mruHandler) || mruHandler->InitCheck() != B_OK) {
158 ERROR("KPPPInterface: Could not add MRU handler!\n");
159 delete mruHandler;
160 }
161 // authentication
162 _KPPPAuthenticationHandler *authenticationHandler =
163 new _KPPPAuthenticationHandler(*this);
164 if (!LCP().AddOptionHandler(authenticationHandler)
165 || authenticationHandler->InitCheck() != B_OK) {
166 ERROR("KPPPInterface: Could not add authentication handler!\n");
167 delete authenticationHandler;
168 }
169 // PFC
170 _KPPPPFCHandler *pfcHandler =
171 new _KPPPPFCHandler(fLocalPFCState, fPeerPFCState, *this);
172 if (!LCP().AddOptionHandler(pfcHandler) || pfcHandler->InitCheck() != B_OK) {
173 ERROR("KPPPInterface: Could not add PFC handler!\n");
174 delete pfcHandler;
175 }
176
177 // set up connect delays
178 fConnectRetryDelay = 3000;
179 // 3s delay between each new attempt to reconnect
180 fReconnectDelay = 1000;
181 // 1s delay between lost connection and reconnect
182
183 if (get_module(PPP_INTERFACE_MODULE_NAME, (module_info**) &fManager) != B_OK)
184 ERROR("KPPPInterface: Manager module not found!\n");
185
186 // are we a multilink subinterface?
187 if (parent && parent->IsMultilink()) {
188 fParent = parent;
189 fParent->AddChild(this);
190 fIsMultilink = true;
191 }
192
193 RegisterInterface();
194
195 if (!fSettings) {
196 fInitStatus = B_ERROR;
197 return;
198 }
199
200 const char *value;
201
202 // get login
203 value = get_settings_value(PPP_USERNAME_KEY, fSettings);
204 fUsername = value ? strdup(value) : strdup("");
205 value = get_settings_value(PPP_PASSWORD_KEY, fSettings);
206 fPassword = value ? strdup(value) : strdup("");
207
208 // get DisonnectAfterIdleSince settings
209 value = get_settings_value(PPP_DISONNECT_AFTER_IDLE_SINCE_KEY, fSettings);
210 if (!value)
211 fDisconnectAfterIdleSince = 0;
212 else
213 fDisconnectAfterIdleSince = atoi(value) * 1000;
214
215 if (fDisconnectAfterIdleSince < 0)
216 fDisconnectAfterIdleSince = 0;
217
218 // get mode settings
219 value = get_settings_value(PPP_MODE_KEY, fSettings);
220 if (value && !strcasecmp(value, PPP_SERVER_MODE_VALUE))
221 fMode = PPP_SERVER_MODE;
222 else
223 fMode = PPP_CLIENT_MODE;
224 // we are a client by default
225
226 SetAutoReconnect(
227 get_boolean_value(
228 get_settings_value(PPP_AUTO_RECONNECT_KEY, fSettings),
229 false)
230 );
231 // auto reconnect is disabled by default
232
233 fAskBeforeConnecting = get_boolean_value(
234 get_settings_value(PPP_ASK_BEFORE_CONNECTING_KEY, fSettings), false);
235
236 // load all protocols and the device
237 if (!LoadModules(fSettings, 0, fSettings->parameter_count)) {
238 ERROR("KPPPInterface: Error loading modules!\n");
239 fInitStatus = B_ERROR;
240 }
241 }
242
243
244 //! Destructor: Disconnects and marks interface for deletion.
~KPPPInterface()245 KPPPInterface::~KPPPInterface()
246 {
247 TRACE("KPPPInterface: Destructor\n");
248
249 // tell protocols to uninit (remove routes, etc.)
250 KPPPProtocol *protocol = FirstProtocol();
251 for (; protocol; protocol = protocol->NextProtocol())
252 protocol->Uninit();
253
254 // make sure we are not accessible by any thread before we continue
255 UnregisterInterface();
256
257 if (fManager)
258 fManager->RemoveInterface(ID());
259
260 // Call Down() until we get a lock on an interface that is down.
261 // This lock is not released until we are actually deleted.
262 while (true) {
263 Down();
264 {
265 MutexLocker locker(fLock);
266 if (State() == PPP_INITIAL_STATE && Phase() == PPP_DOWN_PHASE)
267 break;
268 }
269 }
270
271 Report(PPP_DESTRUCTION_REPORT, 0, &fID, sizeof(ppp_interface_id));
272 // tell all listeners that we are being destroyed
273
274 int32 tmp;
275 send_data_with_timeout(fReconnectThread, 0, NULL, 0, 200);
276 // tell thread that we are being destroyed (200ms timeout)
277 wait_for_thread(fReconnectThread, &tmp);
278
279 while (CountChildren())
280 delete ChildAt(0);
281
282 delete Device();
283
284 while (FirstProtocol()) {
285 if (FirstProtocol() == &LCP())
286 fFirstProtocol = fFirstProtocol->NextProtocol();
287 else
288 delete FirstProtocol();
289 // destructor removes protocol from list
290 }
291
292 for (int32 index = 0; index < fModules.CountItems(); index++) {
293 put_module(fModules.ItemAt(index));
294 delete[] fModules.ItemAt(index);
295 }
296
297 free_driver_settings(fSettings);
298
299 if (Parent())
300 Parent()->RemoveChild(this);
301
302 if (fManager)
303 put_module(PPP_INTERFACE_MODULE_NAME);
304 }
305
306
307 //! Marks interface for deletion.
308 void
Delete()309 KPPPInterface::Delete()
310 {
311 // MutexLocker locker(fLock);
312 // alreay locked in KPPPStatemachine::DownEvent
313 // uncomment this line will cause double lock
314
315 if (fDeleteCounter > 0)
316 return;
317 // only one thread should delete us!
318
319 fDeleteCounter = 1;
320
321 fManager->DeleteInterface(ID());
322 // This will mark us for deletion.
323 // Any subsequent calls to delete_interface() will do nothing.
324 }
325
326
327 //! Returns if interface was initialized correctly.
328 status_t
InitCheck() const329 KPPPInterface::InitCheck() const
330 {
331 if (fInitStatus != B_OK)
332 return fInitStatus;
333
334 if (!fSettings || !fManager)
335 return B_ERROR;
336
337 // sub-interfaces should have a device
338 if (IsMultilink()) {
339 if (Parent() && !fDevice)
340 return B_ERROR;
341 } else if (!fDevice)
342 return B_ERROR;
343
344 return B_OK;
345 }
346
347
348 //! The username used for authentication.
349 const char*
Username() const350 KPPPInterface::Username() const
351 {
352 // this data is not available before we authenticate
353 if (Phase() < PPP_AUTHENTICATION_PHASE)
354 return NULL;
355
356 return fUsername;
357 }
358
359
360 //! The password used for authentication.
361 const char*
Password() const362 KPPPInterface::Password() const
363 {
364 // this data is not available before we authenticate
365 if (Phase() < PPP_AUTHENTICATION_PHASE)
366 return NULL;
367
368 return fPassword;
369 }
370
371
372 //! Sets interface MRU.
373 bool
SetMRU(uint32 MRU)374 KPPPInterface::SetMRU(uint32 MRU)
375 {
376 TRACE("KPPPInterface: SetMRU(%ld)\n", MRU);
377
378 if (Device() && MRU > Device()->MTU() - 2)
379 return false;
380
381 // MutexLocker locker(fLock);
382 // uncomment this line will cause double lock
383 // alreay locked in ::Up and ::KPPPInterface
384
385 fMRU = MRU;
386
387 CalculateInterfaceMTU();
388
389 return true;
390 }
391
392
393 //! Returns number of bytes spent for protocol overhead. Includes device overhead.
394 uint32
PacketOverhead() const395 KPPPInterface::PacketOverhead() const
396 {
397 uint32 overhead = fHeaderLength + 2;
398
399 if (Device())
400 overhead += Device()->Overhead();
401
402 return overhead;
403 }
404
405
406 /*! \brief Allows accessing additional functions.
407
408 This is normally called by userland apps to get information about the interface.
409
410 \param op The op value (see ppp_control_ops enum).
411 \param data (Optional): Additional data may be needed for this op.
412 \param length Length of data.
413
414 \return
415 - \c B_OK: \c Control() was successful.
416 - \c B_ERROR: Either \a length is too small or data is NULL.
417 - \c B_NOT_ALLOWED: Operation not allowed (at this point in time).
418 - \c B_BAD_INDEX: Wrong index (e.g.: when accessing interface submodules).
419 - \c B_BAD_VALUE: Unknown op.
420 - Return value of submodule (when controlling one).
421 */
422 status_t
Control(uint32 op,void * data,size_t length)423 KPPPInterface::Control(uint32 op, void *data, size_t length)
424 {
425 TRACE("%s:%s\n", __FILE__, __func__);
426
427 control_net_module_args* args = (control_net_module_args*)data;
428 if (op != NET_STACK_CONTROL_NET_MODULE) {
429 dprintf("unknow op!!\n");
430 return B_BAD_VALUE;
431 }
432
433 switch (args->op) {
434 case PPPC_COUNT_INTERFACES:
435 {
436 // should be implepented
437 dprintf("PPPC_COUNT_INTERFACES should be implepentd\n");
438
439 return B_OK;
440 }
441
442 case PPPC_GET_INTERFACES:
443 {
444 dprintf("PPPC_GET_INTERFACES\n");
445 ppp_get_interfaces_info* info = (ppp_get_interfaces_info*)args->data;
446 dprintf("info->interfaces: %p\n", info->interfaces);
447 *(info->interfaces) = 1;
448 info->resultCount = 1;
449
450 return B_OK;
451 }
452
453 case PPPC_CONTROL_INTERFACE:
454 {
455 dprintf("PPPC_CONTROL_INTERFACE\n");
456 ppp_control_info* control = (ppp_control_info*)args->data;
457
458 switch (control->op) {
459 case PPPC_GET_INTERFACE_INFO:
460 {
461 dprintf("PPPC_GET_INTERFACE_INFO\n");
462 if (control->length < sizeof(ppp_interface_info_t) || !control->data) {
463 dprintf("size wrong!\n");
464 return B_ERROR;
465 }
466
467 ppp_interface_info *info = (ppp_interface_info*) control->data;
468 dprintf("info addr:%p\n", info);
469 memset(info, 0, sizeof(ppp_interface_info_t));
470 if (Name())
471 strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
472
473 if (Ifnet())
474 info->if_unit = Ifnet()->index;
475 else
476 info->if_unit = -1;
477 info->mode = Mode();
478 info->state = State();
479 info->phase = Phase();
480 info->localAuthenticationStatus =
481 StateMachine().LocalAuthenticationStatus();
482 info->peerAuthenticationStatus =
483 StateMachine().PeerAuthenticationStatus();
484 info->localPFCState = LocalPFCState();
485 info->peerPFCState = PeerPFCState();
486 info->pfcOptions = PFCOptions();
487 info->protocolsCount = CountProtocols();
488 info->optionHandlersCount = LCP().CountOptionHandlers();
489 info->LCPExtensionsCount = 0;
490 info->childrenCount = CountChildren();
491 info->MRU = MRU();
492 info->interfaceMTU = InterfaceMTU();
493 info->connectAttempt = fConnectAttempt;
494 info->connectRetriesLimit = fConnectRetriesLimit;
495 info->connectRetryDelay = ConnectRetryDelay();
496 info->reconnectDelay = ReconnectDelay();
497 info->connectedSince = ConnectedSince();
498 info->idleSince = IdleSince();
499 info->disconnectAfterIdleSince = DisconnectAfterIdleSince();
500 info->doesConnectOnDemand = DoesConnectOnDemand();
501 info->doesAutoReconnect = DoesAutoReconnect();
502 info->hasDevice = Device();
503 info->isMultilink = IsMultilink();
504 info->hasParent = Parent();
505 break;
506 }
507
508 case PPPC_SET_USERNAME:
509 {
510 dprintf("PPPC_SET_USERNAME\n");
511 if (control->length > PPP_HANDLER_NAME_LENGTH_LIMIT || !control->data) {
512 dprintf("size wrong!\n");
513 return B_ERROR;
514 }
515
516 MutexLocker locker(fLock);
517 // login information can only be changed before we authenticate
518 if (Phase() >= PPP_AUTHENTICATION_PHASE)
519 return B_NOT_ALLOWED;
520
521 free(fUsername);
522 fUsername = control->data ? strdup((const char*) control->data) : strdup("");
523 dprintf("set ppp user name to %s\n", fUsername);
524
525 break;
526 }
527
528 case PPPC_SET_PASSWORD:
529 {
530 dprintf("PPPC_SET_PASSWORD\n");
531 if (control->length > PPP_HANDLER_NAME_LENGTH_LIMIT || !control->data) {
532 dprintf("size wrong!\n");
533 return B_ERROR;
534 }
535
536 MutexLocker locker(fLock);
537 // login information can only be changed before we authenticate
538 if (Phase() >= PPP_AUTHENTICATION_PHASE)
539 return B_NOT_ALLOWED;
540
541 free(fPassword);
542 fPassword = control->data ? strdup((const char*) control->data) : strdup("");
543 dprintf("set ppp password to %s!\n", fPassword);
544 break;
545 }
546
547 case PPPC_SET_ASK_BEFORE_CONNECTING:
548 {
549 dprintf("PPPC_SET_ASK_BEFORE_CONNECTING\n");
550 if (control->length < sizeof(uint32) || !control->data) {
551 dprintf("size wrong!\n");
552 return B_ERROR;
553 }
554
555 SetAskBeforeConnecting(*((uint32*)control->data));
556 dprintf("goto PPPC_SET_ASK_BEFORE_CONNECTING here!\n");
557 break;
558 }
559
560 case PPPC_GET_STATISTICS:
561 {
562 dprintf("PPPC_GET_STATISTICS\n");
563 if (control->length < sizeof(ppp_statistics) || !control->data) {
564 dprintf("size wrong!\n");
565 return B_ERROR;
566 }
567
568 dprintf("should PPPC_GET_STATISTICS here!\n");
569
570 memcpy(control->data, &fStatistics, sizeof(ppp_statistics));
571 break;
572 }
573
574 case PPPC_HAS_INTERFACE_SETTINGS:
575 {
576 dprintf("PPPC_HAS_INTERFACE_SETTINGS\n");
577 if (control->length < sizeof(driver_settings) || !control->data) {
578 dprintf("size wrong!\n");
579 return B_ERROR;
580 }
581
582 dprintf("should PPPC_HAS_INTERFACE_SETTINGS here!\n");
583
584 if (equal_interface_settings(Settings(), (driver_settings*)control->data))
585 return B_OK;
586 else
587 return B_ERROR;
588 break;
589
590 }
591
592 case PPPC_ENABLE_REPORTS:
593 {
594 dprintf("PPPC_ENABLE_REPORTS\n");
595 if (control->length < sizeof(ppp_report_request) || !control->data) {
596 dprintf("size wrong!\n");
597 return B_ERROR;
598 }
599
600 dprintf("should PPPC_ENABLE_REPORTS here!\n");
601
602 MutexLocker locker(fLock);
603 ppp_report_request *request = (ppp_report_request*) control->data;
604 // first, we send an initial state report
605 if (request->type == PPP_CONNECTION_REPORT) {
606 ppp_report_packet report;
607 report.type = PPP_CONNECTION_REPORT;
608 report.code = StateMachine().fLastConnectionReportCode;
609 report.length = sizeof(fID);
610 KPPPReportManager::SendReport(request->thread, &report);
611 if (request->flags & PPP_REMOVE_AFTER_REPORT)
612 return B_OK;
613 }
614 ReportManager().EnableReports(request->type, request->thread,
615 request->flags);
616 break;
617 }
618
619 case PPPC_DISABLE_REPORTS:
620 {
621 dprintf("PPPC_DISABLE_REPORTS\n");
622 if (control->length < sizeof(ppp_report_request) || !control->data) {
623 dprintf("size wrong!\n");
624 return B_ERROR;
625 }
626
627 dprintf("should PPPC_DISABLE_REPORTS here!\n");
628
629 ppp_report_request *request = (ppp_report_request*) control->data;
630 ReportManager().DisableReports(request->type, request->thread);
631 break;
632 }
633
634 case PPPC_CONTROL_DEVICE:
635 {
636 dprintf("PPPC_CONTROL_DEVICE\n");
637 if (control->length < sizeof(ppp_control_info) || !control->data)
638 return B_ERROR;
639
640 ppp_control_info *controlInfo = (ppp_control_info*) control->data;
641 if (controlInfo->index != 0 || !Device()) {
642 dprintf("index is 0 or no Device\n");
643 return B_BAD_INDEX;
644 }
645
646 return Device()->Control(controlInfo->op, controlInfo->data, controlInfo->length);
647 }
648
649 case PPPC_CONTROL_PROTOCOL:
650 {
651 dprintf("PPPC_CONTROL_PROTOCOL\n");
652 if (control->length < sizeof(ppp_control_info) || !control->data)
653 return B_ERROR;
654
655 ppp_control_info *controlInfo = (ppp_control_info*) control->data;
656 KPPPProtocol *protocol = ProtocolAt(controlInfo->index);
657 if (!protocol)
658 return B_BAD_INDEX;
659
660 return protocol->Control(controlInfo->op, controlInfo->data, controlInfo->length);
661 }
662
663 case PPPC_CONTROL_OPTION_HANDLER:
664 {
665 dprintf("PPPC_CONTROL_OPTION_HANDLER\n");
666 if (control->length < sizeof(ppp_control_info) || !control->data)
667 return B_ERROR;
668
669 ppp_control_info *controlInfo = (ppp_control_info*) control->data;
670 KPPPOptionHandler *optionHandler = LCP().OptionHandlerAt(controlInfo->index);
671 if (!optionHandler) {
672 dprintf("optionHandler no avail\n");
673 return B_BAD_INDEX;
674 }
675
676 return optionHandler->Control(controlInfo->op, controlInfo->data,
677 controlInfo->length);
678 }
679
680 case PPPC_CONTROL_LCP_EXTENSION:
681 {
682 dprintf("PPPC_CONTROL_LCP_EXTENSION\n");
683 if (control->length < sizeof(ppp_control_info) || !control->data)
684 return B_ERROR;
685
686 ppp_control_info *controlInfo = (ppp_control_info*) control->data;
687 KPPPLCPExtension *lcpExtension = LCP().LCPExtensionAt(controlInfo->index);
688 if (!lcpExtension)
689 return B_BAD_INDEX;
690
691 return lcpExtension->Control(controlInfo->op, controlInfo->data,
692 controlInfo->length);
693 }
694
695 case PPPC_CONTROL_CHILD:
696 {
697 dprintf("PPPC_CONTROL_CHILD\n");
698 if (control->length < sizeof(ppp_control_info) || !control->data)
699 return B_ERROR;
700
701 ppp_control_info *controlInfo = (ppp_control_info*) control->data;
702 KPPPInterface *child = ChildAt(controlInfo->index);
703 if (!child)
704 return B_BAD_INDEX;
705
706 return child->Control(controlInfo->op, controlInfo->data, controlInfo->length);
707 }
708
709 default :
710 return B_ERROR;
711 }
712
713 return B_OK;
714 }
715
716 case PPPC_GET_INTERFACE_INFO:
717 {
718 if (length < sizeof(ppp_interface_info_t) || !data)
719 return B_ERROR;
720
721 ppp_interface_info *info = (ppp_interface_info*) data;
722 memset(info, 0, sizeof(ppp_interface_info_t));
723 if (Name())
724 strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
725 if (Ifnet())
726 info->if_unit = Ifnet()->index;
727 else
728 info->if_unit = -1;
729 info->mode = Mode();
730 info->state = State();
731 info->phase = Phase();
732 info->localAuthenticationStatus =
733 StateMachine().LocalAuthenticationStatus();
734 info->peerAuthenticationStatus =
735 StateMachine().PeerAuthenticationStatus();
736 info->localPFCState = LocalPFCState();
737 info->peerPFCState = PeerPFCState();
738 info->pfcOptions = PFCOptions();
739 info->protocolsCount = CountProtocols();
740 info->optionHandlersCount = LCP().CountOptionHandlers();
741 info->LCPExtensionsCount = 0;
742 info->childrenCount = CountChildren();
743 info->MRU = MRU();
744 info->interfaceMTU = InterfaceMTU();
745 info->connectAttempt = fConnectAttempt;
746 info->connectRetriesLimit = fConnectRetriesLimit;
747 info->connectRetryDelay = ConnectRetryDelay();
748 info->reconnectDelay = ReconnectDelay();
749 info->connectedSince = ConnectedSince();
750 info->idleSince = IdleSince();
751 info->disconnectAfterIdleSince = DisconnectAfterIdleSince();
752 info->doesConnectOnDemand = DoesConnectOnDemand();
753 info->doesAutoReconnect = DoesAutoReconnect();
754 info->hasDevice = Device();
755 info->isMultilink = IsMultilink();
756 info->hasParent = Parent();
757 break;
758 }
759
760 case PPPC_SET_USERNAME:
761 {
762 if (!data)
763 return B_ERROR;
764
765 MutexLocker locker(fLock);
766 // login information can only be changed before we authenticate
767 if (Phase() >= PPP_AUTHENTICATION_PHASE)
768 return B_NOT_ALLOWED;
769
770 free(fUsername);
771 fUsername = data ? strdup((const char*) data) : strdup("");
772 break;
773 }
774
775 case PPPC_SET_PASSWORD:
776 {
777 if (!data)
778 return B_ERROR;
779
780 MutexLocker locker(fLock);
781 // login information can only be changed before we authenticate
782 if (Phase() >= PPP_AUTHENTICATION_PHASE)
783 return B_NOT_ALLOWED;
784
785 free(fPassword);
786 fPassword = data ? strdup((const char*) data) : strdup("");
787 break;
788 }
789
790 case PPPC_SET_ASK_BEFORE_CONNECTING:
791 if (length < sizeof(uint32) || !data)
792 return B_ERROR;
793
794 SetAskBeforeConnecting(*((uint32*)data));
795 break;
796
797 case PPPC_SET_MRU:
798 if (length < sizeof(uint32) || !data)
799 return B_ERROR;
800
801 SetMRU(*((uint32*)data));
802 break;
803
804 case PPPC_SET_CONNECT_ON_DEMAND:
805 if (length < sizeof(uint32) || !data)
806 return B_ERROR;
807
808 SetConnectOnDemand(*((uint32*)data));
809 break;
810
811 case PPPC_SET_AUTO_RECONNECT:
812 if (length < sizeof(uint32) || !data)
813 return B_ERROR;
814
815 SetAutoReconnect(*((uint32*)data));
816 break;
817
818 case PPPC_HAS_INTERFACE_SETTINGS:
819 if (length < sizeof(driver_settings) || !data)
820 return B_ERROR;
821
822 if (equal_interface_settings(Settings(), (driver_settings*) data))
823 return B_OK;
824 else
825 return B_ERROR;
826 break;
827
828 case PPPC_ENABLE_REPORTS:
829 {
830 if (length < sizeof(ppp_report_request) || !data)
831 return B_ERROR;
832
833 MutexLocker locker(fLock);
834 ppp_report_request *request = (ppp_report_request*) data;
835 // first, we send an initial state report
836 if (request->type == PPP_CONNECTION_REPORT) {
837 ppp_report_packet report;
838 report.type = PPP_CONNECTION_REPORT;
839 report.code = StateMachine().fLastConnectionReportCode;
840 report.length = sizeof(fID);
841 KPPPReportManager::SendReport(request->thread, &report);
842 if (request->flags & PPP_REMOVE_AFTER_REPORT)
843 return B_OK;
844 }
845 ReportManager().EnableReports(request->type, request->thread,
846 request->flags);
847 break;
848 }
849
850 case PPPC_DISABLE_REPORTS:
851 {
852 if (length < sizeof(ppp_report_request) || !data)
853 return B_ERROR;
854
855 ppp_report_request *request = (ppp_report_request*) data;
856 ReportManager().DisableReports(request->type, request->thread);
857 break;
858 }
859
860 case PPPC_GET_STATISTICS:
861 if (length < sizeof(ppp_statistics) || !data)
862 return B_ERROR;
863
864 memcpy(data, &fStatistics, sizeof(ppp_statistics));
865 break;
866
867 case PPPC_CONTROL_DEVICE:
868 {
869 if (length < sizeof(ppp_control_info) || !data)
870 return B_ERROR;
871
872 ppp_control_info *control = (ppp_control_info*) data;
873 if (control->index != 0 || !Device())
874 return B_BAD_INDEX;
875
876 return Device()->Control(control->op, control->data, control->length);
877 }
878
879 case PPPC_CONTROL_PROTOCOL:
880 {
881 if (length < sizeof(ppp_control_info) || !data)
882 return B_ERROR;
883
884 ppp_control_info *control = (ppp_control_info*) data;
885 KPPPProtocol *protocol = ProtocolAt(control->index);
886 if (!protocol)
887 return B_BAD_INDEX;
888
889 return protocol->Control(control->op, control->data, control->length);
890 }
891
892 case PPPC_CONTROL_OPTION_HANDLER:
893 {
894 if (length < sizeof(ppp_control_info) || !data)
895 return B_ERROR;
896
897 ppp_control_info *control = (ppp_control_info*) data;
898 KPPPOptionHandler *optionHandler = LCP().OptionHandlerAt(control->index);
899 if (!optionHandler)
900 return B_BAD_INDEX;
901
902 return optionHandler->Control(control->op, control->data,
903 control->length);
904 }
905
906 case PPPC_CONTROL_LCP_EXTENSION:
907 {
908 if (length < sizeof(ppp_control_info) || !data)
909 return B_ERROR;
910
911 ppp_control_info *control = (ppp_control_info*) data;
912 KPPPLCPExtension *lcpExtension = LCP().LCPExtensionAt(control->index);
913 if (!lcpExtension)
914 return B_BAD_INDEX;
915
916 return lcpExtension->Control(control->op, control->data,
917 control->length);
918 }
919
920 case PPPC_CONTROL_CHILD:
921 {
922 if (length < sizeof(ppp_control_info) || !data)
923 return B_ERROR;
924
925 ppp_control_info *control = (ppp_control_info*) data;
926 KPPPInterface *child = ChildAt(control->index);
927 if (!child)
928 return B_BAD_INDEX;
929
930 return child->Control(control->op, control->data, control->length);
931 }
932
933 default:
934 dprintf("bad ppp_interface_control!\n");
935 return B_BAD_VALUE;
936 }
937
938 return B_OK;
939 }
940
941
942 /*! \brief Sets a new device for this interface.
943
944 A device add-on should call this method to register itself. The best place to do
945 this is in your module's \c add_to() function.
946
947 \param device The device object.
948
949 \return \c true if successful or \c false otherwise.
950
951 \sa KPPPDevice
952 \sa kppp_module_info
953 */
954 bool
SetDevice(KPPPDevice * device)955 KPPPInterface::SetDevice(KPPPDevice *device)
956 {
957 TRACE("KPPPInterface: SetDevice(%p)\n", device);
958
959 if (device && &device->Interface() != this)
960 return false;
961
962 if (IsMultilink() && !Parent())
963 return false;
964 // main interfaces do not have devices
965
966 MutexLocker locker(fLock);
967
968 if (Phase() != PPP_DOWN_PHASE)
969 return false;
970 // a running connection may not change
971
972 if (fDevice && (IsUp() || fDevice->IsUp()))
973 Down();
974
975 fDevice = device;
976 SetNext(device);
977
978 if (fDevice)
979 fMRU = fDevice->MTU() - 2;
980
981 CalculateInterfaceMTU();
982 CalculateBaudRate();
983
984 return true;
985 }
986
987
988 /*! \brief Adds a new protocol to this interface.
989
990 NOTE: You can only add protocols in \c PPP_DOWN_PHASE. \n
991 A protocol add-on should call this method to register itself. The best place to do
992 this is in your module's \c add_to() function.
993
994 \param protocol The protocol object.
995
996 \return \c true if successful or \c false otherwise.
997
998 \sa KPPPProtocol
999 \sa kppp_module_info
1000 */
1001 bool
AddProtocol(KPPPProtocol * protocol)1002 KPPPInterface::AddProtocol(KPPPProtocol *protocol)
1003 {
1004 // Find insert position after the last protocol
1005 // with the same level.
1006
1007 TRACE("KPPPInterface: AddProtocol(%X)\n",
1008 protocol ? protocol->ProtocolNumber() : 0);
1009
1010 if (!protocol || &protocol->Interface() != this
1011 || protocol->Level() == PPP_INTERFACE_LEVEL)
1012 return false;
1013
1014 MutexLocker locker(fLock);
1015
1016 if (Phase() != PPP_DOWN_PHASE)
1017 return false;
1018 // a running connection may not change
1019
1020 KPPPProtocol *current = fFirstProtocol, *previous = NULL;
1021
1022 while (current) {
1023 if (current->Level() < protocol->Level())
1024 break;
1025
1026 previous = current;
1027 current = current->NextProtocol();
1028 }
1029
1030 if (!current) {
1031 if (!previous)
1032 fFirstProtocol = protocol;
1033 else
1034 previous->SetNextProtocol(protocol);
1035
1036 // set up the last protocol in the chain
1037 protocol->SetNextProtocol(NULL);
1038 // this also sets next to NULL
1039 protocol->SetNext(this);
1040 // we need to set us as the next layer for the last protocol
1041 } else {
1042 protocol->SetNextProtocol(current);
1043
1044 if (!previous)
1045 fFirstProtocol = protocol;
1046 else
1047 previous->SetNextProtocol(protocol);
1048 }
1049
1050 if (protocol->Level() < PPP_PROTOCOL_LEVEL)
1051 CalculateInterfaceMTU();
1052
1053 if (IsUp() || Phase() >= protocol->ActivationPhase())
1054 protocol->Up();
1055
1056 return true;
1057 }
1058
1059
1060 /*! \brief Removes a protocol from this interface.
1061
1062 NOTE: You can only remove protocols in \c PPP_DOWN_PHASE. \n
1063 A protocol add-on should call this method to remove itself explicitly from the
1064 interface. \n
1065 Normally, this method is called in KPPPProtocol's destructor. Do not call it
1066 yourself unless you know what you do!
1067
1068 \param protocol The protocol object.
1069
1070 \return \c true if successful or \c false otherwise.
1071 */
1072 bool
RemoveProtocol(KPPPProtocol * protocol)1073 KPPPInterface::RemoveProtocol(KPPPProtocol *protocol)
1074 {
1075 TRACE("KPPPInterface: RemoveProtocol(%X)\n",
1076 protocol ? protocol->ProtocolNumber() : 0);
1077
1078 MutexLocker locker(fLock);
1079
1080 if (Phase() != PPP_DOWN_PHASE)
1081 return false;
1082 // a running connection may not change
1083
1084 KPPPProtocol *current = fFirstProtocol, *previous = NULL;
1085
1086 while (current) {
1087 if (current == protocol) {
1088 if (!protocol->IsDown())
1089 protocol->Down();
1090
1091 if (previous) {
1092 previous->SetNextProtocol(current->NextProtocol());
1093
1094 // set us as next layer if needed
1095 if (!previous->Next())
1096 previous->SetNext(this);
1097 } else
1098 fFirstProtocol = current->NextProtocol();
1099
1100 current->SetNextProtocol(NULL);
1101
1102 CalculateInterfaceMTU();
1103
1104 return true;
1105 }
1106
1107 previous = current;
1108 current = current->NextProtocol();
1109 }
1110
1111 return false;
1112 }
1113
1114
1115 //! Returns the number of protocol modules belonging to this interface.
1116 int32
CountProtocols() const1117 KPPPInterface::CountProtocols() const
1118 {
1119 MutexLocker locker(fLock);
1120
1121 KPPPProtocol *protocol = FirstProtocol();
1122
1123 int32 count = 0;
1124 for (; protocol; protocol = protocol->NextProtocol())
1125 ++count;
1126
1127 return count;
1128 }
1129
1130
1131 //! Returns the protocol at the given \a index or \c NULL if it could not be found.
1132 KPPPProtocol*
ProtocolAt(int32 index) const1133 KPPPInterface::ProtocolAt(int32 index) const
1134 {
1135 MutexLocker locker(fLock);
1136
1137 KPPPProtocol *protocol = FirstProtocol();
1138
1139 int32 currentIndex = 0;
1140 for (; protocol && currentIndex != index; protocol = protocol->NextProtocol())
1141 ++currentIndex;
1142
1143 return protocol;
1144 }
1145
1146
1147 /*! \brief Returns the protocol object responsible for a given protocol number.
1148
1149 \param protocolNumber The protocol number that the object should handle.
1150 \param start (Optional): Start with this protocol. Can be used for iteration.
1151
1152 \return Either the object that was found or \c NULL.
1153 */
1154 KPPPProtocol*
ProtocolFor(uint16 protocolNumber,KPPPProtocol * start) const1155 KPPPInterface::ProtocolFor(uint16 protocolNumber, KPPPProtocol *start) const
1156 {
1157 TRACE("KPPPInterface: ProtocolFor(%X)\n", protocolNumber);
1158
1159 // MutexLocker locker(fLock);
1160 // already locked in ::Receive, uncomment this line will cause double lock
1161
1162 KPPPProtocol *current = start ? start : FirstProtocol();
1163
1164 for (; current; current = current->NextProtocol()) {
1165 if (current->ProtocolNumber() == protocolNumber
1166 || (current->Flags() & PPP_INCLUDES_NCP
1167 && (current->ProtocolNumber() & 0x7FFF)
1168 == (protocolNumber & 0x7FFF)))
1169 return current;
1170 }
1171
1172 return NULL;
1173 }
1174
1175
1176 //! Adds a new child interface (used for multilink interfaces).
1177 bool
AddChild(KPPPInterface * child)1178 KPPPInterface::AddChild(KPPPInterface *child)
1179 {
1180 TRACE("KPPPInterface: AddChild(%lX)\n", child ? child->ID() : 0);
1181
1182 if (!child)
1183 return false;
1184
1185 MutexLocker locker(fLock);
1186
1187 if (fChildren.HasItem(child) || !fChildren.AddItem(child))
1188 return false;
1189
1190 child->SetParent(this);
1191
1192 return true;
1193 }
1194
1195
1196 //! Removes a new child from this interface (used for multilink interfaces).
1197 bool
RemoveChild(KPPPInterface * child)1198 KPPPInterface::RemoveChild(KPPPInterface *child)
1199 {
1200 TRACE("KPPPInterface: RemoveChild(%lX)\n", child ? child->ID() : 0);
1201
1202 MutexLocker locker(fLock);
1203
1204 if (!fChildren.RemoveItem(child))
1205 return false;
1206
1207 child->SetParent(NULL);
1208
1209 // parents cannot exist without their children
1210 if (CountChildren() == 0 && fManager && Ifnet())
1211 Delete();
1212
1213 return true;
1214 }
1215
1216
1217 //! Returns the child interface at the given \a index (used for multilink interfaces).
1218 KPPPInterface*
ChildAt(int32 index) const1219 KPPPInterface::ChildAt(int32 index) const
1220 {
1221 TRACE("KPPPInterface: ChildAt(%ld)\n", index);
1222
1223 MutexLocker locker(fLock);
1224
1225 KPPPInterface *child = fChildren.ItemAt(index);
1226
1227 if (child == fChildren.GetDefaultItem())
1228 return NULL;
1229
1230 return child;
1231 }
1232
1233
1234 //! Enables or disables the auto-reconnect feture.
1235 void
SetAutoReconnect(bool autoReconnect)1236 KPPPInterface::SetAutoReconnect(bool autoReconnect)
1237 {
1238 TRACE("KPPPInterface: SetAutoReconnect(%s)\n", autoReconnect ? "true" : "false");
1239
1240 if (Mode() != PPP_CLIENT_MODE)
1241 return;
1242
1243 fAutoReconnect = autoReconnect;
1244 }
1245
1246
1247 //! Enables or disables the connect-on-demand feature.
1248 void
SetConnectOnDemand(bool connectOnDemand)1249 KPPPInterface::SetConnectOnDemand(bool connectOnDemand)
1250 {
1251 // All protocols must check if ConnectOnDemand was enabled/disabled after this
1252 // interface went down. This is the only situation where a change is relevant.
1253
1254 TRACE("KPPPInterface: SetConnectOnDemand(%s)\n", connectOnDemand ? "true" : "false");
1255
1256 MutexLocker locker(fLock);
1257
1258 // Only clients support ConnectOnDemand.
1259 if (Mode() != PPP_CLIENT_MODE) {
1260 TRACE("KPPPInterface::SetConnectOnDemand(): Wrong mode!\n");
1261 fConnectOnDemand = false;
1262 return;
1263 } else if (DoesConnectOnDemand() == connectOnDemand)
1264 return;
1265
1266 fConnectOnDemand = connectOnDemand;
1267
1268 // Do not allow changes when we are disconnected (only main interfaces).
1269 // This would make no sense because
1270 // - enabling: this cannot happen because hidden interfaces are deleted if they
1271 // could not establish a connection (the user cannot access hidden interfaces)
1272 // - disabling: the interface disappears as seen from the user, so we delete it
1273 if (!Parent() && State() == PPP_INITIAL_STATE && Phase() == PPP_DOWN_PHASE) {
1274 if (!connectOnDemand)
1275 Delete();
1276 // as long as the protocols were not configured we can just delete us
1277
1278 return;
1279 }
1280
1281 // check if we need to set/unset flags
1282 if (connectOnDemand) {
1283 if (Ifnet())
1284 Ifnet()->flags |= IFF_UP;
1285 } else if (!connectOnDemand && Phase() < PPP_ESTABLISHED_PHASE) {
1286 if (Ifnet())
1287 Ifnet()->flags &= ~IFF_UP;
1288 }
1289 }
1290
1291
1292 //! Sets whether the user is asked before establishing the connection.
1293 void
SetAskBeforeConnecting(bool ask)1294 KPPPInterface::SetAskBeforeConnecting(bool ask)
1295 {
1296 MutexLocker locker(fLock);
1297
1298 bool old = fAskBeforeConnecting;
1299 fAskBeforeConnecting = ask;
1300
1301 if (old && fAskBeforeConnecting == false && State() == PPP_STARTING_STATE
1302 && Phase() == PPP_DOWN_PHASE) {
1303 // locker.Unlock();
1304 StateMachine().ContinueOpenEvent();
1305 }
1306 }
1307
1308
1309 //! Sets Protocol-Field-Compression options.
1310 bool
SetPFCOptions(uint8 pfcOptions)1311 KPPPInterface::SetPFCOptions(uint8 pfcOptions)
1312 {
1313 TRACE("KPPPInterface: SetPFCOptions(0x%X)\n", pfcOptions);
1314
1315 MutexLocker locker(fLock);
1316
1317 if (PFCOptions() & PPP_FREEZE_PFC_OPTIONS)
1318 return false;
1319
1320 fPFCOptions = pfcOptions;
1321 return true;
1322 }
1323
1324
1325 /*! \brief Brings this interface up.
1326
1327 \c Down() overrides all \c Up() requests. \n
1328 This method runs an asynchronous process (it returns immediately).
1329
1330 \return \c false on error.
1331 */
1332 bool
Up()1333 KPPPInterface::Up()
1334 {
1335 TRACE("KPPPInterface: Up()\n");
1336
1337 if (InitCheck() != B_OK || Phase() == PPP_TERMINATION_PHASE)
1338 return false;
1339
1340 if (IsUp())
1341 return true;
1342
1343 MutexLocker locker(fLock);
1344 StateMachine().OpenEvent();
1345
1346 return true;
1347 }
1348
1349
1350 /*! \brief Brings this interface down.
1351
1352 \c Down() overrides all \c Up() requests. \n
1353 This method runs an asynchronous process (it returns immediately).
1354
1355 \return \c false on error.
1356 */
1357 bool
Down()1358 KPPPInterface::Down()
1359 {
1360 TRACE("KPPPInterface: Down()\n");
1361
1362 if (InitCheck() != B_OK)
1363 return false;
1364 else if (State() == PPP_INITIAL_STATE && Phase() == PPP_DOWN_PHASE)
1365 return true;
1366
1367 send_data_with_timeout(fReconnectThread, 0, NULL, 0, 200);
1368 // tell the reconnect thread to abort its attempt (if it's still waiting)
1369
1370 MutexLocker locker(fLock);
1371 StateMachine().CloseEvent();
1372
1373 return true;
1374 }
1375
1376
1377 //! Waits for connection establishment. Returns true if successful.
1378 bool
WaitForConnection()1379 KPPPInterface::WaitForConnection()
1380 {
1381 TRACE("KPPPInterface: WaitForConnection()\n");
1382
1383 if (InitCheck() != B_OK)
1384 return false;
1385
1386 // just delay ~3 seconds to wait for ppp go up
1387 for (uint32 i = 0; i < 10000; i++)
1388 for (uint32 j = 0; j < 3000000; j++)
1389
1390 return true; // for temporary
1391
1392 ReportManager().EnableReports(PPP_CONNECTION_REPORT, find_thread(NULL));
1393
1394 ppp_report_packet report;
1395 thread_id sender;
1396 bool successful = false;
1397 while (true) {
1398 if (receive_data(&sender, &report, sizeof(report)) != PPP_REPORT_CODE)
1399 continue;
1400
1401 if (report.type == PPP_DESTRUCTION_REPORT)
1402 break;
1403 else if (report.type != PPP_CONNECTION_REPORT)
1404 continue;
1405
1406 if (report.code == PPP_REPORT_UP_SUCCESSFUL) {
1407 successful = true;
1408 break;
1409 } else if (report.code == PPP_REPORT_DOWN_SUCCESSFUL)
1410 break;
1411 }
1412
1413 ReportManager().DisableReports(PPP_CONNECTION_REPORT, find_thread(NULL));
1414 dprintf("KPPPInterface: WaitForConnection():%s\n", successful ? "True" : "False");
1415 return successful;
1416 }
1417
1418
1419 /*! \brief Loads modules specified in the settings structure.
1420
1421 \param settings PPP interface description file format settings.
1422 \param start Index of driver_parameter to start with.
1423 \param count Number of driver_parameters to look at.
1424
1425 \return \c true if successful or \c false otherwise.
1426 */
1427 bool
LoadModules(driver_settings * settings,int32 start,int32 count)1428 KPPPInterface::LoadModules(driver_settings *settings, int32 start, int32 count)
1429 {
1430 TRACE("KPPPInterface: LoadModules()\n");
1431
1432 if (Phase() != PPP_DOWN_PHASE)
1433 return false;
1434 // a running connection may not change
1435
1436 ppp_module_key_type type;
1437 // which type key was used for loading this module?
1438
1439 const char *name = NULL;
1440
1441 // multilink handling
1442 for (int32 index = start;
1443 index < settings->parameter_count && index < (start + count); index++) {
1444 if (!strcasecmp(settings->parameters[index].name, PPP_MULTILINK_KEY)
1445 && settings->parameters[index].value_count > 0) {
1446 if (!LoadModule(settings->parameters[index].values[0],
1447 &settings->parameters[index], PPP_MULTILINK_KEY_TYPE))
1448 return false;
1449 break;
1450 }
1451 }
1452
1453 // are we a multilink main interface?
1454 if (IsMultilink() && !Parent()) {
1455 // main interfaces only load the multilink module
1456 // and create a child using their settings
1457 fManager->CreateInterface(settings, ID());
1458 return true;
1459 }
1460
1461 for (int32 index = start;
1462 index < settings->parameter_count && index < start + count; index++) {
1463 type = PPP_UNDEFINED_KEY_TYPE;
1464
1465 name = settings->parameters[index].name;
1466
1467 if (!strcasecmp(name, PPP_LOAD_MODULE_KEY))
1468 type = PPP_LOAD_MODULE_KEY_TYPE;
1469 else if (!strcasecmp(name, PPP_DEVICE_KEY))
1470 type = PPP_DEVICE_KEY_TYPE;
1471 else if (!strcasecmp(name, PPP_PROTOCOL_KEY))
1472 type = PPP_PROTOCOL_KEY_TYPE;
1473 else if (!strcasecmp(name, PPP_AUTHENTICATOR_KEY))
1474 type = PPP_AUTHENTICATOR_KEY_TYPE;
1475
1476 if (type >= 0)
1477 for (int32 value_id = 0; value_id < settings->parameters[index].value_count;
1478 value_id++)
1479 if (!LoadModule(settings->parameters[index].values[value_id],
1480 &settings->parameters[index], type))
1481 return false;
1482 }
1483
1484 return true;
1485 }
1486
1487
1488 /*! \brief Loads a specific module.
1489
1490 \param name Name of the module.
1491 \param parameter Module settings.
1492 \param type Type of module.
1493
1494 \return \c true if successful or \c false otherwise.
1495 */
1496 bool
LoadModule(const char * name,driver_parameter * parameter,ppp_module_key_type type)1497 KPPPInterface::LoadModule(const char *name, driver_parameter *parameter,
1498 ppp_module_key_type type)
1499 {
1500 TRACE("KPPPInterface: LoadModule(%s)\n", name ? name : "XXX: NO NAME");
1501
1502 if (Phase() != PPP_DOWN_PHASE)
1503 return false;
1504 // a running connection may not change
1505
1506 if (!name || strlen(name) > B_FILE_NAME_LENGTH)
1507 return false;
1508
1509 char *moduleName = new char[B_PATH_NAME_LENGTH];
1510
1511 sprintf(moduleName, "%s/%s", PPP_MODULES_PATH, name);
1512
1513 ppp_module_info *module;
1514 if (get_module(moduleName, (module_info**) &module) != B_OK) {
1515 delete[] moduleName;
1516 return false;
1517 }
1518
1519 // add the module to the list of loaded modules
1520 // for putting them on our destruction
1521 fModules.AddItem(moduleName);
1522
1523 return module->add_to(Parent() ? *Parent() : *this, this, parameter, type);
1524 }
1525
1526
1527 //! Always returns true.
1528 bool
IsAllowedToSend() const1529 KPPPInterface::IsAllowedToSend() const
1530 {
1531 return true;
1532 }
1533
1534
1535 /*! \brief Sends a packet to the device.
1536
1537 This brings the interface up if connect-on-demand is enabled and we are not
1538 connected. \n
1539 PFC encoding is handled here. \n
1540 NOTE: In order to prevent interface destruction while sending you must either
1541 hold a refcount for this interface or make sure it is locked.
1542
1543 \param packet The packet.
1544 \param protocolNumber The packet's protocol number.
1545
1546 \return
1547 - \c B_OK: Sending was successful.
1548 - \c B_ERROR: Some error occured.
1549 */
1550 status_t
Send(net_buffer * packet,uint16 protocolNumber)1551 KPPPInterface::Send(net_buffer *packet, uint16 protocolNumber)
1552 {
1553 TRACE("KPPPInterface: Send(0x%X)\n", protocolNumber);
1554
1555 if (!packet)
1556 return B_ERROR;
1557
1558 // we must pass the basic tests like:
1559 // do we have a device?
1560 // did we load all modules?
1561 if (InitCheck() != B_OK) {
1562 ERROR("InitCheck() fail\n");
1563 gBufferModule->free(packet);
1564 return B_ERROR;
1565 }
1566
1567
1568 // go up if ConnectOnDemand is enabled and we are disconnected
1569 // TODO: our new netstack will simplify ConnectOnDemand handling, so
1570 // we do not have to handle it here
1571 if ((protocolNumber != PPP_LCP_PROTOCOL && DoesConnectOnDemand()
1572 && (Phase() == PPP_DOWN_PHASE
1573 || Phase() == PPP_ESTABLISHMENT_PHASE)
1574 && !Up()) && !WaitForConnection()) {
1575 dprintf("DoesConnectOnDemand fail!\n");
1576 // gBufferModule->free(packet);
1577 return B_ERROR;
1578 }
1579
1580 // find the protocol handler for the current protocol number
1581 KPPPProtocol *protocol = ProtocolFor(protocolNumber);
1582 while (protocol && !protocol->IsEnabled())
1583 protocol = protocol->NextProtocol() ?
1584 ProtocolFor(protocolNumber, protocol->NextProtocol()) : NULL;
1585
1586 #if DEBUG
1587 if (!protocol)
1588 TRACE("KPPPInterface::Send(): no protocol found!\n");
1589 else if (!Device()->IsUp())
1590 TRACE("KPPPInterface::Send(): device is not up!\n");
1591 else if (!protocol->IsEnabled())
1592 TRACE("KPPPInterface::Send(): protocol not enabled!\n");
1593 else if (!IsProtocolAllowed(*protocol))
1594 TRACE("KPPPInterface::Send(): protocol not allowed to send!\n");
1595 else
1596 TRACE("KPPPInterface::Send(): protocol allowed\n");
1597 #endif
1598
1599 // make sure that protocol is allowed to send and everything is up
1600 if (Device()->IsUp() && protocolNumber == 0x0021) {
1601 // IP_PROTOCOL 0x0021
1602 TRACE("send IP packet!\n");
1603 } else if (!Device()->IsUp() || !protocol || !protocol->IsEnabled()
1604 || !IsProtocolAllowed(*protocol)) {
1605 ERROR("KPPPInterface::Send(): Device is down, throw packet away!!\n");
1606 // gBufferModule->free(packet);
1607 return B_ERROR;
1608 }
1609
1610 // encode in ppp frame and consider using PFC
1611 if (UseLocalPFC() && (protocolNumber & 0xFF00) == 0) {
1612 TRACE("%s::%s should not go here\n", __FILE__, __func__);
1613 NetBufferPrepend<uint8> bufferHeader(packet);
1614 if (bufferHeader.Status() != B_OK)
1615 return bufferHeader.Status();
1616
1617 uint8 &header = bufferHeader.Data();
1618
1619 // memcpy(header.destination, ether_pppoe_ppp_header, 1);
1620 header = (protocolNumber & 0x00FF);
1621 // bufferHeader.Sync();
1622
1623 } else {
1624 NetBufferPrepend<uint16> bufferHeader(packet);
1625 if (bufferHeader.Status() != B_OK)
1626 return bufferHeader.Status();
1627
1628 uint16 &header = bufferHeader.Data();
1629
1630 // set protocol (the only header field)
1631 header = htons(protocolNumber);
1632 // bufferHeader.Sync();
1633 }
1634
1635 // pass to device if we're either not a multilink interface or a child interface
1636 if (!IsMultilink() || Parent()) {
1637 // check if packet is too big for device
1638 uint32 length = packet->size;
1639
1640 if (length > MRU()) {
1641 dprintf("packet too large!\n");
1642 gBufferModule->free(packet);
1643 return B_ERROR;
1644 }
1645
1646 atomic_add64(&fStatistics.bytesSent, length);
1647 atomic_add64(&fStatistics.packetsSent, 1);
1648 TRACE("%s::%s SendToNext\n", __FILE__, __func__);
1649 return SendToNext(packet, 0);
1650 // this is normally the device, but there can be something inbetween
1651 } else {
1652 // the multilink protocol should have sent it to some child interface
1653 TRACE("It is weird to go here!\n");
1654 gBufferModule->free(packet);
1655 return B_ERROR;
1656 }
1657 }
1658
1659
1660 /*! \brief Receives a packet.
1661
1662 Encapsulation protocols may use this method to pass encapsulated packets to the
1663 PPP interface. Packets will be handled as if they were raw packets that came
1664 directly from the device via \c ReceiveFromDevice(). \n
1665 If no handler could be found in this interface the parent's \c Receive() method
1666 is called.
1667
1668 \param packet The packet.
1669 \param protocolNumber The packet's protocol number.
1670
1671 \return
1672 - \c B_OK: Receiving was successful.
1673 - \c B_ERROR: Some error occured.
1674 - \c PPP_REJECTED: No protocol handler could be found for this packet.
1675 - \c PPP_DISCARDED: The protocol handler(s) did not handle this packet.
1676 */
1677 status_t
Receive(net_buffer * packet,uint16 protocolNumber)1678 KPPPInterface::Receive(net_buffer *packet, uint16 protocolNumber)
1679 {
1680 TRACE("KPPPInterface: Receive(0x%X)\n", protocolNumber);
1681
1682 if (!packet)
1683 return B_ERROR;
1684
1685 MutexLocker locker(fLock);
1686
1687 int32 result = PPP_REJECTED;
1688 // assume we have no handler
1689
1690 if (protocolNumber == 0x0021 && Device() && Device()->IsUp()) {
1691 // IP_PROTOCOL 0x0021
1692 TRACE("%s::%s: receiving IP packet\n", __FILE__, __func__);
1693 ppp_device* dev=(ppp_device*)Ifnet();
1694
1695 if (dev)
1696 return gStackModule->fifo_enqueue_buffer(&(dev->ppp_fifo), packet);
1697 else {
1698 dprintf("%s::%s: no ppp_device\n", __FILE__, __func__);
1699 return B_ERROR;
1700 }
1701 }
1702 // // Set our interface as the receiver.
1703 // // The real netstack protocols (IP, IPX, etc.) might get confused if our
1704 // // interface is a main interface and at the same time not registered
1705 // // because then there is no receiver interface.
1706 // // PPP NCPs should be aware of that!
1707 // if (packet->m_flags & M_PKTHDR && Ifnet() != NULL)
1708 // packet->m_pkthdr.rcvif = Ifnet();
1709
1710 // Find handler and let it parse the packet.
1711 // The handler does need not be up because if we are a server
1712 // the handler might be upped by this packet.
1713 // If authenticating we only allow authentication phase protocols.
1714 KPPPProtocol *protocol = ProtocolFor(protocolNumber);
1715 for (; protocol;
1716 protocol = protocol->NextProtocol() ?
1717 ProtocolFor(protocolNumber, protocol->NextProtocol()) : NULL) {
1718 TRACE("KPPPInterface::Receive(): trying protocol\n");
1719
1720 if (!protocol->IsEnabled() || !IsProtocolAllowed(*protocol))
1721 continue;
1722 // skip handler if disabled or not allowed
1723
1724 result = protocol->Receive(packet, protocolNumber);
1725 if (result == PPP_UNHANDLED)
1726 continue;
1727
1728 return result;
1729 }
1730
1731 TRACE("KPPPInterface::Receive(): trying parent\n");
1732
1733 // maybe the parent interface can handle the packet
1734 if (Parent())
1735 return Parent()->Receive(packet, protocolNumber);
1736
1737 if (result == PPP_UNHANDLED) {
1738 gBufferModule->free(packet);
1739 return PPP_DISCARDED;
1740 } else {
1741 StateMachine().RUCEvent(packet, protocolNumber);
1742 return PPP_REJECTED;
1743 }
1744 }
1745
1746
1747 /*! \brief Receives a base PPP packet from the device.
1748
1749 KPPPDevice should call this method when it receives a packet. \n
1750 PFC decoding is handled here.
1751
1752 \param packet The packet.
1753
1754 \return
1755 - \c B_OK: Receiving was successful.
1756 - \c B_ERROR: Some error occured.
1757 - \c PPP_REJECTED: No protocol handler could be found for this packet.
1758 - \c PPP_DISCARDED: The protocol handler(s) did not handle this packet.
1759 */
1760 status_t
ReceiveFromDevice(net_buffer * packet)1761 KPPPInterface::ReceiveFromDevice(net_buffer *packet)
1762 {
1763 TRACE("KPPPInterface: ReceiveFromDevice()\n");
1764
1765 if (!packet)
1766 return B_ERROR;
1767
1768 if (InitCheck() != B_OK) {
1769 gBufferModule->free(packet);
1770 return B_ERROR;
1771 }
1772
1773 uint32 length = packet->size;
1774 // decode ppp frame and recognize PFC
1775 NetBufferHeaderReader<uint16> bufferHeader(packet);
1776 if (bufferHeader.Status() < B_OK)
1777 return bufferHeader.Status();
1778
1779 uint16 &header = bufferHeader.Data();
1780 uint16 protocolNumber = ntohs(header); // copy the protocol number
1781 TRACE("%s::%s: ppp protocol number:%x\n", __FILE__, __func__, protocolNumber);
1782
1783 bufferHeader.Remove();
1784 bufferHeader.Sync();
1785
1786 // PFC only use 1 byte for protocol, the next byte is in first byte of message
1787 if (protocolNumber & (1UL<<8)) {
1788 NetBufferPrepend<uint8> bufferprepend(packet);
1789 if (bufferprepend.Status() < B_OK) {
1790 gBufferModule->free(packet);
1791 return bufferprepend.Status();
1792 }
1793
1794 uint8 &prepend = bufferprepend.Data();
1795 prepend = (uint8)(protocolNumber & 0x00FF);
1796 // bufferprepend.Sync();
1797 TRACE("%s::%s:PFC protocol:%x\n", __FILE__, __func__, protocolNumber>>8);
1798 } else {
1799 TRACE("%s::%s:Non-PFC protocol:%x\n", __FILE__, __func__, protocolNumber);
1800 }
1801
1802 atomic_add64(&fStatistics.bytesReceived, length);
1803 atomic_add64(&fStatistics.packetsReceived, 1);
1804 return Receive(packet, protocolNumber);
1805 }
1806
1807
1808 //! Manages Pulse() calls for all add-ons and hanldes idle-disconnection.
1809 void
Pulse()1810 KPPPInterface::Pulse()
1811 {
1812 MutexLocker locker(fLock);
1813
1814 if (Device())
1815 Device()->Pulse();
1816
1817 KPPPProtocol *protocol = FirstProtocol();
1818 for (; protocol; protocol = protocol->NextProtocol())
1819 protocol->Pulse();
1820
1821 uint32 currentTime = real_time_clock();
1822 if (fUpdateIdleSince) {
1823 fIdleSince = currentTime;
1824 fUpdateIdleSince = false;
1825 }
1826
1827 // check our idle time and disconnect if needed
1828 if (fDisconnectAfterIdleSince > 0 && fIdleSince != 0
1829 && fIdleSince - currentTime >= fDisconnectAfterIdleSince)
1830 StateMachine().CloseEvent();
1831 }
1832
1833
1834 //! Registers an ifnet structure for this interface.
1835 bool
RegisterInterface()1836 KPPPInterface::RegisterInterface()
1837 {
1838 TRACE("KPPPInterface: RegisterInterface()\n");
1839
1840 if (fIfnet)
1841 return true;
1842 // we are already registered
1843
1844 MutexLocker locker(fLock);
1845
1846 // only MainInterfaces get an ifnet
1847 if (IsMultilink() && Parent() && Parent()->RegisterInterface())
1848 return true;
1849
1850 if (!fManager)
1851 return false;
1852
1853 fIfnet = fManager->RegisterInterface(ID());
1854
1855 if (!fIfnet) {
1856 dprintf("%s:%s: damn it no fIfnet device\n", __FILE__, __func__);
1857 return false;
1858 }
1859
1860 if (DoesConnectOnDemand())
1861 fIfnet->flags |= IFF_UP;
1862
1863 CalculateInterfaceMTU();
1864 CalculateBaudRate();
1865
1866 return true;
1867 }
1868
1869
1870 //! Unregisters this interface's ifnet structure.
1871 bool
UnregisterInterface()1872 KPPPInterface::UnregisterInterface()
1873 {
1874 TRACE("KPPPInterface: UnregisterInterface()\n");
1875
1876 if (!fIfnet)
1877 return true;
1878 // we are already unregistered
1879
1880 MutexLocker locker(fLock);
1881
1882 // only MainInterfaces get an ifnet
1883 if (IsMultilink() && Parent())
1884 return true;
1885
1886 if (!fManager)
1887 return false;
1888
1889 fManager->UnregisterInterface(ID());
1890 // this will delete fIfnet, so do not access it anymore!
1891 fIfnet = NULL;
1892
1893 return true;
1894 }
1895
1896
1897 //! Called by KPPPManager: manager routes stack ioctls to the corresponding interface.
1898 status_t
StackControl(uint32 op,void * data)1899 KPPPInterface::StackControl(uint32 op, void *data)
1900 {
1901 TRACE("KPPPInterface: StackControl(0x%lX)\n", op);
1902
1903 switch (op) {
1904 default:
1905 return StackControlEachHandler(op, data);
1906 }
1907
1908 return B_OK;
1909 }
1910
1911
1912 //! Utility class used by ControlEachHandler().
1913 template<class T>
1914 class CallStackControl {
1915 public:
CallStackControl(uint32 op,void * data,status_t & result)1916 inline CallStackControl(uint32 op, void *data, status_t& result)
1917 : fOp(op), fData(data), fResult(result) {}
operator ()(T * item)1918 inline void operator() (T *item)
1919 {
1920 if (!item || !item->IsEnabled())
1921 return;
1922 status_t tmp = item->StackControl(fOp, fData);
1923 if (tmp == B_OK && fResult == B_BAD_VALUE)
1924 fResult = B_OK;
1925 else if (tmp != B_BAD_VALUE)
1926 fResult = tmp;
1927 }
1928 private:
1929 uint32 fOp;
1930 void *fData;
1931 status_t& fResult;
1932 };
1933
1934 /*! \brief This calls Control() with the given parameters for each add-on.
1935
1936 \return
1937 - \c B_OK: All handlers returned B_OK.
1938 - \c B_BAD_VALUE: No handler was found.
1939 - Any other value: Error code which was returned by the last failing handler.
1940 */
1941 status_t
StackControlEachHandler(uint32 op,void * data)1942 KPPPInterface::StackControlEachHandler(uint32 op, void *data)
1943 {
1944 TRACE("KPPPInterface: StackControlEachHandler(0x%lX)\n", op);
1945
1946 status_t result = B_BAD_VALUE, tmp;
1947
1948 MutexLocker locker(fLock);
1949
1950 KPPPProtocol *protocol = FirstProtocol();
1951 for (; protocol; protocol = protocol->NextProtocol()) {
1952 tmp = protocol->StackControl(op, data);
1953 if (tmp == B_OK && result == B_BAD_VALUE)
1954 result = B_OK;
1955 else if (tmp != B_BAD_VALUE)
1956 result = tmp;
1957 }
1958
1959 ForEachItem(LCP().fLCPExtensions,
1960 CallStackControl<KPPPLCPExtension>(op, data, result));
1961 ForEachItem(LCP().fOptionHandlers,
1962 CallStackControl<KPPPOptionHandler>(op, data, result));
1963
1964 return result;
1965 }
1966
1967
1968 //! Recalculates the MTU from the MRU (includes encapsulation protocol overheads).
1969 void
CalculateInterfaceMTU()1970 KPPPInterface::CalculateInterfaceMTU()
1971 {
1972 TRACE("KPPPInterface: CalculateInterfaceMTU()\n");
1973
1974 // MutexLocker locker(fLock);
1975 // uncomment this line will cause double lock
1976 // alreay locked in ::KPPPInterface
1977
1978 fInterfaceMTU = fMRU;
1979 fHeaderLength = 2;
1980
1981 // sum all headers (the protocol field is not counted)
1982 KPPPProtocol *protocol = FirstProtocol();
1983 for (; protocol; protocol = protocol->NextProtocol()) {
1984 if (protocol->Level() < PPP_PROTOCOL_LEVEL)
1985 fHeaderLength += protocol->Overhead();
1986 }
1987
1988 fInterfaceMTU -= fHeaderLength;
1989
1990 if (Ifnet()) {
1991 Ifnet()->mtu = fInterfaceMTU;
1992 Ifnet()->header_length = fHeaderLength;
1993 return;
1994 }
1995
1996 if (Parent())
1997 Parent()->CalculateInterfaceMTU();
1998 }
1999
2000
2001 //! Recalculates the baud rate.
2002 void
CalculateBaudRate()2003 KPPPInterface::CalculateBaudRate()
2004 {
2005 TRACE("KPPPInterface: CalculateBaudRate()\n");
2006
2007 // MutexLocker locker(fLock); // uncomment this will cause double lock
2008
2009 if (!Ifnet())
2010 return;
2011
2012 if (Device())
2013 fIfnet->link_speed = max_c(Device()->InputTransferRate(),
2014 Device()->OutputTransferRate());
2015 else {
2016 fIfnet->link_speed = 0;
2017 for (int32 index = 0; index < CountChildren(); index++) {
2018 if (ChildAt(index)->Ifnet()) {
2019 fIfnet->link_speed = ChildAt(index)->Ifnet()->link_speed;
2020 return;
2021 }
2022 }
2023 }
2024 }
2025
2026
2027 //! Reconnects. Waits a given delay (in miliseconds) before reconnecting.
2028 void
Reconnect(uint32 delay)2029 KPPPInterface::Reconnect(uint32 delay)
2030 {
2031 TRACE("KPPPInterface: Reconnect(%ld)\n", delay);
2032
2033 MutexLocker locker(fLock);
2034
2035 if (fReconnectThread != -1)
2036 return;
2037
2038 ++fConnectAttempt;
2039
2040 // start a new thread that calls our Up() method
2041 reconnect_info info;
2042 info.interface = this;
2043 info.thread = &fReconnectThread;
2044 info.delay = delay;
2045
2046 fReconnectThread = spawn_kernel_thread(reconnect_thread,
2047 "KPPPInterface: reconnect_thread", B_NORMAL_PRIORITY, NULL);
2048
2049 resume_thread(fReconnectThread);
2050
2051 send_data(fReconnectThread, 0, &info, sizeof(reconnect_info));
2052 }
2053
2054
2055 status_t
reconnect_thread(void * data)2056 reconnect_thread(void *data)
2057 {
2058 reconnect_info info;
2059 thread_id sender;
2060 int32 code;
2061
2062 receive_data(&sender, &info, sizeof(reconnect_info));
2063
2064 // we try to receive data instead of snooze, so we can quit on destruction
2065 if (receive_data_with_timeout(&sender, &code, NULL, 0, info.delay) == B_OK) {
2066 *info.thread = -1;
2067 return B_OK;
2068 }
2069
2070 info.interface->Up();
2071 *info.thread = -1;
2072
2073 return B_OK;
2074 }
2075