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