summaryrefslogtreecommitdiff
path: root/src/libnet_if_addr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libnet_if_addr.c')
-rw-r--r--src/libnet_if_addr.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/src/libnet_if_addr.c b/src/libnet_if_addr.c
index ef1d6c0..3f1fac3 100644
--- a/src/libnet_if_addr.c
+++ b/src/libnet_if_addr.c
@@ -47,6 +47,7 @@
#include "../include/ifaddrlist.h"
#define MAX_IPADDR 512
+static size_t ip_addr_num = MAX_IPADDR;
#if !(__WIN32__)
@@ -104,10 +105,17 @@ int
libnet_ifaddrlist(register struct libnet_ifaddr_list **ipaddrp, char *dev, register char *errbuf)
{
(void)dev; /* unused */
- static struct libnet_ifaddr_list ifaddrlist[MAX_IPADDR];
+ static struct libnet_ifaddr_list *ifaddrlist = NULL, *ifaddrlist_tmp = NULL;
struct ifaddrs *ifap, *ifa;
int i = 0;
- memset (ifaddrlist, 0 , sizeof(ifaddrlist));
+
+ if (!ifaddrlist) {
+ ifaddrlist = calloc(ip_addr_num, sizeof(struct libnet_ifaddr_list));
+ if (!ifaddrlist) {
+ snprintf(errbuf, LIBNET_ERRBUF_SIZE, "%s(): OOM when allocating initial ifaddrlist", __func__);
+ return 0;
+ }
+ }
if (getifaddrs(&ifap) != 0)
{
@@ -130,6 +138,18 @@ libnet_ifaddrlist(register struct libnet_ifaddr_list **ipaddrp, char *dev, regis
ifaddrlist[i].addr = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr;
++i;
}
+
+ if (i == ip_addr_num) {
+ // grow by a factor of 1.5, close enough to golden ratio
+ ip_addr_num += ip_addr_num >> 2;
+ ifaddrlist_tmp = realloc(ifaddrlist, ip_addr_num * sizeof(struct libnet_ifaddr_list));
+ if (!ifaddrlist_tmp) {
+ snprintf(errbuf, LIBNET_ERRBUF_SIZE, "%s(): OOM when reallocating larger ifaddrlist", __func__);
+ break;
+ }
+
+ ifaddrlist = ifaddrlist_tmp;
+ }
}
freeifaddrs(ifap);
@@ -485,6 +505,7 @@ good:
free(al[i].device);
al[i].device = NULL;
}
+ free(al);
return (1);
bad:
@@ -493,6 +514,7 @@ bad:
free(al[i].device);
al[i].device = NULL;
}
+ free(al);
return (-1);
}