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