xref: /haiku/src/add-ons/kernel/network/stack/interfaces.h (revision 1294543de9ac0eff000eaea1b18368c36435d08e)
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 			int32				IndexOfAddress(InterfaceAddress* address);
133 			size_t				CountAddresses();
134 			void				RemoveAddresses();
135 
136 			status_t			Control(net_domain* domain, int32 option,
137 									ifreq& request, ifreq* userRequest,
138 									size_t length);
139 
140 			void				SetDown();
141 			void				WentDown();
142 
143 			recursive_lock&		Lock() { return fLock; }
144 
145 			net_device_interface* DeviceInterface() { return fDeviceInterface; }
146 
147 			status_t			CreateDomainDatalinkIfNeeded(
148 									net_domain* domain);
149 			domain_datalink*	DomainDatalink(uint8 family);
150 			domain_datalink*	DomainDatalink(net_domain* domain)
151 									{ return DomainDatalink(domain->family); }
152 
153 #if ENABLE_DEBUGGER_COMMANDS
154 			void				Dump() const;
155 #endif
156 
157 private:
158 			status_t			_SetUp();
159 			InterfaceAddress*	_FirstForFamily(int family);
160 			status_t			_ChangeAddress(RecursiveLocker& locker,
161 									InterfaceAddress* address, int32 option,
162 									const sockaddr* oldAddress,
163 									const sockaddr* newAddress);
164 
165 private:
166 			recursive_lock		fLock;
167 			net_device_interface* fDeviceInterface;
168 			AddressList			fAddresses;
169 			DatalinkTable		fDatalinkTable;
170 };
171 
172 typedef DoublyLinkedList<Interface> InterfaceList;
173 
174 
175 status_t init_interfaces();
176 status_t uninit_interfaces();
177 
178 // interfaces
179 status_t add_interface(const char* name, net_domain_private* domain,
180 	const ifaliasreq& request, net_device_interface* deviceInterface);
181 void remove_interface(Interface* interface);
182 void interface_removed_device_interface(net_device_interface* deviceInterface);
183 
184 status_t add_interface_address(Interface* interface, net_domain_private* domain,
185 	const ifaliasreq& request);
186 status_t update_interface_address(InterfaceAddress* interfaceAddress,
187 	int32 option, const sockaddr* oldAddress, const sockaddr* newAddress);
188 
189 Interface* get_interface(net_domain* domain, uint32 index);
190 Interface* get_interface(net_domain* domain, const char* name);
191 Interface* get_interface_for_device(net_domain* domain, uint32 index);
192 Interface* get_interface_for_link(net_domain* domain, const sockaddr* address);
193 InterfaceAddress* get_interface_address(const struct sockaddr* address);
194 InterfaceAddress* get_interface_address_for_destination(net_domain* domain,
195 	const sockaddr* destination);
196 InterfaceAddress* get_interface_address_for_link(net_domain* domain,
197 	const sockaddr* linkAddress, bool unconfiguredOnly);
198 
199 uint32 count_interfaces();
200 status_t list_interfaces(int family, void* buffer, size_t* _bufferSize);
201 
202 
203 #endif	// INTERFACES_H
204