--- /dev/null
+23.128.24.0/24 24 24
+23.128.25.0/25 25 25
+23.128.25.240/28 28 28
+27.0.0.0/24 24 24
+27.50.0.0/22 22 22
+39.0.1.0/24 24 24
+77.72.224.0/21 21 21
+82.130.64.0/18 18 18
+84.205.64.0/24 24 24
+84.205.65.0/24 24 24
+84.205.66.0/24 24 24
+84.205.67.0/24 24 24
+84.205.68.0/24 24 24
+84.205.69.0/24 24 24
+84.205.70.0/24 24 24
+84.205.71.0/24 24 24
+84.205.72.0/24 24 24
+84.205.73.0/24 24 24
+84.205.74.0/24 24 24
+84.205.75.0/24 24 24
+84.205.76.0/24 24 24
+84.205.77.0/24 24 24
+84.205.78.0/24 24 24
+84.205.79.0/24 24 24
+84.205.80.0/24 24 24
+84.205.81.0/24 24 24
+84.205.82.0/24 24 24
+84.205.83.0/24 24 24
+84.205.84.0/24 24 24
+84.205.85.0/24 24 24
+84.205.86.0/24 24 24
+84.205.87.0/24 24 24
+84.205.88.0/24 24 24
+84.205.89.0/24 24 24
+84.205.90.0/24 24 24
+84.205.91.0/24 24 24
+84.205.92.0/24 24 24
+84.205.93.0/24 24 24
+84.205.94.0/24 24 24
+84.205.95.0/24 24 24
+86.119.0.0/16 16 16
+89.206.64.0/18 18 18
+93.175.144.0/24 24 24
+93.175.146.0/24 24 24
+93.175.147.0/24 24 24
+93.175.148.0/24 24 24
+93.175.149.0/24 24 24
+93.175.150.0/24 24 24
+93.175.151.0/24 24 24
+103.0.0.0/16 16 16
+103.1.0.0/22 22 22
+103.1.4.0/24 24 24
+106.0.1.0/24 24 24
+128.178.0.0/15 15 15
+129.129.0.0/16 16 16
+129.132.0.0/16 16 16
+129.194.0.0/15 15 15
+130.59.0.0/16 16 16
+130.60.0.0/16 16 16
+130.82.0.0/16 16 16
+130.92.0.0/16 16 16
+130.125.0.0/16 16 16
+130.223.0.0/16 16 16
+131.152.0.0/16 16 16
+134.21.0.0/16 16 16
+138.131.0.0/16 16 16
+141.167.0.0/16 16 16
+141.249.0.0/16 16 16
+144.200.0.0/16 16 16
+145.245.0.0/16 16 16
+146.136.0.0/16 16 16
+147.86.0.0/16 16 16
+147.87.0.0/16 16 16
+147.88.0.0/16 16 16
+148.187.0.0/16 16 16
+148.196.0.0/16 16 16
+151.120.0.0/16 16 16
+152.88.0.0/16 16 16
+152.96.0.0/16 16 16
+153.109.0.0/16 16 16
+155.105.0.0/16 16 16
+155.228.0.0/16 16 16
+156.25.0.0/16 16 16
+156.135.0.0/16 16 16
+156.135.0.0/21 21 21
+156.135.12.0/22 22 22
+156.135.16.0/21 21 21
+156.135.28.0/22 22 22
+156.135.32.0/19 19 19
+156.135.64.0/18 18 18
+156.135.128.0/17 17 17
+157.26.0.0/16 16 16
+160.85.0.0/16 16 16
+160.98.0.0/16 16 16
+161.62.0.0/16 16 16
+162.132.0.0/16 16 16
+185.42.136.0/22 22 22
+185.42.136.0/23 23 23
+185.51.68.0/22 22 22
+185.133.44.0/22 22 22
+185.144.36.0/22 22 22
+185.194.180.0/22 22 22
+185.207.116.0/22 22 22
+185.225.92.0/22 22 22
+192.12.247.0/24 24 24
+192.26.28.0/22 22 22
+192.26.28.0/24 24 24
+192.26.29.0/24 24 24
+192.26.30.0/24 24 24
+192.26.31.0/24 24 24
+192.26.32.0/21 21 21
+192.26.33.0/24 24 24
+192.26.40.0/22 22 22
+192.26.44.0/24 24 24
+192.26.46.0/23 23 23
+192.33.87.0/24 24 24
+192.33.88.0/21 21 21
+192.33.96.0/21 21 21
+192.33.104.0/22 22 22
+192.33.108.0/23 23 23
+192.33.110.0/24 24 24
+192.33.118.0/23 23 23
+192.33.120.0/21 21 21
+192.33.192.0/19 19 19
+192.33.192.0/20 20 20
+192.33.200.0/21 21 21
+192.33.202.0/24 24 24
+192.33.208.0/20 20 20
+192.33.208.0/22 22 22
+192.33.224.0/21 21 21
+192.36.106.0/24 24 24
+192.36.108.0/24 24 24
+192.36.144.0/24 24 24
+192.36.148.0/23 23 23
+192.36.148.0/24 24 24
+192.36.149.0/24 24 24
+192.41.132.0/22 22 22
+192.41.136.0/24 24 24
+192.41.149.0/24 24 24
+192.41.150.0/23 23 23
+192.41.152.0/21 21 21
+192.41.160.0/24 24 24
+192.42.42.0/23 23 23
+192.42.44.0/22 22 22
+192.42.180.0/22 22 22
+192.42.184.0/21 21 21
+192.42.192.0/21 21 21
+192.42.200.0/23 23 23
+192.42.200.0/24 24 24
+192.42.201.0/24 24 24
+192.43.192.0/22 22 22
+192.43.192.0/24 24 24
+192.43.196.0/24 24 24
+192.47.244.0/22 22 22
+192.47.248.0/23 23 23
+192.65.92.0/23 23 23
+192.71.53.0/24 24 24
+192.71.80.0/24 24 24
+192.101.176.0/24 24 24
+192.135.145.0/24 24 24
+192.135.146.0/24 24 24
+192.135.147.0/24 24 24
+192.135.148.0/24 24 24
+192.135.149.0/24 24 24
+192.135.150.0/23 23 23
+192.135.150.0/24 24 24
+192.135.151.0/24 24 24
+192.135.152.0/21 21 21
+192.135.160.0/24 24 24
+192.135.161.0/24 24 24
+192.135.162.0/24 24 24
+192.135.163.0/24 24 24
+192.135.164.0/24 24 24
+192.152.98.0/24 24 24
+193.5.22.0/24 24 24
+193.5.26.0/23 23 23
+193.5.54.0/23 23 23
+193.5.58.0/24 24 24
+193.5.60.0/24 24 24
+193.5.80.0/21 21 21
+193.5.152.0/22 22 22
+193.5.168.0/22 22 22
+193.5.180.0/24 24 24
+193.5.181.0/24 24 24
+193.5.182.0/24 24 24
+193.5.185.0/24 24 24
+193.5.186.0/24 24 24
+193.5.187.0/24 24 24
+193.5.188.0/24 24 24
+193.8.136.0/23 23 23
+193.36.32.0/24 24 24
+193.73.125.0/24 24 24
+193.134.200.0/21 21 21
+193.134.202.0/24 24 24
+193.134.216.0/21 21 21
+193.135.168.0/22 22 22
+193.135.172.0/24 24 24
+193.135.240.0/21 21 21
+193.138.69.0/24 24 24
+193.222.112.0/20 20 20
+193.222.241.0/24 24 24
+193.222.242.0/23 23 23
+193.222.244.0/22 22 22
+193.222.248.0/23 23 23
+193.222.250.0/24 24 24
+193.246.121.0/24 24 24
+193.246.124.0/23 23 23
+193.246.176.0/20 20 20
+193.247.190.0/23 23 23
+193.247.203.0/24 24 24
+193.247.240.0/22 22 22
+193.247.248.0/23 23 23
+193.247.254.0/24 24 24
+194.26.26.0/24 24 24
+194.42.48.0/24 24 24
+194.58.192.0/22 22 22
+194.58.192.0/24 24 24
+194.58.193.0/24 24 24
+194.58.194.0/23 23 23
+194.58.194.0/24 24 24
+194.58.195.0/24 24 24
+194.58.196.0/24 24 24
+194.58.197.0/24 24 24
+194.68.128.0/24 24 24
+194.68.132.0/24 24 24
+194.146.105.0/24 24 24
+194.146.106.0/23 23 23
+194.146.106.0/24 24 24
+194.146.107.0/24 24 24
+194.146.108.0/24 24 24
+194.153.96.0/24 24 24
+195.176.0.0/16 16 16
+195.176.0.0/17 17 17
+195.176.160.0/19 19 19
+195.176.224.0/19 19 19
+196.3.35.0/24 24 24
+196.3.36.0/24 24 24
+196.3.37.0/24 24 24
+196.3.38.0/24 24 24
+196.3.39.0/24 24 24
+196.3.40.0/24 24 24
+196.3.43.0/24 24 24
+196.3.44.0/24 24 24
+196.3.46.0/24 24 24
+196.3.47.0/24 24 24
+196.3.48.0/24 24 24
+196.3.49.0/24 24 24
+196.3.50.0/24 24 24
+196.3.56.0/24 24 24
+198.21.16.0/24 24 24
+198.21.17.0/24 24 24
+198.21.19.0/24 24 24
+198.21.20.0/24 24 24
+198.21.21.0/24 24 24
+198.21.31.0/24 24 24
+213.32.232.0/21 21 21
+2001:620::/29 29 29
+2001:620::/32 32 32
+2001:678:678::/48 48 48
+2001:67c:1010::/47 47 47
+2001:67c:1010::/48 48 48
+2001:67c:1011::/48 48 48
+2001:67c:10ec::/48 48 48
+2001:67c:13c0::/48 48 48
+2001:67c:16dc::/48 48 48
+2001:67c:19fc::/48 48 48
+2001:7f8:c::/48 48 48
+2001:7fb:fd02::/48 48 48
+2001:7fb:fd03::/48 48 48
+2001:7fb:fe00::/48 48 48
+2001:7fb:fe01::/48 48 48
+2001:7fb:fe02::/48 48 48
+2001:7fb:fe03::/48 48 48
+2001:7fb:fe04::/48 48 48
+2001:7fb:fe05::/48 48 48
+2001:7fb:fe06::/48 48 48
+2001:7fb:fe07::/48 48 48
+2001:7fb:fe0a::/48 48 48
+2001:7fb:fe0b::/48 48 48
+2001:7fb:fe0c::/48 48 48
+2001:7fb:fe0d::/48 48 48
+2001:7fb:fe0e::/48 48 48
+2001:7fb:fe0f::/48 48 48
+2001:7fb:fe10::/48 48 48
+2001:7fb:fe12::/48 48 48
+2001:7fb:fe13::/48 48 48
+2001:7fb:fe14::/48 48 48
+2001:7fb:fe15::/48 48 48
+2001:7fb:fe16::/48 48 48
+2001:7fb:fe17::/48 48 48
+2001:7fb:ff00::/48 48 48
+2001:7fb:ff01::/48 48 48
+2001:7fb:ff02::/48 48 48
+2001:7fb:ff03::/48 48 48
+2001:7fb:ff04::/48 48 48
+2001:7fb:ff05::/48 48 48
+2001:7fb:ff06::/48 48 48
+2001:7fb:ff07::/48 48 48
+2001:7fb:ff0a::/48 48 48
+2001:7fb:ff0b::/48 48 48
+2001:7fb:ff0c::/48 48 48
+2001:7fb:ff0d::/48 48 48
+2001:7fb:ff0e::/48 48 48
+2001:7fb:ff0f::/48 48 48
+2001:7fb:ff10::/48 48 48
+2001:7fb:ff12::/48 48 48
+2001:7fb:ff13::/48 48 48
+2001:7fb:ff14::/48 48 48
+2001:7fb:ff15::/48 48 48
+2001:7fb:ff16::/48 48 48
+2001:7fb:ff17::/48 48 48
+2001:7fe::/32 32 32
+2001:7fe::/33 33 33
+2a01:3f0::/29 29 29
+2a01:3f0::/32 32 32
+2a01:3f1::/38 38 38
+2a01:3f1:400::/38 38 38
+2a01:3f1:5000::/38 38 38
+2a01:3f1:8000::/38 38 38
+2a01:3f1:a000::/38 38 38
+2a01:3f1:c000::/38 38 38
+2a02:7dc0::/32 32 32
+2a04:c440::/32 32 32
+2a04:c440:ffc::/48 48 48
+2a07:290a::/32 32 32
+2a07:3e00::/29 29 29
+2a07:6b40::/29 29 29
+2a0a:4ec0::/29 29 29
+2a0b:1200::/29 29 29
+2a0b:2040::/29 29 29
+2a0c:d680::/29 29 29
--- /dev/null
+/* $OpenBSD: rde_trie_test.c,v 1.1 2018/09/07 16:10:42 claudio Exp $ */
+
+/*
+ * Copyright (c) 2018 Claudio Jeker <claudio@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+
+#include <err.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <util.h>
+
+#include "bgpd.h"
+#include "rde.h"
+
+
+static int
+host_v4(const char *s, struct bgpd_addr *h, u_int8_t *len)
+{
+ struct in_addr ina = { 0 };
+ int bits = 32;
+
+ memset(h, 0, sizeof(*h));
+ if (strrchr(s, '/') != NULL) {
+ if ((bits = inet_net_pton(AF_INET, s, &ina, sizeof(ina))) == -1)
+ return (0);
+ } else {
+ if (inet_pton(AF_INET, s, &ina) != 1)
+ return (0);
+ }
+ h->aid = AID_INET;
+ h->v4.s_addr = ina.s_addr;
+ *len = bits;
+ return (1);
+}
+
+static int
+host_v6(char *s, struct bgpd_addr *h, u_int8_t *len)
+{
+ struct addrinfo hints, *res;
+ const char *errstr;
+ char *p;
+ int mask = 128;
+
+ if ((p = strrchr(s, '/')) != NULL) {
+ mask = strtonum(p + 1, 0, 128, &errstr);
+ if (errstr)
+ return (0);
+ *p = '\0';
+ }
+
+ bzero(&hints, sizeof(hints));
+ hints.ai_family = AF_INET6;
+ hints.ai_socktype = SOCK_DGRAM; /*dummy*/
+ hints.ai_flags = AI_NUMERICHOST;
+ if (getaddrinfo(s, "0", &hints, &res) == 0) {
+ h->aid = AID_INET6;
+ memcpy(&h->v6, &res->ai_addr->sa_data[6], sizeof(h->v6));
+ freeaddrinfo(res);
+ *len = mask;
+ *p = '/';
+ return (1);
+ }
+ *p = '/';
+
+ return (0);
+}
+
+static int
+host_l(char *s, struct bgpd_addr *h, u_int8_t *len)
+{
+ if (host_v4(s, h, len))
+ return (1);
+ if (host_v6(s, h, len))
+ return (1);
+ return (0);
+}
+
+static const char *
+print_prefix(struct bgpd_addr *p)
+{
+ static char buf[48];
+
+ if (p->aid == AID_INET) {
+ if (inet_ntop(AF_INET, &p->ba, buf, sizeof(buf)) == NULL)
+ return "?";
+ } else if (p->aid == AID_INET6) {
+ if (inet_ntop(AF_INET6, &p->ba, buf, sizeof(buf)) == NULL)
+ return "?";
+ } else {
+ return "???";
+ }
+ return buf;
+}
+
+static void
+parse_file(FILE *in, struct trie_head *th)
+{
+ const char *errstr;
+ char *line, *s;
+ struct bgpd_addr prefix;
+ u_int8_t plen, min, max, maskmax;
+
+
+ while ((line = fparseln(in, NULL, NULL, NULL, FPARSELN_UNESCALL))) {
+ int state = 0;
+ while ((s = strsep(&line, " \t"))) {
+ if (*s == '\0')
+ break;
+ switch (state) {
+ case 0:
+ if (!host_l(s, &prefix, &plen))
+ errx(1, "could not parse prefix \"%s\"",
+ s);
+ break;
+ case 1:
+ if (prefix.aid == AID_INET6)
+ maskmax = 128;
+ else
+ maskmax = 32;
+ min = strtonum(s, 0, maskmax, &errstr);
+ if (errstr != NULL)
+ errx(1, "min is %s: %s", errstr, s);
+ break;
+ case 2:
+ if (prefix.aid == AID_INET6)
+ maskmax = 128;
+ else
+ maskmax = 32;
+ max = strtonum(s, 0, maskmax, &errstr);
+ if (errstr != NULL)
+ errx(1, "max is %s: %s", errstr, s);
+ break;
+ default:
+ errx(1, "could not parse \"%s\", confused", s);
+ }
+ state++;
+ }
+
+ if (trie_add(th, &prefix, plen, min, max) != 0)
+ errx(1, "trie_add(%s, %u, %u, %u) failed",
+ print_prefix(&prefix), plen, min, max);
+
+ free(line);
+ }
+}
+
+static void
+test_file(FILE *in, struct trie_head *th)
+{
+ char *line;
+ struct bgpd_addr prefix;
+ u_int8_t plen;
+
+ while ((line = fparseln(in, NULL, NULL, NULL, FPARSELN_UNESCALL))) {
+ if (!host_l(line, &prefix, &plen))
+ errx(1, "could not parse prefix \"%s\"", line);
+ printf("%s ", line);
+ if (trie_match(th, &prefix, plen))
+ printf("MATCH\n");
+ else
+ printf("miss\n");
+ free(line);
+ }
+}
+
+static void
+usage(void)
+{
+ extern char *__progname;
+ fprintf(stderr, "usage: %s prefixfile testfile\n", __progname);
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ struct trie_head th = { 0 };
+ FILE *in, *tin;
+ int ch;
+
+ if (argc != 3)
+ usage();
+
+ in = fopen(argv[1], "r");
+ if (in == NULL)
+ err(1, "fopen(%s)", argv[0]);
+ tin = fopen(argv[2], "r");
+ if (tin == NULL)
+ err(1, "fopen(%s)", argv[1]);
+
+ parse_file(in, &th);
+ /* trie_dump(&th); */
+ if (trie_equal(&th, &th) == 0)
+ errx(1, "trie_equal failure");
+ test_file(tin, &th);
+
+ trie_free(&th);
+}