5 * Copyright (C) 2007 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 #include <sys/socket.h>
30 #include <arpa/inet.h>
32 #include <linux/netlink.h>
33 #include <linux/rtnetlink.h>
39 static void parse_link(struct nlmsghdr *hdr)
41 struct ifinfomsg *msg;
45 msg = (struct ifinfomsg *) NLMSG_DATA(hdr);
46 bytes = IFLA_PAYLOAD(hdr);
48 DBG("ifi_index %d ifi_flags %d", msg->ifi_index, msg->ifi_flags);
50 for (attr = IFLA_RTA(msg); RTA_OK(attr, bytes);
51 attr = RTA_NEXT(attr, bytes)) {
52 int len = RTA_PAYLOAD(attr);
54 switch (attr->rta_type) {
56 DBG(" rta_type address len %d", len);
59 DBG(" rta_type broadcast len %d", len);
62 DBG(" rta_type ifname %s", (char *) RTA_DATA(attr));
65 DBG(" rta_type mtu len %d", len);
68 DBG(" rta_type link len %d", len);
71 DBG(" rta_type qdisc len %d", len);
74 DBG(" rta_type stats len %d", len);
77 DBG(" rta_type cost len %d", len);
80 DBG(" rta_type priority len %d", len);
83 DBG(" rta_type master len %d", len);
86 DBG(" rta_type wireless len %d", len);
88 unsigned char *data = RTA_DATA(attr);
90 for (i = 0; i < len; i++)
91 printf(" %02x", data[i]);
96 DBG(" rta_type protinfo len %d", len);
99 DBG(" rta_type txqlen len %d", len);
102 DBG(" rta_type map len %d", len);
105 DBG(" rta_type widght len %d", len);
108 DBG(" rta_type operstate len %d", len);
111 DBG(" rta_type linkmode len %d", len);
114 DBG(" rta_type %d len %d", attr->rta_type, len);
120 static void parse_addr(struct nlmsghdr *hdr)
122 struct ifaddrmsg *msg;
126 msg = (struct ifaddrmsg *) NLMSG_DATA(hdr);
127 bytes = IFA_PAYLOAD(hdr);
129 DBG("ifa_family %d ifa_index %d", msg->ifa_family, msg->ifa_index);
131 for (attr = IFA_RTA(msg); RTA_OK(attr, bytes);
132 attr = RTA_NEXT(attr, bytes)) {
133 int len = RTA_PAYLOAD(attr);
135 switch (attr->rta_type) {
137 DBG(" rta_type address len %d", len);
138 if (msg->ifa_family == AF_INET) {
140 addr = *((struct in_addr *) RTA_DATA(attr));
141 DBG(" address %s", inet_ntoa(addr));
145 DBG(" rta_type local len %d", len);
146 if (msg->ifa_family == AF_INET) {
148 addr = *((struct in_addr *) RTA_DATA(attr));
149 DBG(" address %s", inet_ntoa(addr));
153 DBG(" rta_type label %s", (char *) RTA_DATA(attr));
156 DBG(" rta_type broadcast len %d", len);
157 if (msg->ifa_family == AF_INET) {
159 addr = *((struct in_addr *) RTA_DATA(attr));
160 DBG(" address %s", inet_ntoa(addr));
164 DBG(" rta_type anycast len %d", len);
167 DBG(" rta_type cacheinfo len %d", len);
170 DBG(" rta_type multicast len %d", len);
173 DBG(" rta_type %d len %d", attr->rta_type, len);
179 static void parse_route(struct nlmsghdr *hdr)
185 msg = (struct rtmsg *) NLMSG_DATA(hdr);
186 bytes = IFA_PAYLOAD(hdr);
188 DBG("rtm_family %d rtm_flags %d", msg->rtm_family, msg->rtm_flags);
190 for (attr = RTA_DATA(msg); RTA_OK(attr, bytes);
191 attr = RTA_NEXT(attr, bytes)) {
192 int len = RTA_PAYLOAD(attr);
194 switch (attr->rta_type) {
196 DBG(" rta_type dst len %d", len);
199 DBG(" rta_type src len %d", len);
202 DBG(" rta_type iff len %d", len);
205 DBG(" rta_type oif len %d", len);
208 DBG(" rta_type gateway len %d", len);
211 DBG(" rta_type %d len %d", attr->rta_type, len);
217 static void parse_message(unsigned char *buf, size_t size)
219 struct nlmsghdr *hdr = (void *) buf;
221 if (!NLMSG_OK(hdr, size))
224 switch (hdr->nlmsg_type) {
226 DBG("nlmsg_type done");
229 DBG("nlmsg_type noop");
232 DBG("nlmsg_type overrun");
235 DBG("nlmsg_type error");
238 DBG("nlmsg_type RTM_NEWLINK");
242 DBG("nlmsg_type RTM_DELLINK");
246 DBG("nlmsg_type RTM_NEWADDR");
250 DBG("nlmsg_type RTM_DELADDR");
254 DBG("nlmsg_type RTM_NEWROUTE");
258 DBG("nlmsg_type RTM_DELROUTE");
262 DBG("nlmsg_type %d", hdr->nlmsg_type);
267 static gboolean netlink_event(GIOChannel *chan,
268 GIOCondition cond, gpointer data)
270 unsigned char buf[256];
274 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
275 g_io_channel_unref(chan);
279 memset(buf, 0, sizeof(buf));
281 err = g_io_channel_read(chan, (gchar *) buf, sizeof(buf), &len);
283 if (err == G_IO_ERROR_AGAIN)
285 g_io_channel_unref(chan);
289 parse_message(buf, len);
294 static GIOChannel *channel = NULL;
296 int __connman_rtnl_init(void)
298 struct sockaddr_nl addr;
303 sk = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
307 memset(&addr, 0, sizeof(addr));
308 addr.nl_family = AF_NETLINK;
309 addr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE;
310 addr.nl_pid = getpid();
312 if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
317 channel = g_io_channel_unix_new(sk);
318 g_io_channel_set_close_on_unref(channel, TRUE);
320 g_io_add_watch(channel,
321 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
322 netlink_event, NULL);
324 g_io_channel_unref(channel);
329 void __connman_rtnl_cleanup(void)
333 g_io_channel_unref(channel);