]> jfr.im git - irc/quakenet/newserv.git/blobdiff - lib/irc_ipv6.c
build: Clean up workspaces code a bit.
[irc/quakenet/newserv.git] / lib / irc_ipv6.c
index 638db74c378d2d47b39269a2a4c94bcf1d0eadda..6f44d0bfa3df1fe309f35e455a75104d6c369cfa 100644 (file)
@@ -247,6 +247,8 @@ ipmask_parse(const char *input, struct irc_in_addr *ip, unsigned char *pbits)
     default:
       return 0;
     }
+    if (input[pos] != '\0')
+      return 0;
   finish:
     if (colon < 8) {
       unsigned int jj;
@@ -413,7 +415,6 @@ const char* iptobase64(char* buf, const struct irc_in_addr* addr, unsigned int c
     if (curr_zeros > max_zeros) {
       max_start = ii - curr_zeros;
       max_zeros = curr_zeros;
-      curr_zeros = 0;
     }
     /* Print the rest of the address */
     for (ii = zero; ii < 8; ) {
@@ -464,3 +465,24 @@ void base64toip(const char* input, struct irc_in_addr* addr)
   }
 }
 
+/** Test whether an address matches the most significant bits of a mask.
+ * @param[in] addr Address to test.
+ * @param[in] mask Address to test against.
+ * @param[in] bits Number of bits to test.
+ * @return 0 on mismatch, 1 if bits < 128 and all bits match; -1 if
+ * bits == 128 and all bits match.
+ */
+int ipmask_check(const struct irc_in_addr *addr, const struct irc_in_addr *mask, unsigned char bits)
+{
+  int k;
+
+  for (k = 0; k < 8; k++) {
+    if (bits < 16)
+      return !(htons(addr->in6_16[k] ^ mask->in6_16[k]) >> (16-bits));
+    if (addr->in6_16[k] != mask->in6_16[k])
+      return 0;
+    if (!(bits -= 16))
+      return 1;
+  }
+  return -1;
+}