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 = RTM_PAYLOAD(hdr);
188 DBG("rtm_family %d rtm_flags %d", msg->rtm_family, msg->rtm_flags);
190 for (attr = RTM_RTA(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);
197 if (msg->rtm_family == AF_INET) {
199 addr = *((struct in_addr *) RTA_DATA(attr));
200 DBG(" address %s", inet_ntoa(addr));
204 DBG(" rta_type src len %d", len);
205 if (msg->rtm_family == AF_INET) {
207 addr = *((struct in_addr *) RTA_DATA(attr));
208 DBG(" address %s", inet_ntoa(addr));
212 DBG(" rta_type iff len %d", len);
215 DBG(" rta_type oif len %d", len);
218 DBG(" rta_type gateway len %d", len);
219 if (msg->rtm_family == AF_INET) {
221 addr = *((struct in_addr *) RTA_DATA(attr));
222 DBG(" address %s", inet_ntoa(addr));
226 DBG(" rta_type priority len %d", len);
229 DBG(" rta_type prefsrc len %d", len);
230 if (msg->rtm_family == AF_INET) {
232 addr = *((struct in_addr *) RTA_DATA(attr));
233 DBG(" address %s", inet_ntoa(addr));
237 DBG(" rta_type metrics len %d", len);
240 DBG(" rta_type table len %d", len);
243 DBG(" rta_type %d len %d", attr->rta_type, len);
249 static void parse_message(unsigned char *buf, size_t size)
251 struct nlmsghdr *hdr = (void *) buf;
253 if (!NLMSG_OK(hdr, size))
256 switch (hdr->nlmsg_type) {
258 DBG("nlmsg_type done");
261 DBG("nlmsg_type noop");
264 DBG("nlmsg_type overrun");
267 DBG("nlmsg_type error");
270 DBG("nlmsg_type RTM_NEWLINK");
274 DBG("nlmsg_type RTM_DELLINK");
278 DBG("nlmsg_type RTM_NEWADDR");
282 DBG("nlmsg_type RTM_DELADDR");
286 DBG("nlmsg_type RTM_NEWROUTE");
290 DBG("nlmsg_type RTM_DELROUTE");
294 DBG("nlmsg_type %d", hdr->nlmsg_type);
299 static gboolean netlink_event(GIOChannel *chan,
300 GIOCondition cond, gpointer data)
302 unsigned char buf[256];
306 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
307 g_io_channel_unref(chan);
311 memset(buf, 0, sizeof(buf));
313 err = g_io_channel_read(chan, (gchar *) buf, sizeof(buf), &len);
315 if (err == G_IO_ERROR_AGAIN)
317 g_io_channel_unref(chan);
321 parse_message(buf, len);
326 static GIOChannel *channel = NULL;
328 int __connman_rtnl_init(void)
330 struct sockaddr_nl addr;
335 sk = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
339 memset(&addr, 0, sizeof(addr));
340 addr.nl_family = AF_NETLINK;
341 addr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE;
342 addr.nl_pid = getpid();
344 if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
349 channel = g_io_channel_unix_new(sk);
350 g_io_channel_set_close_on_unref(channel, TRUE);
352 g_io_add_watch(channel,
353 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
354 netlink_event, NULL);
356 g_io_channel_unref(channel);
361 void __connman_rtnl_cleanup(void)
365 g_io_channel_unref(channel);