1/* 2 * Copyright 2006-2010, 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 */ 8 9 10#include "domains.h" 11#include "interfaces.h" 12#include "utility.h" 13#include "stack_private.h" 14 15#include <net_device.h> 16#include <NetUtilities.h> 17 18#include <lock.h> 19#include <util/AutoLock.h> 20 21#include <KernelExport.h> 22 23#include <net/if_media.h> 24#include <new> 25#include <string.h> 26#include <sys/sockio.h> 27 28 29#define TRACE_DOMAINS 30#ifdef TRACE_DOMAINS 31# define TRACE(x) dprintf x 32#else 33# define TRACE(x) ; 34#endif 35 36#define ENABLE_DEBUGGER_COMMANDS 1 37 38 39typedef DoublyLinkedList<net_domain_private> DomainList; 40 41static mutex sDomainLock; 42static DomainList sDomains; 43 44 45/*! Scans the domain list for the specified family. 46 You need to hold the sDomainLock when calling this function. 47*/ 48static net_domain_private* 49lookup_domain(int family) 50{ 51 ASSERT_LOCKED_MUTEX(&sDomainLock); 52 53 DomainList::Iterator iterator = sDomains.GetIterator(); 54 while (net_domain_private* domain = iterator.Next()) { 55 if (domain->family == family) 56 return domain; 57 } 58 59 return NULL; 60} 61 62 63#if ENABLE_DEBUGGER_COMMANDS 64 65 66static int 67dump_domains(int argc, char** argv) 68{ 69 DomainList::Iterator iterator = sDomains.GetIterator(); 70 while (net_domain_private* domain = iterator.Next()) { 71 kprintf("domain: %p, %s, %d\n", domain, domain->name, domain->family); 72 kprintf(" module: %p\n", domain->module); 73 kprintf(" address_module: %p\n", domain->address_module); 74 75 if (!domain->routes.IsEmpty()) 76 kprintf(" routes:\n"); 77 78 RouteList::Iterator routeIterator = domain->routes.GetIterator(); 79 while (net_route_private* route = routeIterator.Next()) { 80 kprintf(" %p: dest %s, mask %s, gw %s, flags %" B_PRIx32 ", " 81 "address %p\n", route, AddressString(domain, route->destination 82 ? route->destination : NULL).Data(), 83 AddressString(domain, route->mask ? route->mask : NULL).Data(), 84 AddressString(domain, route->gateway 85 ? route->gateway : NULL).Data(), 86 route->flags, route->interface_address); 87 } 88 89 if (!domain->route_infos.IsEmpty()) 90 kprintf(" route infos:\n"); 91 92 RouteInfoList::Iterator infoIterator = domain->route_infos.GetIterator(); 93 while (net_route_info* info = infoIterator.Next()) { 94 kprintf(" %p\n", info); 95 } 96 } 97 98 return 0; 99} 100 101 102#endif // ENABLE_DEBUGGER_COMMANDS 103 104 105// #pragma mark - 106 107 108/*! Gets the domain of the specified family. 109*/ 110net_domain* 111get_domain(int family) 112{ 113 MutexLocker locker(sDomainLock); 114 return lookup_domain(family); 115} 116 117 118status_t 119register_domain(int family, const char* name, 120 struct net_protocol_module_info* module, 121 struct net_address_module_info* addressModule, 122 net_domain** _domain) 123{ 124 TRACE(("register_domain(%d, %s)\n", family, name)); 125 MutexLocker locker(sDomainLock); 126 127 struct net_domain_private* domain = lookup_domain(family); 128 if (domain != NULL) 129 return B_NAME_IN_USE; 130 131 domain = new(std::nothrow) net_domain_private; 132 if (domain == NULL) 133 return B_NO_MEMORY; 134 135 recursive_lock_init(&domain->lock, name); 136 137 domain->family = family; 138 domain->name = name; 139 domain->module = module; 140 domain->address_module = addressModule; 141 142 sDomains.Add(domain); 143 144 *_domain = domain; 145 return B_OK; 146} 147 148 149status_t 150unregister_domain(net_domain* _domain) 151{ 152 TRACE(("unregister_domain(%p, %d, %s)\n", _domain, _domain->family, 153 _domain->name)); 154 155 net_domain_private* domain = (net_domain_private*)_domain; 156 MutexLocker locker(sDomainLock); 157 158 sDomains.Remove(domain); 159 160 recursive_lock_destroy(&domain->lock); 161 delete domain; 162 return B_OK; 163} 164 165 166status_t 167init_domains() 168{ 169 mutex_init(&sDomainLock, "net domains"); 170 171 new (&sDomains) DomainList; 172 // static C++ objects are not initialized in the module startup 173 174#if ENABLE_DEBUGGER_COMMANDS 175 add_debugger_command("net_domains", &dump_domains, 176 "Dump network domains"); 177#endif 178 return B_OK; 179} 180 181 182status_t 183uninit_domains() 184{ 185#if ENABLE_DEBUGGER_COMMANDS 186 remove_debugger_command("net_domains", &dump_domains); 187#endif 188 189 mutex_destroy(&sDomainLock); 190 return B_OK; 191} 192 193