Skip to content

Commit

Permalink
(netlink_receive): Allocate only one block. (free_netlink_handle): Ad…
Browse files Browse the repository at this point in the history
…just appropriately. (getifaddrs): Lots of cleanups.
  • Loading branch information
Ulrich Drepper committed Apr 16, 2003
1 parent dd9d653 commit 5bdd77c
Showing 1 changed file with 34 additions and 48 deletions.
82 changes: 34 additions & 48 deletions sysdeps/unix/sysv/linux/ifaddrs.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ free_netlink_handle (struct netlink_handle *h)
{
struct netlink_res *tmpptr;

free (ptr->nlh);
tmpptr = ptr->next;
free (ptr);
ptr = tmpptr;
Expand Down Expand Up @@ -169,17 +168,12 @@ netlink_receive (struct netlink_handle *h)
if (msg.msg_flags & MSG_TRUNC)
return -1;

nlm_next = (struct netlink_res *) malloc (sizeof (struct netlink_res));
nlm_next = (struct netlink_res *) malloc (sizeof (struct netlink_res)
+ read_len);
if (nlm_next == NULL)
return -1;
nlm_next->next = NULL;
nlm_next->nlh = (struct nlmsghdr *) malloc (read_len);
if (nlm_next->nlh == NULL)
{
free (nlm_next);
return -1;
}
memcpy (nlm_next->nlh, buf, read_len);
nlm_next->nlh = memcpy (nlm_next + 1, buf, read_len);
nlm_next->size = read_len;
nlm_next->seq = h->seq;
if (h->nlm_list == NULL)
Expand All @@ -202,7 +196,7 @@ netlink_receive (struct netlink_handle *h)

if (nlmh->nlmsg_type == NLMSG_DONE)
{
/* we found the end, leave the loop. */
/* We found the end, leave the loop. */
done = true;
break;
}
Expand Down Expand Up @@ -273,7 +267,7 @@ map_newlink (int index, int *map, int max)
return i;
}
/* This should never be reached. If this will be reached, we have
very big problem. */
a very big problem. */
abort ();
}

Expand All @@ -292,6 +286,7 @@ getifaddrs (struct ifaddrs **ifap)
size_t ifa_data_size = 0; /* Size to allocate for all ifa_data. */
char *ifa_data_ptr; /* Pointer to the unused part of memory for
ifa_data. */
int result = 0;

if (ifap)
*ifap = NULL;
Expand All @@ -316,15 +311,14 @@ getifaddrs (struct ifaddrs **ifap)
active interfaces. */
if (netlink_sendreq (&nh, RTM_GETLINK) < 0)
{
netlink_close (&nh);
return -1;
result = -1;
goto exit_close;
}
/* Collect all data for every interface. */
if (netlink_receive (&nh) < 0)
{
free_netlink_handle (&nh);
netlink_close (&nh);
return -1;
result = -1;
goto exit_free;
}


Expand All @@ -333,18 +327,12 @@ getifaddrs (struct ifaddrs **ifap)
interfaces in the list, we will later always find the
interface before the corresponding addresses. */
++nh.seq;
if (netlink_sendreq (&nh, RTM_GETADDR) < 0)
{
free_netlink_handle (&nh);
netlink_close (&nh);
return -1;
}
/* Collect all data for every inerface. */
if (netlink_receive (&nh) < 0)
if (netlink_sendreq (&nh, RTM_GETADDR) < 0
/* Collect all data for every interface. */
|| netlink_receive (&nh) < 0)
{
free_netlink_handle (&nh);
netlink_close (&nh);
return -1;
result = -1;
goto exit_free;
}

/* Count all RTM_NEWLINK and RTM_NEWADDR entries to allocate
Expand Down Expand Up @@ -399,11 +387,7 @@ getifaddrs (struct ifaddrs **ifap)

/* Return if no interface is up. */
if ((newlink + newaddr) == 0)
{
free_netlink_handle (&nh);
netlink_close (&nh);
return 0;
}
goto exit_free;

/* Table for mapping kernel index to entry in our list. */
map_newlink_data = alloca (newlink * sizeof (int));
Expand All @@ -416,17 +400,16 @@ getifaddrs (struct ifaddrs **ifap)
+ ifa_data_size);
if (ifas == NULL)
{
free_netlink_handle (&nh);
netlink_close (&nh);
return -1;
result = -1;
goto exit_free;
}

for (i = 0; i < newlink + newaddr - 1; i++)
{
ifas[i].ifa.ifa_next = &ifas[i + 1].ifa;
map_newlink_data[i] = -1;
}
ifa_data_ptr = (char *)&ifas[newlink + newaddr];
ifa_data_ptr = (char *) &ifas[newlink + newaddr];
newaddr_idx = 0; /* Counter for newaddr index. */

/* Walk through the list of data we got from the kernel. */
Expand All @@ -446,21 +429,22 @@ getifaddrs (struct ifaddrs **ifap)
{
int ifa_index = 0;

/* check if the message is the one we want */
/* Check if the message is the one we want */
if ((pid_t) nlh->nlmsg_pid != nh.pid || nlh->nlmsg_seq != nlp->seq)
continue;

if (nlh->nlmsg_type == NLMSG_DONE)
break; /* ok */
else if (nlh->nlmsg_type == RTM_NEWLINK)

if (nlh->nlmsg_type == RTM_NEWLINK)
{
/* We found a new interface. Now extract everything from the
interface data we got and need. */
struct ifinfomsg *ifim = (struct ifinfomsg *) NLMSG_DATA (nlh);
struct rtattr *rta = IFLA_RTA (ifim);
size_t rtasize = IFLA_PAYLOAD (nlh);

/* interfaces are stored in the first "newlink" entries
/* Interfaces are stored in the first "newlink" entries
of our list, starting in the order as we got from the
kernel. */
ifa_index = map_newlink (ifim->ifi_index - 1,
Expand Down Expand Up @@ -537,7 +521,7 @@ getifaddrs (struct ifaddrs **ifap)
size_t rtasize = IFA_PAYLOAD (nlh);

/* New Addresses are stored in the order we got them from
the kernel after interfaces. Theoretical it is possible
the kernel after interfaces. Theoretically it is possible
that we have holes in the interface part of the list,
but we always have already the interface for this address. */
ifa_index = newlink + newaddr_idx;
Expand Down Expand Up @@ -662,10 +646,10 @@ getifaddrs (struct ifaddrs **ifap)
case AF_INET6:
memcpy (&ifas[ifa_index].broadaddr.s6.sin6_addr,
rta_data, rta_payload);
if (IN6_IS_ADDR_LINKLOCAL (rta_data) ||
IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
ifas[ifa_index].broadaddr.s6.sin6_scope_id =
ifam->ifa_scope;
if (IN6_IS_ADDR_LINKLOCAL (rta_data)
|| IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
ifas[ifa_index].broadaddr.s6.sin6_scope_id
= ifam->ifa_scope;
break;

default:
Expand Down Expand Up @@ -754,14 +738,16 @@ getifaddrs (struct ifaddrs **ifap)
}
}

if (ifap != NULL)
*ifap = &ifas[0].ifa;

exit_free:
free_netlink_handle (&nh);

exit_close:
netlink_close (&nh);

if (ifap != NULL)
*ifap = &ifas[0].ifa;

return 0;
return result;
}


Expand Down

0 comments on commit 5bdd77c

Please sign in to comment.