+static bool cidr_prev6(struct cidr *a, struct cidr *b)
+{
+ uint8_t idx, carry = 1, underflow = 0;
+ struct cidr *n = cidr_clone(a);
+ struct in6_addr *x = &n->addr.v6;
+
+ if (b->prefix == 0)
+ {
+ fprintf(stderr, "underflow during 'prev'\n");
+ return false;
+ }
+
+ idx = (b->prefix - 1) / 8;
+
+ do {
+ underflow = !!((x->s6_addr[idx] - carry) < 0);
+ x->s6_addr[idx] -= carry;
+ carry = underflow;
+ }
+ while (idx-- > 0);
+
+ if (carry)
+ {
+ fprintf(stderr, "underflow during 'prev'\n");
+ return false;
+ }
+
+ n->prefix = b->prefix;
+
+ return true;
+}
+
+static bool cidr_next6(struct cidr *a, struct cidr *b)
+{
+ uint8_t idx, carry = 1, overflow = 0;
+ struct cidr *n = cidr_clone(a);
+ struct in6_addr *x = &n->addr.v6;
+
+ if (b->prefix == 0)
+ {
+ fprintf(stderr, "overflow during 'next'\n");
+ return false;
+ }
+
+ idx = (b->prefix - 1) / 8;
+
+ do {
+ overflow = !!((x->s6_addr[idx] + carry) >= 256);
+ x->s6_addr[idx] += carry;
+ carry = overflow;
+ }
+ while (idx-- > 0);
+
+ if (carry)
+ {
+ fprintf(stderr, "overflow during 'next'\n");
+ return false;
+ }
+
+ n->prefix = b->prefix;
+
+ return true;
+}
+