xref: /haiku/src/add-ons/kernel/network/ppp/ppp_manager/KPPPManager.cpp (revision 632e56d8e514ba6ac41f582ce580e51a3cd8922e)
1 /*
2  * Copyright 2006-2014, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Axel Dörfler, axeld@pinc-software.de
7  *		Lin Longzhou, linlongzhou@163.com
8  */
9 
10 #include <net_stack.h>
11 #include <NetBufferUtilities.h>
12 
13 #include <KernelExport.h>
14 
15 #include <lock.h>
16 #include <util/AutoLock.h>
17 #include <util/DoublyLinkedList.h>
18 
19 #include <new>
20 
21 #include <ppp_device.h>
22 #include <KPPPManager.h>
23 
24 
25 struct entry_private : ppp_interface_entry, DoublyLinkedListLinkImpl<entry_private> {
26 };
27 
28 static DoublyLinkedList<entry_private> sEntryList;
29 
30 net_buffer_module_info* gBufferModule = NULL;
31 net_stack_module_info* gStackModule = NULL;
32 // static struct net_interface* sinterface;
33 static mutex sListLock;
34 static uint32 ppp_interface_count;
35 
36 
37 //	#pragma mark -
38 static KPPPInterface * GetInterface(ppp_interface_id ID);
39 
40 static ppp_interface_id
41 CreateInterface(const driver_settings *settings, ppp_interface_id parentID)
42 {
43 	MutexLocker _(sListLock); // auto_lock
44 
45 	if (parentID > 0) {
46 		TRACE("Not support Multi_Link yet!\n");
47 		return 0l;
48 	}
49 
50 	if (settings == NULL) {
51 		TRACE("No driver_settings yet!\n");
52 		return 0l;
53 	}
54 
55 	ppp_interface_count++;
56 
57 	if (GetInterface(ppp_interface_count) != NULL)
58 		return 0l;
59 
60 	entry_private* pentry = new (std::nothrow) entry_private;
61 	memset(pentry, 0, sizeof(entry_private));
62 	pentry->accessing = ppp_interface_count;
63 	sEntryList.Add(pentry);
64 
65 	KPPPInterface *device = new (std::nothrow) KPPPInterface(NULL,
66 		pentry, ppp_interface_count, NULL, NULL);
67 
68 	if (device == NULL || pentry == NULL) {
69 		TRACE("device or pentry is NULL\n");
70 		ppp_interface_count--;
71 		return 0l;
72 	}
73 
74 	TRACE("setting ppp_interface_count %ld\n", ppp_interface_count);
75 
76 	return ppp_interface_count; // only support 1 ppp connection right now
77 }
78 
79 
80 static ppp_interface_id
81 CreateInterfaceWithName(const char *name, ppp_interface_id parentID)
82 {
83 	MutexLocker _(sListLock); // auto_lock
84 
85 	if (parentID > 0) {
86 		dprintf("Not support Multi_Link yet!\n");
87 		return(0);
88 	}
89 
90 	if (strncmp(name, "ppp", 3)) {
91 		dprintf("%s is not ppp device!\n", name);
92 		return(0);
93 	}
94 
95 	ppp_interface_count++;
96 	if (GetInterface(ppp_interface_count) != NULL) {
97 		TRACE("PPP Interface already exist!\n");
98 		return 0l;
99 	}
100 
101 	entry_private* pentry = new (std::nothrow) entry_private;
102 	memset(pentry, 0, sizeof(entry_private));
103 	pentry->accessing = ppp_interface_count;
104 	sEntryList.Add(pentry);
105 
106 	KPPPInterface* device = new (std::nothrow) KPPPInterface(name,
107 		pentry, ppp_interface_count, NULL, NULL);
108 
109 
110 	if (device == NULL || pentry == NULL) {
111 		TRACE("can not create ppp interface!\n");
112 		ppp_interface_count--;
113 		return 0l;
114 	}
115 
116 	TRACE("setting ppp_interface_count %ld\n", ppp_interface_count);
117 
118 	return ppp_interface_count;
119 }
120 
121 
122 static bool
123 DeleteInterface(ppp_interface_id ID)
124 {
125 	MutexLocker _(sListLock); // auto_lock
126 
127 	DoublyLinkedList<entry_private>::Iterator iterator
128 		= sEntryList.GetIterator();
129 	while (iterator.HasNext()) {
130 		entry_private* pentry = iterator.Next();
131 		if ((ppp_interface_id)pentry->accessing == ID) {
132 			pentry->deleting = true;
133 			return true;
134 		}
135 	}
136 
137 	return false;
138 }
139 
140 
141 static bool
142 RemoveInterface(ppp_interface_id ID)
143 {
144 	MutexLocker _(sListLock); // auto_lock
145 	if (ID <= 0 || ID > ppp_interface_count)
146 		return false;
147 
148 	DoublyLinkedList<entry_private>::Iterator iterator
149 		= sEntryList.GetIterator();
150 	while (iterator.HasNext()) {
151 		entry_private* pentry = iterator.Next();
152 		if ((ppp_interface_id)pentry->accessing == ID) {
153 			pentry->deleting = true;
154 			break;
155 		}
156 	}
157 
158 	return false;
159 }
160 
161 
162 static net_device *
163 RegisterInterface(ppp_interface_id ID)
164 {
165 	// MutexLocker _(sListLock); // auto_lock
166 
167 	entry_private* entry = NULL;
168 
169 	DoublyLinkedList<entry_private>::Iterator iterator
170 		= sEntryList.GetIterator();
171 	while (iterator.HasNext()) {
172 		entry_private* pentry = iterator.Next();
173 		if ((ppp_interface_id)pentry->accessing == ID) {
174 			entry = pentry;
175 			break;
176 		}
177 	}
178 
179 	if (entry == NULL)
180 		return NULL;
181 
182 	ppp_device *device = new (std::nothrow) ppp_device;
183 	if (device == NULL)
184 		return NULL;
185 
186 	memset(device, 0, sizeof(ppp_device));
187 	device->KPPP_Interface = entry->interface;
188 
189 	return device;
190 }
191 
192 
193 static KPPPInterface *
194 GetInterface(ppp_interface_id ID)
195 {
196 	// MutexLocker _(sListLock); // auto_lock
197 
198 	DoublyLinkedList<entry_private>::Iterator iterator
199 		= sEntryList.GetIterator();
200 	while (iterator.HasNext()) {
201 		entry_private* pentry = iterator.Next();
202 		TRACE("testing interface id:%ld\n", pentry->accessing);
203 		if ((ppp_interface_id)(pentry->accessing) == ID) {
204 			TRACE("get interface id:%ld\n", ID);
205 			return pentry->interface;
206 		}
207 	}
208 
209 	TRACE("can not get interface id:%ld\n", ID);
210 
211 	return NULL;
212 }
213 
214 
215 static bool
216 UnregisterInterface(ppp_interface_id ID)
217 {
218 	MutexLocker _(sListLock); // auto_lock
219 
220 	if (ID <= 0 || ID > ppp_interface_count)
221 		return false;
222 	return true;
223 }
224 
225 
226 static status_t
227 ControlInterface(ppp_interface_id ID, uint32 op, void *data, size_t length)
228 {
229 	MutexLocker _(sListLock); // auto_lock
230 
231 	if (ID <= 0 || ID > ppp_interface_count)
232 		return B_ERROR;
233 
234 	DoublyLinkedList<entry_private>::Iterator iterator
235 		= sEntryList.GetIterator();
236 	while (iterator.HasNext()) {
237 		entry_private* pentry = iterator.Next();
238 		if ((ppp_interface_id)pentry->accessing == ID)
239 			return B_OK;
240 	}
241 
242 	return B_ERROR;
243 }
244 
245 
246 static int32
247 GetInterfaces(ppp_interface_id *interfaces, int32 count, ppp_interface_filter filter)
248 {
249 	MutexLocker _(sListLock);
250 
251 	if (count <= 0 || count > (int32)ppp_interface_count)
252 		return(0);
253 
254 	uint32 ppp_count = 0;
255 
256 	DoublyLinkedList<entry_private>::Iterator iterator
257 		= sEntryList.GetIterator();
258 	while (iterator.HasNext()) {
259 		entry_private* pentry = iterator.Next();
260 		interfaces[ppp_count] = pentry->accessing;
261 		ppp_count++;
262 	}
263 
264 	return ppp_count;
265 }
266 
267 
268 static int32
269 CountInterfaces(ppp_interface_filter filter)
270 {
271 	MutexLocker _(sListLock); // auto_lock
272 
273 	uint32 ppp_count = 0;
274 
275 	DoublyLinkedList<entry_private>::Iterator iterator
276 		= sEntryList.GetIterator();
277 	while (iterator.HasNext()) {
278 		iterator.Next();
279 		ppp_count++;
280 	}
281 
282 	return ppp_count;
283 }
284 
285 
286 static void
287 EnableReports(ppp_report_type type, thread_id thread, int32 flags)
288 {
289 	MutexLocker _(sListLock); // auto_lock
290 
291 	return; // need more portrait
292 }
293 
294 
295 static void
296 DisableReports(ppp_report_type type, thread_id thread)
297 {
298 	MutexLocker _(sListLock); // auto_lock
299 
300 	return; // need more portrait
301 }
302 
303 
304 static bool
305 DoesReport(ppp_report_type type, thread_id thread)
306 {
307 	MutexLocker _(sListLock); // auto_lock
308 
309 	return false; // need more portrait
310 }
311 
312 
313 static status_t
314 KPPPManager_std_ops(int32 op, ...)
315 {
316 	switch (op) {
317 		case B_MODULE_INIT:
318 			mutex_init(&sListLock, "KPPPManager");
319 			new (&sEntryList) DoublyLinkedList<entry_private>;
320 				// static C++ objects are not initialized in the module startup
321 			ppp_interface_count = 0;
322 
323 			if (get_module(NET_STACK_MODULE_NAME, (module_info**)&gStackModule)
324 				!= B_OK)
325 				return B_ERROR;
326 
327 			if (get_module(NET_BUFFER_MODULE_NAME, (module_info**)&gBufferModule)
328 				!= B_OK) {
329 				put_module(NET_STACK_MODULE_NAME);
330 				return B_ERROR;
331 			}
332 
333 			return B_OK;
334 
335 		case B_MODULE_UNINIT:
336 			mutex_destroy(&sListLock);
337 
338 			put_module(NET_BUFFER_MODULE_NAME);
339 			put_module(NET_STACK_MODULE_NAME);
340 			return B_OK;
341 
342 		default:
343 			return B_ERROR;
344 	}
345 }
346 
347 
348 static ppp_interface_module_info sKPPPManagerModule = {
349 	{
350 		PPP_INTERFACE_MODULE_NAME,
351 		0,
352 		KPPPManager_std_ops
353 	},
354 	CreateInterface,
355 	CreateInterfaceWithName,
356 	DeleteInterface,
357 	RemoveInterface,
358 	RegisterInterface,
359 	GetInterface,
360 	UnregisterInterface,
361 	ControlInterface,
362 	GetInterfaces,
363 	CountInterfaces,
364 	EnableReports,
365 	DisableReports,
366 	DoesReport
367 };
368 
369 
370 module_info* modules[] = {
371 	(module_info*)&sKPPPManagerModule,
372 	NULL
373 };
374