summaryrefslogtreecommitdiff
path: root/src/platform/nm-netlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/platform/nm-netlink.c')
-rw-r--r--src/platform/nm-netlink.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/src/platform/nm-netlink.c b/src/platform/nm-netlink.c
index 34128e54c7..45bc1cf75b 100644
--- a/src/platform/nm-netlink.c
+++ b/src/platform/nm-netlink.c
@@ -22,4 +22,101 @@
#include "nm-netlink.h"
+/*****************************************************************************
+ * Reimplementations/copied from libnl3/genl
+ *****************************************************************************/
+
+void *
+genlmsg_put (struct nl_msg *msg, uint32_t port, uint32_t seq, int family,
+ int hdrlen, int flags, uint8_t cmd, uint8_t version)
+{
+ struct nlmsghdr *nlh;
+ struct genlmsghdr hdr = {
+ .cmd = cmd,
+ .version = version,
+ };
+
+ nlh = nlmsg_put (msg, port, seq, family, GENL_HDRLEN + hdrlen, flags);
+ if (nlh == NULL)
+ return NULL;
+
+ memcpy (nlmsg_data (nlh), &hdr, sizeof (hdr));
+
+ return (char *) nlmsg_data (nlh) + GENL_HDRLEN;
+}
+
+void *
+genlmsg_data (const struct genlmsghdr *gnlh)
+{
+ return ((unsigned char *) gnlh + GENL_HDRLEN);
+}
+
+void *
+genlmsg_user_hdr (const struct genlmsghdr *gnlh)
+{
+ return genlmsg_data (gnlh);
+}
+
+struct genlmsghdr *
+genlmsg_hdr (struct nlmsghdr *nlh)
+{
+ return nlmsg_data (nlh);
+}
+
+void *
+genlmsg_user_data (const struct genlmsghdr *gnlh, const int hdrlen)
+{
+ return (char *) genlmsg_user_hdr (gnlh) + NLMSG_ALIGN (hdrlen);
+}
+
+struct nlattr *
+genlmsg_attrdata (const struct genlmsghdr *gnlh, int hdrlen)
+{
+ return genlmsg_user_data (gnlh, hdrlen);
+}
+
+int
+genlmsg_len (const struct genlmsghdr *gnlh)
+{
+ const struct nlmsghdr *nlh;
+
+ nlh = (const struct nlmsghdr *) ((const unsigned char *) gnlh - NLMSG_HDRLEN);
+ return (nlh->nlmsg_len - GENL_HDRLEN - NLMSG_HDRLEN);
+}
+
+int
+genlmsg_attrlen (const struct genlmsghdr *gnlh, int hdrlen)
+{
+ return genlmsg_len (gnlh) - NLMSG_ALIGN (hdrlen);
+}
+
+int
+genlmsg_valid_hdr (struct nlmsghdr *nlh, int hdrlen)
+{
+ struct genlmsghdr *ghdr;
+
+ if (!nlmsg_valid_hdr (nlh, GENL_HDRLEN))
+ return 0;
+
+ ghdr = nlmsg_data (nlh);
+ if (genlmsg_len (ghdr) < NLMSG_ALIGN (hdrlen))
+ return 0;
+
+ return 1;
+}
+
+int
+genlmsg_parse (struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[],
+ int maxtype, const struct nla_policy *policy)
+{
+ struct genlmsghdr *ghdr;
+
+ if (!genlmsg_valid_hdr (nlh, hdrlen))
+ return -NLE_MSG_TOOSHORT;
+
+ ghdr = nlmsg_data (nlh);
+ return nla_parse (tb, maxtype, genlmsg_attrdata (ghdr, hdrlen),
+ genlmsg_attrlen (ghdr, hdrlen), policy);
+}
+
/*****************************************************************************/