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