1/*
2 * Copyright 2003-2007, Waldemar Kornewald <wkornew@gmx.net>
3 * Distributed under the terms of the MIT License.
4 */
5
6/*!	\class KPPPProtocol.
7	\brief Represents a PPP protocol object.
8
9	This class is the base for all protocols, encapsulators, and authenticators.
10*/
11
12#include <KPPPInterface.h>
13#include <KPPPUtils.h>
14#include <PPPControl.h>
15#include "settings_tools.h"
16
17#include <cstring>
18
19
20/*!	\brief Constructs a PPP protocol.
21
22	If you are creating a normal protocol use a level of \c PPP_PROTOCOL_LEVEL.
23	Encapsulators like compression protocols should use a different level. \n
24	Authenticators are identified by a type string equal to "Authenticator" and they
25	have an optionHandler that implements only the following methods:
26	- AddToRequest
27	- ParseRequest
28
29	\param name The protocol name.
30	\param activationPhase Our activation phase.
31	\param protocolNumber Our protocol number.
32	\param level The level at which we get inserted into the list of protocols.
33	\param addressFamily The address family.  Values < 0 and > 0xFF are ignored.
34	\param overhead The protocol's header size.
35	\param interface The owner.
36	\param settings Our settings.
37	\param flags Optional flags. See \c ppp_protocol_flags for more information.
38	\param type Optional type string. Used by authenticators, for example.
39	\param optionHandler Optional handler associated with this protocol.
40*/
41KPPPProtocol::KPPPProtocol(const char *name, ppp_phase activationPhase,
42	uint16 protocolNumber, ppp_level level, int32 addressFamily,
43	uint32 overhead, KPPPInterface& interface,
44	driver_parameter *settings, int32 flags,
45	const char *type, KPPPOptionHandler *optionHandler)
46	:
47	KPPPLayer(name, level, overhead),
48	fActivationPhase(activationPhase),
49	fProtocolNumber(protocolNumber),
50	fAddressFamily(addressFamily),
51	fInterface(interface),
52	fSettings(settings),
53	fFlags(flags),
54	fOptionHandler(optionHandler),
55	fNextProtocol(NULL),
56	fEnabled(true),
57	fUpRequested(true),
58	fConnectionPhase(PPP_DOWN_PHASE)
59{
60	if (type)
61		fType = strdup(type);
62	else
63		fType = NULL;
64
65	const char *sideString = get_parameter_value("side", settings);
66	if (sideString)
67		fSide = get_side_string_value(sideString, PPP_LOCAL_SIDE);
68	else {
69		if (interface.Mode() == PPP_CLIENT_MODE)
70			fSide = PPP_LOCAL_SIDE;
71		else
72			fSide = PPP_PEER_SIDE;
73	}
74}
75
76
77//!	Removes this protocol from the interface and frees the type.
78KPPPProtocol::~KPPPProtocol()
79{
80	Interface().RemoveProtocol(this);
81	free(fType);
82}
83
84
85/*!	\brief This should uninit the protocol before it gets deleted.
86
87	You may want to remove all routes of this protocol.
88*/
89void
90KPPPProtocol::Uninit()
91{
92	// do nothing by default
93}
94
95
96/*!	\brief Allows private extensions.
97
98	If you override this method you must call the parent's method for unknown ops.
99*/
100status_t
101KPPPProtocol::Control(uint32 op, void *data, size_t length)
102{
103	switch (op) {
104		case PPPC_GET_PROTOCOL_INFO:
105		{
106			if (length < sizeof(ppp_protocol_info_t) || !data)
107				return B_ERROR;
108
109			ppp_protocol_info *info = (ppp_protocol_info*) data;
110			memset(info, 0, sizeof(ppp_protocol_info_t));
111			if (Name())
112				strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
113			if (Type())
114				strncpy(info->type, Type(), PPP_HANDLER_NAME_LENGTH_LIMIT);
115			info->activationPhase = ActivationPhase();
116			info->addressFamily = AddressFamily();
117			info->flags = Flags();
118			info->side = Side();
119			info->level = Level();
120			info->overhead = Overhead();
121			info->connectionPhase = fConnectionPhase;
122			info->protocolNumber = ProtocolNumber();
123			info->isEnabled = IsEnabled();
124			info->isUpRequested = IsUpRequested();
125			break;
126		}
127
128		case PPPC_ENABLE:
129			if (length < sizeof(uint32) || !data)
130				return B_ERROR;
131
132			SetEnabled(*((uint32*)data));
133			break;
134
135		default:
136			return B_BAD_VALUE;
137	}
138
139	return B_OK;
140}
141
142
143//!	Stack ioctl handler.
144status_t
145KPPPProtocol::StackControl(uint32 op, void *data)
146{
147	switch (op) {
148		default:
149			return B_BAD_VALUE;
150	}
151
152	return B_OK;
153}
154
155
156/*!	\brief Enables or disables this protocol.
157
158	A disabled protocol is ignored and Up() is not called!
159*/
160void
161KPPPProtocol::SetEnabled(bool enabled)
162{
163	fEnabled = enabled;
164
165	if (!enabled) {
166		if (IsUp() || IsGoingUp())
167			Down();
168	} else if (!IsUp() && !IsGoingUp() && IsUpRequested() && Interface().IsUp())
169		Up();
170}
171
172
173//!	Returns if this protocol is allowed to send a packet (enabled, up, etc.).
174bool
175KPPPProtocol::IsAllowedToSend() const
176{
177	return IsEnabled() && IsUp() && IsProtocolAllowed(*this);
178}
179
180
181/*!	\brief Report that the protocol is going up.
182
183	Called by Up(). \n
184	From now on, the connection attempt can may be aborted by calling Down().
185*/
186void
187KPPPProtocol::UpStarted()
188{
189	fConnectionPhase = PPP_ESTABLISHMENT_PHASE;
190}
191
192
193/*!	\brief Report that the protocol is going down.
194
195	Called by Down().
196*/
197void
198KPPPProtocol::DownStarted()
199{
200	fConnectionPhase = PPP_TERMINATION_PHASE;
201}
202
203
204/*!	\brief Reports that we failed going up. May only be called after Up() was called.
205
206	Authenticators \e must call the state machine's authentication notification first!
207*/
208void
209KPPPProtocol::UpFailedEvent()
210{
211	fConnectionPhase = PPP_DOWN_PHASE;
212	Interface().StateMachine().UpFailedEvent(this);
213}
214
215
216/*!	\brief Reports that we went up. May only be called after Up() was called.
217
218	Authenticators \e must call the state machine's authentication notification first!
219*/
220void
221KPPPProtocol::UpEvent()
222{
223	fConnectionPhase = PPP_ESTABLISHED_PHASE;
224	Interface().StateMachine().UpEvent(this);
225}
226
227
228/*!	\brief Reports that we went down. This may be called to indicate connection loss.
229
230	Authenticators \e must call the state machine's authentication notification first!
231*/
232void
233KPPPProtocol::DownEvent()
234{
235	fConnectionPhase = PPP_DOWN_PHASE;
236	Interface().StateMachine().DownEvent(this);
237}
238