"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/netlink.c" between
dnsmasq-2.80.tar.gz and dnsmasq-2.81.tar.xz

About: Dnsmasq is a lightweight caching DNS forwarder and DHCP server.

netlink.c  (dnsmasq-2.80):netlink.c  (dnsmasq-2.81.tar.xz)
/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley /* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991, or the Free Software Foundation; version 2 dated June, 1991, or
(at your option) version 3 dated 29 June, 2007. (at your option) version 3 dated 29 June, 2007.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
skipping to change at line 25 skipping to change at line 25
*/ */
#include "dnsmasq.h" #include "dnsmasq.h"
#ifdef HAVE_LINUX_NETWORK #ifdef HAVE_LINUX_NETWORK
#include <linux/types.h> #include <linux/types.h>
#include <linux/netlink.h> #include <linux/netlink.h>
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
/* Blergh. Radv does this, so that's our excuse. */
#ifndef SOL_NETLINK
#define SOL_NETLINK 270
#endif
#ifndef NETLINK_NO_ENOBUFS
#define NETLINK_NO_ENOBUFS 5
#endif
/* linux 2.6.19 buggers up the headers, patch it up here. */ /* linux 2.6.19 buggers up the headers, patch it up here. */
#ifndef IFA_RTA #ifndef IFA_RTA
# define IFA_RTA(r) \ # define IFA_RTA(r) \
((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg)))) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))))
# include <linux/if_addr.h> # include <linux/if_addr.h>
#endif #endif
#ifndef NDA_RTA #ifndef NDA_RTA
# define NDA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg)))) # define NDA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg))))
skipping to change at line 46 skipping to change at line 55
static struct iovec iov; static struct iovec iov;
static u32 netlink_pid; static u32 netlink_pid;
static void nl_async(struct nlmsghdr *h); static void nl_async(struct nlmsghdr *h);
void netlink_init(void) void netlink_init(void)
{ {
struct sockaddr_nl addr; struct sockaddr_nl addr;
socklen_t slen = sizeof(addr); socklen_t slen = sizeof(addr);
int opt = 1;
addr.nl_family = AF_NETLINK; addr.nl_family = AF_NETLINK;
addr.nl_pad = 0; addr.nl_pad = 0;
addr.nl_pid = 0; /* autobind */ addr.nl_pid = 0; /* autobind */
addr.nl_groups = RTMGRP_IPV4_ROUTE; addr.nl_groups = RTMGRP_IPV4_ROUTE;
if (option_bool(OPT_CLEVERBIND)) if (option_bool(OPT_CLEVERBIND))
addr.nl_groups |= RTMGRP_IPV4_IFADDR; addr.nl_groups |= RTMGRP_IPV4_IFADDR;
#ifdef HAVE_IPV6
addr.nl_groups |= RTMGRP_IPV6_ROUTE; addr.nl_groups |= RTMGRP_IPV6_ROUTE;
if (option_bool(OPT_CLEVERBIND)) if (option_bool(OPT_CLEVERBIND))
addr.nl_groups |= RTMGRP_IPV6_IFADDR; addr.nl_groups |= RTMGRP_IPV6_IFADDR;
#endif
#ifdef HAVE_DHCP6 #ifdef HAVE_DHCP6
if (daemon->doing_ra || daemon->doing_dhcp6) if (daemon->doing_ra || daemon->doing_dhcp6)
addr.nl_groups |= RTMGRP_IPV6_IFADDR; addr.nl_groups |= RTMGRP_IPV6_IFADDR;
#endif #endif
/* May not be able to have permission to set multicast groups don't die in tha t case */ /* May not be able to have permission to set multicast groups don't die in tha t case */
if ((daemon->netlinkfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) != -1) if ((daemon->netlinkfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) != -1)
{ {
if (bind(daemon->netlinkfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) if (bind(daemon->netlinkfd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
{ {
addr.nl_groups = 0; addr.nl_groups = 0;
if (errno != EPERM || bind(daemon->netlinkfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) if (errno != EPERM || bind(daemon->netlinkfd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
daemon->netlinkfd = -1; daemon->netlinkfd = -1;
} }
} }
if (daemon->netlinkfd == -1 || if (daemon->netlinkfd == -1 ||
(daemon->kernel_version >= KERNEL_VERSION(2,6,30) &&
setsockopt(daemon->netlinkfd, SOL_NETLINK, NETLINK_NO_ENOBUFS, &opt, size
of(opt)) == -1) ||
getsockname(daemon->netlinkfd, (struct sockaddr *)&addr, &slen) == -1) getsockname(daemon->netlinkfd, (struct sockaddr *)&addr, &slen) == -1)
die(_("cannot create netlink socket: %s"), NULL, EC_MISC); die(_("cannot create netlink socket: %s"), NULL, EC_MISC);
/* save pid assigned by bind() and retrieved by getsockname() */ /* save pid assigned by bind() and retrieved by getsockname() */
netlink_pid = addr.nl_pid; netlink_pid = addr.nl_pid;
iov.iov_len = 100; iov.iov_len = 100;
iov.iov_base = safe_malloc(iov.iov_len); iov.iov_base = safe_malloc(iov.iov_len);
} }
skipping to change at line 236 skipping to change at line 247
else if (rta->rta_type == IFA_LABEL) else if (rta->rta_type == IFA_LABEL)
label = RTA_DATA(rta); label = RTA_DATA(rta);
rta = RTA_NEXT(rta, len1); rta = RTA_NEXT(rta, len1);
} }
if (addr.s_addr && callback_ok) if (addr.s_addr && callback_ok)
if (!((*callback)(addr, ifa->ifa_index, label, netmask, br oadcast, parm))) if (!((*callback)(addr, ifa->ifa_index, label, netmask, br oadcast, parm)))
callback_ok = 0; callback_ok = 0;
} }
#ifdef HAVE_IPV6
else if (ifa->ifa_family == AF_INET6) else if (ifa->ifa_family == AF_INET6)
{ {
struct in6_addr *addrp = NULL; struct in6_addr *addrp = NULL;
u32 valid = 0, preferred = 0; u32 valid = 0, preferred = 0;
int flags = 0; int flags = 0;
while (RTA_OK(rta, len1)) while (RTA_OK(rta, len1))
{ {
if (rta->rta_type == IFA_ADDRESS) if (rta->rta_type == IFA_ADDRESS)
addrp = ((struct in6_addr *)(rta+1)); addrp = ((struct in6_addr *)(rta+1));
skipping to change at line 271 skipping to change at line 281
if (!(ifa->ifa_flags & IFA_F_TEMPORARY)) if (!(ifa->ifa_flags & IFA_F_TEMPORARY))
flags |= IFACE_PERMANENT; flags |= IFACE_PERMANENT;
if (addrp && callback_ok) if (addrp && callback_ok)
if (!((*callback)(addrp, (int)(ifa->ifa_prefixlen), (int)(i fa->ifa_scope), if (!((*callback)(addrp, (int)(ifa->ifa_prefixlen), (int)(i fa->ifa_scope),
(int)(ifa->ifa_index), flags, (int)(ifa->ifa_index), flags,
(int) preferred, (int)valid, parm))) (int) preferred, (int)valid, parm)))
callback_ok = 0; callback_ok = 0;
} }
#endif
} }
} }
else if (h->nlmsg_type == RTM_NEWNEIGH && family == AF_UNSPEC) else if (h->nlmsg_type == RTM_NEWNEIGH && family == AF_UNSPEC)
{ {
struct ndmsg *neigh = NLMSG_DATA(h); struct ndmsg *neigh = NLMSG_DATA(h);
struct rtattr *rta = NDA_RTA(neigh); struct rtattr *rta = NDA_RTA(neigh);
unsigned int len1 = h->nlmsg_len - NLMSG_LENGTH(sizeof(*neigh)); unsigned int len1 = h->nlmsg_len - NLMSG_LENGTH(sizeof(*neigh));
size_t maclen = 0; size_t maclen = 0;
char *inaddr = NULL, *mac = NULL; char *inaddr = NULL, *mac = NULL;
skipping to change at line 364 skipping to change at line 373
} }
else if (h->nlmsg_pid == 0 && h->nlmsg_type == RTM_NEWROUTE) else if (h->nlmsg_pid == 0 && h->nlmsg_type == RTM_NEWROUTE)
{ {
/* We arrange to receive netlink multicast messages whenever the network r oute is added. /* We arrange to receive netlink multicast messages whenever the network r oute is added.
If this happens and we still have a DNS packet in the buffer, we re-send it. If this happens and we still have a DNS packet in the buffer, we re-send it.
This helps on DoD links, where frequently the packet which triggers dial ling is This helps on DoD links, where frequently the packet which triggers dial ling is
a DNS query, which then gets lost. By re-sending, we can avoid the looku p a DNS query, which then gets lost. By re-sending, we can avoid the looku p
failing. */ failing. */
struct rtmsg *rtm = NLMSG_DATA(h); struct rtmsg *rtm = NLMSG_DATA(h);
if (rtm->rtm_type == RTN_UNICAST && rtm->rtm_scope == RT_SCOPE_LINK) if (rtm->rtm_type == RTN_UNICAST && rtm->rtm_scope == RT_SCOPE_LINK &&
(rtm->rtm_table == RT_TABLE_MAIN ||
rtm->rtm_table == RT_TABLE_LOCAL))
queue_event(EVENT_NEWROUTE); queue_event(EVENT_NEWROUTE);
} }
else if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR) else if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR)
queue_event(EVENT_NEWADDR); queue_event(EVENT_NEWADDR);
} }
#endif #endif
 End of changes. 9 change blocks. 
6 lines changed or deleted 18 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)