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.
65typedef struct reconnect_info {
66	KPPPInterface *interface;
67	thread_id *thread;
68	uint32 delay;
69} reconnect_info;
70
71extern net_buffer_module_info *gBufferModule;
72extern net_stack_module_info *gStackModule;
73
74status_t reconnect_thread(void *data);
75
76// other functions
77status_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*/
88KPPPInterface::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.
245KPPPInterface::~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.
308void
309KPPPInterface::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.
328status_t
329KPPPInterface::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.
349const char*
350KPPPInterface::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.
361const char*
362KPPPInterface::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.
373bool
374KPPPInterface::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.
394uint32
395KPPPInterface::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*/
422status_t
423KPPPInterface::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*/
954bool
955KPPPInterface::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*/
1001bool
1002KPPPInterface::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*/
1072bool
1073KPPPInterface::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.
1116int32
1117KPPPInterface::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.
1132KPPPProtocol*
1133KPPPInterface::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*/
1154KPPPProtocol*
1155KPPPInterface::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).
1177bool
1178KPPPInterface::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).
1197bool
1198KPPPInterface::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).
1218KPPPInterface*
1219KPPPInterface::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.
1235void
1236KPPPInterface::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.
1248void
1249KPPPInterface::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.
1293void
1294KPPPInterface::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.
1310bool
1311KPPPInterface::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*/
1332bool
1333KPPPInterface::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*/
1357bool
1358KPPPInterface::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.
1378bool
1379KPPPInterface::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*/
1427bool
1428KPPPInterface::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*/
1496bool
1497KPPPInterface::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.
1528bool
1529KPPPInterface::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*/
1550status_t
1551KPPPInterface::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*/
1677status_t
1678KPPPInterface::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*/
1760status_t
1761KPPPInterface::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.
1809void
1810KPPPInterface::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.
1835bool
1836KPPPInterface::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.
1871bool
1872KPPPInterface::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.
1898status_t
1899KPPPInterface::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().
1913template<class T>
1914class CallStackControl {
1915	public:
1916		inline CallStackControl(uint32 op, void *data, status_t& result)
1917			: fOp(op), fData(data), fResult(result) {}
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*/
1941status_t
1942KPPPInterface::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).
1969void
1970KPPPInterface::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.
2002void
2003KPPPInterface::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.
2028void
2029KPPPInterface::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
2055status_t
2056reconnect_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