xref: /haiku/src/add-ons/kernel/network/stack/interfaces.h (revision 22440f4105cafc95cc1d49f9bc65bb395c527d86)
1 /*
2  * Copyright 2006-2011, 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, BReferenceable {
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 			bool				LocalIsDefined() const;
51 
52 			InterfaceAddress*&	HashTableLink() { return fLink; }
53 
54 #if ENABLE_DEBUGGER_COMMANDS
55 			void				Dump(size_t index = 0,
56 									bool hideInterface = false);
57 #endif
58 
59 	static	status_t			Set(sockaddr** _address, const sockaddr* to);
60 	static	sockaddr*			Prepare(sockaddr** _address, size_t length);
61 
62 private:
63 			void				_Init(net_interface* interface,
64 									net_domain* domain);
65 
66 private:
67 			InterfaceAddress*	fLink;
68 };
69 
70 typedef DoublyLinkedList<InterfaceAddress> AddressList;
71 
72 struct domain_datalink {
73 	domain_datalink*	hash_link;
74 	net_domain*			domain;
75 
76 	struct net_datalink_protocol* first_protocol;
77 	struct net_datalink_protocol_module_info* first_info;
78 
79 	// support for binding to an interface
80 	net_route_private	direct_route;
81 	InterfaceAddress	direct_address;
82 };
83 
84 struct DatalinkHashDefinition {
85 	typedef const int KeyType;
86 	typedef domain_datalink ValueType;
87 
88 	DatalinkHashDefinition()
89 	{
90 	}
91 
92 	size_t HashKey(const KeyType& key) const
93 	{
94 		return (size_t)key;
95 	}
96 
97 	size_t Hash(domain_datalink* datalink) const
98 	{
99 		return datalink->domain->family;
100 	}
101 
102 	bool Compare(const KeyType& key, domain_datalink* datalink) const
103 	{
104 		return datalink->domain->family == key;
105 	}
106 
107 	domain_datalink*& GetLink(domain_datalink* datalink) const
108 	{
109 		return datalink->hash_link;
110 	}
111 };
112 
113 typedef BOpenHashTable<DatalinkHashDefinition, true, true> DatalinkTable;
114 
115 
116 class Interface : public DoublyLinkedListLinkImpl<Interface>,
117 		public net_interface, public BReferenceable {
118 public:
119 								Interface(const char* name,
120 									net_device_interface* deviceInterface);
121 	virtual						~Interface();
122 
123 			InterfaceAddress*	FirstForFamily(int family);
124 			InterfaceAddress*	FirstUnconfiguredForFamily(int family);
125 			InterfaceAddress*	AddressForDestination(net_domain* domain,
126 									const sockaddr* destination);
127 			InterfaceAddress*	AddressForLocal(net_domain* domain,
128 									const sockaddr* local);
129 
130 			status_t			AddAddress(InterfaceAddress* address);
131 			void				RemoveAddress(InterfaceAddress* address);
132 			bool				GetNextAddress(InterfaceAddress** _address);
133 			InterfaceAddress*	AddressAt(size_t index);
134 			int32				IndexOfAddress(InterfaceAddress* address);
135 			size_t				CountAddresses();
136 			void				RemoveAddresses();
137 
138 			status_t			Control(net_domain* domain, int32 option,
139 									ifreq& request, ifreq* userRequest,
140 									size_t length);
141 
142 			void				SetDown();
143 			void				WentDown();
144 
145 			recursive_lock&		Lock() { return fLock; }
146 
147 			net_device_interface* DeviceInterface() { return fDeviceInterface; }
148 
149 			status_t			CreateDomainDatalinkIfNeeded(
150 									net_domain* domain);
151 			domain_datalink*	DomainDatalink(uint8 family);
152 			domain_datalink*	DomainDatalink(net_domain* domain)
153 									{ return DomainDatalink(domain->family); }
154 
155 #if ENABLE_DEBUGGER_COMMANDS
156 			void				Dump() const;
157 #endif
158 
159 private:
160 			status_t			_SetUp();
161 			InterfaceAddress*	_FirstForFamily(int family);
162 			status_t			_ChangeAddress(RecursiveLocker& locker,
163 									InterfaceAddress* address, int32 option,
164 									const sockaddr* oldAddress,
165 									const sockaddr* newAddress);
166 
167 private:
168 			recursive_lock		fLock;
169 			net_device_interface* fDeviceInterface;
170 			AddressList			fAddresses;
171 			DatalinkTable		fDatalinkTable;
172 };
173 
174 typedef DoublyLinkedList<Interface> InterfaceList;
175 
176 
177 status_t init_interfaces();
178 status_t uninit_interfaces();
179 
180 // interfaces
181 status_t add_interface(const char* name, net_domain_private* domain,
182 	const ifaliasreq& request, net_device_interface* deviceInterface);
183 void remove_interface(Interface* interface);
184 void interface_removed_device_interface(net_device_interface* deviceInterface);
185 
186 status_t add_interface_address(Interface* interface, net_domain_private* domain,
187 	const ifaliasreq& request);
188 status_t update_interface_address(InterfaceAddress* interfaceAddress,
189 	int32 option, const sockaddr* oldAddress, const sockaddr* newAddress);
190 
191 Interface* get_interface(net_domain* domain, uint32 index);
192 Interface* get_interface(net_domain* domain, const char* name);
193 Interface* get_interface_for_device(net_domain* domain, uint32 index);
194 Interface* get_interface_for_link(net_domain* domain, const sockaddr* address);
195 InterfaceAddress* get_interface_address(const struct sockaddr* address);
196 InterfaceAddress* get_interface_address_for_destination(net_domain* domain,
197 	const sockaddr* destination);
198 InterfaceAddress* get_interface_address_for_link(net_domain* domain,
199 	const sockaddr* linkAddress, bool unconfiguredOnly);
200 
201 uint32 count_interfaces();
202 status_t list_interfaces(int family, void* buffer, size_t* _bufferSize);
203 
204 
205 #endif	// INTERFACES_H
206