acl_ifconf.c is supporting IPV6

This commit is contained in:
zsx 2018-09-13 15:14:58 +08:00
parent 050da06552
commit 828610b2d7
4 changed files with 211 additions and 147 deletions

View File

@ -1,21 +1,21 @@
#include "lib_acl.h"
int main(void)
static void test1(void)
{
ACL_IFCONF *ifconf; /* 网卡查询结果对象 */
ACL_IFADDR *ifaddr; /* 每个网卡信息对象 */
ACL_ITER iter; /* 遍历对象 */
const char *pattern = "127.*.*.*:8290, 192.168.*.*:8290, 172.16.*.*.:8290, 172.17.*.*.:8290, /unix_server@unix";
ACL_ARGV *addrs;
/* 查询本机所有网卡信息 */
ifconf = acl_get_ifaddrs();
if (ifconf == NULL) {
printf("acl_get_ifaddrs error: %s\r\n", acl_last_serror());
return 1;
return;
}
printf("acl_get_ifaddrs:\r\n");
/* 遍历所有网卡的信息 */
acl_foreach(iter, ifconf) {
ifaddr = (ACL_IFADDR*) iter.data;
@ -24,13 +24,17 @@ int main(void)
/* 释放查询结果 */
acl_free_ifaddrs(ifconf);
}
printf("\r\n----------------------------------------------\r\n");
static void test2(const char *pattern)
{
ACL_ITER iter; /* ±éÀú¶ÔÏó */
ACL_ARGV *addrs;
addrs = acl_ifconf_search(pattern);
if (addrs == NULL) {
printf("acl_ifconf_search error\r\n");
return 1;
return;
}
printf("pattern=%s\r\n", pattern);
@ -38,8 +42,34 @@ int main(void)
const char *addr = (const char *)iter.data;
printf(">>>ip: %s\r\n", addr);
}
acl_argv_free(addrs);
acl_argv_free(addrs);
}
int main(void)
{
const char *patterns[] = {
"8190",
"#8190",
":8190",
"*#8190",
"*.*.*.*:8190",
"0.0.0.0:8190",
"127.*.*.*:8290, 192.168.*.*:8291, 172.16.*.*.:8292, 172.17.*.*.:8293, /unix_server@unix",
"127.*.*.*:8290, 0.0.0.0:8191, *.*.*.*:8292",
":8191, #8192, *:8193, *#8194",
NULL,
};
int i;
test1();
for (i = 0; patterns[i]; i++) {
if (i >= 0) {
printf("\r\n-----------------------------------\r\n");
test2(patterns[i]);
}
}
return 0;
}

0
lib_acl/samples/ifconf/valgrind.sh Normal file → Executable file
View File

View File

@ -9,23 +9,24 @@
#include "stdlib/acl_stringops.h"
#include "net/acl_sane_inet.h"
#include "net/acl_sane_socket.h"
#include "net/acl_valid_hostname.h"
#include "net/acl_ifconf.h"
#endif
static const ACL_IFADDR *ifaddrs_iter_head(ACL_ITER *iter, struct ACL_IFCONF *ifconf)
static const ACL_IFADDR *iter_head(ACL_ITER *iter, struct ACL_IFCONF *ifconf)
{
iter->dlen = -1;
iter->key = NULL;
iter->key = NULL;
iter->klen = -1;
iter->i = 0;
iter->size = ifconf->length;
iter->ptr = iter->data = &ifconf->addrs[0];
iter->ptr = iter->data = &ifconf->addrs[0];
return (iter->ptr);
}
static const ACL_IFADDR *ifaddrs_iter_next(ACL_ITER *iter, struct ACL_IFCONF *ifconf)
static const ACL_IFADDR *iter_next(ACL_ITER *iter, struct ACL_IFCONF *ifconf)
{
iter->i++;
if (iter->i >= ifconf->length)
@ -35,13 +36,13 @@ static const ACL_IFADDR *ifaddrs_iter_next(ACL_ITER *iter, struct ACL_IFCONF *if
return (iter->ptr);
}
static const ACL_IFADDR *ifaddrs_iter_tail(ACL_ITER *iter, struct ACL_IFCONF *ifconf)
static const ACL_IFADDR *iter_tail(ACL_ITER *iter, struct ACL_IFCONF *ifconf)
{
iter->dlen = -1;
iter->key = NULL;
iter->key = NULL;
iter->klen = -1;
iter->i = ifconf->length - 1;
iter->i = ifconf->length - 1;
iter->size = ifconf->length;
if (iter->i < 0)
iter->data = iter->ptr = NULL;
@ -50,7 +51,7 @@ static const ACL_IFADDR *ifaddrs_iter_tail(ACL_ITER *iter, struct ACL_IFCONF *if
return (iter->ptr);
}
static const ACL_IFADDR *ifaddrs_iter_prev(ACL_ITER *iter, struct ACL_IFCONF *ifconf)
static const ACL_IFADDR *iter_prev(ACL_ITER *iter, struct ACL_IFCONF *ifconf)
{
iter->i--;
if (iter->i < 0)
@ -73,18 +74,16 @@ static const ACL_IFADDR *ifaddrs_iter_prev(ACL_ITER *iter, struct ACL_IFCONF *if
ACL_IFCONF *acl_get_ifaddrs()
{
const char *myname = "acl_get_ifaddrs";
ACL_IFCONF *ifconf;
struct ifreq *ifaces;
int ifaces_size = 8 * sizeof(struct ifreq);
struct ifconf param;
int sock;
int i, j;
int sock, i, j;
sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
if (sock <= 0) {
acl_msg_error("%s(%d): create socket error(%s)",
myname, __LINE__, acl_last_serror());
__FUNCTION__, __LINE__, acl_last_serror());
return (NULL);
}
@ -94,7 +93,7 @@ ACL_IFCONF *acl_get_ifaddrs()
param.ifc_req = ifaces;
if (ioctl(sock, SIOCGIFCONF, &param)) {
acl_msg_error("%s(%d): ioctl error(%s)",
myname, __LINE__, acl_last_serror());
__FUNCTION__, __LINE__, acl_last_serror());
close(sock);
acl_myfree(ifaces);
return (NULL);
@ -115,28 +114,12 @@ ACL_IFCONF *acl_get_ifaddrs()
for (i = 0, j = 0; i < ifconf->length; i++) {
ACL_SOCKADDR *saddr = (ACL_SOCKADDR *) &ifaces[i].ifr_addr;
ACL_IFADDR *ifa = (ACL_IFADDR *) &ifconf->addrs[j];
ACL_IFADDR *ifa = (ACL_IFADDR *) &ifconf->addrs[j];
size_t size;
if (saddr->sa.sa_family == AF_INET) {
if (inet_ntop(AF_INET, &saddr->in.sin_addr,
ifa->ip, sizeof(ifa->ip)) == NULL) {
continue;
}
size = sizeof(struct sockaddr_in);
#ifdef AF_INET6
} else if (saddr->sa.sa_family == AF_INET6) {
if (inet_ntop(AF_INET6, &saddr->in6.sin6_addr,
ifa->ip, sizeof(ifa->ip)) == NULL) {
continue;
}
size = sizeof(struct sockaddr_in6);
#endif
} else {
size = acl_inet_ntop(&saddr->sa, ifa->ip, sizeof(ifa->ip));
if (size == 0)
continue;
}
ifconf->addrs[j].name = acl_mystrdup(ifaces[i].ifr_name);
memcpy(&ifconf->addrs[j].saddr, saddr, size);
@ -153,10 +136,10 @@ ACL_IFCONF *acl_get_ifaddrs()
ifconf->length = j; /* reset the ifconf->length */
/* set the iterator callback */
ifconf->iter_head = ifaddrs_iter_head;
ifconf->iter_next = ifaddrs_iter_next;
ifconf->iter_tail = ifaddrs_iter_tail;
ifconf->iter_prev = ifaddrs_iter_prev;
ifconf->iter_head = iter_head;
ifconf->iter_next = iter_next;
ifconf->iter_tail = iter_tail;
ifconf->iter_prev = iter_prev;
acl_myfree(ifaces);
return ifconf;
@ -174,40 +157,37 @@ typedef HRESULT STDAPICALLTYPE PGAINFO(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOu
ACL_IFCONF *acl_get_ifaddrs(void)
{
const char *myname = "acl_get_ifaddrs";
IP_ADAPTER_INFO info_temp, *infos, *info;
ACL_IFCONF *ifconf;
ULONG len = 0;
int j;
int j;
HMODULE hInst;
PGAINFO *pGAInfo;
hInst = LoadLibrary("iphlpapi.dll");
if(!hInst) {
MessageBox(0, "iphlpapi.dll not supported in this platform!", "Error", 0);
return (NULL);
MessageBox(0, "iphlpapi.dll not supported!", "Error", 0);
return NULL;
}
pGAInfo = (PGAINFO*) GetProcAddress(hInst,"GetAdaptersInfo");
if (pGAInfo == NULL) {
MessageBox(0, "can't find GetAdaptersInfo function!", "Error", 0);
return (NULL);
MessageBox(0, "can't find GetAdaptersInfo!", "Error", 0);
return NULL;
}
if (pGAInfo(&info_temp, &len) != ERROR_BUFFER_OVERFLOW) {
acl_msg_error("%s(%d): GetAdaptersInfo eror(%s)",
myname, __LINE__, acl_last_serror());
MessageBox(0, "GetAdaptersInfo error", 0);
FreeLibrary(hInst);
return (NULL);
return NULL;
}
infos = (IP_ADAPTER_INFO *) acl_mymalloc(len);
if (pGAInfo(infos, &len) != NO_ERROR) {
acl_msg_error("%s(%d): GetAdaptersInfo eror(%s)",
myname, __LINE__, acl_last_serror());
MessageBox(0, "GetAdaptersInfo eror", 0);
acl_myfree(infos);
FreeLibrary(hInst);
return (NULL);
return NULL;
}
ifconf = (ACL_IFCONF*) acl_mymalloc(sizeof(ACL_IFCONF));
@ -249,10 +229,10 @@ ACL_IFCONF *acl_get_ifaddrs(void)
ifconf->length = j; /* reset the ifconf->length */
/* set the iterator callback */
ifconf->iter_head = ifaddrs_iter_head;
ifconf->iter_next = ifaddrs_iter_next;
ifconf->iter_tail = ifaddrs_iter_tail;
ifconf->iter_prev = ifaddrs_iter_prev;
ifconf->iter_head = iter_head;
ifconf->iter_next = iter_next;
ifconf->iter_tail = iter_tail;
ifconf->iter_prev = iter_prev;
FreeLibrary(hInst);
return (ifconf);
@ -264,7 +244,6 @@ ACL_IFCONF *acl_get_ifaddrs(void)
ACL_IFCONF *acl_get_ifaddrs()
{
const char *myname = "acl_get_ifaddrs";
IP_ADAPTER_INFO info_temp, *infos, *info;
ACL_IFCONF *ifconf;
ULONG len = 0;
@ -272,14 +251,14 @@ ACL_IFCONF *acl_get_ifaddrs()
if (GetAdaptersInfo(&info_temp, &len) != ERROR_BUFFER_OVERFLOW) {
acl_msg_error("%s(%d): GetAdaptersInfo eror(%s)",
myname, __LINE__, acl_last_serror());
__FUNCTION__, __LINE__, acl_last_serror());
return NULL;
}
infos = (IP_ADAPTER_INFO *) acl_mymalloc(len);
if (GetAdaptersInfo(infos, &len) != NO_ERROR) {
acl_msg_error("%s(%d): GetAdaptersInfo eror(%s)",
myname, __LINE__, acl_last_serror());
__FUNCTION__, __LINE__, acl_last_serror());
acl_myfree(infos);
return NULL;
}
@ -292,7 +271,7 @@ ACL_IFCONF *acl_get_ifaddrs()
for (info = infos, j = 0; info != NULL; info = info->Next) {
if (info->Type == MIB_IF_TYPE_LOOPBACK)
continue;
if (strcmp(info->IpAddressList.IpAddress.String, "0.0.0.0") == 0)
if (!strcmp(info->IpAddressList.IpAddress.String, "0.0.0.0"))
continue;
if (!acl_is_ip(info->IpAddressList.IpAddress.String))
continue;
@ -300,7 +279,7 @@ ACL_IFCONF *acl_get_ifaddrs()
ifconf->addrs[j].name = acl_mystrdup(info->AdapterName);
ifconf->addrs[j].desc = acl_mystrdup(info->Description);
snprintf(ifconf->addrs[j].ip, sizeof(ifconf->addrs[j].ip),
"%s", info->IpAddressList.IpAddress.String);
"%s", info->IpAddressList.IpAddress.String);
ifconf->addrs[j].saddr.in.sin_addr.s_addr
= inet_addr(ifconf->addrs[j].ip);
j++;
@ -322,10 +301,10 @@ ACL_IFCONF *acl_get_ifaddrs()
ifconf->length = j; /* reset the ifconf->length */
/* set the iterator callback */
ifconf->iter_head = ifaddrs_iter_head;
ifconf->iter_next = ifaddrs_iter_next;
ifconf->iter_tail = ifaddrs_iter_tail;
ifconf->iter_prev = ifaddrs_iter_prev;
ifconf->iter_head = iter_head;
ifconf->iter_next = iter_next;
ifconf->iter_tail = iter_tail;
ifconf->iter_prev = iter_prev;
return (ifconf);
}
@ -353,55 +332,6 @@ void acl_free_ifaddrs(ACL_IFCONF *ifconf)
acl_myfree(ifconf);
}
#define MAX 1024
static int match_wildcard(const char *pattern, ACL_ARGV *addrs)
{
const char any[] = "0.0.0.0:";
const char domain[] = "@unix";
const char udp[] = "@udp";
char addr[MAX];
ACL_ARGV *tokens;
#define PREFIX_EQ(x, y) !acl_strncasecmp((x), (y), strlen(y))
if (PREFIX_EQ(pattern, any)) {
acl_argv_add(addrs, pattern, NULL);
return 1;
}
#define SUFFIX_EQ(x, y) !acl_strrncasecmp((x), (y), strlen((y)))
/* for unix domain socket path */
if (SUFFIX_EQ(pattern, udp) || SUFFIX_EQ(pattern, domain)) {
acl_argv_add(addrs, pattern, NULL);
return 1;
}
/* for "port" */
if (acl_alldig(pattern)) {
snprintf(addr, sizeof(addr), "0.0.0.0:%s", pattern);
acl_argv_add(addrs, addr, NULL);
return 1;
}
/* for ":port" */
if (*pattern == ':' && acl_alldig(++pattern)) {
snprintf(addr, sizeof(addr), "0.0.0.0:%s", pattern);
acl_argv_add(addrs, addr, NULL);
return 1;
}
/* for unix domain socket path */
tokens = acl_argv_split(pattern, ".");
if (tokens->argc != 4) {
acl_argv_add(addrs, pattern, NULL);
acl_argv_free(tokens);
return 1;
}
acl_argv_free(tokens);
return 0;
}
static int match_ipv4(const char *pattern, const char *ip)
{
/* format: xxx.xxx.xxx.* or xxx.xxx.*.* or xxx.*.*.* */
@ -410,6 +340,14 @@ static int match_ipv4(const char *pattern, const char *ip)
ACL_ITER iter;
int i = 0;
#define EQ !strcmp
#define IPV4_MATCH(p) (EQ((p), "*") || EQ((p), "*.*.*.*") || EQ((p), "0.0.0.0"))
/* for "*" or "*.*.*.*" or "0.0.0.0" */
if (IPV4_MATCH(pattern)) {
return 1;
}
pattern_tokens = acl_argv_split(pattern, ".");
ip_tokens = acl_argv_split(ip, ".");
@ -446,34 +384,115 @@ static int match_ipv4(const char *pattern, const char *ip)
return 1;
}
static void match_addrs_add(const char *pattern, ACL_IFCONF *ifconf,
ACL_ARGV *addrs)
/* for ":port" or "#port" */
#define MATCH1(p) ((*(p) == ':' || *(p) == '#'))
/* for "*:port" or "*#port" */
#define MATCH2(p) (*(p) == '*' && (*((p) + 1) == ':' || *((p) + 1) == '#'))
/**
* pattern for ipv4:
* *#port, *:port, #port, :port, *.*.*.*:port, 0.0.0.0:port, xxx.xxx.xxx.xxx:port,
* *, *.*.*.*, 0.0.0.0, xxx.xxx.xxx.xxx
*/
static int ipv4_pattern_match_add(const char *pattern,
const ACL_IFADDR *ifaddr, ACL_ARGV *addrs)
{
char buf[256], *ptr, addr[256];
/* for "port" */
if (acl_alldig(pattern)) {
snprintf(addr, sizeof(addr), "%s:%s", ifaddr->ip, pattern);
acl_argv_add(addrs, addr, NULL);
return 1;
}
ACL_SAFE_STRNCPY(buf, pattern, sizeof(buf));
if ((ptr = strrchr(buf, ACL_ADDR_SEP)) || (ptr = strrchr(buf, ':')))
*ptr++ = 0;
else
ptr = NULL;
if (MATCH1(pattern) || MATCH2(pattern)) {
if (ptr && *ptr && acl_alldig(ptr))
snprintf(addr, sizeof(addr), "%s:%s", ifaddr->ip, ptr);
else
snprintf(addr, sizeof(addr), "%s", ifaddr->ip);
acl_argv_add(addrs, addr, NULL);
return 1;
}
if (!match_ipv4(buf, ifaddr->ip))
return 0;
if (ptr && *ptr) {
snprintf(addr, sizeof(addr), "%s:%s", ifaddr->ip, ptr);
acl_argv_add(addrs, addr, NULL);
} else
acl_argv_add(addrs, ifaddr->ip, NULL);
return 1;
}
/**
* pattern for ipv6:
* *#port, #port, *, port
*/
#ifdef AF_INET6
static int ipv6_pattern_match_add(const char *pattern,
const ACL_IFADDR *ifaddr, ACL_ARGV *addrs)
{
char buf[256], *ptr, addr[256];
/* for "port" */
if (acl_alldig(pattern)) {
snprintf(addr, sizeof(addr), "%s:%s", ifaddr->ip, pattern);
acl_argv_add(addrs, addr, NULL);
return 1;
}
if (MATCH1(pattern) || MATCH2(pattern)) {
snprintf(addr, sizeof(addr), "%s%s", ifaddr->ip, pattern);
acl_argv_add(addrs, addr, NULL);
return 1;
}
ACL_SAFE_STRNCPY(buf, pattern, sizeof(buf));
if ((ptr = strrchr(buf, ACL_ADDR_SEP)) || (ptr = strrchr(buf, ':')))
*ptr++ = 0;
else
ptr = NULL;
if (!acl_valid_ipv6_hostaddr(buf, 0))
return 0;
if (ptr && *ptr) {
snprintf(addr, sizeof(addr), "%s:%s", ifaddr->ip, pattern);
acl_argv_add(addrs, addr, NULL);
} else
acl_argv_add(addrs, ifaddr->ip, NULL);
return 1;
}
#endif
static void patterns_match_add(ACL_ARGV *patterns,
const ACL_IFADDR *ifaddr, ACL_ARGV *addrs)
{
ACL_ITER iter;
acl_foreach(iter, ifconf) {
ACL_IFADDR *ifaddr = (ACL_IFADDR*) iter.data;
const char *ip = (const char *) ifaddr->ip;
char tmp[MAX], *colon, addr[MAX];
int port;
acl_foreach(iter, patterns) {
const char *pattern = (const char *) iter.data;
const struct sockaddr *sa = &ifaddr->saddr.sa;
/* xxx.xxx.xxx.xxx:port or xxx.xxx.xxx.*:port ...*/
snprintf(tmp, sizeof(tmp), "%s", pattern);
colon = strchr(tmp, ':');
if (colon) {
*colon++ = 0;
port = atoi(colon);
} else
port = -1;
if (!match_ipv4(tmp, ip))
continue;
if (port >= 0)
snprintf(addr, sizeof(addr), "%s:%d", ip, port);
else
snprintf(addr, sizeof(addr), "%s", ip);
acl_argv_add(addrs, addr, NULL);
if (sa->sa_family == AF_INET) {
ipv4_pattern_match_add(pattern, ifaddr, addrs);
}
#ifdef AF_INET6
else if (sa->sa_family == AF_INET6) {
ipv6_pattern_match_add(pattern, ifaddr, addrs);
}
#endif
}
}
@ -492,12 +511,20 @@ ACL_ARGV *acl_ifconf_search(const char *patterns)
addrs = acl_argv_alloc(1);
patterns_tokens = acl_argv_split(patterns, "\"',; \t\r\n");
acl_foreach(iter, ifconf) {
const ACL_IFADDR *ifaddr = (const ACL_IFADDR *) iter.data;
patterns_match_add(patterns_tokens, ifaddr, addrs);
}
#ifdef ACL_UNIX
/* just for all unix domain path */
acl_foreach(iter, patterns_tokens) {
const char *pattern = (const char *) iter.data;
if (match_wildcard(pattern, addrs) == 0)
match_addrs_add(pattern, ifconf, addrs);
if (*pattern == '/' || (*pattern == '.' && *pattern == '/'))
acl_argv_add(addrs, pattern, NULL);
}
#endif
acl_argv_free(patterns_tokens);
acl_free_ifaddrs(ifconf);

View File

@ -159,7 +159,10 @@ size_t acl_inet_ntop(const struct sockaddr *sa, char *buf, size_t size)
if (!inet_ntop(sa->sa_family, &in->sin_addr, ip, IPLEN))
return 0;
port = ntohs(in->sin_port);
snprintf(buf, size, "%s%c%d", ip, ACL_ADDR_SEP, port);
if (port > 0)
snprintf(buf, size, "%s%c%d", ip, ACL_ADDR_SEP, port);
else
snprintf(buf, size, "%s", ip);
return sizeof(struct sockaddr_in);
#ifdef AF_INET6
} else if (sa->sa_family == AF_INET6) {
@ -170,7 +173,10 @@ size_t acl_inet_ntop(const struct sockaddr *sa, char *buf, size_t size)
if (!inet_ntop(sa->sa_family, &in6->sin6_addr, ip, IPLEN))
return 0;
port = ntohs(in6->sin6_port);
snprintf(buf, size, "%s%c%d", ip, ACL_ADDR_SEP, port);
if (port > 0)
snprintf(buf, size, "%s%c%d", ip, ACL_ADDR_SEP, port);
else
snprintf(buf, size, "%s", ip);
return sizeof(struct sockaddr_in6);
#endif
#ifdef ACL_UNIX
@ -180,8 +186,9 @@ size_t acl_inet_ntop(const struct sockaddr *sa, char *buf, size_t size)
ACL_SAFE_STRNCPY(buf, un->sun_path, size);
return sizeof(struct sockaddr_un);
#endif
} else
} else {
return 0;
}
}
size_t acl_inet_pton(int af, const char *src, struct sockaddr *dst)