NetlinkEvent.cpp revision b982bce73b7e2c824ffb50115ea382fe45c751a4
1168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat/* 2168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * Copyright (C) 2008 The Android Open Source Project 3168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * 4168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * Licensed under the Apache License, Version 2.0 (the "License"); 5168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * you may not use this file except in compliance with the License. 6168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * You may obtain a copy of the License at 7168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * 8168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * http://www.apache.org/licenses/LICENSE-2.0 9168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * 10168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * Unless required by applicable law or agreed to in writing, software 11168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * distributed under the License is distributed on an "AS IS" BASIS, 12168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * See the License for the specific language governing permissions and 14168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * limitations under the License. 15168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat */ 16168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <stdlib.h> 173d40729054803fae1c4d4bb5ac7554665a132b26San Mehat#include <string.h> 18168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 19168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#define LOG_TAG "NetlinkEvent" 20168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <cutils/log.h> 21168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 22168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <sysutils/NetlinkEvent.h> 23168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 24ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen#include <sys/types.h> 25ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen#include <sys/socket.h> 26ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen#include <linux/if.h> 27e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall#include <linux/netfilter/nfnetlink.h> 28e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall#include <linux/netfilter_ipv4/ipt_ULOG.h> 29e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall/* From kernel's net/netfilter/xt_quota2.c */ 30e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrallconst int QLOG_NL_EVENT = 112; 31e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall 32e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall#include <linux/netlink.h> 33e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall#include <linux/rtnetlink.h> 34ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen 35168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehatconst int NetlinkEvent::NlActionUnknown = 0; 36168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehatconst int NetlinkEvent::NlActionAdd = 1; 37168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehatconst int NetlinkEvent::NlActionRemove = 2; 38168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehatconst int NetlinkEvent::NlActionChange = 3; 39ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chenconst int NetlinkEvent::NlActionLinkUp = 4; 40ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chenconst int NetlinkEvent::NlActionLinkDown = 5; 41168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 42168415b822cae1f8b54ef09c41c11a9b97b87f40San MehatNetlinkEvent::NetlinkEvent() { 43168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat mAction = NlActionUnknown; 44ebfe3db361c51d9d99bf6cfd495bd16bdf815e1fSan Mehat memset(mParams, 0, sizeof(mParams)); 45ebfe3db361c51d9d99bf6cfd495bd16bdf815e1fSan Mehat mPath = NULL; 46ebfe3db361c51d9d99bf6cfd495bd16bdf815e1fSan Mehat mSubsystem = NULL; 47168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat} 48168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 49168415b822cae1f8b54ef09c41c11a9b97b87f40San MehatNetlinkEvent::~NetlinkEvent() { 50168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat int i; 51168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat if (mPath) 52168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat free(mPath); 53168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat if (mSubsystem) 54168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat free(mSubsystem); 55168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat for (i = 0; i < NL_PARAMS_MAX; i++) { 56168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat if (!mParams[i]) 57168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat break; 58168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat free(mParams[i]); 59168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 60168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat} 61168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 62d674413ff460afe1da049e54bb7a489132799749San Mehatvoid NetlinkEvent::dump() { 63d674413ff460afe1da049e54bb7a489132799749San Mehat int i; 64d674413ff460afe1da049e54bb7a489132799749San Mehat 65d674413ff460afe1da049e54bb7a489132799749San Mehat for (i = 0; i < NL_PARAMS_MAX; i++) { 66d674413ff460afe1da049e54bb7a489132799749San Mehat if (!mParams[i]) 67d674413ff460afe1da049e54bb7a489132799749San Mehat break; 687e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGD("NL param '%s'\n", mParams[i]); 69d674413ff460afe1da049e54bb7a489132799749San Mehat } 70d674413ff460afe1da049e54bb7a489132799749San Mehat} 71d674413ff460afe1da049e54bb7a489132799749San Mehat 72ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen/* 73b982bce73b7e2c824ffb50115ea382fe45c751a4JP Abgrall * Parse an binary message from a NETLINK_ROUTE netlink socket. 74ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen */ 75ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chenbool NetlinkEvent::parseBinaryNetlinkMessage(char *buffer, int size) { 76ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen size_t sz = size; 7717260b14682d4fe59dad3de2de8c9370e6ba9a71Mike J. Chen const struct nlmsghdr *nh = (struct nlmsghdr *) buffer; 78ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen 79ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen while (NLMSG_OK(nh, sz) && (nh->nlmsg_type != NLMSG_DONE)) { 80e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall 81ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen if (nh->nlmsg_type == RTM_NEWLINK) { 82ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen int len = nh->nlmsg_len - sizeof(*nh); 83ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen struct ifinfomsg *ifi; 84ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen 85e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall if (sizeof(*ifi) > (size_t) len) { 86e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall SLOGE("Got a short RTM_NEWLINK message\n"); 87e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall continue; 88e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall } 89e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall 90e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall ifi = (ifinfomsg *)NLMSG_DATA(nh); 91e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall if ((ifi->ifi_flags & IFF_LOOPBACK) != 0) { 92e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall continue; 93e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall } 94e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall 95e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall struct rtattr *rta = (struct rtattr *) 96e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall ((char *) ifi + NLMSG_ALIGN(sizeof(*ifi))); 97e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall len = NLMSG_PAYLOAD(nh, sizeof(*ifi)); 98e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall 99e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall while(RTA_OK(rta, len)) { 100e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall switch(rta->rta_type) { 101e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall case IFLA_IFNAME: 102e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall char buffer[16 + IFNAMSIZ]; 103e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall snprintf(buffer, sizeof(buffer), "INTERFACE=%s", 104e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall (char *) RTA_DATA(rta)); 105e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall mParams[0] = strdup(buffer); 106e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall mAction = (ifi->ifi_flags & IFF_LOWER_UP) ? 107e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall NlActionLinkUp : NlActionLinkDown; 108e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall mSubsystem = strdup("net"); 109e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall break; 110ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen } 111e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall 112e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall rta = RTA_NEXT(rta, len); 113ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen } 114ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen 115e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall } else if (nh->nlmsg_type == QLOG_NL_EVENT) { 116e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall char *devname; 117e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall ulog_packet_msg_t *pm; 118e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall size_t len = nh->nlmsg_len - sizeof(*nh); 119e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall if (sizeof(*pm) > len) { 120e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall SLOGE("Got a short QLOG message\n"); 121e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall continue; 122e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall } 123e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall pm = (ulog_packet_msg_t *)NLMSG_DATA(nh); 124e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall devname = pm->indev_name[0] ? pm->indev_name : pm->outdev_name; 125e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall asprintf(&mParams[0], "ALERT_NAME=%s", pm->prefix); 126e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall asprintf(&mParams[1], "INTERFACE=%s", devname); 127e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall mSubsystem = strdup("qlog"); 128e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall mAction = NlActionChange; 129e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall 130e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall } else { 131e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall SLOGD("Unexpected netlink message. type=0x%x\n", nh->nlmsg_type); 132e6f80149a201e02ddd1e251e0690ad100b688cd6JP Abgrall } 133ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen nh = NLMSG_NEXT(nh, size); 134ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen } 135ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen 136ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen return true; 137ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen} 138ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen 1393311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner/* If the string between 'str' and 'end' begins with 'prefixlen' characters 1403311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner * from the 'prefix' array, then return 'str + prefixlen', otherwise return 1413311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner * NULL. 1423311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner */ 1433311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turnerstatic const char* 1443311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turnerhas_prefix(const char* str, const char* end, const char* prefix, size_t prefixlen) 1453311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner{ 1463311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner if ((end-str) >= (ptrdiff_t)prefixlen && !memcmp(str, prefix, prefixlen)) 1473311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner return str + prefixlen; 1483311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner else 1493311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner return NULL; 1503311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner} 1513311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner 1523311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner/* Same as strlen(x) for constant string literals ONLY */ 1533311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner#define CONST_STRLEN(x) (sizeof(x)-1) 1543311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner 1553311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner/* Convenience macro to call has_prefix with a constant string literal */ 1563311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner#define HAS_CONST_PREFIX(str,end,prefix) has_prefix((str),(end),prefix,CONST_STRLEN(prefix)) 1573311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner 1583311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner 159ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen/* 160ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen * Parse an ASCII-formatted message from a NETLINK_KOBJECT_UEVENT 161ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen * netlink socket. 162ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen */ 163ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chenbool NetlinkEvent::parseAsciiNetlinkMessage(char *buffer, int size) { 16417260b14682d4fe59dad3de2de8c9370e6ba9a71Mike J. Chen const char *s = buffer; 16517260b14682d4fe59dad3de2de8c9370e6ba9a71Mike J. Chen const char *end; 166168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat int param_idx = 0; 167168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat int i; 168168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat int first = 1; 169168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 1703311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner if (size == 0) 1713311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner return false; 1723311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner 1733311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner /* Ensure the buffer is zero-terminated, the code below depends on this */ 1743311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner buffer[size-1] = '\0'; 1753311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner 176168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat end = s + size; 177168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat while (s < end) { 178168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat if (first) { 1793311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner const char *p; 1803311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner /* buffer is 0-terminated, no need to check p < end */ 1813311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner for (p = s; *p != '@'; p++) { 1823311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner if (!*p) { /* no '@', should not happen */ 1833311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner return false; 1843311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner } 1853311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner } 1863311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner mPath = strdup(p+1); 187168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat first = 0; 188168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } else { 1893311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner const char* a; 1903311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner if ((a = HAS_CONST_PREFIX(s, end, "ACTION=")) != NULL) { 191168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat if (!strcmp(a, "add")) 192168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat mAction = NlActionAdd; 193168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat else if (!strcmp(a, "remove")) 194168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat mAction = NlActionRemove; 195168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat else if (!strcmp(a, "change")) 196168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat mAction = NlActionChange; 1973311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner } else if ((a = HAS_CONST_PREFIX(s, end, "SEQNUM=")) != NULL) { 1983311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner mSeq = atoi(a); 1993311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner } else if ((a = HAS_CONST_PREFIX(s, end, "SUBSYSTEM=")) != NULL) { 2003311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner mSubsystem = strdup(a); 2013311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner } else if (param_idx < NL_PARAMS_MAX) { 202168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat mParams[param_idx++] = strdup(s); 2033311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner } 204168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 2053311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner s += strlen(s) + 1; 206168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 207168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat return true; 208168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat} 209168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 210ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chenbool NetlinkEvent::decode(char *buffer, int size, int format) { 21117260b14682d4fe59dad3de2de8c9370e6ba9a71Mike J. Chen if (format == NetlinkListener::NETLINK_FORMAT_BINARY) { 21217260b14682d4fe59dad3de2de8c9370e6ba9a71Mike J. Chen return parseBinaryNetlinkMessage(buffer, size); 21317260b14682d4fe59dad3de2de8c9370e6ba9a71Mike J. Chen } else { 21417260b14682d4fe59dad3de2de8c9370e6ba9a71Mike J. Chen return parseAsciiNetlinkMessage(buffer, size); 21517260b14682d4fe59dad3de2de8c9370e6ba9a71Mike J. Chen } 216ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen} 217ec16b9d47cacb0d873ee0ff80c919f49215c0005Mike J. Chen 218168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehatconst char *NetlinkEvent::findParam(const char *paramName) { 21980ec37aa15c138beee5889a257d1241c30a1e8d7Chih-Wei Huang size_t len = strlen(paramName); 2203311eea1d3881e6f3d6806988b7db3de0a5f68d5David 'Digit' Turner for (int i = 0; i < NL_PARAMS_MAX && mParams[i] != NULL; ++i) { 22180ec37aa15c138beee5889a257d1241c30a1e8d7Chih-Wei Huang const char *ptr = mParams[i] + len; 22280ec37aa15c138beee5889a257d1241c30a1e8d7Chih-Wei Huang if (!strncmp(mParams[i], paramName, len) && *ptr == '=') 22380ec37aa15c138beee5889a257d1241c30a1e8d7Chih-Wei Huang return ++ptr; 224168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 225168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 2267e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGE("NetlinkEvent::FindParam(): Parameter '%s' not found", paramName); 227168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat return NULL; 228168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat} 229