xref: /haiku/src/add-ons/kernel/network/stack/interfaces.h (revision 910ffb32fee4d6e04cd47f915a0e4e5292e05e0e)
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 #ifndef INTERFACES_H
9 #define INTERFACES_H
10 
11 
12 #include "routes.h"
13 #include "stack_private.h"
14 
15 #include <net_datalink.h>
16 #include <net_stack.h>
17 
18 #include <Referenceable.h>
19 
20 #include <util/AutoLock.h>
21 #include <util/DoublyLinkedList.h>
22 #include <util/OpenHashTable.h>
23 
24 
25 struct net_device_interface;
26 
27 
28 // Additional address flags
29 #define IFAF_DIRECT_ADDRESS		0x1000
30 
31 
32 struct InterfaceAddress : DoublyLinkedListLinkImpl<InterfaceAddress>,
33 		net_interface_address, Referenceable {
34 								InterfaceAddress();
35 								InterfaceAddress(net_interface* interface,
36 									net_domain* domain);
37 	virtual						~InterfaceAddress();
38 
39 			status_t			SetTo(const ifaliasreq& request);
40 
41 			status_t			SetLocal(const sockaddr* to);
42 			status_t			SetDestination(const sockaddr* to);
43 			status_t			SetMask(const sockaddr* to);
44 
45 			sockaddr**			AddressFor(int32 option);
46 
47 			void				AddDefaultRoutes(int32 option);
48 			void				RemoveDefaultRoutes(int32 option);
49 
50 			InterfaceAddress*&	HashTableLink() { return fLink; }
51 
52 #if ENABLE_DEBUGGER_COMMANDS
53 			void				Dump(size_t index = 0,
54 									bool hideInterface = false);
55 #endif
56 
57 	static	status_t			Set(sockaddr** _address, const sockaddr* to);
58 	static	sockaddr*			Prepare(sockaddr** _address, size_t length);
59 
60 private:
61 			void				_Init(net_interface* interface,
62 									net_domain* domain);
63 
64 private:
65 			InterfaceAddress*	fLink;
66 };
67 
68 typedef DoublyLinkedList<InterfaceAddress> AddressList;
69 
70 struct domain_datalink {
71 	domain_datalink*	hash_link;
72 	net_domain*			domain;
73 
74 	struct net_datalink_protocol* first_protocol;
75 	struct net_datalink_protocol_module_info* first_info;
76 
77 	// support for binding to an interface
78 	net_route_private	direct_route;
79 	InterfaceAddress	direct_address;
80 };
81 
82 struct DatalinkHashDefinition {
83 	typedef const int KeyType;
84 	typedef domain_datalink ValueType;
85 
86 	DatalinkHashDefinition()
87 	{
88 	}
89 
90 	size_t HashKey(const KeyType& key) const
91 	{
92 		return (size_t)key;
93 	}
94 
95 	size_t Hash(domain_datalink* datalink) const
96 	{
97 		return datalink->domain->family;
98 	}
99 
100 	bool Compare(const KeyType& key, domain_datalink* datalink) const
101 	{
102 		return datalink->domain->family == key;
103 	}
104 
105 	domain_datalink*& GetLink(domain_datalink* datalink) const
106 	{
107 		return datalink->hash_link;
108 	}
109 };
110 
111 typedef BOpenHashTable<DatalinkHashDefinition, true, true> DatalinkTable;
112 
113 
114 class Interface : public DoublyLinkedListLinkImpl<Interface>,
115 		public net_interface, public Referenceable {
116 public:
117 								Interface(const char* name,
118 									net_device_interface* deviceInterface);
119 	virtual						~Interface();
120 
121 			InterfaceAddress*	FirstForFamily(int family);
122 			InterfaceAddress*	FirstUnconfiguredForFamily(int family);
123 			InterfaceAddress*	AddressForDestination(net_domain* domain,
124 									const sockaddr* destination);
125 			InterfaceAddress*	AddressForLocal(net_domain* domain,
126 									const sockaddr* local);
127 
128 			status_t			AddAddress(InterfaceAddress* address);
129 			void				RemoveAddress(InterfaceAddress* address);
130 			bool				GetNextAddress(InterfaceAddress** _address);
131 			InterfaceAddress*	AddressAt(size_t index);
132 			size_t				CountAddresses();
133 			void				RemoveAddresses();
134 
135 			status_t			Control(net_domain* domain, int32 option,
136 									ifreq& request, ifreq* userRequest,
137 									size_t length);
138 
139 			void				SetDown();
140 			void				WentDown();
141 
142 			recursive_lock&		Lock() { return fLock; }
143 
144 			net_device_interface* DeviceInterface() { return fDeviceInterface; }
145 
146 			status_t			CreateDomainDatalinkIfNeeded(
147 									net_domain* domain);
148 			domain_datalink*	DomainDatalink(uint8 family);
149 			domain_datalink*	DomainDatalink(net_domain* domain)
150 									{ return DomainDatalink(domain->family); }
151 
152 #if ENABLE_DEBUGGER_COMMANDS
153 			void				Dump() const;
154 #endif
155 
156 private:
157 			status_t			_SetUp();
158 			InterfaceAddress*	_FirstForFamily(int family);
159 			status_t			_ChangeAddress(RecursiveLocker& locker,
160 									InterfaceAddress* address, int32 option,
161 									const sockaddr* oldAddress,
162 									const sockaddr* newAddress);
163 
164 private:
165 			recursive_lock		fLock;
166 			net_device_interface* fDeviceInterface;
167 			AddressList			fAddresses;
168 			DatalinkTable		fDatalinkTable;
169 };
170 
171 typedef DoublyLinkedList<Interface> InterfaceList;
172 
173 
174 status_t init_interfaces();
175 status_t uninit_interfaces();
176 
177 // interfaces
178 status_t add_interface(const char* name, net_domain_private* domain,
179 	const ifaliasreq& request, net_device_interface* deviceInterface);
180 void remove_interface(Interface* interface);
181 void interface_removed_device_interface(net_device_interface* deviceInterface);
182 
183 status_t add_interface_address(Interface* interface, net_domain_private* domain,
184 	const ifaliasreq& request);
185 status_t update_interface_address(InterfaceAddress* interfaceAddress,
186 	int32 option, const sockaddr* oldAddress, const sockaddr* newAddress);
187 
188 Interface* get_interface(net_domain* domain, uint32 index);
189 Interface* get_interface(net_domain* domain, const char* name);
190 Interface* get_interface_for_device(net_domain* domain, uint32 index);
191 Interface* get_interface_for_link(net_domain* domain, const sockaddr* address);
192 InterfaceAddress* get_interface_address(const struct sockaddr* address);
193 InterfaceAddress* get_interface_address_for_destination(net_domain* domain,
194 	const sockaddr* destination);
195 InterfaceAddress* get_interface_address_for_link(net_domain* domain,
196 	const sockaddr* linkAddress, bool unconfiguredOnly);
197 
198 uint32 count_interfaces();
199 status_t list_interfaces(int family, void* buffer, size_t* _bufferSize);
200 
201 
202 #endif	// INTERFACES_H
203