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 */
KPPPProtocol(const char * name,ppp_phase activationPhase,uint16 protocolNumber,ppp_level level,int32 addressFamily,uint32 overhead,KPPPInterface & interface,driver_parameter * settings,int32 flags,const char * type,KPPPOptionHandler * optionHandler)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.
~KPPPProtocol()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
Uninit()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
Control(uint32 op,void * data,size_t length)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
StackControl(uint32 op,void * data)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
SetEnabled(bool enabled)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
IsAllowedToSend() const175 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
UpStarted()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
DownStarted()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
UpFailedEvent()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
UpEvent()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
DownEvent()233 KPPPProtocol::DownEvent()
234 {
235 fConnectionPhase = PPP_DOWN_PHASE;
236 Interface().StateMachine().DownEvent(this);
237 }
238