#pragma GCC diagnostic ignored "-Wcast-align"
for (rta = __NLMSG_RTA(h, sizeof(*ifi)); __NLMSG_RTAOK(rta, h);
rta = __RTA_NEXT(rta)) {
+#if HAVE_STRUCT_RTNL_LINK_STATS64
+ if (rta->rta_type != IFLA_STATS64)
+#else
if (rta->rta_type != IFLA_STATS)
+#endif
continue;
stats_len = __RTA_DATALEN(rta);
__RTA_DATA(rta), __RTA_DATALEN(rta),
ifi->ifi_index, ifi->ifi_type);
break;
+#if HAVE_STRUCT_RTNL_LINK_STATS64
+ case IFLA_STATS64:
+ ifs->ifa.ifa_stats_type = IFLA_STATS64;
+#else
case IFLA_STATS:
- ifs->ifa.ifa_data = (void *)(ifs + 1);
- memcpy(ifs->ifa.ifa_data, __RTA_DATA(rta),
+ ifs->ifa.ifa_stats_type = IFLA_STATS;
+#endif
+ memcpy(&ifs->ifa.ifa_stats, __RTA_DATA(rta),
__RTA_DATALEN(rta));
break;
case IFLA_MTU:
struct nlmsghdr *h),
void *ctx)
{
- char getlink_buf[__NETLINK_ALIGN(sizeof(struct nlmsghdr)) +
- __NETLINK_ALIGN(sizeof(struct ifinfomsg)) +
- __NETLINK_ALIGN(1024)];
- char getaddr_buf[__NETLINK_ALIGN(sizeof(struct nlmsghdr)) +
- __NETLINK_ALIGN(sizeof(struct ifaddrmsg)) +
- __NETLINK_ALIGN(1024)];
+ int r, property, ret;
char *buf;
struct nlmsghdr *hdr;
struct ifinfomsg *ifi_msg;
} req;
struct nlmsghdr reply;
} u;
- int r, property, ret;
-
- if (type == RTM_GETLINK)
- buf = getlink_buf;
- else if (type == RTM_GETADDR)
- buf = getaddr_buf;
- else
- return -1;
-
- memset(buf, 0, sizeof(*buf));
+ char getlink_buf[__NETLINK_ALIGN(sizeof(struct nlmsghdr)) +
+ __NETLINK_ALIGN(sizeof(struct ifinfomsg)) +
+ __NETLINK_ALIGN(1024)] = {0};
+ char getaddr_buf[__NETLINK_ALIGN(sizeof(struct nlmsghdr)) +
+ __NETLINK_ALIGN(sizeof(struct ifaddrmsg)) +
+ __NETLINK_ALIGN(1024)] = {0};
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-align"
- hdr = (struct nlmsghdr *)buf;
- if (type == RTM_GETLINK)
+ if (type == RTM_GETLINK) {
+ buf = getlink_buf;
+ hdr = (struct nlmsghdr *)buf;
+ hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*ifi_msg));
+
ifi_msg = (struct ifinfomsg *)__NLMSG_DATA(hdr);
- else
- ifa_msg = (struct ifaddrmsg *)__NLMSG_DATA(hdr);
+ ifi_msg->ifi_family = af;
- if (type == RTM_GETLINK)
- hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*ifi_msg));
- else
+ property = IFLA_TARGET_NETNSID;
+ } else if (type == RTM_GETADDR) {
+ buf = getaddr_buf;
+ hdr = (struct nlmsghdr *)buf;
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*ifa_msg));
+
+ ifa_msg = (struct ifaddrmsg *)__NLMSG_DATA(hdr);
+ ifa_msg->ifa_family = af;
+
+ property = IFA_TARGET_NETNSID;
+ } else {
+ errno = EINVAL;
+ return -1;
+ }
#pragma GCC diagnostic pop
hdr->nlmsg_type = type;
hdr->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;
hdr->nlmsg_pid = 0;
hdr->nlmsg_seq = seq;
- if (type == RTM_GETLINK)
- ifi_msg->ifi_family = af;
- else
- ifa_msg->ifa_family = af;
-
- errno = EINVAL;
- if (type == RTM_GETLINK)
- property = IFLA_TARGET_NETNSID;
- else if (type == RTM_GETADDR)
- property = IFA_TARGET_NETNSID;
- else
- return -1;
if (netns_id >= 0)
addattr(hdr, 1024, property, &netns_id, sizeof(netns_id));
if (fd < 0)
return -1;
+ r = setsockopt(fd, SOL_NETLINK, NETLINK_DUMP_STRICT_CHK, &(int){1},
+ sizeof(int));
+ if (r < 0 && netns_id >= 0) {
+ close(fd);
+ *netnsid_aware = false;
+ return -1;
+ }
+
r = __ifaddrs_netlink_recv(fd, 1, RTM_GETLINK, link_af, netns_id,
&getlink_netnsid_aware, cb, ctx);
if (!r)
return r;
}
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-align"
-/* Get a pointer to the address structure from a sockaddr. */
-static void *get_addr_ptr(struct sockaddr *sockaddr_ptr)
-{
- if (sockaddr_ptr->sa_family == AF_INET)
- return &((struct sockaddr_in *)sockaddr_ptr)->sin_addr;
-
- if (sockaddr_ptr->sa_family == AF_INET6)
- return &((struct sockaddr_in6 *)sockaddr_ptr)->sin6_addr;
-
- return NULL;
-}
-#pragma GCC diagnostic pop
-
-static char *get_packet_address(struct sockaddr *sockaddr_ptr, char *buf, size_t buflen)
-{
- char *slider = buf;
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-align"
- unsigned char *m = ((struct sockaddr_ll *)sockaddr_ptr)->sll_addr;
- unsigned char n = ((struct sockaddr_ll *)sockaddr_ptr)->sll_halen;
-#pragma GCC diagnostic pop
-
- for (unsigned char i = 0; i < n; i++) {
- int ret;
-
- ret = snprintf(slider, buflen, "%02x%s", m[i], (i + 1) < n ? ":" : "");
- if (ret < 0 || (size_t)ret >= buflen)
- return NULL;
-
- buflen -= ret;
- slider = (slider + ret);
- }
-
- return buf;
-}
-
void netns_freeifaddrs(struct netns_ifaddrs *ifp)
{
struct netns_ifaddrs *n;