#include <linux/rtnetlink.h>
#include "netwatch.h"
+#include "mdnsd.h"
#define NL_BUFSIZE 8192
int
netwatch_open (void)
{
- int fd;
- struct sockaddr_nl local;
+ int fd;
+ struct sockaddr_nl local;
- /* Create Socket */
- if ((fd = socket (PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0)
- return -1;
+ /* Create Socket */
+ if ((fd = socket (PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0)
+ return -1;
- memset (&local, 0, sizeof (local));
- local.nl_family = AF_NETLINK;
- local.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR;
+ memset (&local, 0, sizeof (local));
+ local.nl_family = AF_NETLINK;
+ local.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR;
- if (bind (fd, (struct sockaddr*) &local, sizeof (local)) < 0)
- return -1;
+ if (bind (fd, (struct sockaddr*) &local, sizeof (local)) < 0)
+ return -1;
- if (fcntl (fd, F_SETFL, O_NONBLOCK))
- return -1;
+ if (fcntl (fd, F_SETFL, O_NONBLOCK))
+ return -1;
- return fd;
+ return fd;
}
int
netwatch_queue_inforequest (int fd)
{
- char buf[NLMSG_LENGTH (sizeof (struct ifaddrmsg))];
- struct nlmsghdr *nl_msg;
+ char buf[NLMSG_LENGTH (sizeof (struct ifaddrmsg))];
+ struct nlmsghdr *nl_msg;
- bzero (buf, sizeof(buf));
- nl_msg = (struct nlmsghdr *) buf;
+ bzero (buf, sizeof(buf));
+ nl_msg = (struct nlmsghdr *) buf;
- /* For getting interface addresses */
- nl_msg->nlmsg_len = NLMSG_LENGTH (sizeof (struct ifaddrmsg));
- nl_msg->nlmsg_type = RTM_GETADDR;
- nl_msg->nlmsg_flags = NLM_F_ROOT | NLM_F_REQUEST;
- nl_msg->nlmsg_pid = getpid ();
+ /* For getting interface addresses */
+ nl_msg->nlmsg_len = NLMSG_LENGTH (sizeof (struct ifaddrmsg));
+ nl_msg->nlmsg_type = RTM_GETADDR;
+ nl_msg->nlmsg_flags = NLM_F_ROOT | NLM_F_REQUEST;
+ nl_msg->nlmsg_pid = getpid ();
- return write (fd, nl_msg, nl_msg->nlmsg_len);
+ return write (fd, nl_msg, nl_msg->nlmsg_len);
}
int
netwatch_dispatch (int fd)
{
- struct nlmsghdr *nl_msg;
- char buf[NL_BUFSIZE];
- int len, count;
+ struct nlmsghdr *nl_msg;
+ char buf[NL_BUFSIZE];
+ int len, count;
- count = 0;
- if ((len = recv (fd, buf, NL_BUFSIZE, 0)) < 0)
+ count = 0;
+ if ((len = recv (fd, buf, NL_BUFSIZE, 0)) < 0)
{
- return (errno == EAGAIN) ? 0 : -1;
+ return (errno == EAGAIN) ? 0 : -1;
}
- for (nl_msg = (struct nlmsghdr *) buf;
- NLMSG_OK (nl_msg, len);
- nl_msg = NLMSG_NEXT (nl_msg, len))
+ for (nl_msg = (struct nlmsghdr *) buf;
+ NLMSG_OK (nl_msg, (unsigned int) len);
+ nl_msg = NLMSG_NEXT (nl_msg, len))
{
- switch (nl_msg->nlmsg_type)
+ switch (nl_msg->nlmsg_type)
{
- case RTM_NEWADDR:
- case RTM_DELADDR:
- netwatch_handle_ifaddrmsg (nl_msg);
- break;
- case RTM_NEWLINK:
- case RTM_DELLINK:
- netwatch_handle_ifinfomsg (nl_msg);
- break;
- case NLMSG_DONE:
- break;
- default:
- fprintf (stderr, "unhandled message (%d)\n",
- nl_msg->nlmsg_type);
- break;
+ case RTM_NEWADDR:
+ case RTM_DELADDR:
+ netwatch_handle_ifaddrmsg (nl_msg);
+ break;
+ case RTM_NEWLINK:
+ case RTM_DELLINK:
+ netwatch_handle_ifinfomsg (nl_msg);
+ break;
+ case NLMSG_DONE:
+ break;
+ default:
+ fprintf (stderr, "unhandled message (%d)\n",
+ nl_msg->nlmsg_type);
+ break;
}
- count++;
+ count++;
}
- return count;
+ return count;
}
NW_LinkChangeCallback link_cb,
void *userdata)
{
- user_data = userdata;
- on_ip_change = ip_cb;
- on_link_change = link_cb;
+ user_data = userdata;
+ on_ip_change = ip_cb;
+ on_link_change = link_cb;
}
static void
netwatch_handle_ifaddrmsg (struct nlmsghdr *nl_msg)
{
- struct ifaddrmsg *if_msg;
- struct rtattr *attrib;
- int len;
+ struct ifaddrmsg *if_msg;
+ struct rtattr *attrib;
+ int len;
- char address[100];
- char *label = NULL;
+ char address[100];
+ char *label = NULL;
- if_msg = (struct ifaddrmsg *) NLMSG_DATA (nl_msg);
+ if_msg = (struct ifaddrmsg *) NLMSG_DATA (nl_msg);
- if (if_msg->ifa_family != AF_INET)
- return;
+ if (if_msg->ifa_family != AF_INET)
+ return;
- address[0] = '\0';
+ address[0] = '\0';
- len = IFA_PAYLOAD (nl_msg);
- for (attrib = IFA_RTA (if_msg);
- RTA_OK (attrib, len);
- attrib = RTA_NEXT (attrib, len))
+ len = IFA_PAYLOAD (nl_msg);
+ for (attrib = IFA_RTA (if_msg);
+ RTA_OK (attrib, len);
+ attrib = RTA_NEXT (attrib, len))
{
- switch (attrib->rta_type)
+ switch (attrib->rta_type)
{
- case IFA_LOCAL:
- inet_ntop (AF_INET, RTA_DATA (attrib), address, sizeof (address));
- break;
+ case IFA_LOCAL:
+ inet_ntop (AF_INET, RTA_DATA (attrib), address, sizeof (address));
+ break;
- case IFA_LABEL:
- label = (char *) RTA_DATA (attrib);
- break;
+ case IFA_LABEL:
+ label = (char *) RTA_DATA (attrib);
+ break;
- default:
- /* ignore all other attributes */
- break;
+ default:
+ /* ignore all other attributes */
+ break;
}
}
- /* if we got both a label and an IP address */
- if (on_ip_change && label && address[0] &&
- (nl_msg->nlmsg_type == RTM_NEWADDR || nl_msg->nlmsg_type == RTM_DELADDR))
+ /* if we got both a label and an IP address */
+ if (on_ip_change && label && address[0] &&
+ (nl_msg->nlmsg_type == RTM_NEWADDR || nl_msg->nlmsg_type == RTM_DELADDR))
{
- on_ip_change (if_msg->ifa_index, label, address,
- nl_msg->nlmsg_type == RTM_NEWADDR, user_data);
+ on_ip_change (if_msg->ifa_index, label, address,
+ nl_msg->nlmsg_type == RTM_NEWADDR, user_data);
}
- return;
+ return;
}
static void
netwatch_handle_ifinfomsg (struct nlmsghdr *nl_msg)
{
- static unsigned long have_state = 0;
- static unsigned long linkstate = 0;
- struct ifinfomsg *ifi;
+ static unsigned long have_state = 0;
+ static unsigned long linkstate = 0;
+ struct ifinfomsg *ifi;
- ifi = (struct ifinfomsg *) NLMSG_DATA (nl_msg);
+ ifi = (struct ifinfomsg *) NLMSG_DATA (nl_msg);
- if (on_link_change && ifi->ifi_index < sizeof (unsigned long) * 8)
+ if (on_link_change && ((unsigned int)ifi->ifi_index < sizeof (unsigned long) * 8))
{
- if (!((1 << ifi->ifi_index) & have_state) ||
- ((ifi->ifi_flags & IFF_RUNNING) && !((1 << ifi->ifi_index) & linkstate)) ||
- (!(ifi->ifi_flags & IFF_RUNNING) && ((1 << ifi->ifi_index) & linkstate)))
+ if (!((1 << ifi->ifi_index) & have_state) ||
+ ((ifi->ifi_flags & IFF_RUNNING) && !((1 << ifi->ifi_index) & linkstate)) ||
+ (!(ifi->ifi_flags & IFF_RUNNING) && ((1 << ifi->ifi_index) & linkstate)))
{
- have_state |= (1 << ifi->ifi_index);
- if (ifi->ifi_flags & IFF_RUNNING)
- linkstate |= (1 << ifi->ifi_index);
- else
- linkstate &= ~(1 << ifi->ifi_index);
-
- on_link_change (ifi->ifi_index,
- ifi->ifi_flags & IFF_RUNNING ? 1 : 0,
- user_data);
+ have_state |= (1 << ifi->ifi_index);
+ if (ifi->ifi_flags & IFF_RUNNING)
+ linkstate |= (1 << ifi->ifi_index);
+ else
+ linkstate &= ~(1 << ifi->ifi_index);
+
+ on_link_change (ifi->ifi_index,
+ ifi->ifi_flags & IFF_RUNNING ? 1 : 0,
+ user_data);
}
}
}
char *label,
char *ipaddr,
int add,
- void *user_data)
+ void *UNUSED(user_data))
{
- fprintf (stdout, "Link No. %d %s address %s (label %s)\n",
- link_index, add ? "got" : "lost", ipaddr, label);
+ fprintf (stdout, "Link No. %d %s address %s (label %s)\n",
+ link_index, add ? "got" : "lost", ipaddr, label);
}
void print_link_change (int link_index,
int running,
- void *user_data)
+ void *UNUSED(user_data))
{
- fprintf (stdout, "Link No. %d is %sconnected\n",
- link_index, running ? "" : "no longer ");
+ fprintf (stdout, "Link No. %d is %sconnected\n",
+ link_index, running ? "" : "no longer ");
}
int
-main (int argc, char *argv[])
+main (int UNUSED(argc), char **UNUSED(argv))
{
- struct pollfd pollfd;
- int fd;
+ struct pollfd pollfd;
+ int fd;
- netwatch_register_callbacks (print_ip_change, print_link_change, NULL);
+ netwatch_register_callbacks (print_ip_change, print_link_change, NULL);
- fd = netwatch_open ();
- if (fd < 0)
+ fd = netwatch_open ();
+ if (fd < 0)
{
- perror ("Error opening netlink socket");
- exit (1);
+ perror ("Error opening netlink socket");
+ exit (1);
}
- netwatch_queue_inforequest (fd);
+ netwatch_queue_inforequest (fd);
- while (1)
+ while (1)
{
- pollfd.fd = fd;
- pollfd.events = POLLIN;
- pollfd.revents = 0;
+ pollfd.fd = fd;
+ pollfd.events = POLLIN;
+ pollfd.revents = 0;
- if (poll (&pollfd, 1, 20000))
- netwatch_dispatch (fd);
+ if (poll (&pollfd, 1, 20000))
+ netwatch_dispatch (fd);
}
- close (fd);
- return 0;
+ close (fd);
+ return 0;
}
#endif