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 39 typedef DoublyLinkedList<net_domain_private> DomainList; 40 41 static mutex sDomainLock; 42 static 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 */ 48 static net_domain_private* 49 lookup_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 66 static int 67 dump_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 */ 110 net_domain* 111 get_domain(int family) 112 { 113 MutexLocker locker(sDomainLock); 114 return lookup_domain(family); 115 } 116 117 118 status_t 119 register_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 149 status_t 150 unregister_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 166 status_t 167 init_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 182 status_t 183 uninit_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