1/*
2 * Copyright 2003-2007, Waldemar Kornewald <wkornew@gmx.net>
3 * Distributed under the terms of the MIT License.
4 */
5
6/*!	\class KPPPStateMachine
7	\brief PPP state machine belonging to the LCP protocol
8
9	The state machine is responsible for handling events and state changes.
10
11	\sa KPPPLCP
12*/
13
14#include <OS.h>
15
16#include <KPPPInterface.h>
17#include <KPPPConfigurePacket.h>
18#include <KPPPDevice.h>
19#include <KPPPLCPExtension.h>
20#include <KPPPOptionHandler.h>
21
22#include <KPPPUtils.h>
23
24#include <net/if.h>
25#include <arpa/inet.h>
26
27#include <ByteOrder.h>
28#include <net_buffer.h>
29#include <NetBufferUtilities.h>
30
31extern net_buffer_module_info *gBufferModule;
32
33static const bigtime_t kPPPStateMachineTimeout = 3000000;
34	// 3 seconds
35
36
37//!	Constructor.
38KPPPStateMachine::KPPPStateMachine(KPPPInterface& interface)
39	: fInterface(interface),
40	fLCP(interface.LCP()),
41	fState(PPP_INITIAL_STATE),
42	fPhase(PPP_DOWN_PHASE),
43	fID(system_time() & 0xFF),
44	fMagicNumber(0),
45	fLastConnectionReportCode(PPP_REPORT_DOWN_SUCCESSFUL),
46	fLocalAuthenticationStatus(PPP_NOT_AUTHENTICATED),
47	fPeerAuthenticationStatus(PPP_NOT_AUTHENTICATED),
48	fLocalAuthenticationName(NULL),
49	fPeerAuthenticationName(NULL),
50	fMaxRequest(10),
51	fMaxTerminate(2),
52	fMaxNak(5),
53	fRequestID(0),
54	fTerminateID(0),
55	fEchoID(0),
56	fNextTimeout(0),
57	fLock(mutex())
58{
59	mutex_init(&fLock, "KPPPStateMachine");
60}
61
62
63//!	Destructor. Frees loaded memory.
64KPPPStateMachine::~KPPPStateMachine()
65{
66	free(fLocalAuthenticationName);
67	free(fPeerAuthenticationName);
68}
69
70
71//!	Creates an ID for the next LCP packet.
72uint8
73KPPPStateMachine::NextID()
74{
75	return (uint8) atomic_add(&fID, 1);
76}
77
78
79/*!	\brief Changes the current state.
80
81	Remember: NewState() must always be called \e after IllegalEvent() because
82	IllegalEvent() also looks at the current state.
83*/
84void
85KPPPStateMachine::NewState(ppp_state next)
86{
87	TRACE("KPPPSM: NewState(%d) state=%d\n", next, State());
88
89	// maybe we do not need the timer anymore
90	if (next < PPP_CLOSING_STATE || next == PPP_OPENED_STATE)
91		fNextTimeout = 0;
92
93	if (State() == PPP_OPENED_STATE && next != State())
94		ResetLCPHandlers();
95
96	fState = next;
97}
98
99
100/*!	\brief Changes the current phase.
101
102	This method is responsible for setting the \c if_flags and sending the
103	\c PPP_REPORT_UP_SUCCESSFUL report message.
104*/
105void
106KPPPStateMachine::NewPhase(ppp_phase next)
107{
108#if DEBUG
109	if (next <= PPP_ESTABLISHMENT_PHASE || next == PPP_ESTABLISHED_PHASE)
110		TRACE("KPPPSM: NewPhase(%d) phase=%d\n", next, Phase());
111#endif
112
113	// there is nothing after established phase and nothing before down phase
114	if (next > PPP_ESTABLISHED_PHASE)
115		next = PPP_ESTABLISHED_PHASE;
116	else if (next < PPP_DOWN_PHASE)
117		next = PPP_DOWN_PHASE;
118
119	// Report a down event to parent if we are not usable anymore.
120	// The report threads get their notification later.
121	if (Phase() == PPP_ESTABLISHED_PHASE && next != Phase()) {
122		if (Interface().Ifnet()) {
123			// Interface().Ifnet()->flags &= ~IFF_RUNNING;
124			Interface().Ifnet()->flags &= ~IFF_UP;
125		}
126
127		if (Interface().Parent())
128			Interface().Parent()->StateMachine().DownEvent(Interface());
129	}
130
131	fPhase = next;
132
133	if (Phase() == PPP_ESTABLISHED_PHASE) {
134		Interface().fConnectedSince = system_time();
135
136		if (Interface().Ifnet())
137			Interface().Ifnet()->flags |= IFF_UP;// | IFF_RUNNING;
138
139		Interface().fConnectAttempt = 0;
140			// when we Reconnect() this becomes 1 (the first connection attempt)
141		send_data_with_timeout(Interface().fReconnectThread, 0, NULL, 0, 200);
142			// abort possible reconnect attempt
143		fLastConnectionReportCode = PPP_REPORT_UP_SUCCESSFUL;
144		Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_UP_SUCCESSFUL,
145			&fInterface.fID, sizeof(ppp_interface_id));
146	}
147}
148
149
150// public actions
151
152//!	Reconfigures the state machine. This initiates a new configure request handshake.
153bool
154KPPPStateMachine::Reconfigure()
155{
156	TRACE("KPPPSM: Reconfigure() state=%d phase=%d\n", State(), Phase());
157
158	if (State() < PPP_REQ_SENT_STATE)
159		return false;
160
161	NewState(PPP_REQ_SENT_STATE);
162	NewPhase(PPP_ESTABLISHMENT_PHASE);
163		// indicates to handlers that we are reconfiguring
164
165	DownProtocols();
166	ResetLCPHandlers();
167
168	return SendConfigureRequest();
169}
170
171
172//!	Sends an echo request packet.
173bool
174KPPPStateMachine::SendEchoRequest()
175{
176	TRACE("KPPPSM: SendEchoRequest() state=%d phase=%d\n", State(), Phase());
177
178	if (State() != PPP_OPENED_STATE)
179		return false;
180
181	net_buffer *packet = gBufferModule->create(256);
182	if (packet == NULL)
183		return false;
184
185	void *data;
186	status_t status = gBufferModule->append_size(packet, 1492, &data);
187	if (status == B_OK && data == NULL) {
188		gBufferModule->free(packet);
189		return false;
190	}
191
192	// echo requests are at least eight bytes long
193	ppp_lcp_packet request;
194	request.code = PPP_ECHO_REQUEST;
195	request.id = NextID();
196	request.length = htons(8);
197	fEchoID = request.id;
198
199	memcpy(data, &request, sizeof(request));
200	memcpy(request.data, &fMagicNumber, sizeof(fMagicNumber));
201
202	status = gBufferModule->trim(packet, sizeof(request) + sizeof(fMagicNumber));
203	if (status < B_OK) {
204		gBufferModule->free(packet);
205		return false;
206	}
207
208	return LCP().Send(packet) == B_OK;
209}
210
211
212//!	Sends a discard request packet.
213bool
214KPPPStateMachine::SendDiscardRequest()
215{
216	TRACE("KPPPSM: SendDiscardRequest() state=%d phase=%d\n", State(), Phase());
217
218	net_buffer *packet = gBufferModule->create(256);
219	if (packet == NULL)
220		return false;
221
222	void *data;
223	status_t status = gBufferModule->append_size(packet, 1492, &data);
224	if (status == B_OK && data == NULL) {
225		gBufferModule->free(packet);
226		return false;
227	}
228
229		// discard requests are at least eight bytes long
230	// echo requests are at least eight bytes long
231	ppp_lcp_packet request;
232	request.code = PPP_DISCARD_REQUEST;
233	request.id = NextID();
234	request.length = htons(8);
235	fEchoID = request.id;
236
237	memcpy(data, &request, sizeof(request));
238	memcpy(request.data, &fMagicNumber, sizeof(fMagicNumber));
239
240	status = gBufferModule->trim(packet, sizeof(request) + sizeof(fMagicNumber));
241	if (status < B_OK) {
242		gBufferModule->free(packet);
243		return false;
244	}
245
246	return LCP().Send(packet) == B_OK;
247}
248
249
250// authentication events
251
252/*!	Notification that local authentication is requested.
253
254	NOTE: This must be called \e after \c KPPPProtocol::Up().
255*/
256void
257KPPPStateMachine::LocalAuthenticationRequested()
258{
259	TRACE("KPPPSM: LocalAuthenticationRequested() state=%d phase=%d\n",
260		State(), Phase());
261
262	fLastConnectionReportCode = PPP_REPORT_AUTHENTICATION_REQUESTED;
263	Interface().Report(PPP_CONNECTION_REPORT,
264		PPP_REPORT_AUTHENTICATION_REQUESTED, &fInterface.fID,
265		sizeof(ppp_interface_id));
266
267	fLocalAuthenticationStatus = PPP_AUTHENTICATING;
268	free(fLocalAuthenticationName);
269	fLocalAuthenticationName = NULL;
270}
271
272
273/*!	\brief Notification that local authentication was accepted.
274
275	NOTE: This must be called \e before \c UpEvent().
276
277	\param name The username/login that was accepted.
278*/
279void
280KPPPStateMachine::LocalAuthenticationAccepted(const char *name)
281{
282	TRACE("KPPPSM: LocalAuthenticationAccepted() state=%d phase=%d\n",
283		State(), Phase());
284
285	fLocalAuthenticationStatus = PPP_AUTHENTICATION_SUCCESSFUL;
286	free(fLocalAuthenticationName);
287	if (name)
288		fLocalAuthenticationName = strdup(name);
289	else
290		fLocalAuthenticationName = NULL;
291}
292
293
294/*!	\brief Notification that local authentication was denied.
295
296	NOTE: This must be called \e before \c UpFailedEvent().
297
298	\param name The username/login that was denied.
299*/
300void
301KPPPStateMachine::LocalAuthenticationDenied(const char *name)
302{
303	TRACE("KPPPSM: LocalAuthenticationDenied() state=%d phase=%d\n", State(), Phase());
304
305	fLocalAuthenticationStatus = PPP_AUTHENTICATION_FAILED;
306	free(fLocalAuthenticationName);
307	if (name)
308		fLocalAuthenticationName = strdup(name);
309	else
310		fLocalAuthenticationName = NULL;
311
312	// the report will be sent in DownEvent()
313}
314
315
316//!	Notification that peer authentication is requested.
317void
318KPPPStateMachine::PeerAuthenticationRequested()
319{
320	TRACE("KPPPSM: PeerAuthenticationRequested() state=%d phase=%d\n",
321		State(), Phase());
322
323	fLastConnectionReportCode = PPP_REPORT_AUTHENTICATION_REQUESTED;
324	Interface().Report(PPP_CONNECTION_REPORT,
325		PPP_REPORT_AUTHENTICATION_REQUESTED, &fInterface.fID,
326		sizeof(ppp_interface_id));
327
328	fPeerAuthenticationStatus = PPP_AUTHENTICATING;
329	free(fPeerAuthenticationName);
330	fPeerAuthenticationName = NULL;
331}
332
333
334/*!	\brief Notification that peer authentication was accepted.
335
336	NOTE: This must be called \e before \c UpEvent().
337
338	\param name The username/login that was accepted.
339*/
340void
341KPPPStateMachine::PeerAuthenticationAccepted(const char *name)
342{
343	TRACE("KPPPSM: PeerAuthenticationAccepted() state=%d phase=%d\n",
344		State(), Phase());
345
346	fPeerAuthenticationStatus = PPP_AUTHENTICATION_SUCCESSFUL;
347	free(fPeerAuthenticationName);
348	if (name)
349		fPeerAuthenticationName = strdup(name);
350	else
351		fPeerAuthenticationName = NULL;
352}
353
354
355/*!	\brief Notification that peer authentication was denied.
356
357	NOTE: This must be called \e before \c UpFailedEvent().
358
359	\param name The username/login that was denied.
360*/
361void
362KPPPStateMachine::PeerAuthenticationDenied(const char *name)
363{
364	TRACE("KPPPSM: PeerAuthenticationDenied() state=%d phase=%d\n", State(), Phase());
365
366	fPeerAuthenticationStatus = PPP_AUTHENTICATION_FAILED;
367	free(fPeerAuthenticationName);
368	if (name)
369		fPeerAuthenticationName = strdup(name);
370	else
371		fPeerAuthenticationName = NULL;
372
373	CloseEvent();
374
375	// the report will be sent in DownEvent()
376}
377
378
379//!	Notification that a child interface failed to go up.
380void
381KPPPStateMachine::UpFailedEvent(KPPPInterface& interface)
382{
383	TRACE("KPPPSM: UpFailedEvent(interface) state=%d phase=%d\n", State(), Phase());
384
385	// TODO:
386	// log that an interface did not go up
387}
388
389
390//!	Notification that a child interface went up successfully.
391void
392KPPPStateMachine::UpEvent(KPPPInterface& interface)
393{
394	TRACE("KPPPSM: UpEvent(interface) state=%d phase=%d\n", State(), Phase());
395
396	if (Phase() <= PPP_TERMINATION_PHASE) {
397		interface.StateMachine().CloseEvent();
398		return;
399	}
400
401	Interface().CalculateBaudRate();
402
403	if (Phase() == PPP_ESTABLISHMENT_PHASE) {
404		// this is the first interface that went up
405		Interface().SetMRU(interface.MRU());
406		ThisLayerUp();
407	} else if (Interface().MRU() > interface.MRU())
408		Interface().SetMRU(interface.MRU());
409			// MRU should always be the smallest value of all children
410
411	NewState(PPP_OPENED_STATE);
412}
413
414
415//!	Notification that a child interface went down.
416void
417KPPPStateMachine::DownEvent(KPPPInterface& interface)
418{
419	TRACE("KPPPSM: DownEvent(interface) state=%d phase=%d\n", State(), Phase());
420
421	uint32 MRU = 0;
422		// the new MRU
423
424	Interface().CalculateBaudRate();
425
426	// when all children are down we should not be running
427	if (Interface().IsMultilink() && !Interface().Parent()) {
428		uint32 count = 0;
429		KPPPInterface *child;
430		for (int32 index = 0; index < Interface().CountChildren(); index++) {
431			child = Interface().ChildAt(index);
432
433			if (child && child->IsUp()) {
434				// set MRU to the smallest value of all children
435				if (MRU == 0)
436					MRU = child->MRU();
437				else if (MRU > child->MRU())
438					MRU = child->MRU();
439
440				++count;
441			}
442		}
443
444		if (MRU == 0)
445			Interface().SetMRU(1500);
446		else
447			Interface().SetMRU(MRU);
448
449		if (count == 0)
450			DownEvent();
451	}
452}
453
454
455/*!	\brief Notification that a protocol failed to go up.
456
457	NOTE FOR AUTHENTICATORS: This \e must be called \e after an authentication
458	notification method like \c LocalAuthenticationFailed().
459*/
460void
461KPPPStateMachine::UpFailedEvent(KPPPProtocol *protocol)
462{
463	TRACE("KPPPSM: UpFailedEvent(protocol) state=%d phase=%d\n", State(), Phase());
464
465	if ((protocol->Flags() & PPP_NOT_IMPORTANT) == 0) {
466		if (Interface().Mode() == PPP_CLIENT_MODE) {
467			// pretend we lost connection
468			if (Interface().IsMultilink() && !Interface().Parent())
469				for (int32 index = 0; index < Interface().CountChildren(); index++)
470					Interface().ChildAt(index)->StateMachine().CloseEvent();
471			else if (Interface().Device())
472				Interface().Device()->Down();
473			else
474				CloseEvent();
475					// just to be on the secure side ;)
476		} else
477			CloseEvent();
478	}
479}
480
481
482/*!	\brief Notification that a protocol went up successfully.
483
484	NOTE FOR AUTHENTICATORS: This \e must be called \e after an authentication
485	notification method like \c LocalAuthenticationSuccessful().
486*/
487void
488KPPPStateMachine::UpEvent(KPPPProtocol *protocol)
489{
490	TRACE("KPPPSM: UpEvent(protocol) state=%d phase=%d\n", State(), Phase());
491
492	if (Phase() >= PPP_ESTABLISHMENT_PHASE)
493		BringProtocolsUp();
494}
495
496
497/*!	\brief Notification that a protocol went down.
498
499	NOTE FOR AUTHENTICATORS: This \e must be called \e after an authentication
500	notification method like \c LocalAuthenticationFailed().
501*/
502void
503KPPPStateMachine::DownEvent(KPPPProtocol *protocol)
504{
505	TRACE("KPPPSM: DownEvent(protocol) state=%d phase=%d\n", State(), Phase());
506}
507
508
509/*!	\brief Notification that the device entered establishment phase.
510
511	We can use \c Device::Down() to abort establishment until \c UpEvent() is called.
512
513	\return
514		- \c true: We are waiting for an \c UpEvent()
515		- \c false: The device should immediately abort its attempt to connect.
516*/
517bool
518KPPPStateMachine::TLSNotify()
519{
520	TRACE("KPPPSM: TLSNotify() state=%d phase=%d\n", State(), Phase());
521
522	if (State() == PPP_STARTING_STATE) {
523			if (Phase() == PPP_DOWN_PHASE)
524				NewPhase(PPP_ESTABLISHMENT_PHASE);
525					// this says that the device is going up
526			return true;
527	}
528
529	return false;
530}
531
532
533/*!	\brief Notification that the device entered termination phase.
534
535	A \c Device::Up() should wait until the device went down.
536
537	\return
538		- \c true: Continue terminating.
539		- \c false: We want to stay connected, though we called \c Device::Down().
540*/
541bool
542KPPPStateMachine::TLFNotify()
543{
544	TRACE("KPPPSM: TLFNotify() state=%d phase=%d\n", State(), Phase());
545
546	NewPhase(PPP_TERMINATION_PHASE);
547		// tell DownEvent() that it may create a connection-lost-report
548
549	return true;
550}
551
552
553//!	Notification that the device failed to go up.
554void
555KPPPStateMachine::UpFailedEvent()
556{
557	TRACE("KPPPSM: UpFailedEvent() state=%d phase=%d\n", State(), Phase());
558
559	switch (State()) {
560		case PPP_STARTING_STATE:
561			fLastConnectionReportCode = PPP_REPORT_DEVICE_UP_FAILED;
562			Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_DEVICE_UP_FAILED,
563				&fInterface.fID, sizeof(ppp_interface_id));
564			if (Interface().Parent())
565				Interface().Parent()->StateMachine().UpFailedEvent(Interface());
566
567			NewPhase(PPP_DOWN_PHASE);
568				// tell DownEvent() that it should not create a connection-lost-report
569			DownEvent();
570			break;
571
572		default:
573			IllegalEvent(PPP_UP_FAILED_EVENT);
574	}
575}
576
577
578//!	Notification that the device went up successfully.
579void
580KPPPStateMachine::UpEvent()
581{
582	TRACE("KPPPSM: UpEvent() state=%d phase=%d\n", State(), Phase());
583
584	// This call is public, thus, it might not only be called by the device.
585	// We must recognize these attempts to fool us and handle them correctly.
586
587	if (!Interface().Device() || !Interface().Device()->IsUp())
588		return;
589			// it is not our device that went up...
590
591	Interface().CalculateBaudRate();
592
593	switch (State()) {
594		case PPP_INITIAL_STATE:
595			if (Interface().Mode() != PPP_SERVER_MODE
596					|| Phase() != PPP_ESTABLISHMENT_PHASE) {
597				// we are a client or we do not listen for an incoming
598				// connection, so this is an illegal event
599				IllegalEvent(PPP_UP_EVENT);
600				NewState(PPP_CLOSED_STATE);
601				ThisLayerFinished();
602
603				return;
604			}
605
606			// TODO: handle server-up! (maybe already done correctly)
607			NewState(PPP_REQ_SENT_STATE);
608			InitializeRestartCount();
609			SendConfigureRequest();
610			break;
611
612		case PPP_STARTING_STATE:
613			// we must have called TLS() which sets establishment phase
614			if (Phase() != PPP_ESTABLISHMENT_PHASE) {
615				// there must be a BUG in the device add-on or someone is trying to
616				// fool us (UpEvent() is public) as we did not request the device
617				// to go up
618				IllegalEvent(PPP_UP_EVENT);
619				NewState(PPP_CLOSED_STATE);
620				ThisLayerFinished();
621				break;
622			}
623
624			NewState(PPP_REQ_SENT_STATE);
625			InitializeRestartCount();
626			SendConfigureRequest();
627			break;
628
629		default:
630			IllegalEvent(PPP_UP_EVENT);
631	}
632}
633
634
635/*!	\brief Notification that the device went down.
636
637	If this is called without a prior \c TLFNotify() the state machine will assume
638	that we lost our connection.
639*/
640void
641KPPPStateMachine::DownEvent()
642{
643	TRACE("KPPPSM: DownEvent() state=%d phase=%d\n", State(), Phase());
644
645	if (Interface().Device() && Interface().Device()->IsUp())
646		return;
647			// it is not our device that went down...
648
649	Interface().CalculateBaudRate();
650
651	// reset IdleSince
652	Interface().fIdleSince = 0;
653
654	switch (State()) {
655		// XXX: this does not belong to the standard, but may happen in our
656		// implementation
657		case PPP_STARTING_STATE:
658			break;
659
660		case PPP_CLOSED_STATE:
661		case PPP_CLOSING_STATE:
662			NewState(PPP_INITIAL_STATE);
663			break;
664
665		case PPP_STOPPED_STATE:
666			// The RFC says we should reconnect, but our implementation
667			// will only do this if auto-reconnect is enabled (only clients).
668			NewState(PPP_STARTING_STATE);
669			break;
670
671		case PPP_STOPPING_STATE:
672		case PPP_REQ_SENT_STATE:
673		case PPP_ACK_RCVD_STATE:
674		case PPP_ACK_SENT_STATE:
675		case PPP_OPENED_STATE:
676			NewState(PPP_STARTING_STATE);
677			break;
678
679		default:
680			IllegalEvent(PPP_DOWN_EVENT);
681	}
682
683	ppp_phase oldPhase = Phase();
684	NewPhase(PPP_DOWN_PHASE);
685
686	DownProtocols();
687
688	// maybe we need to reconnect
689	if (State() == PPP_STARTING_STATE) {
690		bool deleteInterface = false, retry = false;
691
692		// we do not try to reconnect if authentication failed
693		if (fLocalAuthenticationStatus == PPP_AUTHENTICATION_FAILED
694				|| fLocalAuthenticationStatus == PPP_AUTHENTICATING
695				|| fPeerAuthenticationStatus == PPP_AUTHENTICATION_FAILED
696				|| fPeerAuthenticationStatus == PPP_AUTHENTICATING) {
697			fLastConnectionReportCode = PPP_REPORT_AUTHENTICATION_FAILED;
698			Interface().Report(PPP_CONNECTION_REPORT,
699				PPP_REPORT_AUTHENTICATION_FAILED, &fInterface.fID,
700				sizeof(ppp_interface_id));
701			deleteInterface = true;
702		} else {
703			if (Interface().fConnectAttempt > (Interface().fConnectRetriesLimit + 1))
704				deleteInterface = true;
705
706			if (oldPhase == PPP_DOWN_PHASE) {
707				// failed to bring device up (UpFailedEvent() was called)
708				retry = true;
709					// this may have been overridden by "deleteInterface = true"
710			} else {
711				// lost connection (TLFNotify() was called)
712				fLastConnectionReportCode = PPP_REPORT_CONNECTION_LOST;
713				Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_CONNECTION_LOST,
714					&fInterface.fID, sizeof(ppp_interface_id));
715			}
716		}
717
718		if (Interface().Parent())
719			Interface().Parent()->StateMachine().UpFailedEvent(Interface());
720
721		NewState(PPP_INITIAL_STATE);
722
723		if (!deleteInterface && (retry || Interface().DoesAutoReconnect()))
724			Interface().Reconnect(Interface().ReconnectDelay());
725		else
726			Interface().Delete();
727	} else {
728		fLastConnectionReportCode = PPP_REPORT_DOWN_SUCCESSFUL;
729		Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_DOWN_SUCCESSFUL,
730			&fInterface.fID, sizeof(ppp_interface_id));
731		Interface().Delete();
732	}
733
734	fLocalAuthenticationStatus = PPP_NOT_AUTHENTICATED;
735	fPeerAuthenticationStatus = PPP_NOT_AUTHENTICATED;
736}
737
738
739// private events
740void
741KPPPStateMachine::OpenEvent()
742{
743	TRACE("KPPPSM: OpenEvent() state=%d phase=%d\n", State(), Phase());
744
745	// reset all handlers
746	if (Phase() != PPP_ESTABLISHED_PHASE) {
747		DownProtocols();
748		ResetLCPHandlers();
749	}
750
751	switch (State()) {
752		case PPP_INITIAL_STATE:
753			fLastConnectionReportCode = PPP_REPORT_GOING_UP;
754			Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_GOING_UP,
755					&fInterface.fID, sizeof(ppp_interface_id));
756
757			if (Interface().Mode() == PPP_SERVER_MODE) {
758				NewPhase(PPP_ESTABLISHMENT_PHASE);
759
760				if (Interface().Device() && !Interface().Device()->Up()) {
761					Interface().Device()->UpFailedEvent();
762					return;
763				}
764			} else
765				NewState(PPP_STARTING_STATE);
766
767			if (Interface().fAskBeforeConnecting == false)
768				ContinueOpenEvent();
769			break;
770
771		case PPP_CLOSED_STATE:
772			if (Phase() == PPP_DOWN_PHASE) {
773				// the device is already going down
774				return;
775			}
776
777			NewState(PPP_REQ_SENT_STATE);
778			NewPhase(PPP_ESTABLISHMENT_PHASE);
779			InitializeRestartCount();
780			SendConfigureRequest();
781			break;
782
783		case PPP_CLOSING_STATE:
784			NewState(PPP_STOPPING_STATE);
785			break;
786
787		default:
788			;
789	}
790}
791
792
793void
794KPPPStateMachine::ContinueOpenEvent()
795{
796	TRACE("KPPPSM: ContinueOpenEvent() state=%d phase=%d\n", State(), Phase());
797
798	if (Interface().IsMultilink() && !Interface().Parent()) {
799		NewPhase(PPP_ESTABLISHMENT_PHASE);
800		for (int32 index = 0; index < Interface().CountChildren(); index++)
801			if (Interface().ChildAt(index)->Mode() == Interface().Mode())
802				Interface().ChildAt(index)->StateMachine().OpenEvent();
803	} else
804		ThisLayerStarted();
805}
806
807
808void
809KPPPStateMachine::CloseEvent()
810{
811	TRACE("KPPPSM: CloseEvent() state=%d phase=%d\n", State(), Phase());
812
813	if (Interface().IsMultilink() && !Interface().Parent()) {
814		NewState(PPP_INITIAL_STATE);
815
816		if (Phase() != PPP_DOWN_PHASE)
817			NewPhase(PPP_TERMINATION_PHASE);
818
819		ThisLayerDown();
820
821		for (int32 index = 0; index < Interface().CountChildren(); index++)
822			Interface().ChildAt(index)->StateMachine().CloseEvent();
823
824		return;
825	}
826
827	switch (State()) {
828		case PPP_OPENED_STATE:
829		case PPP_REQ_SENT_STATE:
830		case PPP_ACK_RCVD_STATE:
831		case PPP_ACK_SENT_STATE:
832			NewState(PPP_CLOSING_STATE);
833			NewPhase(PPP_TERMINATION_PHASE);
834				// indicates to handlers that we are terminating
835			InitializeRestartCount();
836			if (State() == PPP_OPENED_STATE)
837				ThisLayerDown();
838			SendTerminateRequest();
839			break;
840
841		case PPP_STARTING_STATE:
842			NewState(PPP_INITIAL_STATE);
843
844			// TLSNotify() will know that we were faster because we
845			// are in PPP_INITIAL_STATE now
846			if (Phase() == PPP_ESTABLISHMENT_PHASE) {
847				// the device is already up
848				NewPhase(PPP_DOWN_PHASE);
849					// this says the following DownEvent() was not caused by
850					// a connection fault
851				ThisLayerFinished();
852			}
853			break;
854
855		case PPP_STOPPING_STATE:
856			NewState(PPP_CLOSING_STATE);
857			break;
858
859		case PPP_STOPPED_STATE:
860			NewState(PPP_STOPPED_STATE);
861			break;
862
863		default:
864			;
865	}
866}
867
868
869// timeout (restart counters are > 0)
870void
871KPPPStateMachine::TOGoodEvent()
872{
873	TRACE("KPPPSM: TOGoodEvent() state=%d phase=%d\n", State(), Phase());
874
875	switch (State()) {
876		case PPP_CLOSING_STATE:
877		case PPP_STOPPING_STATE:
878			SendTerminateRequest();
879			break;
880
881		case PPP_ACK_RCVD_STATE:
882			NewState(PPP_REQ_SENT_STATE);
883
884		case PPP_REQ_SENT_STATE:
885		case PPP_ACK_SENT_STATE:
886			SendConfigureRequest();
887			break;
888
889		default:
890			IllegalEvent(PPP_TO_GOOD_EVENT);
891	}
892}
893
894
895// timeout (restart counters are <= 0)
896void
897KPPPStateMachine::TOBadEvent()
898{
899	TRACE("KPPPSM: TOBadEvent() state=%d phase=%d\n", State(), Phase());
900
901	switch (State()) {
902		case PPP_CLOSING_STATE:
903			NewState(PPP_CLOSED_STATE);
904			NewPhase(PPP_TERMINATION_PHASE);
905			ThisLayerFinished();
906			break;
907
908		case PPP_STOPPING_STATE:
909		case PPP_REQ_SENT_STATE:
910		case PPP_ACK_RCVD_STATE:
911		case PPP_ACK_SENT_STATE:
912			NewState(PPP_STOPPED_STATE);
913			NewPhase(PPP_TERMINATION_PHASE);
914			ThisLayerFinished();
915			break;
916
917		default:
918			IllegalEvent(PPP_TO_BAD_EVENT);
919	}
920}
921
922
923// receive configure request (acceptable request)
924void
925KPPPStateMachine::RCRGoodEvent(net_buffer *packet)
926{
927	TRACE("KPPPSM: RCRGoodEvent() state=%d phase=%d\n", State(), Phase());
928
929	switch (State()) {
930		case PPP_INITIAL_STATE:
931		case PPP_STARTING_STATE:
932			TRACE("%s::%s: PPP_STARTING_STATE\n", __FILE__, __func__);
933			IllegalEvent(PPP_RCR_GOOD_EVENT);
934			gBufferModule->free(packet);
935			break;
936
937		case PPP_CLOSED_STATE:
938			TRACE("%s::%s: PPP_CLOSED_STATE\n", __FILE__, __func__);
939			SendTerminateAck();
940			gBufferModule->free(packet);
941			break;
942
943		case PPP_STOPPED_STATE:
944			TRACE("%s::%s: PPP_STOPPED_STATE\n", __FILE__, __func__);
945			// irc,scr,sca/8
946			// XXX: should we do nothing and wait for DownEvent()?
947			gBufferModule->free(packet);
948			break;
949
950		case PPP_REQ_SENT_STATE:
951			NewState(PPP_ACK_SENT_STATE);
952
953		case PPP_ACK_SENT_STATE:
954			TRACE("%s::%s: PPP_ACK_SENT_STATE size %ld\n", __FILE__, __func__,
955						packet->size);
956			SendConfigureAck(packet);
957			break;
958
959		case PPP_ACK_RCVD_STATE:
960			TRACE("%s::%s: PPP_ACK_RCVD_STATE\n", __FILE__, __func__);
961			NewState(PPP_OPENED_STATE);
962			SendConfigureAck(packet);
963			ThisLayerUp();
964			break;
965
966		case PPP_OPENED_STATE:
967			TRACE("%s::%s: PPP_OPENED_STATE\n", __FILE__, __func__);
968			NewState(PPP_ACK_SENT_STATE);
969			NewPhase(PPP_ESTABLISHMENT_PHASE);
970				// indicates to handlers that we are reconfiguring
971			ThisLayerDown();
972			SendConfigureRequest();
973			SendConfigureAck(packet);
974			break;
975
976		default:
977			TRACE("free peer's ppp request packet\n");
978			gBufferModule->free(packet);
979	}
980}
981
982
983// receive configure request (unacceptable request)
984void
985KPPPStateMachine::RCRBadEvent(net_buffer *nak, net_buffer *reject)
986{
987	TRACE("KPPPSM: RCRBadEvent() state=%d phase=%d\n", State(), Phase());
988
989	uint16 lenNak = 0;
990	uint16 lenReject = 0;
991
992	switch (State()) {
993		case PPP_INITIAL_STATE:
994		case PPP_STARTING_STATE:
995			IllegalEvent(PPP_RCR_BAD_EVENT);
996			break;
997
998		case PPP_CLOSED_STATE:
999			SendTerminateAck();
1000			break;
1001
1002		case PPP_STOPPED_STATE:
1003			// irc,scr,scn/6
1004			// XXX: should we do nothing and wait for DownEvent()?
1005			break;
1006
1007		case PPP_OPENED_STATE:
1008			NewState(PPP_REQ_SENT_STATE);
1009			NewPhase(PPP_ESTABLISHMENT_PHASE);
1010				// indicates to handlers that we are reconfiguring
1011			ThisLayerDown();
1012			SendConfigureRequest();
1013
1014		case PPP_ACK_SENT_STATE:
1015			if (State() == PPP_ACK_SENT_STATE)
1016				NewState(PPP_REQ_SENT_STATE);
1017					// OPENED_STATE might have set this already
1018
1019		case PPP_REQ_SENT_STATE:
1020		case PPP_ACK_RCVD_STATE:
1021			if (nak) {
1022				NetBufferHeaderReader<ppp_lcp_packet> nakBufferHeader(nak);
1023				if (nakBufferHeader.Status() < B_OK)
1024					break;
1025				ppp_lcp_packet &nakHeader = nakBufferHeader.Data();
1026				lenNak = nakHeader.length;
1027			}
1028
1029			if (reject) {
1030				NetBufferHeaderReader<ppp_lcp_packet> rejectBufferHeader(reject);
1031				if (rejectBufferHeader.Status() < B_OK)
1032					break;
1033				ppp_lcp_packet &rejectHeader = rejectBufferHeader.Data();
1034				lenReject = rejectHeader.length;
1035			}
1036
1037			if (nak && lenNak > 3)
1038				SendConfigureNak(nak);
1039			else if (reject && lenReject > 3)
1040				SendConfigureNak(reject);
1041			return;
1042			// prevents the nak/reject from being m_freem()'d
1043
1044		default:
1045			;
1046	}
1047
1048	if (nak)
1049		gBufferModule->free(nak);
1050	if (reject)
1051		gBufferModule->free(reject);
1052}
1053
1054
1055// receive configure ack
1056void
1057KPPPStateMachine::RCAEvent(net_buffer *packet)
1058{
1059	TRACE("KPPPSM: RCAEvent() state=%d phase=%d\n", State(), Phase());
1060
1061	NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(packet);
1062	if (bufferHeader.Status() < B_OK)
1063		return;
1064	ppp_lcp_packet &header = bufferHeader.Data();
1065
1066	if (fRequestID != header.id) {
1067		// this packet is not a reply to our request
1068
1069		// TODO:
1070		// log this event
1071		gBufferModule->free(packet);
1072		return;
1073	}
1074
1075	// let the option handlers parse this ack
1076	KPPPConfigurePacket ack(packet);
1077	KPPPOptionHandler *optionHandler;
1078	for (int32 index = 0; index < LCP().CountOptionHandlers(); index++) {
1079		optionHandler = LCP().OptionHandlerAt(index);
1080		if (optionHandler->ParseAck(ack) != B_OK) {
1081			gBufferModule->free(packet);
1082			CloseEvent();
1083			return;
1084		}
1085	}
1086
1087	switch (State()) {
1088		case PPP_INITIAL_STATE:
1089		case PPP_STARTING_STATE:
1090			IllegalEvent(PPP_RCA_EVENT);
1091			break;
1092
1093		case PPP_CLOSED_STATE:
1094		case PPP_STOPPED_STATE:
1095			SendTerminateAck();
1096			break;
1097
1098		case PPP_REQ_SENT_STATE:
1099			NewState(PPP_ACK_RCVD_STATE);
1100			InitializeRestartCount();
1101			break;
1102
1103		case PPP_ACK_RCVD_STATE:
1104			NewState(PPP_REQ_SENT_STATE);
1105			SendConfigureRequest();
1106			break;
1107
1108		case PPP_ACK_SENT_STATE:
1109			NewState(PPP_OPENED_STATE);
1110			InitializeRestartCount();
1111			ThisLayerUp();
1112			break;
1113
1114		case PPP_OPENED_STATE:
1115			NewState(PPP_REQ_SENT_STATE);
1116			NewPhase(PPP_ESTABLISHMENT_PHASE);
1117				// indicates to handlers that we are reconfiguring
1118			ThisLayerDown();
1119			SendConfigureRequest();
1120			break;
1121
1122		default:
1123			;
1124	}
1125
1126	gBufferModule->free(packet);
1127}
1128
1129
1130// receive configure nak/reject
1131void
1132KPPPStateMachine::RCNEvent(net_buffer *packet)
1133{
1134	TRACE("KPPPSM: RCNEvent() state=%d phase=%d\n", State(), Phase());
1135
1136	NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(packet);
1137	if (bufferHeader.Status() < B_OK)
1138		return;
1139	ppp_lcp_packet &header = bufferHeader.Data();
1140
1141	if (fRequestID != header.id) {
1142		// this packet is not a reply to our request
1143
1144		// TODO:
1145		// log this event
1146		gBufferModule->free(packet);
1147		return;
1148	}
1149
1150	// let the option handlers parse this nak/reject
1151	KPPPConfigurePacket nak_reject(packet);
1152	KPPPOptionHandler *optionHandler;
1153	for (int32 index = 0; index < LCP().CountOptionHandlers(); index++) {
1154		optionHandler = LCP().OptionHandlerAt(index);
1155
1156		if (nak_reject.Code() == PPP_CONFIGURE_NAK) {
1157			if (optionHandler->ParseNak(nak_reject) != B_OK) {
1158				gBufferModule->free(packet);
1159				CloseEvent();
1160				return;
1161			}
1162		} else if (nak_reject.Code() == PPP_CONFIGURE_REJECT) {
1163			if (optionHandler->ParseReject(nak_reject) != B_OK) {
1164				gBufferModule->free(packet);
1165				CloseEvent();
1166				return;
1167			}
1168		}
1169	}
1170
1171	switch (State()) {
1172		case PPP_INITIAL_STATE:
1173		case PPP_STARTING_STATE:
1174			IllegalEvent(PPP_RCN_EVENT);
1175			break;
1176
1177		case PPP_CLOSED_STATE:
1178		case PPP_STOPPED_STATE:
1179			SendTerminateAck();
1180			break;
1181
1182		case PPP_REQ_SENT_STATE:
1183		case PPP_ACK_SENT_STATE:
1184			InitializeRestartCount();
1185
1186		case PPP_ACK_RCVD_STATE:
1187			if (State() == PPP_ACK_RCVD_STATE)
1188				NewState(PPP_REQ_SENT_STATE);
1189			SendConfigureRequest();
1190			break;
1191
1192		case PPP_OPENED_STATE:
1193			NewState(PPP_REQ_SENT_STATE);
1194			NewPhase(PPP_ESTABLISHMENT_PHASE);
1195				// indicates to handlers that we are reconfiguring
1196			ThisLayerDown();
1197			SendConfigureRequest();
1198			break;
1199
1200		default:
1201			;
1202	}
1203
1204	gBufferModule->free(packet);
1205}
1206
1207
1208// receive terminate request
1209void
1210KPPPStateMachine::RTREvent(net_buffer *packet)
1211{
1212	TRACE("KPPPSM: RTREvent() state=%d phase=%d\n", State(), Phase());
1213
1214	NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(packet);
1215	if (bufferHeader.Status() < B_OK)
1216		return;
1217	ppp_lcp_packet &header = bufferHeader.Data();
1218
1219	// we should not use the same ID as the peer
1220	if (fID == header.id)
1221		fID -= 128;
1222
1223	fLocalAuthenticationStatus = PPP_NOT_AUTHENTICATED;
1224	fPeerAuthenticationStatus = PPP_NOT_AUTHENTICATED;
1225
1226	switch (State()) {
1227		case PPP_INITIAL_STATE:
1228		case PPP_STARTING_STATE:
1229			IllegalEvent(PPP_RTR_EVENT);
1230			gBufferModule->free(packet);
1231			break;
1232
1233		case PPP_ACK_RCVD_STATE:
1234		case PPP_ACK_SENT_STATE:
1235			NewState(PPP_REQ_SENT_STATE);
1236			NewPhase(PPP_TERMINATION_PHASE);
1237				// indicates to handlers that we are terminating
1238			SendTerminateAck(packet);
1239			break;
1240
1241		case PPP_OPENED_STATE:
1242			NewState(PPP_STOPPING_STATE);
1243			NewPhase(PPP_TERMINATION_PHASE);
1244				// indicates to handlers that we are terminating
1245			ZeroRestartCount();
1246			ThisLayerDown();
1247			SendTerminateAck(packet);
1248			break;
1249
1250		default:
1251			NewPhase(PPP_TERMINATION_PHASE);
1252				// indicates to handlers that we are terminating
1253			SendTerminateAck(packet);
1254	}
1255}
1256
1257
1258// receive terminate ack
1259void
1260KPPPStateMachine::RTAEvent(net_buffer *packet)
1261{
1262	TRACE("KPPPSM: RTAEvent() state=%d phase=%d\n", State(), Phase());
1263
1264	NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(packet);
1265	if (bufferHeader.Status() < B_OK)
1266		return;
1267	ppp_lcp_packet &header = bufferHeader.Data();
1268
1269	if (fTerminateID != header.id) {
1270		// this packet is not a reply to our request
1271
1272		// TODO:
1273		// log this event
1274		gBufferModule->free(packet);
1275		return;
1276	}
1277
1278	switch (State()) {
1279		case PPP_INITIAL_STATE:
1280		case PPP_STARTING_STATE:
1281			IllegalEvent(PPP_RTA_EVENT);
1282			break;
1283
1284		case PPP_CLOSING_STATE:
1285			NewState(PPP_CLOSED_STATE);
1286			ThisLayerFinished();
1287			break;
1288
1289		case PPP_STOPPING_STATE:
1290			NewState(PPP_STOPPED_STATE);
1291			ThisLayerFinished();
1292			break;
1293
1294		case PPP_ACK_RCVD_STATE:
1295			NewState(PPP_REQ_SENT_STATE);
1296			break;
1297
1298		case PPP_OPENED_STATE:
1299			NewState(PPP_REQ_SENT_STATE);
1300			NewPhase(PPP_ESTABLISHMENT_PHASE);
1301				// indicates to handlers that we are reconfiguring
1302			ThisLayerDown();
1303			SendConfigureRequest();
1304			break;
1305
1306		default:
1307			;
1308	}
1309
1310	gBufferModule->free(packet);
1311}
1312
1313
1314// receive unknown code
1315void
1316KPPPStateMachine::RUCEvent(net_buffer *packet, uint16 protocolNumber,
1317	uint8 code)
1318{
1319	TRACE("KPPPSM: RUCEvent() state=%d phase=%d\n", State(), Phase());
1320
1321	switch (State()) {
1322		case PPP_INITIAL_STATE:
1323		case PPP_STARTING_STATE:
1324			IllegalEvent(PPP_RUC_EVENT);
1325			gBufferModule->free(packet);
1326			break;
1327
1328		default:
1329			SendCodeReject(packet, protocolNumber, code);
1330	}
1331}
1332
1333
1334// receive code/protocol reject (acceptable such as IPX reject)
1335void
1336KPPPStateMachine::RXJGoodEvent(net_buffer *packet)
1337{
1338	TRACE("KPPPSM: RXJGoodEvent() state=%d phase=%d\n", State(), Phase());
1339
1340	// This method does not m_freem(packet) because the acceptable rejects are
1341	// also passed to the parent. RXJEvent() will m_freem(packet) when needed.
1342
1343	switch (State()) {
1344		case PPP_INITIAL_STATE:
1345		case PPP_STARTING_STATE:
1346			IllegalEvent(PPP_RXJ_GOOD_EVENT);
1347			break;
1348
1349		case PPP_ACK_RCVD_STATE:
1350			NewState(PPP_REQ_SENT_STATE);
1351			break;
1352
1353		default:
1354			;
1355	}
1356}
1357
1358
1359// receive code/protocol reject (catastrophic such as LCP reject)
1360void
1361KPPPStateMachine::RXJBadEvent(net_buffer *packet)
1362{
1363	TRACE("KPPPSM: RXJBadEvent() state=%d phase=%d\n", State(), Phase());
1364
1365	switch (State()) {
1366		case PPP_INITIAL_STATE:
1367		case PPP_STARTING_STATE:
1368			IllegalEvent(PPP_RXJ_BAD_EVENT);
1369			break;
1370
1371		case PPP_CLOSING_STATE:
1372			NewState(PPP_CLOSED_STATE);
1373
1374		case PPP_CLOSED_STATE:
1375			ThisLayerFinished();
1376			break;
1377
1378		case PPP_REQ_SENT_STATE:
1379		case PPP_ACK_RCVD_STATE:
1380		case PPP_ACK_SENT_STATE:
1381			NewState(PPP_STOPPED_STATE);
1382
1383		case PPP_STOPPING_STATE:
1384			NewPhase(PPP_TERMINATION_PHASE);
1385
1386		case PPP_STOPPED_STATE:
1387			ThisLayerFinished();
1388			break;
1389
1390		case PPP_OPENED_STATE:
1391			NewState(PPP_STOPPING_STATE);
1392			NewPhase(PPP_TERMINATION_PHASE);
1393				// indicates to handlers that we are terminating
1394			InitializeRestartCount();
1395			ThisLayerDown();
1396			SendTerminateRequest();
1397			break;
1398	}
1399
1400	gBufferModule->free(packet);
1401}
1402
1403
1404// receive echo request/reply, discard request
1405void
1406KPPPStateMachine::RXREvent(net_buffer *packet)
1407{
1408	TRACE("KPPPSM: RXREvent() state=%d phase=%d\n", State(), Phase());
1409
1410	NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(packet);
1411	if (bufferHeader.Status() < B_OK)
1412		return;
1413	ppp_lcp_packet &echo = bufferHeader.Data();
1414
1415	if (echo.code == PPP_ECHO_REPLY && echo.id != fEchoID) {
1416		// TODO:
1417		// log that we got a reply, but no request was sent
1418	}
1419
1420	switch (State()) {
1421		case PPP_INITIAL_STATE:
1422		case PPP_STARTING_STATE:
1423			IllegalEvent(PPP_RXR_EVENT);
1424			break;
1425
1426		case PPP_OPENED_STATE:
1427			if (echo.code == PPP_ECHO_REQUEST)
1428				SendEchoReply(packet);
1429			return;
1430				// this prevents the packet from being freed
1431
1432		default:
1433			;
1434	}
1435
1436	gBufferModule->free(packet);
1437}
1438
1439
1440// general events (for Good/Bad events)
1441void
1442KPPPStateMachine::TimerEvent()
1443{
1444#if DEBUG
1445	if (fNextTimeout != 0)
1446		TRACE("KPPPSM: TimerEvent()\n");
1447#endif
1448
1449	if (fNextTimeout == 0 || fNextTimeout > system_time())
1450		return;
1451
1452	fNextTimeout = 0;
1453
1454	switch (State()) {
1455		case PPP_CLOSING_STATE:
1456		case PPP_STOPPING_STATE:
1457			if (fTerminateCounter <= 0)
1458				TOBadEvent();
1459			else
1460				TOGoodEvent();
1461			break;
1462
1463		case PPP_REQ_SENT_STATE:
1464		case PPP_ACK_RCVD_STATE:
1465		case PPP_ACK_SENT_STATE:
1466			if (fRequestCounter <= 0)
1467				TOBadEvent();
1468			else
1469				TOGoodEvent();
1470			break;
1471
1472		default:
1473			;
1474	}
1475}
1476
1477
1478// ReceiveConfigureRequest
1479// Here we get a configure-request packet from LCP and ask all OptionHandlers
1480// if its values are acceptable. From here we call our Good/Bad counterparts.
1481void
1482KPPPStateMachine::RCREvent(net_buffer *packet)
1483{
1484	TRACE("KPPPSM: RCREvent() state=%d phase=%d lcppacket size=%ld\n", State(), Phase(),
1485				packet->size);
1486
1487	KPPPConfigurePacket request(packet);
1488	KPPPConfigurePacket nak(PPP_CONFIGURE_NAK);
1489	KPPPConfigurePacket reject(PPP_CONFIGURE_REJECT);
1490
1491	NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(packet);
1492	if (bufferHeader.Status() < B_OK)
1493		return;
1494	ppp_lcp_packet &header = bufferHeader.Data();
1495
1496	// we should not use the same id as the peer
1497	if (fID == header.id)
1498		fID -= 128;
1499		// or maybe we should use peer's ID plus 1 ?
1500
1501	nak.SetID(request.ID());
1502	reject.SetID(request.ID());
1503
1504	// each handler should add unacceptable values for each item
1505	status_t result;
1506		// the return value of ParseRequest()
1507	KPPPOptionHandler *optionHandler;
1508	for (int32 index = 0; index < request.CountItems(); index++) {
1509		optionHandler = LCP().OptionHandlerFor(request.ItemAt(index)->type);
1510
1511		if (!optionHandler || !optionHandler->IsEnabled()) {
1512			TRACE("KPPPSM::RCREvent():unknown type:%d\n", request.ItemAt(index)->type);
1513			if (request.ItemAt(index)->type == 0x5)
1514			{
1515				// type 0x5 is Magic Number, Need no processing.
1516				TRACE("Peer Magic Number:%02x %02x %02x %02x\n",
1517					(request.ItemAt(index)->data)[0],
1518					(request.ItemAt(index)->data)[1],
1519					(request.ItemAt(index)->data)[2],
1520					(request.ItemAt(index)->data)[3]);
1521				continue;
1522			} else {
1523				// unhandled items should be added to the reject
1524				TRACE("why come here %ld\n", index);
1525				reject.AddItem(request.ItemAt(index));
1526				continue;
1527			}
1528		}
1529
1530		TRACE("KPPPSM::RCREvent(): OH=%s\n",
1531			optionHandler->Name() ? optionHandler->Name() : "Unknown");
1532		result = optionHandler->ParseRequest(request, index, nak, reject);
1533
1534		if (result == PPP_UNHANDLED) {
1535			// unhandled items should be added to the reject
1536			TRACE("PPP_UNHANDLED %ld\n", index);
1537			reject.AddItem(request.ItemAt(index));
1538			continue;
1539		} else if (result != B_OK) {
1540			// the request contains a value that has been sent more than
1541			// once or the value is corrupted
1542			ERROR("KPPPSM::RCREvent(): OptionHandler returned parse error!\n");
1543			gBufferModule->free(packet);
1544			CloseEvent();
1545			return;
1546		}
1547	}
1548
1549	// Additional values may be appended.
1550	// If we sent too many naks we should not append additional values.
1551	if (fNakCounter > 0) {
1552		for (int32 index = 0; index < LCP().CountOptionHandlers(); index++) {
1553			optionHandler = LCP().OptionHandlerAt(index);
1554			if (optionHandler && optionHandler->IsEnabled()) {
1555				result = optionHandler->ParseRequest(request, request.CountItems(),
1556					nak, reject);
1557
1558				if (result != B_OK) {
1559					// the request contains a value that has been sent more than
1560					// once or the value is corrupted
1561					ERROR("KPPPSM::RCREvent():OptionHandler returned append error!\n");
1562					gBufferModule->free(packet);
1563					CloseEvent();
1564					return;
1565				}
1566			}
1567		}
1568	}
1569
1570	if (reject.CountItems() > 0) {
1571		TRACE("%s:reject number more than 0\n", __func__);
1572		RCRBadEvent(NULL, reject.ToNetBuffer(Interface().MRU()));
1573		gBufferModule->free(packet);
1574	} else if (nak.CountItems() > 0) {
1575		TRACE("%s:nak number more than 0\n", __func__);
1576		RCRBadEvent(nak.ToNetBuffer(Interface().MRU()), NULL);
1577		gBufferModule->free(packet);
1578	} else
1579		RCRGoodEvent(packet);
1580}
1581
1582
1583// ReceiveCodeReject
1584// LCP received a code/protocol-reject packet and we look if it is acceptable.
1585// From here we call our Good/Bad counterparts.
1586void
1587KPPPStateMachine::RXJEvent(net_buffer *packet)
1588{
1589	TRACE("KPPPSM: RXJEvent() state=%d phase=%d\n", State(), Phase());
1590
1591	NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(packet);
1592	if (bufferHeader.Status() < B_OK)
1593		return;
1594	ppp_lcp_packet &reject = bufferHeader.Data();
1595
1596	if (reject.code == PPP_CODE_REJECT) {
1597		uint8 rejectedCode = reject.data[0];
1598
1599		// test if the rejected code belongs to the minimum LCP requirements
1600		if (rejectedCode >= PPP_MIN_LCP_CODE && rejectedCode <= PPP_MAX_LCP_CODE) {
1601			if (Interface().IsMultilink() && !Interface().Parent()) {
1602				// Main interfaces do not have states between STARTING and OPENED.
1603				// An RXJBadEvent() would enter one of those states which is bad.
1604				gBufferModule->free(packet);
1605				CloseEvent();
1606			} else
1607				RXJBadEvent(packet);
1608
1609			return;
1610		}
1611
1612		// find the LCP extension and disable it
1613		KPPPLCPExtension *lcpExtension;
1614		for (int32 index = 0; index < LCP().CountLCPExtensions(); index++) {
1615			lcpExtension = LCP().LCPExtensionAt(index);
1616
1617			if (lcpExtension->Code() == rejectedCode)
1618				lcpExtension->SetEnabled(false);
1619		}
1620
1621		gBufferModule->free(packet);
1622	} else if (reject.code == PPP_PROTOCOL_REJECT) {
1623		// disable all handlers for rejected protocol type
1624		uint16 rejected = *((uint16*) reject.data);
1625			// rejected protocol number
1626
1627		if (rejected == PPP_LCP_PROTOCOL) {
1628			// LCP must not be rejected!
1629			RXJBadEvent(packet);
1630			return;
1631		}
1632
1633		// disable protocols with the rejected protocol number
1634		KPPPProtocol *protocol = Interface().FirstProtocol();
1635		for (; protocol; protocol = protocol->NextProtocol()) {
1636			if (protocol->ProtocolNumber() == rejected)
1637				protocol->SetEnabled(false);
1638					// disable protocol
1639		}
1640
1641		RXJGoodEvent(packet);
1642			// this event handler does not m_freem(packet)!!!
1643
1644		// notify parent, too
1645		if (Interface().Parent())
1646			Interface().Parent()->StateMachine().RXJEvent(packet);
1647		else
1648			gBufferModule->free(packet);
1649	}
1650}
1651
1652
1653// actions (all private)
1654void
1655KPPPStateMachine::IllegalEvent(ppp_event event)
1656{
1657	// TODO:
1658	// update error statistics
1659	TRACE("KPPPSM: IllegalEvent(event=%d) state=%d phase=%d\n",
1660		event, State(), Phase());
1661}
1662
1663
1664void
1665KPPPStateMachine::ThisLayerUp()
1666{
1667	TRACE("KPPPSM: ThisLayerUp() state=%d phase=%d\n", State(), Phase());
1668
1669	// We begin with authentication phase and wait until each phase is done.
1670	// We stop when we reach established phase.
1671
1672	// Do not forget to check if we are going down.
1673	if (Phase() != PPP_ESTABLISHMENT_PHASE)
1674		return;
1675
1676	NewPhase(PPP_AUTHENTICATION_PHASE);
1677
1678	BringProtocolsUp();
1679}
1680
1681
1682void
1683KPPPStateMachine::ThisLayerDown()
1684{
1685	TRACE("KPPPSM: ThisLayerDown() state=%d phase=%d\n", State(), Phase());
1686
1687	// KPPPProtocol::Down() should block if needed.
1688	DownProtocols();
1689}
1690
1691
1692void
1693KPPPStateMachine::ThisLayerStarted()
1694{
1695	TRACE("KPPPSM: ThisLayerStarted() state=%d phase=%d\n", State(), Phase());
1696
1697	if (Interface().Device() && !Interface().Device()->Up())
1698		Interface().Device()->UpFailedEvent();
1699}
1700
1701
1702void
1703KPPPStateMachine::ThisLayerFinished()
1704{
1705	TRACE("KPPPSM: ThisLayerFinished() state=%d phase=%d\n", State(), Phase());
1706
1707	if (Interface().Device())
1708		Interface().Device()->Down();
1709}
1710
1711
1712void
1713KPPPStateMachine::InitializeRestartCount()
1714{
1715	fRequestCounter = fMaxRequest;
1716	fTerminateCounter = fMaxTerminate;
1717	fNakCounter = fMaxNak;
1718}
1719
1720
1721void
1722KPPPStateMachine::ZeroRestartCount()
1723{
1724	fRequestCounter = 0;
1725	fTerminateCounter = 0;
1726	fNakCounter = 0;
1727}
1728
1729
1730bool
1731KPPPStateMachine::SendConfigureRequest()
1732{
1733	TRACE("KPPPSM: SendConfigureRequest() state=%d phase=%d\n", State(), Phase());
1734
1735	--fRequestCounter;
1736	fNextTimeout = system_time() + kPPPStateMachineTimeout;
1737
1738	KPPPConfigurePacket request(PPP_CONFIGURE_REQUEST);
1739	request.SetID(NextID());
1740	fRequestID = request.ID();
1741
1742	for (int32 index = 0; index < LCP().CountOptionHandlers(); index++) {
1743		// add all items
1744		if (LCP().OptionHandlerAt(index)->AddToRequest(request) != B_OK) {
1745			CloseEvent();
1746			return false;
1747		}
1748	}
1749
1750	return LCP().Send(request.ToNetBuffer(Interface().MRU())) == B_OK;
1751}
1752
1753
1754bool
1755KPPPStateMachine::SendConfigureAck(net_buffer *packet)
1756{
1757	TRACE("KPPPSM: SendConfigureAck() state=%d phase=%d\n", State(), Phase());
1758
1759	if (!packet)
1760		return false;
1761
1762	NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(packet);
1763	if (bufferHeader.Status() < B_OK)
1764		return false;
1765	ppp_lcp_packet &header = bufferHeader.Data();
1766
1767	header.code = PPP_CONFIGURE_ACK;
1768	bufferHeader.Sync();
1769
1770	KPPPConfigurePacket ack(packet);
1771
1772	// notify all option handlers that we are sending an ack for each value
1773	for (int32 index = 0; index < LCP().CountOptionHandlers(); index++) {
1774		if (LCP().OptionHandlerAt(index)->SendingAck(ack) != B_OK) {
1775			TRACE("%s::%s: SendingAck %ld fail\n", __FILE__, __func__, index);
1776			gBufferModule->free(packet);
1777			CloseEvent();
1778			return false;
1779		}
1780	}
1781
1782	TRACE("%s::%s: LCP().Send\n", __FILE__, __func__);
1783	return LCP().Send(packet) == B_OK;
1784}
1785
1786
1787bool
1788KPPPStateMachine::SendConfigureNak(net_buffer *packet)
1789{
1790	TRACE("KPPPSM: SendConfigureNak() state=%d phase=%d\n", State(), Phase());
1791
1792	if (!packet)
1793		return false;
1794
1795	NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(packet);
1796	if (bufferHeader.Status() < B_OK)
1797		return false;
1798	ppp_lcp_packet &nak = bufferHeader.Data();
1799
1800	if (nak.code == PPP_CONFIGURE_NAK) {
1801		if (fNakCounter == 0) {
1802			// We sent enough naks. Let's try a reject.
1803			nak.code = PPP_CONFIGURE_REJECT;
1804		} else
1805			--fNakCounter;
1806	}
1807
1808	return LCP().Send(packet) == B_OK;
1809}
1810
1811
1812bool
1813KPPPStateMachine::SendTerminateRequest()
1814{
1815	TRACE("KPPPSM: SendTerminateRequest() state=%d phase=%d\n", State(), Phase());
1816
1817	--fTerminateCounter;
1818	fNextTimeout = system_time() + kPPPStateMachineTimeout;
1819
1820	net_buffer *buffer = gBufferModule->create(256);
1821	if (buffer == NULL)
1822		return false;
1823
1824	ppp_lcp_packet *packet;
1825	status_t status = gBufferModule->append_size(buffer, 1492, (void **)&packet);
1826	if (status == B_OK && packet == NULL) {
1827		gBufferModule->free(buffer);
1828		return false;
1829	}
1830
1831	if (!packet)
1832		return false;
1833
1834	packet->code = PPP_TERMINATE_REQUEST;
1835	packet->id = fTerminateID = NextID();
1836	packet->length = htons(4);
1837
1838	status = gBufferModule->trim(buffer, 4);
1839	if (status < B_OK) {
1840		gBufferModule->free(buffer);
1841		return false;
1842	}
1843
1844	return LCP().Send(buffer) == B_OK;
1845}
1846
1847
1848bool
1849KPPPStateMachine::SendTerminateAck(net_buffer *request)
1850{
1851	TRACE("KPPPSM: SendTerminateAck() state=%d phase=%d\n", State(), Phase());
1852
1853	net_buffer *reply = request;
1854
1855	NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(request);
1856	if (bufferHeader.Status() < B_OK)
1857		return false;
1858	ppp_lcp_packet &ack = bufferHeader.Data();
1859
1860	if (!reply) {
1861		ack.length = htons(4);
1862		ack.id = NextID();
1863	}
1864
1865	ack.code = PPP_TERMINATE_ACK;
1866	ack.length = htons(4);
1867
1868	return LCP().Send(reply) == B_OK;
1869}
1870
1871
1872bool
1873KPPPStateMachine::SendCodeReject(net_buffer *packet, uint16 protocolNumber, uint8 code)
1874{
1875	TRACE("KPPPSM: SendCodeReject(protocolNumber=%X;code=%d) state=%d phase=%d\n",
1876		protocolNumber, code, State(), Phase());
1877
1878	if (!packet)
1879		return false;
1880
1881	int32 length;
1882		// additional space needed for this reject
1883	if (code == PPP_PROTOCOL_REJECT)
1884		length = 6;
1885	else
1886		length = 4;
1887
1888	NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(packet);
1889	if (bufferHeader.Status() < B_OK)
1890		return false;
1891	ppp_lcp_packet &reject = bufferHeader.Data();
1892
1893	reject.code = code;
1894	reject.id = NextID();
1895	reject.length = htons(length);
1896
1897	protocolNumber = htons(protocolNumber);
1898	if (code == PPP_PROTOCOL_REJECT)
1899		memcpy(&reject.data, &protocolNumber, sizeof(protocolNumber));
1900
1901	return LCP().Send(packet) == B_OK;
1902}
1903
1904
1905bool
1906KPPPStateMachine::SendEchoReply(net_buffer *request)
1907{
1908	TRACE("KPPPSM: SendEchoReply() state=%d phase=%d\n", State(), Phase());
1909
1910	if (!request)
1911		return false;
1912
1913	NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(request);
1914	if (bufferHeader.Status() < B_OK)
1915		return false;
1916	ppp_lcp_packet &reply = bufferHeader.Data();
1917
1918	reply.code = PPP_ECHO_REPLY;
1919		// the request becomes a reply
1920
1921	memcpy(reply.data, &fMagicNumber, sizeof(fMagicNumber));
1922
1923	return LCP().Send(request) == B_OK;
1924}
1925
1926
1927// methods for bringing protocols up
1928void
1929KPPPStateMachine::BringProtocolsUp()
1930{
1931	// use a simple check for phase changes (e.g., caused by CloseEvent())
1932	while (Phase() <= PPP_ESTABLISHED_PHASE && Phase() >= PPP_AUTHENTICATION_PHASE) {
1933		if (BringPhaseUp() > 0)
1934			break;
1935
1936		if (Phase() < PPP_AUTHENTICATION_PHASE)
1937			return;
1938				// phase was changed by another event
1939		else if (Phase() == PPP_ESTABLISHED_PHASE) {
1940			if (Interface().Parent())
1941				Interface().Parent()->StateMachine().UpEvent(Interface());
1942			break;
1943		} else
1944			NewPhase((ppp_phase) (Phase() + 1));
1945	}
1946}
1947
1948
1949// this returns the number of handlers waiting to go up
1950uint32
1951KPPPStateMachine::BringPhaseUp()
1952{
1953	// Servers do not need to bring all protocols up.
1954	// The client specifies which protocols he wants to go up.
1955
1956	// check for phase change
1957	if (Phase() < PPP_AUTHENTICATION_PHASE)
1958		return 0;
1959
1960	uint32 count = 0;
1961	KPPPProtocol *protocol = Interface().FirstProtocol();
1962	for (; protocol; protocol = protocol->NextProtocol()) {
1963		if (protocol->IsEnabled() && protocol->ActivationPhase() == Phase()) {
1964			if (protocol->IsGoingUp() && Interface().Mode() == PPP_CLIENT_MODE)
1965				++count;
1966			else if (protocol->IsDown() && protocol->IsUpRequested()) {
1967				if (Interface().Mode() == PPP_CLIENT_MODE)
1968					++count;
1969
1970				protocol->Up();
1971			}
1972		}
1973	}
1974
1975	// We only wait until authentication is complete.
1976	if (Interface().Mode() == PPP_SERVER_MODE
1977			&& (LocalAuthenticationStatus() == PPP_AUTHENTICATING
1978			|| PeerAuthenticationStatus() == PPP_AUTHENTICATING))
1979		++count;
1980
1981	return count;
1982}
1983
1984
1985void
1986KPPPStateMachine::DownProtocols()
1987{
1988	KPPPProtocol *protocol = Interface().FirstProtocol();
1989
1990	for (; protocol; protocol = protocol->NextProtocol())
1991		if (protocol->IsEnabled())
1992			protocol->Down();
1993}
1994
1995
1996void
1997KPPPStateMachine::ResetLCPHandlers()
1998{
1999	for (int32 index = 0; index < LCP().CountOptionHandlers(); index++)
2000		LCP().OptionHandlerAt(index)->Reset();
2001
2002	for (int32 index = 0; index < LCP().CountLCPExtensions(); index++)
2003		LCP().LCPExtensionAt(index)->Reset();
2004}
2005