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