projects
/
musl
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
b3792c8
)
getifaddrs: less malloc
author
rofl0r
<retnyg@gmx.net>
Fri, 5 Apr 2013 20:06:35 +0000
(22:06 +0200)
committer
rofl0r
<retnyg@gmx.net>
Fri, 5 Apr 2013 20:06:35 +0000
(22:06 +0200)
src/network/getifaddrs.c
patch
|
blob
|
history
diff --git
a/src/network/getifaddrs.c
b/src/network/getifaddrs.c
index
d96d109
..
50eaee8
100644
(file)
--- a/
src/network/getifaddrs.c
+++ b/
src/network/getifaddrs.c
@@
-12,17
+12,27
@@
#include <unistd.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <sys/ioctl.h>
-static struct ifaddrs* list_add(struct ifaddrs** list, struct ifaddrs** head, char* ifname)
+typedef union {
+ struct sockaddr_in6 v6;
+ struct sockaddr_in v4;
+} soa;
+
+typedef struct ifaddrs_storage {
+ struct ifaddrs ifa;
+ soa addr;
+ soa netmask;
+ soa dst;
+ char name[IFNAMSIZ+1];
+} stor;
+#define next ifa.ifa_next
+
+static stor* list_add(stor** list, stor** head, char* ifname)
{
{
- st
ruct ifaddrs* curr = calloc(1, sizeof(struct ifaddrs
));
+ st
or* curr = calloc(1, sizeof(stor
));
if(curr) {
if(curr) {
- curr->ifa_name = strdup(ifname);
- if(!curr->ifa_name) {
- free(curr);
- curr = 0;
- goto out;
- }
- if(*head) (*head)->ifa_next = curr;
+ strcpy(curr->name, ifname);
+ curr->ifa.ifa_name = curr->name;
+ if(*head) (*head)->next = (struct ifaddrs*) curr;
*head = curr;
if(!*list) *list = curr;
}
*head = curr;
if(!*list) *list = curr;
}
@@
-32,40
+42,21
@@
static struct ifaddrs* list_add(struct ifaddrs** list, struct ifaddrs** head, ch
void freeifaddrs(struct ifaddrs *ifp)
{
void freeifaddrs(struct ifaddrs *ifp)
{
- st
ruct ifaddrs *head =
ifp;
+ st
or *head = (stor *)
ifp;
while(head) {
while(head) {
- free(head->ifa_name);
- free(head->ifa_addr);
- free(head->ifa_netmask);
- free(head->ifa_ifu.ifu_dstaddr);
- free(head->ifa_data);
void *p = head;
void *p = head;
- head =
head->ifa_
next;
+ head =
(stor *) head->
next;
free(p);
}
}
free(p);
}
}
-static struct sockaddr *sockaddr_in_dup(struct sockaddr_in *src)
-{
- struct sockaddr_in *nu = malloc(sizeof(struct sockaddr_in));
- if(nu) *nu = *src;
- return (struct sockaddr*) nu;
-}
-
-static struct sockaddr *sockaddr_in6_dup(struct sockaddr_in6 *src)
-{
- struct sockaddr_in6 *nu = malloc(sizeof(struct sockaddr_in6));
- if(nu) *nu = *src;
- return (struct sockaddr*) nu;
-}
-
static void ipv6netmask(unsigned prefix_length, struct sockaddr_in6 *sa)
{
// FIXME: left for bit-wizard rich
memset(&sa->sin6_addr, -1, sizeof(sa->sin6_addr));
}
static void ipv6netmask(unsigned prefix_length, struct sockaddr_in6 *sa)
{
// FIXME: left for bit-wizard rich
memset(&sa->sin6_addr, -1, sizeof(sa->sin6_addr));
}
-static void dealwithipv6(st
ruct ifaddrs **list, struct ifaddrs
** head)
+static void dealwithipv6(st
or **list, stor
** head)
{
FILE* f = fopen("/proc/net/if_inet6", "r");
/* 00000000000000000000000000000001 01 80 10 80 lo
{
FILE* f = fopen("/proc/net/if_inet6", "r");
/* 00000000000000000000000000000001 01 80 10 80 lo
@@
-94,16
+85,18
@@
static void dealwithipv6(struct ifaddrs **list, struct ifaddrs** head)
struct sockaddr_in6 sa = {0};
if(1 == inet_pton(AF_INET6, v6conv, &sa.sin6_addr)) {
sa.sin6_family = AF_INET6;
struct sockaddr_in6 sa = {0};
if(1 == inet_pton(AF_INET6, v6conv, &sa.sin6_addr)) {
sa.sin6_family = AF_INET6;
- st
ruct ifaddrs
* curr = list_add(list, head, name);
+ st
or
* curr = list_add(list, head, name);
if(!curr) goto out;
if(!curr) goto out;
- curr->ifa_addr = sockaddr_in6_dup(&sa);
+ curr->addr.v6 = sa;
+ curr->ifa.ifa_addr = (struct sockaddr*) &curr->addr;
ipv6netmask(c, &sa);
ipv6netmask(c, &sa);
- curr->ifa_netmask = sockaddr_in6_dup(&sa);
+ curr->netmask.v6 = sa;
+ curr->ifa.ifa_netmask = (struct sockaddr*) &curr->netmask;
/* find ipv4 struct with the same interface name to copy flags */
/* find ipv4 struct with the same interface name to copy flags */
- st
ruct ifaddrs
* scan = *list;
- for(;scan && strcmp(name, scan->
ifa_name);scan=scan->ifa_
next);
- if(scan) curr->ifa
_flags=scan->
ifa_flags;
- else curr->ifa_flags = 0;
+ st
or
* scan = *list;
+ for(;scan && strcmp(name, scan->
name);scan=(stor*)scan->
next);
+ if(scan) curr->ifa
.ifa_flags = scan->ifa.
ifa_flags;
+ else curr->ifa
.ifa
_flags = 0;
} else errno = 0;
}
}
} else errno = 0;
}
}
@@
-114,12
+107,13
@@
static void dealwithipv6(struct ifaddrs **list, struct ifaddrs** head)
int getifaddrs(struct ifaddrs **ifap)
{
FILE* f = fopen("/proc/net/dev", "r");
int getifaddrs(struct ifaddrs **ifap)
{
FILE* f = fopen("/proc/net/dev", "r");
+ if(!f) return -1;
+
/* the alternative to parsing /proc.. seems to be iterating
through the interfaces using an index number in ifreq.ifr_ifindex
until we get some error code back. the kernel will fill ifr_name field
for valid ifindices (SIOCGIFINDEX) */
/* the alternative to parsing /proc.. seems to be iterating
through the interfaces using an index number in ifreq.ifr_ifindex
until we get some error code back. the kernel will fill ifr_name field
for valid ifindices (SIOCGIFINDEX) */
- if(!f) return -1;
- struct ifaddrs *list = 0, *head = 0;
+ stor *list = 0, *head = 0;
char* line; char linebuf[512];
while((line = fgets(linebuf, sizeof linebuf, f))) {
char* line; char linebuf[512];
while((line = fgets(linebuf, sizeof linebuf, f))) {
@@
-129,7
+123,7
@@
int getifaddrs(struct ifaddrs **ifap)
if(line > start && *line == ':') {
// found interface
*line = 0;
if(line > start && *line == ':') {
// found interface
*line = 0;
- st
ruct ifaddrs
* curr = list_add(&list, &head, start);
+ st
or
* curr = list_add(&list, &head, start);
if(!curr) {
fclose(f);
goto err2;
if(!curr) {
fclose(f);
goto err2;
@@
-145,47
+139,50
@@
int getifaddrs(struct ifaddrs **ifap)
if(-1 == ioctl(sock, SIOCGIFCONF, &conf)) goto err;
else {
size_t reqitems = conf.ifc_len / sizeof(struct ifreq);
if(-1 == ioctl(sock, SIOCGIFCONF, &conf)) goto err;
else {
size_t reqitems = conf.ifc_len / sizeof(struct ifreq);
- for(head = list; head; head
=head->ifa_
next) {
+ for(head = list; head; head
= (stor*)head->
next) {
size_t i;
for(i = 0; i < reqitems; i++) {
// get SIOCGIFADDR of active interfaces.
size_t i;
for(i = 0; i < reqitems; i++) {
// get SIOCGIFADDR of active interfaces.
- if(!strcmp(reqs[i].ifr_name, head->ifa_name)) {
- head->ifa_addr = sockaddr_in_dup((struct sockaddr_in*) &reqs[i].ifr_addr);
+ if(!strcmp(reqs[i].ifr_name, head->name)) {
+ head->addr.v4 = *(struct sockaddr_in*)&reqs[i].ifr_addr;
+ head->ifa.ifa_addr = (struct sockaddr*) &head->addr;
break;
}
}
struct ifreq req;
break;
}
}
struct ifreq req;
- snprintf(req.ifr_name, sizeof req.ifr_name, "%s", head->
ifa_
name);
+ snprintf(req.ifr_name, sizeof req.ifr_name, "%s", head->name);
if(-1 == ioctl(sock, SIOCGIFFLAGS, &req)) goto err;
if(-1 == ioctl(sock, SIOCGIFFLAGS, &req)) goto err;
- head->ifa_flags = req.ifr_flags;
- if(head->ifa_addr) {
+ head->ifa
.ifa
_flags = req.ifr_flags;
+ if(head->ifa
.ifa
_addr) {
/* or'ing flags with IFF_LOWER_UP on active interfaces to mimic glibc */
/* or'ing flags with IFF_LOWER_UP on active interfaces to mimic glibc */
- head->ifa_flags |= IFF_LOWER_UP;
+ head->ifa
.ifa
_flags |= IFF_LOWER_UP;
if(-1 == ioctl(sock, SIOCGIFNETMASK, &req)) goto err;
if(-1 == ioctl(sock, SIOCGIFNETMASK, &req)) goto err;
- head->ifa_netmask = sockaddr_in_dup((struct sockaddr_in*) &req.ifr_netmask);
+ head->netmask.v4 = *(struct sockaddr_in*)&req.ifr_netmask;
+ head->ifa.ifa_netmask = (struct sockaddr*) &head->netmask;
- if(head->ifa_flags & IFF_POINTOPOINT) {
+ if(head->ifa
.ifa
_flags & IFF_POINTOPOINT) {
if(-1 == ioctl(sock, SIOCGIFDSTADDR, &req)) goto err;
if(-1 == ioctl(sock, SIOCGIFDSTADDR, &req)) goto err;
- head->
ifa_ifu.ifu_dstaddr = sockaddr_in_dup((struct sockaddr_in*) &req.ifr_dstaddr)
;
+ head->
dst.v4 = *(struct sockaddr_in*)&req.ifr_dstaddr
;
} else {
if(-1 == ioctl(sock, SIOCGIFBRDADDR, &req)) goto err;
} else {
if(-1 == ioctl(sock, SIOCGIFBRDADDR, &req)) goto err;
- head->
ifa_ifu.ifu_broadaddr = sockaddr_in_dup((struct sockaddr_in*) &req.ifr_broadaddr)
;
+ head->
dst.v4 = *(struct sockaddr_in*)&req.ifr_broadaddr
;
}
}
+ head->ifa.ifa_ifu.ifu_dstaddr = (struct sockaddr*) &head->dst;
}
}
}
close(sock);
void* last = 0;
}
}
}
close(sock);
void* last = 0;
- for(head = list; head; head=
head->ifa_
next) last=head;
+ for(head = list; head; head=
(stor*)head->
next) last=head;
head = last;
dealwithipv6(&list, &head);
head = last;
dealwithipv6(&list, &head);
- *ifap = list;
+ *ifap =
(struct ifaddrs*)
list;
return 0;
err:
close(sock);
err2:
return 0;
err:
close(sock);
err2:
- freeifaddrs(list);
+ freeifaddrs(
(struct ifaddrs*)
list);
return -1;
}
return -1;
}