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.
This commit is contained in:
Nicholas J. Kain 2014-03-17 20:22:20 -04:00
parent 8416d5a633
commit a052d069b7
4 changed files with 15 additions and 63 deletions

View File

@ -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)
{

View File

@ -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]);

View File

@ -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)
{

View File

@ -33,27 +33,6 @@
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
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);