static int wpa_driver_nl80211_own_ifname(struct wpa_driver_nl80211_data *drv,
- struct nlmsghdr *h)
+ u8 *buf, size_t len)
{
- struct ifinfomsg *ifi;
- int attrlen, _nlmsg_len, rta_len;
+ int attrlen, rta_len;
struct rtattr *attr;
- ifi = NLMSG_DATA(h);
-
- _nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
-
- attrlen = NLMSG_PAYLOAD(h, sizeof(struct ifinfomsg));
- if (attrlen < 0)
- return 0;
-
- attr = (struct rtattr *) (((char *) ifi) + _nlmsg_len);
+ attrlen = len;
+ attr = (struct rtattr *) buf;
rta_len = RTA_ALIGN(sizeof(struct rtattr));
while (RTA_OK(attr, attrlen)) {
static int wpa_driver_nl80211_own_ifindex(struct wpa_driver_nl80211_data *drv,
- int ifindex, struct nlmsghdr *h)
+ int ifindex, u8 *buf, size_t len)
{
if (drv->ifindex == ifindex)
return 1;
- if (drv->if_removed && wpa_driver_nl80211_own_ifname(drv, h)) {
+ if (drv->if_removed && wpa_driver_nl80211_own_ifname(drv, buf, len)) {
drv->ifindex = if_nametoindex(drv->ifname);
wpa_printf(MSG_DEBUG, "nl80211: Update ifindex for a removed "
"interface");
}
-static void wpa_driver_nl80211_event_rtm_newlink(void *ctx, struct nlmsghdr *h,
- size_t len)
+static void wpa_driver_nl80211_event_rtm_newlink(void *ctx,
+ struct ifinfomsg *ifi,
+ u8 *buf, size_t len)
{
struct wpa_driver_nl80211_data *drv = ctx;
- struct ifinfomsg *ifi;
- int attrlen, _nlmsg_len, rta_len;
- struct rtattr * attr;
-
- if (len < sizeof(*ifi))
- return;
-
- ifi = NLMSG_DATA(h);
+ int attrlen, rta_len;
+ struct rtattr *attr;
- if (!wpa_driver_nl80211_own_ifindex(drv, ifi->ifi_index, h)) {
+ if (!wpa_driver_nl80211_own_ifindex(drv, ifi->ifi_index, buf, len)) {
wpa_printf(MSG_DEBUG, "Ignore event for foreign ifindex %d",
ifi->ifi_index);
return;
netlink_send_oper_ifla(drv->netlink, drv->ifindex,
-1, IF_OPER_UP);
- _nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
-
- attrlen = NLMSG_PAYLOAD(h, sizeof(struct ifinfomsg));
- if (attrlen < 0)
- return;
-
- attr = (struct rtattr *) (((char *) ifi) + _nlmsg_len);
-
+ attrlen = len;
+ attr = (struct rtattr *) buf;
rta_len = RTA_ALIGN(sizeof(struct rtattr));
while (RTA_OK(attr, attrlen)) {
if (attr->rta_type == IFLA_IFNAME) {
}
-static void wpa_driver_nl80211_event_rtm_dellink(void *ctx, struct nlmsghdr *h,
- size_t len)
+static void wpa_driver_nl80211_event_rtm_dellink(void *ctx,
+ struct ifinfomsg *ifi,
+ u8 *buf, size_t len)
{
struct wpa_driver_nl80211_data *drv = ctx;
- struct ifinfomsg *ifi;
- int attrlen, _nlmsg_len, rta_len;
- struct rtattr * attr;
-
- if (len < sizeof(*ifi))
- return;
-
- ifi = NLMSG_DATA(h);
-
- _nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
-
- attrlen = NLMSG_PAYLOAD(h, sizeof(struct ifinfomsg));
- if (attrlen < 0)
- return;
+ int attrlen, rta_len;
+ struct rtattr *attr;
- attr = (struct rtattr *) (((char *) ifi) + _nlmsg_len);
+ attrlen = len;
+ attr = (struct rtattr *) buf;
rta_len = RTA_ALIGN(sizeof(struct rtattr));
while (RTA_OK(attr, attrlen)) {
static int wpa_driver_wext_own_ifname(struct wpa_driver_wext_data *drv,
- struct nlmsghdr *h)
+ u8 *buf, size_t len)
{
- struct ifinfomsg *ifi;
- int attrlen, nlmsg_len, rta_len;
+ int attrlen, rta_len;
struct rtattr *attr;
- ifi = NLMSG_DATA(h);
-
- nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
-
- attrlen = NLMSG_PAYLOAD(h, sizeof(struct ifinfomsg));
- if (attrlen < 0)
- return 0;
-
- attr = (struct rtattr *) (((char *) ifi) + nlmsg_len);
+ attrlen = len;
+ attr = (struct rtattr *) buf;
rta_len = RTA_ALIGN(sizeof(struct rtattr));
while (RTA_OK(attr, attrlen)) {
static int wpa_driver_wext_own_ifindex(struct wpa_driver_wext_data *drv,
- int ifindex, struct nlmsghdr *h)
+ int ifindex, u8 *buf, size_t len)
{
if (drv->ifindex == ifindex || drv->ifindex2 == ifindex)
return 1;
- if (drv->if_removed && wpa_driver_wext_own_ifname(drv, h)) {
+ if (drv->if_removed && wpa_driver_wext_own_ifname(drv, buf, len)) {
drv->ifindex = if_nametoindex(drv->ifname);
wpa_printf(MSG_DEBUG, "WEXT: Update ifindex for a removed "
"interface");
}
-static void wpa_driver_wext_event_rtm_newlink(void *ctx, struct nlmsghdr *h,
- size_t len)
+static void wpa_driver_wext_event_rtm_newlink(void *ctx, struct ifinfomsg *ifi,
+ u8 *buf, size_t len)
{
struct wpa_driver_wext_data *drv = ctx;
- struct ifinfomsg *ifi;
- int attrlen, nlmsg_len, rta_len;
+ int attrlen, rta_len;
struct rtattr *attr;
- if (len < sizeof(*ifi))
- return;
-
- ifi = NLMSG_DATA(h);
-
- if (!wpa_driver_wext_own_ifindex(drv, ifi->ifi_index, h)) {
+ if (!wpa_driver_wext_own_ifindex(drv, ifi->ifi_index, buf, len)) {
wpa_printf(MSG_DEBUG, "Ignore event for foreign ifindex %d",
ifi->ifi_index);
return;
netlink_send_oper_ifla(drv->netlink, drv->ifindex,
-1, IF_OPER_UP);
- nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
-
- attrlen = NLMSG_PAYLOAD(h, sizeof(struct ifinfomsg));
- if (attrlen < 0)
- return;
-
- attr = (struct rtattr *) (((char *) ifi) + nlmsg_len);
+ attrlen = len;
+ attr = (struct rtattr *) buf;
rta_len = RTA_ALIGN(sizeof(struct rtattr));
while (RTA_OK(attr, attrlen)) {
}
-static void wpa_driver_wext_event_rtm_dellink(void *ctx, struct nlmsghdr *h,
- size_t len)
+static void wpa_driver_wext_event_rtm_dellink(void *ctx, struct ifinfomsg *ifi,
+ u8 *buf, size_t len)
{
struct wpa_driver_wext_data *drv = ctx;
- struct ifinfomsg *ifi;
- int attrlen, nlmsg_len, rta_len;
+ int attrlen, rta_len;
struct rtattr *attr;
- if (len < sizeof(*ifi))
- return;
-
- ifi = NLMSG_DATA(h);
-
- nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
-
- attrlen = NLMSG_PAYLOAD(h, sizeof(struct ifinfomsg));
- if (attrlen < 0)
- return;
-
- attr = (struct rtattr *) (((char *) ifi) + nlmsg_len);
+ attrlen = len;
+ attr = (struct rtattr *) buf;
rta_len = RTA_ALIGN(sizeof(struct rtattr));
while (RTA_OK(attr, attrlen)) {
};
+static void netlink_receive_link(struct netlink_data *netlink,
+ void (*cb)(void *ctx, struct ifinfomsg *ifi,
+ u8 *buf, size_t len),
+ struct nlmsghdr *h)
+{
+ if (cb == NULL || NLMSG_PAYLOAD(h, 0) < sizeof(struct ifinfomsg))
+ return;
+ cb(netlink->cfg->ctx, NLMSG_DATA(h),
+ NLMSG_DATA(h) + NLMSG_ALIGN(sizeof(struct ifinfomsg)),
+ NLMSG_PAYLOAD(h, sizeof(struct ifinfomsg)));
+}
+
+
static void netlink_receive(int sock, void *eloop_ctx, void *sock_ctx)
{
struct netlink_data *netlink = eloop_ctx;
h = (struct nlmsghdr *) buf;
while (NLMSG_OK(h, left)) {
- int plen;
-
- plen = h->nlmsg_len - sizeof(*h);
-
switch (h->nlmsg_type) {
case RTM_NEWLINK:
- if (netlink->cfg->newlink_cb)
- netlink->cfg->newlink_cb(netlink->cfg->ctx,
- h, plen);
+ netlink_receive_link(netlink, netlink->cfg->newlink_cb,
+ h);
break;
case RTM_DELLINK:
- if (netlink->cfg->dellink_cb)
- netlink->cfg->dellink_cb(netlink->cfg->ctx,
- h, plen);
+ netlink_receive_link(netlink, netlink->cfg->dellink_cb,
+ h);
break;
}
struct netlink_config {
void *ctx;
- void (*newlink_cb)(void *ctx, struct nlmsghdr *buf, size_t len);
- void (*dellink_cb)(void *ctx, struct nlmsghdr *buf, size_t len);
+ void (*newlink_cb)(void *ctx, struct ifinfomsg *ifi, u8 *buf,
+ size_t len);
+ void (*dellink_cb)(void *ctx, struct ifinfomsg *ifi, u8 *buf,
+ size_t len);
};
struct netlink_data * netlink_init(struct netlink_config *cfg);