From a052d069b77e0608d1e7f766ad151fe028739d37 Mon Sep 17 00:00:00 2001 From: "Nicholas J. Kain" Date: Mon, 17 Mar 2014 20:22:20 -0400 Subject: [PATCH] nlattr was being used where rtattr should have been used. Happily, the types are almost identical (same number of fields, each field has the same length), so the code worked anyway, but nlattr and rtattr are distinct. nlattr is the type/length part of the nlmsg header. rtattr is the type/length part of the individual rt attribute items attached after a nlmsg. Use the correct rtattr type, and use the standard macros where appropriate. --- ndhc/ifset.c | 9 --------- ndhc/netlink.c | 19 +++++-------------- ndhc/nl.c | 25 +++++++++---------------- ndhc/nl.h | 25 +------------------------ 4 files changed, 15 insertions(+), 63 deletions(-) diff --git a/ndhc/ifset.c b/ndhc/ifset.c index 91bfaed..9546865 100644 --- a/ndhc/ifset.c +++ b/ndhc/ifset.c @@ -82,15 +82,6 @@ struct ipbcpfx { bool already_ok; }; -static int rtattr_assign(struct rtattr *attr, int type, void *data) -{ - struct rtattr **tb = data; - if (type >= IFA_MAX) - return 0; - tb[type] = attr; - return 0; -} - static ssize_t rtnl_do_send(int fd, uint8_t *sbuf, size_t slen, const char *fnname) { diff --git a/ndhc/netlink.c b/ndhc/netlink.c index 2455ce4..87b07f9 100644 --- a/ndhc/netlink.c +++ b/ndhc/netlink.c @@ -43,15 +43,6 @@ #include "nl.h" #include "state.h" -static int nlattr_assign(struct nlattr *attr, int type, void *data) -{ - struct nlattr **tb = data; - if (type >= IFLA_MAX) - return 0; - tb[type] = attr; - return 0; -} - static void nl_process_msgs(const struct nlmsghdr *nlh, void *data) { struct ifinfomsg *ifm = nlmsg_get_data(nlh); @@ -112,21 +103,21 @@ void handle_nl_message(struct client_state_t *cs) static int get_if_index_and_mac(const struct nlmsghdr *nlh, struct ifinfomsg *ifm) { - struct nlattr *tb[IFLA_MAX] = {0}; - nl_attr_parse(nlh, sizeof *ifm, nlattr_assign, tb); + struct rtattr *tb[IFLA_MAX] = {0}; + nl_rtattr_parse(nlh, sizeof *ifm, rtattr_assign, tb); if (tb[IFLA_IFNAME] && !strncmp(client_config.interface, - nlattr_get_data(tb[IFLA_IFNAME]), + rtattr_get_data(tb[IFLA_IFNAME]), sizeof client_config.interface)) { client_config.ifindex = ifm->ifi_index; if (!tb[IFLA_ADDRESS]) suicide("FATAL: Adapter %s lacks a hardware address."); - int maclen = nlattr_get_len(tb[IFLA_ADDRESS]) - 4; + int maclen = tb[IFLA_ADDRESS]->rta_len - 4; if (maclen != 6) suicide("FATAL: Adapter hardware address length should be 6, but is %u.", maclen); const unsigned char *mac = - (unsigned char *)nlattr_get_data(tb[IFLA_ADDRESS]); + (unsigned char *)rtattr_get_data(tb[IFLA_ADDRESS]); log_line("%s hardware address %x:%x:%x:%x:%x:%x", client_config.interface, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); diff --git a/ndhc/nl.c b/ndhc/nl.c index 5bd8b25..06e2576 100644 --- a/ndhc/nl.c +++ b/ndhc/nl.c @@ -38,6 +38,15 @@ #include "log.h" #include "nl.h" +int rtattr_assign(struct rtattr *attr, int type, void *data) +{ + struct rtattr **tb = data; + if (type >= IFA_MAX) + return 0; + tb[type] = attr; + return 0; +} + #define NLMSG_TAIL(nmsg) \ ((struct rtattr *) (((uint8_t*) (nmsg)) + \ NLMSG_ALIGN((nmsg)->nlmsg_len))) @@ -62,22 +71,6 @@ int nl_add_rtattr(struct nlmsghdr *n, size_t max_length, int type, return 0; } -void nl_attr_parse(const struct nlmsghdr *nlh, size_t offset, - nl_attr_parse_fn workfn, void *data) -{ - struct nlattr *attr; - for (attr = (struct nlattr *) - ((char *)nlh + NLMSG_HDRLEN + NLMSG_ALIGN(offset)); - nl_attr_ok(attr, (char *)nlh + NLMSG_ALIGN(nlh->nlmsg_len) - - (char *)attr); - attr = (struct nlattr *)((char *)attr + NLMSG_ALIGN(attr->nla_len))) - { - int type = attr->nla_type & NLA_TYPE_MASK; - if (workfn(attr, type, data) < 0) - break; - } -} - void nl_rtattr_parse(const struct nlmsghdr *nlh, size_t offset, nl_rtattr_parse_fn workfn, void *data) { diff --git a/ndhc/nl.h b/ndhc/nl.h index 0077c0e..0cb1a24 100644 --- a/ndhc/nl.h +++ b/ndhc/nl.h @@ -33,27 +33,6 @@ #include #include -static inline int nl_attr_ok(const struct nlattr *attr, size_t len) -{ - if (len < sizeof *attr) - return 0; - if (attr->nla_len < sizeof *attr) - return 0; - if (attr->nla_len > len) - return 0; - return 1; -} - -static inline size_t nlattr_get_len(const struct nlattr *attr) -{ - return attr->nla_len; -} - -static inline void *nlattr_get_data(const struct nlattr *attr) -{ - return (char *)attr + NLA_HDRLEN; -} - static inline void *rtattr_get_data(const struct rtattr *attr) { return (char *)RTA_DATA(attr); @@ -72,11 +51,9 @@ static inline int nlmsg_get_error(const struct nlmsghdr *nlh) return err->error & 0x7fffffff; } +extern int rtattr_assign(struct rtattr *attr, int type, void *data); extern int nl_add_rtattr(struct nlmsghdr *n, size_t max_length, int type, const void *data, size_t data_length); -typedef int (*nl_attr_parse_fn)(struct nlattr *attr, int type, void *data); -extern void nl_attr_parse(const struct nlmsghdr *nlh, size_t offset, - nl_attr_parse_fn workfn, void *data); typedef int (*nl_rtattr_parse_fn)(struct rtattr *attr, int type, void *data); extern void nl_rtattr_parse(const struct nlmsghdr *nlh, size_t offset, nl_rtattr_parse_fn workfn, void *data);