Diff for /embedaddon/dnsmasq/src/ipset.c between versions 1.1.1.1 and 1.1.1.4

version 1.1.1.1, 2013/07/29 19:37:40 version 1.1.1.4, 2021/03/17 00:56:46
Line 16 Line 16
   
 #include "dnsmasq.h"  #include "dnsmasq.h"
   
#ifdef HAVE_IPSET#if defined(HAVE_IPSET) && defined(HAVE_LINUX_NETWORK)
   
 #include <string.h>  #include <string.h>
 #include <errno.h>  #include <errno.h>
 #include <sys/types.h>  #include <sys/types.h>
 #include <sys/socket.h>  #include <sys/socket.h>
 #include <sys/utsname.h>  
 #include <arpa/inet.h>  #include <arpa/inet.h>
 #include <linux/version.h>  
 #include <linux/netlink.h>  #include <linux/netlink.h>
#include <linux/netfilter/nfnetlink.h>
#ifndef NFNL_SUBSYS_IPSET/* We want to be able to compile against old header files
    Kernel version is handled at run-time. */
 
 #define NFNL_SUBSYS_IPSET 6  #define NFNL_SUBSYS_IPSET 6
   
 #define IPSET_ATTR_DATA 7  #define IPSET_ATTR_DATA 7
 #define IPSET_ATTR_IP 1  #define IPSET_ATTR_IP 1
 #define IPSET_ATTR_IPADDR_IPV4 1  #define IPSET_ATTR_IPADDR_IPV4 1
Line 39 Line 40
 #define IPSET_CMD_DEL 10  #define IPSET_CMD_DEL 10
 #define IPSET_MAXNAMELEN 32  #define IPSET_MAXNAMELEN 32
 #define IPSET_PROTOCOL 6  #define IPSET_PROTOCOL 6
#else
#include <linux/netfilter/ipset/ip_set.h>#ifndef NFNETLINK_V0
 #define NFNETLINK_V0    0
 #endif  #endif
   
   #ifndef NLA_F_NESTED
   #define NLA_F_NESTED            (1 << 15)
   #endif
   
   #ifndef NLA_F_NET_BYTEORDER
   #define NLA_F_NET_BYTEORDER     (1 << 14)
   #endif
   
   struct my_nlattr {
           __u16           nla_len;
           __u16           nla_type;
   };
   
   struct my_nfgenmsg {
           __u8  nfgen_family;             /* AF_xxx */
           __u8  version;          /* nfnetlink version */
           __be16    res_id;               /* resource id */
   };
   
   
 /* data structure size in here is fixed */  /* data structure size in here is fixed */
 #define BUFF_SZ 256  #define BUFF_SZ 256
   
Line 53  static char *buffer; Line 75  static char *buffer;
   
 static inline void add_attr(struct nlmsghdr *nlh, uint16_t type, size_t len, const void *data)  static inline void add_attr(struct nlmsghdr *nlh, uint16_t type, size_t len, const void *data)
 {  {
  struct nlattr *attr = (void *)nlh + NL_ALIGN(nlh->nlmsg_len);  struct my_nlattr *attr = (void *)nlh + NL_ALIGN(nlh->nlmsg_len);
  uint16_t payload_len = NL_ALIGN(sizeof(struct nlattr)) + len;  uint16_t payload_len = NL_ALIGN(sizeof(struct my_nlattr)) + len;
   attr->nla_type = type;    attr->nla_type = type;
   attr->nla_len = payload_len;    attr->nla_len = payload_len;
  memcpy((void *)attr + NL_ALIGN(sizeof(struct nlattr)), data, len);  memcpy((void *)attr + NL_ALIGN(sizeof(struct my_nlattr)), data, len);
   nlh->nlmsg_len += NL_ALIGN(payload_len);    nlh->nlmsg_len += NL_ALIGN(payload_len);
 }  }
   
 void ipset_init(void)  void ipset_init(void)
 {  {
  struct utsname utsname;  old_kernel = (daemon->kernel_version < KERNEL_VERSION(2,6,32));
  int version; 
  char *split; 
       
   if (uname(&utsname) < 0)  
     die(_("failed to find kernel version: %s"), NULL, EC_MISC);  
     
   split = strtok(utsname.release, ".");  
   version = (split ? atoi(split) : 0);  
   split = strtok(NULL, ".");  
   version = version * 256 + (split ? atoi(split) : 0);  
   split = strtok(NULL, ".");  
   version = version * 256 + (split ? atoi(split) : 0);  
   old_kernel = (version < KERNEL_VERSION(2,6,32));  
     
   if (old_kernel && (ipset_sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) != -1)    if (old_kernel && (ipset_sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) != -1)
     return;      return;
       
Line 90  void ipset_init(void) Line 99  void ipset_init(void)
   die (_("failed to create IPset control socket: %s"), NULL, EC_MISC);    die (_("failed to create IPset control socket: %s"), NULL, EC_MISC);
 }  }
   
static int new_add_to_ipset(const char *setname, const struct all_addr *ipaddr, int af, int remove)static int new_add_to_ipset(const char *setname, const union all_addr *ipaddr, int af, int remove)
 {  {
   struct nlmsghdr *nlh;    struct nlmsghdr *nlh;
  struct nfgenmsg *nfg;  struct my_nfgenmsg *nfg;
  struct nlattr *nested[2];  struct my_nlattr *nested[2];
   uint8_t proto;    uint8_t proto;
  int addrsz = INADDRSZ;  int addrsz = (af == AF_INET6) ? IN6ADDRSZ : INADDRSZ;
  ssize_t rc; 
   
 #ifdef HAVE_IPV6  
   if (af == AF_INET6)  
     addrsz = IN6ADDRSZ;  
 #endif  
       
   if (strlen(setname) >= IPSET_MAXNAMELEN)     if (strlen(setname) >= IPSET_MAXNAMELEN) 
     {      {
       errno = ENAMETOOLONG;        errno = ENAMETOOLONG;
       return -1;        return -1;
     }      }
       
  memset(buffer, 0, sizeof(buffer));  memset(buffer, 0, BUFF_SZ);
   
   nlh = (struct nlmsghdr *)buffer;    nlh = (struct nlmsghdr *)buffer;
   nlh->nlmsg_len = NL_ALIGN(sizeof(struct nlmsghdr));    nlh->nlmsg_len = NL_ALIGN(sizeof(struct nlmsghdr));
   nlh->nlmsg_type = (remove ? IPSET_CMD_DEL : IPSET_CMD_ADD) | (NFNL_SUBSYS_IPSET << 8);    nlh->nlmsg_type = (remove ? IPSET_CMD_DEL : IPSET_CMD_ADD) | (NFNL_SUBSYS_IPSET << 8);
   nlh->nlmsg_flags = NLM_F_REQUEST;    nlh->nlmsg_flags = NLM_F_REQUEST;
       
  nfg = (struct nfgenmsg *)(buffer + nlh->nlmsg_len);  nfg = (struct my_nfgenmsg *)(buffer + nlh->nlmsg_len);
  nlh->nlmsg_len += NL_ALIGN(sizeof(struct nfgenmsg));  nlh->nlmsg_len += NL_ALIGN(sizeof(struct my_nfgenmsg));
   nfg->nfgen_family = af;    nfg->nfgen_family = af;
   nfg->version = NFNETLINK_V0;    nfg->version = NFNETLINK_V0;
   nfg->res_id = htons(0);    nfg->res_id = htons(0);
Line 126  static int new_add_to_ipset(const char *setname, const Line 129  static int new_add_to_ipset(const char *setname, const
   proto = IPSET_PROTOCOL;    proto = IPSET_PROTOCOL;
   add_attr(nlh, IPSET_ATTR_PROTOCOL, sizeof(proto), &proto);    add_attr(nlh, IPSET_ATTR_PROTOCOL, sizeof(proto), &proto);
   add_attr(nlh, IPSET_ATTR_SETNAME, strlen(setname) + 1, setname);    add_attr(nlh, IPSET_ATTR_SETNAME, strlen(setname) + 1, setname);
  nested[0] = (struct nlattr *)(buffer + NL_ALIGN(nlh->nlmsg_len));  nested[0] = (struct my_nlattr *)(buffer + NL_ALIGN(nlh->nlmsg_len));
  nlh->nlmsg_len += NL_ALIGN(sizeof(struct nlattr));  nlh->nlmsg_len += NL_ALIGN(sizeof(struct my_nlattr));
   nested[0]->nla_type = NLA_F_NESTED | IPSET_ATTR_DATA;    nested[0]->nla_type = NLA_F_NESTED | IPSET_ATTR_DATA;
  nested[1] = (struct nlattr *)(buffer + NL_ALIGN(nlh->nlmsg_len));  nested[1] = (struct my_nlattr *)(buffer + NL_ALIGN(nlh->nlmsg_len));
  nlh->nlmsg_len += NL_ALIGN(sizeof(struct nlattr));  nlh->nlmsg_len += NL_ALIGN(sizeof(struct my_nlattr));
   nested[1]->nla_type = NLA_F_NESTED | IPSET_ATTR_IP;    nested[1]->nla_type = NLA_F_NESTED | IPSET_ATTR_IP;
   add_attr(nlh,     add_attr(nlh, 
            (af == AF_INET ? IPSET_ATTR_IPADDR_IPV4 : IPSET_ATTR_IPADDR_IPV6) | NLA_F_NET_BYTEORDER,             (af == AF_INET ? IPSET_ATTR_IPADDR_IPV4 : IPSET_ATTR_IPADDR_IPV6) | NLA_F_NET_BYTEORDER,
           addrsz, &ipaddr->addr);           addrsz, ipaddr);
   nested[1]->nla_len = (void *)buffer + NL_ALIGN(nlh->nlmsg_len) - (void *)nested[1];    nested[1]->nla_len = (void *)buffer + NL_ALIGN(nlh->nlmsg_len) - (void *)nested[1];
   nested[0]->nla_len = (void *)buffer + NL_ALIGN(nlh->nlmsg_len) - (void *)nested[0];    nested[0]->nla_len = (void *)buffer + NL_ALIGN(nlh->nlmsg_len) - (void *)nested[0];
                   
  while ((rc = sendto(ipset_sock, buffer, nlh->nlmsg_len, 0,  while (retry_send(sendto(ipset_sock, buffer, nlh->nlmsg_len, 0,
                      (struct sockaddr *)&snl, sizeof(snl))) == -1 && retry_send());                           (struct sockaddr *)&snl, sizeof(snl))));
  return rc;                                                                    
   return errno == 0 ? 0 : -1;
 }  }
   
   
static int old_add_to_ipset(const char *setname, const struct all_addr *ipaddr, int remove)static int old_add_to_ipset(const char *setname, const union all_addr *ipaddr, int remove)
 {  {
   socklen_t size;    socklen_t size;
   struct ip_set_req_adt_get {    struct ip_set_req_adt_get {
Line 176  static int old_add_to_ipset(const char *setname, const Line 180  static int old_add_to_ipset(const char *setname, const
     return -1;      return -1;
   req_adt.op = remove ? 0x102 : 0x101;    req_adt.op = remove ? 0x102 : 0x101;
   req_adt.index = req_adt_get.set.index;    req_adt.index = req_adt_get.set.index;
  req_adt.ip = ntohl(ipaddr->addr.addr4.s_addr);  req_adt.ip = ntohl(ipaddr->addr4.s_addr);
   if (setsockopt(ipset_sock, SOL_IP, 83, &req_adt, sizeof(req_adt)) < 0)    if (setsockopt(ipset_sock, SOL_IP, 83, &req_adt, sizeof(req_adt)) < 0)
     return -1;      return -1;
       
Line 185  static int old_add_to_ipset(const char *setname, const Line 189  static int old_add_to_ipset(const char *setname, const
   
   
   
int add_to_ipset(const char *setname, const struct all_addr *ipaddr, int flags, int remove)int add_to_ipset(const char *setname, const union all_addr *ipaddr, int flags, int remove)
 {  {
  int af = AF_INET;  int ret = 0, af = AF_INET;
   
 #ifdef HAVE_IPV6  
   if (flags & F_IPV6)    if (flags & F_IPV6)
     {      {
       af = AF_INET6;        af = AF_INET6;
       /* old method only supports IPv4 */        /* old method only supports IPv4 */
       if (old_kernel)        if (old_kernel)
        return -1;        {
           errno = EAFNOSUPPORT ;
           ret = -1;
         }
     }      }
 #endif  
       
  return old_kernel ? old_add_to_ipset(setname, ipaddr, remove) : new_add_to_ipset(setname, ipaddr, af, remove);  if (ret != -1) 
     ret = old_kernel ? old_add_to_ipset(setname, ipaddr, remove) : new_add_to_ipset(setname, ipaddr, af, remove);
 
   if (ret == -1)
      my_syslog(LOG_ERR, _("failed to update ipset %s: %s"), setname, strerror(errno));
 
   return ret;
 }  }
   
 #endif  #endif

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.4


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>