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