xref: /haiku/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPProtocol.cpp (revision 1acbe440b8dd798953bec31d18ee589aa3f71b73)
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 */
41 KPPPProtocol::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.
78 KPPPProtocol::~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 */
89 void
90 KPPPProtocol::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 */
100 status_t
101 KPPPProtocol::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.
144 status_t
145 KPPPProtocol::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 */
160 void
161 KPPPProtocol::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.).
174 bool
175 KPPPProtocol::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 */
186 void
187 KPPPProtocol::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 */
197 void
198 KPPPProtocol::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 */
208 void
209 KPPPProtocol::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 */
220 void
221 KPPPProtocol::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 */
232 void
233 KPPPProtocol::DownEvent()
234 {
235 	fConnectionPhase = PPP_DOWN_PHASE;
236 	Interface().StateMachine().DownEvent(this);
237 }
238