xref: /haiku/src/add-ons/kernel/network/stack/domains.cpp (revision 820dca4df6c7bf955c46e8f6521b9408f50b2900)
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