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