xref: /haiku/src/add-ons/kernel/network/ppp/shared/libppp/PPPInterface.cpp (revision f2b4344867e97c3f4e742a1b4a15e6879644601a)
1 /*
2  * Copyright 2003-2007, Waldemar Kornewald <wkornew@gmx.net>
3  * Distributed under the terms of the MIT License.
4  */
5 
6 /*!	\class PPPInterface
7 	\brief This class represents a PPP interface living in kernel space.
8 
9 	Use this class to control PPP interfaces and get the current interface settings.
10 	You can also use it to enable/disable report messages.
11 */
12 
13 #include "PPPInterface.h"
14 
15 #include <cstring>
16 #include <unistd.h>
17 #include "_libppputils.h"
18 
19 #include <Path.h>
20 #include <Directory.h>
21 #include <Entry.h>
22 
23 
24 /*!	\brief Sets the interface to \a ID.
25 
26 	\param ID The ID of the new interface.
27 */
28 PPPInterface::PPPInterface(ppp_interface_id ID)
29 {
30 	fFD = open(get_stack_driver_path(), O_RDWR);
31 
32 	SetTo(ID);
33 }
34 
35 
36 //!	Copy constructor.
37 PPPInterface::PPPInterface(const PPPInterface& copy)
38 {
39 	fFD = open(get_stack_driver_path(), O_RDWR);
40 
41 	SetTo(copy.ID());
42 }
43 
44 
45 //!	Destructor.
46 PPPInterface::~PPPInterface()
47 {
48 	if (fFD >= 0)
49 		close(fFD);
50 }
51 
52 
53 /*!	\brief Checks if object was created correctly.
54 
55 	You should always call this method after you constructed a PPPInterface object.
56 
57 	\return
58 		- \c B_OK: Object could be initialized successfully and the interface exists.
59 		- \c B_BAD_INDEX: The interface does not exist.
60 		- \c B_ERROR: The PPP stack could not be loaded.
61 */
62 status_t
63 PPPInterface::InitCheck() const
64 {
65 	if (fFD < 0)
66 		return B_ERROR;
67 	if (fID == PPP_UNDEFINED_INTERFACE_ID)
68 		return B_BAD_INDEX;
69 
70 	return B_OK;
71 }
72 
73 
74 /*!	\brief Changes the current interface.
75 
76 	If this fails it will set the interface's \a ID to \c PPP_UNDEFINED_INTERFACE_ID.
77 
78 	\param ID The ID of the new interface.
79 
80 	\return
81 		- \c B_OK: Object could be initialized successfully and the interface exists.
82 		- \c B_BAD_INDEX: The interface does not exist.
83 		- any other value: The PPP stack could not be loaded.
84 
85 	\sa Control()
86 */
87 status_t
88 PPPInterface::SetTo(ppp_interface_id ID)
89 {
90 	if (fFD < 0)
91 		return B_ERROR;
92 
93 	ppp_interface_info_t info;
94 	if (GetInterfaceInfo(&info)) {
95 		fName = info.info.name;
96 		fID = ID;
97 	} else {
98 		fName = "";
99 		fID = PPP_UNDEFINED_INTERFACE_ID;
100 		return B_ERROR;
101 	}
102 
103 	return B_OK;
104 }
105 
106 
107 /*!	\brief Use this method for accessing additional PPP features.
108 
109 	\param op Any value of ppp_control_ops.
110 	\param data Some ops require you to pass a structure or other data using this
111 		argument.
112 	\param length Make sure this value is correct (e.g.: size of structure).
113 
114 	\return
115 		- \c B_OK: Operation was successful.
116 		- \c B_BAD_INDEX: The interface does not exist.
117 		- any other value: The PPP stack could not be loaded.
118 */
119 status_t
120 PPPInterface::Control(uint32 op, void *data, size_t length) const
121 {
122 	if (InitCheck() != B_OK)
123 		return InitCheck();
124 
125 	ppp_control_info control;
126 	control_net_module_args args;
127 
128 	args.name = PPP_INTERFACE_MODULE_NAME;
129 	args.op = PPPC_CONTROL_INTERFACE;
130 	args.data = &control;
131 	args.length = sizeof(control);
132 
133 	control.index = ID();
134 	control.op = op;
135 	control.data = data;
136 	control.length = length;
137 
138 	return ioctl(fFD, NET_STACK_CONTROL_NET_MODULE, &args);
139 }
140 
141 
142 //!	Sets the username used for authentication.
143 bool
144 PPPInterface::SetUsername(const char *username) const
145 {
146 	if (InitCheck() != B_OK || !username)
147 		return false;
148 
149 	return Control(PPPC_SET_USERNAME, const_cast<char*>(username), strlen(username))
150 		== B_OK;
151 }
152 
153 
154 //!	Sets the password used for authentication.
155 bool
156 PPPInterface::SetPassword(const char *password) const
157 {
158 	if (InitCheck() != B_OK || !password)
159 		return false;
160 
161 	return Control(PPPC_SET_PASSWORD, const_cast<char*>(password), strlen(password))
162 		== B_OK;
163 }
164 
165 
166 //!	Sets whether a request window should be shown before connecting.
167 bool
168 PPPInterface::SetAskBeforeConnecting(bool askBeforeConnecting) const
169 {
170 	if (InitCheck() != B_OK)
171 		return false;
172 
173 	uint32 value = askBeforeConnecting ? 1 : 0;
174 	return Control(PPPC_SET_ASK_BEFORE_CONNECTING, &value, sizeof(value)) == B_OK;
175 }
176 
177 
178 /*!	\brief Find BEntry to the interface settings that this object represents.
179 
180 	\param entry The entry gets stored in this argument.
181 
182 	\return
183 		- \c B_OK: The settings file was saved in \a entry.
184 		- \c B_BAD_INDEX: The interface does not exist.
185 		- \c B_BAD_VALUE: Either \a entry was \c NULL or the interface is anonymous.
186 		- any other value: The interface could not be found.
187 */
188 status_t
189 PPPInterface::GetSettingsEntry(BEntry *entry) const
190 {
191 	if (InitCheck() != B_OK)
192 		return InitCheck();
193 	else if (!entry || strlen(Name()) == 0)
194 		return B_BAD_VALUE;
195 
196 	BDirectory directory(PTP_INTERFACE_SETTINGS_PATH);
197 	return directory.FindEntry(Name(), entry, true);
198 }
199 
200 
201 /*!	\brief Get the ppp_interface_info_t structure.
202 
203 	\return \c true on success, \c false otherwise.
204 */
205 bool
206 PPPInterface::GetInterfaceInfo(ppp_interface_info_t *info) const
207 {
208 	if (InitCheck() != B_OK || !info)
209 		return false;
210 
211 	return Control(PPPC_GET_INTERFACE_INFO, &info, sizeof(ppp_interface_info_t))
212 		== B_OK;
213 }
214 
215 
216 /*!	\brief Get transfer statistics for this interface.
217 
218 	\param statistics The structure is copied into this argument.
219 
220 	\return \c true on success, \c false otherwise.
221 */
222 bool
223 PPPInterface::GetStatistics(ppp_statistics *statistics) const
224 {
225 	if (!statistics)
226 		return false;
227 
228 	return Control(PPPC_GET_STATISTICS, statistics, sizeof(ppp_statistics)) == B_OK;
229 }
230 
231 
232 //!	Compares interface's settings to given driver_settings structure.
233 bool
234 PPPInterface::HasSettings(const driver_settings *settings) const
235 {
236 	if (InitCheck() != B_OK || !settings)
237 		return false;
238 
239 	if (Control(PPPC_HAS_INTERFACE_SETTINGS, const_cast<driver_settings*>(settings),
240 			sizeof(driver_settings)) == B_OK)
241 		return true;
242 
243 	return false;
244 }
245 
246 
247 //!	Brings the interface up.
248 bool
249 PPPInterface::Up() const
250 {
251 	if (InitCheck() != B_OK)
252 		return false;
253 
254 	int32 id = ID();
255 	control_net_module_args args;
256 	args.name = PPP_INTERFACE_MODULE_NAME;
257 	args.op = PPPC_BRING_INTERFACE_UP;
258 	args.data = &id;
259 	args.length = sizeof(id);
260 
261 	return ioctl(fFD, NET_STACK_CONTROL_NET_MODULE, &args) == B_OK;
262 }
263 
264 
265 //!	Brings the interface down which causes the deletion of the interface.
266 bool
267 PPPInterface::Down() const
268 {
269 	if (InitCheck() != B_OK)
270 		return false;
271 
272 	int32 id = ID();
273 	control_net_module_args args;
274 	args.name = PPP_INTERFACE_MODULE_NAME;
275 	args.op = PPPC_BRING_INTERFACE_DOWN;
276 	args.data = &id;
277 	args.length = sizeof(id);
278 
279 	return ioctl(fFD, NET_STACK_CONTROL_NET_MODULE, &args) == B_OK;
280 }
281 
282 
283 /*!	\brief Requests report messages from the interface.
284 
285 	\param type The type of report.
286 	\param thread Receiver thread.
287 	\param flags Optional flags.
288 
289 	\return \c true on success \c false otherwise.
290 */
291 bool
292 PPPInterface::EnableReports(ppp_report_type type, thread_id thread,
293 	int32 flags) const
294 {
295 	ppp_report_request request;
296 	request.type = type;
297 	request.thread = thread;
298 	request.flags = flags;
299 
300 	return Control(PPPC_ENABLE_REPORTS, &request, sizeof(request)) == B_OK;
301 }
302 
303 
304 /*!	\brief Removes thread from list of report requestors of this interface.
305 
306 	\param type The type of report.
307 	\param thread Receiver thread.
308 
309 	\return \c true on success \c false otherwise.
310 */
311 bool
312 PPPInterface::DisableReports(ppp_report_type type, thread_id thread) const
313 {
314 	ppp_report_request request;
315 	request.type = type;
316 	request.thread = thread;
317 
318 	return Control(PPPC_DISABLE_REPORTS, &request, sizeof(request)) == B_OK;
319 }
320