diff options
author | Martin Mares <mj@ucw.cz> | 2000-06-21 11:58:09 +0200 |
---|---|---|
committer | Martin Mares <mj@ucw.cz> | 2000-06-21 11:58:09 +0200 |
commit | 2836ce3951bbdda62c3dddd509669127f46e776d (patch) | |
tree | 28e65b1bf4cdca1830291799d299d6ddc713384d /sysdep/linux/netlink | |
parent | bcbdcbb6ae7256e01165220bb3b2d5b72850f665 (diff) | |
download | bird-2836ce3951bbdda62c3dddd509669127f46e776d.tar bird-2836ce3951bbdda62c3dddd509669127f46e776d.zip |
Check broadcast address sanity before believing it.
Diffstat (limited to 'sysdep/linux/netlink')
-rw-r--r-- | sysdep/linux/netlink/netlink.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/sysdep/linux/netlink/netlink.c b/sysdep/linux/netlink/netlink.c index 1a0f5d2..fd9b371 100644 --- a/sysdep/linux/netlink/netlink.c +++ b/sysdep/linux/netlink/netlink.c @@ -377,24 +377,28 @@ nl_parse_addr(struct nlmsghdr *h) else { ip_addr netmask = ipa_mkmask(ifa.pxlen); + ip_addr xbrd; + ifa.prefix = ipa_and(ifa.ip, netmask); + ifa.brd = ipa_or(ifa.ip, ipa_not(netmask)); #ifndef IPV6 if (i->ifa_prefixlen == BITS_PER_IP_ADDRESS - 2) ifa.opposite = ipa_opposite(ifa.ip); if ((ifi->flags & IF_BROADCAST) && a[IFA_BROADCAST]) { - memcpy(&ifa.brd, RTA_DATA(a[IFA_BROADCAST]), sizeof(ifa.brd)); - ipa_ntoh(ifa.brd); + memcpy(&xbrd, RTA_DATA(a[IFA_BROADCAST]), sizeof(xbrd)); + ipa_ntoh(xbrd); + if (ipa_equal(xbrd, ifa.prefix) || ipa_equal(xbrd, ifa.brd)) + ifa.brd = xbrd; + else + log(L_ERR "KIF: Invalid broadcast address %I for %s", xbrd, ifi->name); } - else - ifa.brd = ipa_or(ifa.ip, ipa_not(netmask)); #endif - ifa.prefix = ipa_and(ifa.ip, netmask); } scope = ipa_classify(ifa.ip); if (scope < 0) { - log(L_ERR "KIF: Invalid interface address %I", ifa.ip); + log(L_ERR "KIF: Invalid interface address %I for %s", ifa.ip, ifi->name); return; } ifa.scope = scope & IADDR_SCOPE_MASK; |