NetlinkHandler.cpp revision c79bcc491f01b4d7956d7bd01f0e912e22307f41
1/* 2 * Copyright (C) 2008 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 <stdarg.h> 18#include <stdio.h> 19#include <stdlib.h> 20#include <string.h> 21#include <errno.h> 22 23#define LOG_TAG "Netd" 24 25#include <cutils/log.h> 26 27#include <sysutils/NetlinkEvent.h> 28#include "NetlinkHandler.h" 29#include "NetlinkManager.h" 30#include "ResponseCode.h" 31 32NetlinkHandler::NetlinkHandler(NetlinkManager *nm, int listenerSocket, 33 int format) : 34 NetlinkListener(listenerSocket, format) { 35 mNm = nm; 36} 37 38NetlinkHandler::~NetlinkHandler() { 39} 40 41int NetlinkHandler::start() { 42 return this->startListener(); 43} 44 45int NetlinkHandler::stop() { 46 return this->stopListener(); 47} 48 49void NetlinkHandler::onEvent(NetlinkEvent *evt) { 50 const char *subsys = evt->getSubsystem(); 51 if (!subsys) { 52 ALOGW("No subsystem found in netlink event"); 53 return; 54 } 55 56 if (!strcmp(subsys, "net")) { 57 int action = evt->getAction(); 58 const char *iface = evt->findParam("INTERFACE"); 59 60 if (action == evt->NlActionAdd) { 61 notifyInterfaceAdded(iface); 62 } else if (action == evt->NlActionRemove) { 63 notifyInterfaceRemoved(iface); 64 } else if (action == evt->NlActionChange) { 65 evt->dump(); 66 notifyInterfaceChanged("nana", true); 67 } else if (action == evt->NlActionLinkUp) { 68 notifyInterfaceLinkChanged(iface, true); 69 } else if (action == evt->NlActionLinkDown) { 70 notifyInterfaceLinkChanged(iface, false); 71 } else if (action == evt->NlActionAddressUpdated || 72 action == evt->NlActionAddressRemoved) { 73 const char *address = evt->findParam("ADDRESS"); 74 const char *flags = evt->findParam("FLAGS"); 75 const char *scope = evt->findParam("SCOPE"); 76 if (iface && flags && scope) { 77 notifyAddressChanged(action, address, iface, flags, scope); 78 } 79 } else if (action == evt->NlActionRdnss) { 80 const char *lifetime = evt->findParam("LIFETIME"); 81 const char *servers = evt->findParam("SERVERS"); 82 if (lifetime && servers) { 83 notifyInterfaceDnsServers(iface, lifetime, servers); 84 } 85 } 86 87 } else if (!strcmp(subsys, "qlog")) { 88 const char *alertName = evt->findParam("ALERT_NAME"); 89 const char *iface = evt->findParam("INTERFACE"); 90 notifyQuotaLimitReached(alertName, iface); 91 92 } else if (!strcmp(subsys, "xt_idletimer")) { 93 int action = evt->getAction(); 94 const char *label = evt->findParam("INTERFACE"); 95 const char *state = evt->findParam("STATE"); 96 if (state) 97 notifyInterfaceClassActivity(label, !strcmp("active", state)); 98 99#if !LOG_NDEBUG 100 } else if (strcmp(subsys, "platform") && strcmp(subsys, "backlight")) { 101 /* It is not a VSYNC or a backlight event */ 102 ALOGV("unexpected event from subsystem %s", subsys); 103#endif 104 } 105} 106 107void NetlinkHandler::notify(int code, const char *format, ...) { 108 char *msg; 109 va_list args; 110 va_start(args, format); 111 if (vasprintf(&msg, format, args) >= 0) { 112 mNm->getBroadcaster()->sendBroadcast(code, msg, false); 113 free(msg); 114 } else { 115 SLOGE("Failed to send notification: vasprintf: %s", strerror(errno)); 116 } 117 va_end(args); 118} 119 120void NetlinkHandler::notifyInterfaceAdded(const char *name) { 121 notify(ResponseCode::InterfaceChange, "Iface added %s", name); 122} 123 124void NetlinkHandler::notifyInterfaceRemoved(const char *name) { 125 notify(ResponseCode::InterfaceChange, "Iface removed %s", name); 126} 127 128void NetlinkHandler::notifyInterfaceChanged(const char *name, bool isUp) { 129 notify(ResponseCode::InterfaceChange, 130 "Iface changed %s %s", name, (isUp ? "up" : "down")); 131} 132 133void NetlinkHandler::notifyInterfaceLinkChanged(const char *name, bool isUp) { 134 notify(ResponseCode::InterfaceChange, 135 "Iface linkstate %s %s", name, (isUp ? "up" : "down")); 136} 137 138void NetlinkHandler::notifyQuotaLimitReached(const char *name, const char *iface) { 139 notify(ResponseCode::BandwidthControl, "limit alert %s %s", name, iface); 140} 141 142void NetlinkHandler::notifyInterfaceClassActivity(const char *name, 143 bool isActive) { 144 notify(ResponseCode::InterfaceClassActivity, 145 "IfaceClass %s %s", isActive ? "active" : "idle", name); 146} 147 148void NetlinkHandler::notifyAddressChanged(int action, const char *addr, 149 const char *iface, const char *flags, 150 const char *scope) { 151 notify(ResponseCode::InterfaceAddressChange, 152 "Address %s %s %s %s %s", 153 (action == NetlinkEvent::NlActionAddressUpdated) ? 154 "updated" : "removed", addr, iface, flags, scope); 155} 156 157void NetlinkHandler::notifyInterfaceDnsServers(const char *iface, 158 const char *lifetime, 159 const char *servers) { 160 notify(ResponseCode::InterfaceDnsInfo, "DnsInfo servers %s %s %s", 161 iface, lifetime, servers); 162} 163