1 /* 2 * Copyright 2018, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "address_assigner.h" 18 19 #include "log.h" 20 21 #include <errno.h> 22 #include <net/if.h> 23 #include <string.h> 24 #include <sys/socket.h> 25 #include <sys/types.h> 26 #include <unistd.h> 27 28 AddressAssigner::AddressAssigner(const char* interfacePrefix, 29 in_addr_t baseAddress, 30 uint32_t maskLength) : 31 mInterfacePrefix(interfacePrefix), 32 mPrefixLength(strlen(interfacePrefix)), 33 mBaseAddress(baseAddress), 34 mMaskLength(maskLength) { 35 36 } 37 38 void AddressAssigner::onInterfaceState(unsigned int /*index*/, 39 const char* name, 40 InterfaceState state) { 41 if (strncmp(name, mInterfacePrefix, mPrefixLength) != 0) { 42 // The interface does not match the prefix, ignore this change 43 return; 44 } 45 46 switch (state) { 47 case InterfaceState::Up: 48 assignAddress(name); 49 break; 50 case InterfaceState::Down: 51 freeAddress(name); 52 break; 53 } 54 } 55 56 void AddressAssigner::assignAddress(const char* interfaceName) { 57 if (mMaskLength > 30) { 58 // The mask length is too long, we can't assign enough IP addresses from 59 // this. A maximum of 30 bits is supported, leaving 4 remaining 60 // addresses, one is network, one is broadcast, one is gateway, one is 61 // client. 62 return; 63 } 64 // Each subnet will have an amount of bits available to it that equals 65 // 32-bits - <mask length>, so if mask length is 29 there will be 3 66 // remaining bits for each subnet. Then the distance between each subnet 67 // is 2 to the power of this number, in our example 2^3 = 8 so to get to the 68 // next subnet we add 8 to the network address. 69 in_addr_t increment = 1 << (32 - mMaskLength); 70 71 // Convert the address to host byte-order first so we can do math on it. 72 for (in_addr_t addr = ntohl(mBaseAddress); true; addr += increment) { 73 // Take the reference of this lookup, that way we can assign a name to 74 // it if needed. 75 auto& usedName = mUsedIpAddresses[addr]; 76 if (usedName.empty()) { 77 // This address is not in use, let's use it 78 usedName = interfaceName; 79 // Make sure we convert back to network byte-order when setting it. 80 setIpAddress(interfaceName, htonl(addr)); 81 break; 82 } 83 } 84 } 85 86 void AddressAssigner::setIpAddress(const char* interfaceName, 87 in_addr_t address) { 88 int sock = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); 89 if (sock == -1) { 90 LOGE("AddressAssigner unable to open IP socket: %s", strerror(errno)); 91 return; 92 } 93 if (!setAddress(sock, SIOCSIFADDR, interfaceName, address)) { 94 LOGE("AddressAssigner unable to set interface address: %s", 95 strerror(errno)); 96 ::close(sock); 97 return; 98 } 99 100 // The netmask is the inverted maximum value of the lower bits. That is if 101 // the mask length is 29 then the the largest value of the 3 (32-29) lowest 102 // bits is 7 (2^3 - 1) (111 binary). Inverting this value gives the netmask 103 // because it excludes those three bits and sets every other bit. 104 in_addr_t netmask = htonl(~((1 << (32 - mMaskLength)) - 1)); 105 106 if (!setAddress(sock, SIOCSIFNETMASK, interfaceName, netmask)) { 107 LOGE("AddressAssigner unable to set interface netmask: %s", 108 strerror(errno)); 109 ::close(sock); 110 return; 111 } 112 113 // The broadcast address is just the assigned address with all bits outside 114 // of the netmask set to one. 115 in_addr_t broadcast = address | ~netmask; 116 117 if (!setAddress(sock, SIOCSIFBRDADDR, interfaceName, broadcast)) { 118 LOGE("AddressAssigner unable to set interface broadcast: %s", 119 strerror(errno)); 120 ::close(sock); 121 return; 122 } 123 ::close(sock); 124 } 125 126 bool AddressAssigner::setAddress(int sock, 127 int type, 128 const char* interfaceName, 129 in_addr_t address) { 130 struct ifreq request; 131 memset(&request, 0, sizeof(request)); 132 strlcpy(request.ifr_name, interfaceName, sizeof(request.ifr_name)); 133 auto addr = reinterpret_cast<struct sockaddr_in*>(&request.ifr_addr); 134 addr->sin_family = AF_INET; 135 addr->sin_addr.s_addr = address; 136 137 if (::ioctl(sock, type, &request) != 0) { 138 return false; 139 } 140 return true; 141 } 142 143 void AddressAssigner::freeAddress(const char* interfaceName) { 144 for (auto& ipName : mUsedIpAddresses) { 145 if (ipName.second == interfaceName) { 146 // This is the one, free it up for future use 147 mUsedIpAddresses.erase(ipName.first); 148 } 149 } 150 } 151 152