version 1.1.1.2, 2014/06/15 16:31:38
|
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> |
|
|
/* We want to be able to compile against old header files |
/* We want to be able to compile against old header files |
Line 87 static inline void add_attr(struct nlmsghdr *nlh, uint
|
Line 85 static inline void add_attr(struct nlmsghdr *nlh, uint
|
|
|
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 114 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 my_nfgenmsg *nfg; |
struct my_nfgenmsg *nfg; |
struct my_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; |
Line 158 static int new_add_to_ipset(const char *setname, const
|
Line 137 static int new_add_to_ipset(const char *setname, const
|
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 200 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 209 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 |