| 231 | } |
| 232 | |
| 233 | void LinuxNetworkConfigMonitor::process_message(nlmsghdr* header) |
| 234 | { |
| 235 | switch (header->nlmsg_type) { |
| 236 | case NLMSG_ERROR: |
| 237 | { |
| 238 | const nlmsgerr* msg = reinterpret_cast<nlmsgerr*>(NLMSG_DATA(header)); |
| 239 | if (log_level >= LogLevel::Error) { |
| 240 | ACE_ERROR((LM_ERROR, "(%P|%t) ERROR: LinuxNetworkConfigMonitor::process_message: NETLINK error: %C\n", strerror(-msg->error))); |
| 241 | } |
| 242 | } |
| 243 | break; |
| 244 | case RTM_NEWADDR: |
| 245 | case RTM_DELADDR: |
| 246 | { |
| 247 | ifaddrmsg* msg = reinterpret_cast<ifaddrmsg*>(NLMSG_DATA(header)); |
| 248 | size_t address_length = 0; |
| 249 | switch (msg->ifa_family) { |
| 250 | case AF_INET: |
| 251 | address_length = 4; |
| 252 | break; |
| 253 | case AF_INET6: |
| 254 | address_length = 16; |
| 255 | break; |
| 256 | default: |
| 257 | return; |
| 258 | } |
| 259 | unsigned int rta_length = IFA_PAYLOAD(header); |
| 260 | const int address_length_int = static_cast<int>(address_length); |
| 261 | const bool new_addr = header->nlmsg_type == RTM_NEWADDR; |
| 262 | for (rtattr* attr = reinterpret_cast<rtattr*>(IFA_RTA(msg)); |
| 263 | RTA_OK(attr, rta_length); |
| 264 | attr = RTA_NEXT(attr, rta_length)) { |
| 265 | if (attr->rta_type == IFA_ADDRESS) { |
| 266 | if (RTA_PAYLOAD(attr) != address_length) { |
| 267 | if (log_level >= LogLevel::Warning) { |
| 268 | ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: LinuxNetworkConfigMonitor::process_message: incorrect address byte count\n")); |
| 269 | } |
| 270 | return; |
| 271 | } |
| 272 | |
| 273 | const char* addr_str = reinterpret_cast<const char*>(RTA_DATA(attr)); |
| 274 | const int ifa_index = static_cast<int>(msg->ifa_index); |
| 275 | if (new_addr) { |
| 276 | ACE_INET_Addr addr; |
| 277 | addr.set_address(addr_str, address_length_int, 0); |
| 278 | NetworkInterfaceMap::const_iterator pos = network_interface_map_.find(ifa_index); |
| 279 | if (pos != network_interface_map_.end()) { |
| 280 | set(NetworkInterfaceAddress(pos->second.name, pos->second.can_multicast, NetworkAddress(addr))); |
| 281 | } else if (log_level >= LogLevel::Warning) { |
| 282 | ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: LinuxNetworkConfigMonitor::process_message: cannot find interface for address\n")); |
| 283 | } |
| 284 | } else { |
| 285 | NetworkInterfaceMap::iterator pos = network_interface_map_.find(ifa_index); |
| 286 | if (pos != network_interface_map_.end()) { |
| 287 | ACE_INET_Addr addr; |
| 288 | addr.set_address(addr_str, address_length_int, 0); |
| 289 | remove_address(pos->second.name, NetworkAddress(addr)); |
| 290 | } |
nothing calls this directly
no test coverage detected