summaryrefslogtreecommitdiffstats
path: root/watchlink/netlink_utils.cc
diff options
context:
space:
mode:
Diffstat (limited to 'watchlink/netlink_utils.cc')
-rw-r--r--watchlink/netlink_utils.cc59
1 files changed, 59 insertions, 0 deletions
diff --git a/watchlink/netlink_utils.cc b/watchlink/netlink_utils.cc
new file mode 100644
index 00000000..18a4b3ff
--- /dev/null
+++ b/watchlink/netlink_utils.cc
@@ -0,0 +1,59 @@
+#include <errno.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include <linux/types.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <linux/rtnetlink.h>
+#include <syslog.h>
+
+#include "netlink_utils.hh"
+
+
+/* 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);
+}
+
+in_addr_t
+ipv4_first_addr (in_addr_t hostaddr, int masklen)
+{
+ struct in_addr mask;
+ masklen2ip (masklen, &mask);
+ return (hostaddr & mask.s_addr);
+}
+