summaryrefslogtreecommitdiffstats
path: root/isi/netlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'isi/netlink.c')
-rw-r--r--isi/netlink.c197
1 files changed, 0 insertions, 197 deletions
diff --git a/isi/netlink.c b/isi/netlink.c
deleted file mode 100644
index 3bb61db6..00000000
--- a/isi/netlink.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * This file is part of oFono - Open Source Telephony
- *
- * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
- *
- * Contact: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#ifndef SOL_NETLINK
-#define SOL_NETLINK 270 /* libc!? */
-#endif
-#ifndef AF_PHONET
-#define AF_PHONET 35
-#endif
-#include <linux/rtnetlink.h>
-#include <linux/phonet.h>
-#include <glib.h>
-
-#include "netlink.h"
-
-struct pn_netlink {
- pn_netlink_cb_t callback;
- void *opaque;
- guint watch;
-};
-
-/* Parser Netlink messages */
-static gboolean pn_nl_process(GIOChannel *channel, GIOCondition cond,
- gpointer data)
-{
- struct {
- struct nlmsghdr nlh;
- struct rtmsg rtm;
- char buf[1024];
- } req;
- struct iovec iov = { &req, sizeof(req), };
- struct msghdr msg = { .msg_iov = &iov, .msg_iovlen = 1, };
- ssize_t ret;
- struct nlmsghdr *nlh;
- int fd = g_io_channel_unix_get_fd(channel);
- struct pn_netlink *self = data;
-
- if (cond & (G_IO_NVAL|G_IO_HUP))
- return FALSE;
-
- ret = recvmsg(fd, &msg, 0);
- if (ret == -1 || (msg.msg_flags & MSG_TRUNC))
- return TRUE;
-
- for (nlh = (struct nlmsghdr *)&req; NLMSG_OK(nlh, (size_t)ret);
- nlh = NLMSG_NEXT(nlh, ret)) {
- const struct ifaddrmsg *ifa;
- const struct rtattr *rta;
- int len;
- bool up;
- uint8_t addr = 0;
-
- if (nlh->nlmsg_type == NLMSG_DONE)
- break;
- switch (nlh->nlmsg_type) {
- case NLMSG_ERROR: {
- const struct nlmsgerr *err;
- err = (struct nlmsgerr *)NLMSG_DATA(nlh);
- g_critical("Netlink error: %s", strerror(-err->error));
- return FALSE;
- }
- case RTM_NEWADDR:
- up = true;
- break;
- case RTM_DELADDR:
- up = false;
- break;
- default:
- continue;
- }
- /* We have a route message */
- ifa = NLMSG_DATA(nlh);
- len = RTM_PAYLOAD(nlh);
-
- /* If Phonet is absent, kernel transmits other families... */
- if (ifa->ifa_family != AF_PHONET)
- continue;
- for (rta = IFA_RTA(ifa); RTA_OK(rta, len);
- rta = RTA_NEXT(rta, len))
- if (rta->rta_type == IFA_LOCAL)
- memcpy(&addr, RTA_DATA(rta), 1);
- self->callback(up, addr, ifa->ifa_index, self->opaque);
- }
- return TRUE;
-}
-
-/* Dump current Phonet address table */
-static int pn_netlink_query(int fd)
-{
- struct {
- struct nlmsghdr nlh;
- struct rtmsg rtm;
- } req;
- struct sockaddr_nl addr = { .nl_family = AF_NETLINK, };
-
- req.nlh.nlmsg_type = RTM_GETADDR;
- req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(req.rtm));
- req.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
- req.nlh.nlmsg_seq = 0;
- req.nlh.nlmsg_pid = getpid();
-
- req.rtm.rtm_family = AF_PHONET;
- req.rtm.rtm_dst_len = 6;
- req.rtm.rtm_src_len = 0;
- req.rtm.rtm_tos = 0;
-
- req.rtm.rtm_table = RT_TABLE_MAIN;
- req.rtm.rtm_protocol = RTPROT_STATIC;
- req.rtm.rtm_scope = RT_SCOPE_UNIVERSE;
- req.rtm.rtm_type = RTN_UNICAST;
- req.rtm.rtm_flags = 0;
-
- if (sendto(fd, &req, req.nlh.nlmsg_len, 0,
- (struct sockaddr *)&addr, sizeof(addr)) == -1)
- return -1;
- return 0;
-}
-
-struct pn_netlink *pn_netlink_start(pn_netlink_cb_t cb, void *opaque)
-{
- GIOChannel *chan;
- struct pn_netlink *self;
- unsigned group = RTNLGRP_PHONET_IFADDR;
- int fd;
-
- self = malloc(sizeof(*self));
- if (self == NULL)
- return NULL;
-
- fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
- if (fd == -1)
- goto error;
-
- fcntl(fd, F_SETFL, O_NONBLOCK | fcntl(fd, F_GETFL));
- if (setsockopt(fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP,
- &group, sizeof(group)))
- goto error;
- pn_netlink_query(fd);
-
- chan = g_io_channel_unix_new(fd);
- if (chan == NULL)
- goto error;
- g_io_channel_set_close_on_unref(chan, TRUE);
- g_io_channel_set_encoding(chan, NULL, NULL);
- g_io_channel_set_buffered(chan, FALSE);
-
- self->callback = cb;
- self->opaque = opaque;
- self->watch = g_io_add_watch(chan, G_IO_IN|G_IO_ERR|G_IO_HUP,
- pn_nl_process, self);
- g_io_channel_unref(chan);
- return 0;
-
-error:
- if (fd != -1)
- close(fd);
- free(self);
- return NULL;
-}
-
-void pn_netlink_stop(struct pn_netlink *self)
-{
- g_source_remove(self->watch);
- g_free(self);
-}