mirror of
https://sourceware.org/git/glibc.git
synced 2025-01-18 06:30:05 +00:00
(netlink_receive): Allocate only one block. (free_netlink_handle): Adjust appropriately. (getifaddrs): Lots of cleanups.
This commit is contained in:
parent
dd9d65384e
commit
5bdd77cb60
@ -102,7 +102,6 @@ free_netlink_handle (struct netlink_handle *h)
|
|||||||
{
|
{
|
||||||
struct netlink_res *tmpptr;
|
struct netlink_res *tmpptr;
|
||||||
|
|
||||||
free (ptr->nlh);
|
|
||||||
tmpptr = ptr->next;
|
tmpptr = ptr->next;
|
||||||
free (ptr);
|
free (ptr);
|
||||||
ptr = tmpptr;
|
ptr = tmpptr;
|
||||||
@ -169,17 +168,12 @@ netlink_receive (struct netlink_handle *h)
|
|||||||
if (msg.msg_flags & MSG_TRUNC)
|
if (msg.msg_flags & MSG_TRUNC)
|
||||||
return -1;
|
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)
|
if (nlm_next == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
nlm_next->next = NULL;
|
nlm_next->next = NULL;
|
||||||
nlm_next->nlh = (struct nlmsghdr *) malloc (read_len);
|
nlm_next->nlh = memcpy (nlm_next + 1, buf, read_len);
|
||||||
if (nlm_next->nlh == NULL)
|
|
||||||
{
|
|
||||||
free (nlm_next);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
memcpy (nlm_next->nlh, buf, read_len);
|
|
||||||
nlm_next->size = read_len;
|
nlm_next->size = read_len;
|
||||||
nlm_next->seq = h->seq;
|
nlm_next->seq = h->seq;
|
||||||
if (h->nlm_list == NULL)
|
if (h->nlm_list == NULL)
|
||||||
@ -202,7 +196,7 @@ netlink_receive (struct netlink_handle *h)
|
|||||||
|
|
||||||
if (nlmh->nlmsg_type == NLMSG_DONE)
|
if (nlmh->nlmsg_type == NLMSG_DONE)
|
||||||
{
|
{
|
||||||
/* we found the end, leave the loop. */
|
/* We found the end, leave the loop. */
|
||||||
done = true;
|
done = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -273,7 +267,7 @@ map_newlink (int index, int *map, int max)
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
/* This should never be reached. If this will be reached, we have
|
/* This should never be reached. If this will be reached, we have
|
||||||
very big problem. */
|
a very big problem. */
|
||||||
abort ();
|
abort ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,6 +286,7 @@ getifaddrs (struct ifaddrs **ifap)
|
|||||||
size_t ifa_data_size = 0; /* Size to allocate for all ifa_data. */
|
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
|
char *ifa_data_ptr; /* Pointer to the unused part of memory for
|
||||||
ifa_data. */
|
ifa_data. */
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
if (ifap)
|
if (ifap)
|
||||||
*ifap = NULL;
|
*ifap = NULL;
|
||||||
@ -316,15 +311,14 @@ getifaddrs (struct ifaddrs **ifap)
|
|||||||
active interfaces. */
|
active interfaces. */
|
||||||
if (netlink_sendreq (&nh, RTM_GETLINK) < 0)
|
if (netlink_sendreq (&nh, RTM_GETLINK) < 0)
|
||||||
{
|
{
|
||||||
netlink_close (&nh);
|
result = -1;
|
||||||
return -1;
|
goto exit_close;
|
||||||
}
|
}
|
||||||
/* Collect all data for every interface. */
|
/* Collect all data for every interface. */
|
||||||
if (netlink_receive (&nh) < 0)
|
if (netlink_receive (&nh) < 0)
|
||||||
{
|
{
|
||||||
free_netlink_handle (&nh);
|
result = -1;
|
||||||
netlink_close (&nh);
|
goto exit_free;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -333,18 +327,12 @@ getifaddrs (struct ifaddrs **ifap)
|
|||||||
interfaces in the list, we will later always find the
|
interfaces in the list, we will later always find the
|
||||||
interface before the corresponding addresses. */
|
interface before the corresponding addresses. */
|
||||||
++nh.seq;
|
++nh.seq;
|
||||||
if (netlink_sendreq (&nh, RTM_GETADDR) < 0)
|
if (netlink_sendreq (&nh, RTM_GETADDR) < 0
|
||||||
|
/* Collect all data for every interface. */
|
||||||
|
|| netlink_receive (&nh) < 0)
|
||||||
{
|
{
|
||||||
free_netlink_handle (&nh);
|
result = -1;
|
||||||
netlink_close (&nh);
|
goto exit_free;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
/* Collect all data for every inerface. */
|
|
||||||
if (netlink_receive (&nh) < 0)
|
|
||||||
{
|
|
||||||
free_netlink_handle (&nh);
|
|
||||||
netlink_close (&nh);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Count all RTM_NEWLINK and RTM_NEWADDR entries to allocate
|
/* Count all RTM_NEWLINK and RTM_NEWADDR entries to allocate
|
||||||
@ -399,11 +387,7 @@ getifaddrs (struct ifaddrs **ifap)
|
|||||||
|
|
||||||
/* Return if no interface is up. */
|
/* Return if no interface is up. */
|
||||||
if ((newlink + newaddr) == 0)
|
if ((newlink + newaddr) == 0)
|
||||||
{
|
goto exit_free;
|
||||||
free_netlink_handle (&nh);
|
|
||||||
netlink_close (&nh);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Table for mapping kernel index to entry in our list. */
|
/* Table for mapping kernel index to entry in our list. */
|
||||||
map_newlink_data = alloca (newlink * sizeof (int));
|
map_newlink_data = alloca (newlink * sizeof (int));
|
||||||
@ -416,9 +400,8 @@ getifaddrs (struct ifaddrs **ifap)
|
|||||||
+ ifa_data_size);
|
+ ifa_data_size);
|
||||||
if (ifas == NULL)
|
if (ifas == NULL)
|
||||||
{
|
{
|
||||||
free_netlink_handle (&nh);
|
result = -1;
|
||||||
netlink_close (&nh);
|
goto exit_free;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < newlink + newaddr - 1; i++)
|
for (i = 0; i < newlink + newaddr - 1; i++)
|
||||||
@ -426,7 +409,7 @@ getifaddrs (struct ifaddrs **ifap)
|
|||||||
ifas[i].ifa.ifa_next = &ifas[i + 1].ifa;
|
ifas[i].ifa.ifa_next = &ifas[i + 1].ifa;
|
||||||
map_newlink_data[i] = -1;
|
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. */
|
newaddr_idx = 0; /* Counter for newaddr index. */
|
||||||
|
|
||||||
/* Walk through the list of data we got from the kernel. */
|
/* Walk through the list of data we got from the kernel. */
|
||||||
@ -446,13 +429,14 @@ getifaddrs (struct ifaddrs **ifap)
|
|||||||
{
|
{
|
||||||
int ifa_index = 0;
|
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)
|
if ((pid_t) nlh->nlmsg_pid != nh.pid || nlh->nlmsg_seq != nlp->seq)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (nlh->nlmsg_type == NLMSG_DONE)
|
if (nlh->nlmsg_type == NLMSG_DONE)
|
||||||
break; /* ok */
|
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
|
/* We found a new interface. Now extract everything from the
|
||||||
interface data we got and need. */
|
interface data we got and need. */
|
||||||
@ -460,7 +444,7 @@ getifaddrs (struct ifaddrs **ifap)
|
|||||||
struct rtattr *rta = IFLA_RTA (ifim);
|
struct rtattr *rta = IFLA_RTA (ifim);
|
||||||
size_t rtasize = IFLA_PAYLOAD (nlh);
|
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
|
of our list, starting in the order as we got from the
|
||||||
kernel. */
|
kernel. */
|
||||||
ifa_index = map_newlink (ifim->ifi_index - 1,
|
ifa_index = map_newlink (ifim->ifi_index - 1,
|
||||||
@ -537,7 +521,7 @@ getifaddrs (struct ifaddrs **ifap)
|
|||||||
size_t rtasize = IFA_PAYLOAD (nlh);
|
size_t rtasize = IFA_PAYLOAD (nlh);
|
||||||
|
|
||||||
/* New Addresses are stored in the order we got them from
|
/* 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,
|
that we have holes in the interface part of the list,
|
||||||
but we always have already the interface for this address. */
|
but we always have already the interface for this address. */
|
||||||
ifa_index = newlink + newaddr_idx;
|
ifa_index = newlink + newaddr_idx;
|
||||||
@ -662,10 +646,10 @@ getifaddrs (struct ifaddrs **ifap)
|
|||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
memcpy (&ifas[ifa_index].broadaddr.s6.sin6_addr,
|
memcpy (&ifas[ifa_index].broadaddr.s6.sin6_addr,
|
||||||
rta_data, rta_payload);
|
rta_data, rta_payload);
|
||||||
if (IN6_IS_ADDR_LINKLOCAL (rta_data) ||
|
if (IN6_IS_ADDR_LINKLOCAL (rta_data)
|
||||||
IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
|
|| IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
|
||||||
ifas[ifa_index].broadaddr.s6.sin6_scope_id =
|
ifas[ifa_index].broadaddr.s6.sin6_scope_id
|
||||||
ifam->ifa_scope;
|
= ifam->ifa_scope;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -754,14 +738,16 @@ getifaddrs (struct ifaddrs **ifap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free_netlink_handle (&nh);
|
|
||||||
|
|
||||||
netlink_close (&nh);
|
|
||||||
|
|
||||||
if (ifap != NULL)
|
if (ifap != NULL)
|
||||||
*ifap = &ifas[0].ifa;
|
*ifap = &ifas[0].ifa;
|
||||||
|
|
||||||
return 0;
|
exit_free:
|
||||||
|
free_netlink_handle (&nh);
|
||||||
|
|
||||||
|
exit_close:
|
||||||
|
netlink_close (&nh);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user