summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Larson <slioch@eng-140.vyatta.com>2008-01-21 11:47:38 -0800
committerMichael Larson <slioch@eng-140.vyatta.com>2008-01-21 11:47:38 -0800
commit34d0c42af20c0f3259436462cf88ecba0322442d (patch)
tree1d12f02ef6215d11c081c205fdaab09c65db10a8
parent8e685e15d469dbc1b52ef151b38d626ceb5b402c (diff)
downloadquagga-34d0c42af20c0f3259436462cf88ecba0322442d.tar.bz2
quagga-34d0c42af20c0f3259436462cf88ecba0322442d.tar.xz
fix for bc addr and fix for parsing iface for show cmds and filter
-rw-r--r--watchlink/netlink_event.cc3
-rw-r--r--watchlink/netlink_send.cc45
2 files changed, 46 insertions, 2 deletions
diff --git a/watchlink/netlink_event.cc b/watchlink/netlink_event.cc
index 0cf3b88e..eb2cdbc2 100644
--- a/watchlink/netlink_event.cc
+++ b/watchlink/netlink_event.cc
@@ -219,7 +219,7 @@ NetlinkEventManager::parse_msg(const struct nlmsghdr *nlHdr)
addr = IPv4(address);
break;
case IFA_LABEL:
- iface = *((char*)RTA_DATA(rtAttr));
+ iface = string((char*)RTA_DATA(rtAttr));
break;
case IFA_BROADCAST:
address = *(uint32_t *)RTA_DATA(rtAttr);
@@ -314,4 +314,3 @@ std::ostream & operator <<(std::ostream & Stream, const NetlinkEvent & instance)
return Stream;
}
-
diff --git a/watchlink/netlink_send.cc b/watchlink/netlink_send.cc
index 1f6c62f6..656eb5d9 100644
--- a/watchlink/netlink_send.cc
+++ b/watchlink/netlink_send.cc
@@ -41,6 +41,9 @@
using namespace std;
+in_addr_t
+ipv4_broadcast_addr (in_addr_t hostaddr, int masklen);
+
/**
*
*
@@ -104,6 +107,10 @@ NetlinkSend::send_set(int sock, int ifindex, uint32_t local_addr, uint32_t addr,
// addr = htonl( addr );
addattr_l(&req.n, sizeof(req), IFA_LOCAL, &local_addr, sizeof(addr) );
+
+ in_addr_t broadcast_addr = ipv4_broadcast_addr(local_addr,mask_len);
+ addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &broadcast_addr, sizeof(addr) );
+
if (addr != -1 && local_addr != addr) {
addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &addr, sizeof(addr) );
}
@@ -196,3 +203,41 @@ NetlinkSend::addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, int
return 0;
}
+/* Maskbit. */
+static u_char maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
+ 0xf8, 0xfc, 0xfe, 0xff};
+
+/* Convert masklen into IP address's netmask. */
+void
+masklen2ip (int masklen, struct in_addr *netmask)
+{
+ u_char *pnt;
+ int bit;
+ int offset;
+
+ memset (netmask, 0, sizeof (struct in_addr));
+ pnt = (unsigned char *) netmask;
+
+ offset = masklen / 8;
+ bit = masklen % 8;
+
+ while (offset--)
+ *pnt++ = 0xff;
+
+ if (bit)
+ *pnt = maskbit[bit];
+}
+
+
+in_addr_t
+ipv4_broadcast_addr (in_addr_t hostaddr, int masklen)
+{
+ struct in_addr mask;
+
+ masklen2ip (masklen, &mask);
+ return (masklen != 32-1) ?
+ /* normal case */
+ (hostaddr | ~mask.s_addr) :
+ /* special case for /31 */
+ (hostaddr ^ ~mask.s_addr);
+}