mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2024-11-25 08:48:31 -05:00
netlink: Move more of the newlink/dellink parsing into shared code
This commit is contained in:
parent
f37cf89ccb
commit
62d680c3ca
@ -353,21 +353,13 @@ static void wpa_driver_nl80211_event_link(struct wpa_driver_nl80211_data *drv,
|
|||||||
|
|
||||||
|
|
||||||
static int wpa_driver_nl80211_own_ifname(struct wpa_driver_nl80211_data *drv,
|
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, rta_len;
|
||||||
int attrlen, _nlmsg_len, rta_len;
|
|
||||||
struct rtattr *attr;
|
struct rtattr *attr;
|
||||||
|
|
||||||
ifi = NLMSG_DATA(h);
|
attrlen = len;
|
||||||
|
attr = (struct rtattr *) buf;
|
||||||
_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);
|
|
||||||
|
|
||||||
rta_len = RTA_ALIGN(sizeof(struct rtattr));
|
rta_len = RTA_ALIGN(sizeof(struct rtattr));
|
||||||
while (RTA_OK(attr, attrlen)) {
|
while (RTA_OK(attr, attrlen)) {
|
||||||
@ -386,12 +378,12 @@ static int wpa_driver_nl80211_own_ifname(struct wpa_driver_nl80211_data *drv,
|
|||||||
|
|
||||||
|
|
||||||
static int wpa_driver_nl80211_own_ifindex(struct wpa_driver_nl80211_data *drv,
|
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)
|
if (drv->ifindex == ifindex)
|
||||||
return 1;
|
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);
|
drv->ifindex = if_nametoindex(drv->ifname);
|
||||||
wpa_printf(MSG_DEBUG, "nl80211: Update ifindex for a removed "
|
wpa_printf(MSG_DEBUG, "nl80211: Update ifindex for a removed "
|
||||||
"interface");
|
"interface");
|
||||||
@ -403,20 +395,15 @@ static int wpa_driver_nl80211_own_ifindex(struct wpa_driver_nl80211_data *drv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void wpa_driver_nl80211_event_rtm_newlink(void *ctx, struct nlmsghdr *h,
|
static void wpa_driver_nl80211_event_rtm_newlink(void *ctx,
|
||||||
size_t len)
|
struct ifinfomsg *ifi,
|
||||||
|
u8 *buf, size_t len)
|
||||||
{
|
{
|
||||||
struct wpa_driver_nl80211_data *drv = ctx;
|
struct wpa_driver_nl80211_data *drv = ctx;
|
||||||
struct ifinfomsg *ifi;
|
int attrlen, rta_len;
|
||||||
int attrlen, _nlmsg_len, rta_len;
|
struct rtattr *attr;
|
||||||
struct rtattr * attr;
|
|
||||||
|
|
||||||
if (len < sizeof(*ifi))
|
if (!wpa_driver_nl80211_own_ifindex(drv, ifi->ifi_index, buf, len)) {
|
||||||
return;
|
|
||||||
|
|
||||||
ifi = NLMSG_DATA(h);
|
|
||||||
|
|
||||||
if (!wpa_driver_nl80211_own_ifindex(drv, ifi->ifi_index, h)) {
|
|
||||||
wpa_printf(MSG_DEBUG, "Ignore event for foreign ifindex %d",
|
wpa_printf(MSG_DEBUG, "Ignore event for foreign ifindex %d",
|
||||||
ifi->ifi_index);
|
ifi->ifi_index);
|
||||||
return;
|
return;
|
||||||
@ -441,14 +428,8 @@ static void wpa_driver_nl80211_event_rtm_newlink(void *ctx, struct nlmsghdr *h,
|
|||||||
netlink_send_oper_ifla(drv->netlink, drv->ifindex,
|
netlink_send_oper_ifla(drv->netlink, drv->ifindex,
|
||||||
-1, IF_OPER_UP);
|
-1, IF_OPER_UP);
|
||||||
|
|
||||||
_nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
|
attrlen = len;
|
||||||
|
attr = (struct rtattr *) buf;
|
||||||
attrlen = NLMSG_PAYLOAD(h, sizeof(struct ifinfomsg));
|
|
||||||
if (attrlen < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
attr = (struct rtattr *) (((char *) ifi) + _nlmsg_len);
|
|
||||||
|
|
||||||
rta_len = RTA_ALIGN(sizeof(struct rtattr));
|
rta_len = RTA_ALIGN(sizeof(struct rtattr));
|
||||||
while (RTA_OK(attr, attrlen)) {
|
while (RTA_OK(attr, attrlen)) {
|
||||||
if (attr->rta_type == IFLA_IFNAME) {
|
if (attr->rta_type == IFLA_IFNAME) {
|
||||||
@ -462,26 +443,16 @@ static void wpa_driver_nl80211_event_rtm_newlink(void *ctx, struct nlmsghdr *h,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void wpa_driver_nl80211_event_rtm_dellink(void *ctx, struct nlmsghdr *h,
|
static void wpa_driver_nl80211_event_rtm_dellink(void *ctx,
|
||||||
size_t len)
|
struct ifinfomsg *ifi,
|
||||||
|
u8 *buf, size_t len)
|
||||||
{
|
{
|
||||||
struct wpa_driver_nl80211_data *drv = ctx;
|
struct wpa_driver_nl80211_data *drv = ctx;
|
||||||
struct ifinfomsg *ifi;
|
int attrlen, rta_len;
|
||||||
int attrlen, _nlmsg_len, rta_len;
|
struct rtattr *attr;
|
||||||
struct rtattr * attr;
|
|
||||||
|
|
||||||
if (len < sizeof(*ifi))
|
attrlen = len;
|
||||||
return;
|
attr = (struct rtattr *) buf;
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
rta_len = RTA_ALIGN(sizeof(struct rtattr));
|
rta_len = RTA_ALIGN(sizeof(struct rtattr));
|
||||||
while (RTA_OK(attr, attrlen)) {
|
while (RTA_OK(attr, attrlen)) {
|
||||||
|
@ -569,21 +569,13 @@ static void wpa_driver_wext_event_link(struct wpa_driver_wext_data *drv,
|
|||||||
|
|
||||||
|
|
||||||
static int wpa_driver_wext_own_ifname(struct wpa_driver_wext_data *drv,
|
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, rta_len;
|
||||||
int attrlen, nlmsg_len, rta_len;
|
|
||||||
struct rtattr *attr;
|
struct rtattr *attr;
|
||||||
|
|
||||||
ifi = NLMSG_DATA(h);
|
attrlen = len;
|
||||||
|
attr = (struct rtattr *) buf;
|
||||||
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);
|
|
||||||
|
|
||||||
rta_len = RTA_ALIGN(sizeof(struct rtattr));
|
rta_len = RTA_ALIGN(sizeof(struct rtattr));
|
||||||
while (RTA_OK(attr, attrlen)) {
|
while (RTA_OK(attr, attrlen)) {
|
||||||
@ -602,12 +594,12 @@ static int wpa_driver_wext_own_ifname(struct wpa_driver_wext_data *drv,
|
|||||||
|
|
||||||
|
|
||||||
static int wpa_driver_wext_own_ifindex(struct wpa_driver_wext_data *drv,
|
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)
|
if (drv->ifindex == ifindex || drv->ifindex2 == ifindex)
|
||||||
return 1;
|
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);
|
drv->ifindex = if_nametoindex(drv->ifname);
|
||||||
wpa_printf(MSG_DEBUG, "WEXT: Update ifindex for a removed "
|
wpa_printf(MSG_DEBUG, "WEXT: Update ifindex for a removed "
|
||||||
"interface");
|
"interface");
|
||||||
@ -619,20 +611,14 @@ static int wpa_driver_wext_own_ifindex(struct wpa_driver_wext_data *drv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void wpa_driver_wext_event_rtm_newlink(void *ctx, struct nlmsghdr *h,
|
static void wpa_driver_wext_event_rtm_newlink(void *ctx, struct ifinfomsg *ifi,
|
||||||
size_t len)
|
u8 *buf, size_t len)
|
||||||
{
|
{
|
||||||
struct wpa_driver_wext_data *drv = ctx;
|
struct wpa_driver_wext_data *drv = ctx;
|
||||||
struct ifinfomsg *ifi;
|
int attrlen, rta_len;
|
||||||
int attrlen, nlmsg_len, rta_len;
|
|
||||||
struct rtattr *attr;
|
struct rtattr *attr;
|
||||||
|
|
||||||
if (len < sizeof(*ifi))
|
if (!wpa_driver_wext_own_ifindex(drv, ifi->ifi_index, buf, len)) {
|
||||||
return;
|
|
||||||
|
|
||||||
ifi = NLMSG_DATA(h);
|
|
||||||
|
|
||||||
if (!wpa_driver_wext_own_ifindex(drv, ifi->ifi_index, h)) {
|
|
||||||
wpa_printf(MSG_DEBUG, "Ignore event for foreign ifindex %d",
|
wpa_printf(MSG_DEBUG, "Ignore event for foreign ifindex %d",
|
||||||
ifi->ifi_index);
|
ifi->ifi_index);
|
||||||
return;
|
return;
|
||||||
@ -657,13 +643,8 @@ static void wpa_driver_wext_event_rtm_newlink(void *ctx, struct nlmsghdr *h,
|
|||||||
netlink_send_oper_ifla(drv->netlink, drv->ifindex,
|
netlink_send_oper_ifla(drv->netlink, drv->ifindex,
|
||||||
-1, IF_OPER_UP);
|
-1, IF_OPER_UP);
|
||||||
|
|
||||||
nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
|
attrlen = len;
|
||||||
|
attr = (struct rtattr *) buf;
|
||||||
attrlen = NLMSG_PAYLOAD(h, sizeof(struct ifinfomsg));
|
|
||||||
if (attrlen < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
attr = (struct rtattr *) (((char *) ifi) + nlmsg_len);
|
|
||||||
|
|
||||||
rta_len = RTA_ALIGN(sizeof(struct rtattr));
|
rta_len = RTA_ALIGN(sizeof(struct rtattr));
|
||||||
while (RTA_OK(attr, attrlen)) {
|
while (RTA_OK(attr, attrlen)) {
|
||||||
@ -681,26 +662,15 @@ static void wpa_driver_wext_event_rtm_newlink(void *ctx, struct nlmsghdr *h,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void wpa_driver_wext_event_rtm_dellink(void *ctx, struct nlmsghdr *h,
|
static void wpa_driver_wext_event_rtm_dellink(void *ctx, struct ifinfomsg *ifi,
|
||||||
size_t len)
|
u8 *buf, size_t len)
|
||||||
{
|
{
|
||||||
struct wpa_driver_wext_data *drv = ctx;
|
struct wpa_driver_wext_data *drv = ctx;
|
||||||
struct ifinfomsg *ifi;
|
int attrlen, rta_len;
|
||||||
int attrlen, nlmsg_len, rta_len;
|
|
||||||
struct rtattr *attr;
|
struct rtattr *attr;
|
||||||
|
|
||||||
if (len < sizeof(*ifi))
|
attrlen = len;
|
||||||
return;
|
attr = (struct rtattr *) buf;
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
rta_len = RTA_ALIGN(sizeof(struct rtattr));
|
rta_len = RTA_ALIGN(sizeof(struct rtattr));
|
||||||
while (RTA_OK(attr, attrlen)) {
|
while (RTA_OK(attr, attrlen)) {
|
||||||
|
@ -26,6 +26,19 @@ struct netlink_data {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
static void netlink_receive(int sock, void *eloop_ctx, void *sock_ctx)
|
||||||
{
|
{
|
||||||
struct netlink_data *netlink = eloop_ctx;
|
struct netlink_data *netlink = eloop_ctx;
|
||||||
@ -49,20 +62,14 @@ try_again:
|
|||||||
|
|
||||||
h = (struct nlmsghdr *) buf;
|
h = (struct nlmsghdr *) buf;
|
||||||
while (NLMSG_OK(h, left)) {
|
while (NLMSG_OK(h, left)) {
|
||||||
int plen;
|
|
||||||
|
|
||||||
plen = h->nlmsg_len - sizeof(*h);
|
|
||||||
|
|
||||||
switch (h->nlmsg_type) {
|
switch (h->nlmsg_type) {
|
||||||
case RTM_NEWLINK:
|
case RTM_NEWLINK:
|
||||||
if (netlink->cfg->newlink_cb)
|
netlink_receive_link(netlink, netlink->cfg->newlink_cb,
|
||||||
netlink->cfg->newlink_cb(netlink->cfg->ctx,
|
h);
|
||||||
h, plen);
|
|
||||||
break;
|
break;
|
||||||
case RTM_DELLINK:
|
case RTM_DELLINK:
|
||||||
if (netlink->cfg->dellink_cb)
|
netlink_receive_link(netlink, netlink->cfg->dellink_cb,
|
||||||
netlink->cfg->dellink_cb(netlink->cfg->ctx,
|
h);
|
||||||
h, plen);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,8 +19,10 @@ struct netlink_data;
|
|||||||
|
|
||||||
struct netlink_config {
|
struct netlink_config {
|
||||||
void *ctx;
|
void *ctx;
|
||||||
void (*newlink_cb)(void *ctx, struct nlmsghdr *buf, size_t len);
|
void (*newlink_cb)(void *ctx, struct ifinfomsg *ifi, u8 *buf,
|
||||||
void (*dellink_cb)(void *ctx, struct nlmsghdr *buf, size_t len);
|
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);
|
struct netlink_data * netlink_init(struct netlink_config *cfg);
|
||||||
|
Loading…
Reference in New Issue
Block a user