├── testfns.h ├── .gitignore ├── openbsd ├── stdalign.h └── sys.c ├── testdata ├── mkripdata ├── testipmapinsert.data ├── testipmapinsert.data2 └── testipmapinsert.data3 ├── testrevbits.c ├── testbitvec.c ├── testlib.c ├── compat.c ├── README.md ├── LICENSE ├── dat.h ├── amprroute.c ├── uptunnel.c ├── Makefile ├── testipmapfind.c ├── rip.c ├── testipmapnearest.c ├── fns.h ├── testnetmask2cidr.c ├── testipmapinsert.c ├── main.c ├── lib.c └── testisvalidnetmask.c /testfns.h: -------------------------------------------------------------------------------- 1 | uint32_t mkkey(const char *addr); 2 | size_t mkkeylen(const char *subnetmask); 3 | void u32tobin(uint32_t w, size_t len, char bin[static 33]); 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **.o 2 | **.core 3 | 44ripd 4 | amprroute 5 | testbitvec 6 | testipmapfind 7 | testipmapinsert 8 | testipmapnearest 9 | testisvalidnetmask 10 | testnetmask2cidr 11 | testrevbits 12 | uptunnel 13 | -------------------------------------------------------------------------------- /openbsd/stdalign.h: -------------------------------------------------------------------------------- 1 | #ifndef _STDALIGN_H_ 2 | #define _STDALIGN_H_ 3 | 4 | #ifndef alignas 5 | #define alignas _Alignas 6 | #endif // !alignas 7 | 8 | #ifndef alignof 9 | #define alignof _Alignof 10 | #endif // !alignof 11 | 12 | #endif // !_STDALIGN_H_ 13 | -------------------------------------------------------------------------------- /testdata/mkripdata: -------------------------------------------------------------------------------- 1 | doas tcpdump -r rip.tcp -vvv -e -n > data 2 | sed -e 's/^[^{]*{//' data > d1 3 | sed -e 's/}[^}]*$//' d1 > d2 4 | sed 's/ tag [0-9][0-9]*//g' < d2 > d3 5 | sed 's/(1)//g' < d3 > d4 6 | tr ' ' '\n' < d4 | tr -d '{}' > d5 7 | sed 's,/, ,;s/->.*$//' < d5 > d6 8 | -------------------------------------------------------------------------------- /testrevbits.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "dat.h" 5 | #include "fns.h" 6 | 7 | void 8 | test(uint32_t w, uint32_t expected) 9 | { 10 | if (revbits(w) != expected) { 11 | printf("revbits(%08x) != %08x: %08x\n", w, expected, revbits(w)); 12 | } 13 | } 14 | 15 | int 16 | main(void) 17 | { 18 | test(0xF0000000, 0x0000000F); 19 | test(0xFF000000, 0x000000FF); 20 | test(0xF00FF00F, 0xF00FF00F); 21 | test(0xDEADBEEF, 0xF77DB57B); 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /testbitvec.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "dat.h" 7 | #include "fns.h" 8 | 9 | int 10 | main(void) 11 | { 12 | Bitvec *bv = mkbitvec(); 13 | 14 | for (int k = 0; k < 65; k++) { 15 | size_t bit = nextbit(bv); 16 | if (bit != k) { 17 | fprintf(stderr, "bit != k: %zu, %d\n", bit, k); 18 | exit(EXIT_FAILURE); 19 | } 20 | assert(bitget(bv, k) == 0); 21 | bitset(bv, bit); 22 | assert(bitget(bv, k) == 1); 23 | } 24 | assert(bitget(bv, 1024) == 0); 25 | 26 | freebitvec(bv); 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /testlib.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "dat.h" 11 | #include "fns.h" 12 | 13 | uint32_t 14 | mkkey(const char *addr) 15 | { 16 | return ntohl(inet_addr(addr)); 17 | } 18 | 19 | size_t 20 | mkkeylen(const char *subnetmask) 21 | { 22 | in_addr_t netmask = ntohl(inet_addr(subnetmask)); 23 | assert(isvalidnetmask(netmask)); 24 | return netmask2cidr(netmask); 25 | } 26 | 27 | void 28 | u32tobin(uint32_t w, size_t len, char bin[static 33]) 29 | { 30 | assert(len <= 32); 31 | for (int k = 0; k < len; k++) 32 | bin[k] = '0' + ((w >> k) & 0x01); 33 | bin[len] = '\0'; 34 | } 35 | -------------------------------------------------------------------------------- /compat.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #ifdef USE_COMPAT 8 | 9 | #define SIZE_T_MAX ~(size_t)0 10 | #define SQRT_MAX (1 << (sizeof(size_t)*8/4)) 11 | 12 | void * 13 | reallocarray(void *p, size_t nelem, size_t size) 14 | { 15 | if ((nelem >= SQRT_MAX || size >= SQRT_MAX) && 16 | size > 0 && (SIZE_T_MAX/size) < nelem) 17 | { 18 | errno = ENOMEM; 19 | return NULL; 20 | } 21 | return realloc(p, nelem*size); 22 | } 23 | 24 | void * 25 | recallocarray(void *p, size_t oelem, size_t nelem, size_t size) 26 | { 27 | char *np; 28 | size_t nlen, olen; 29 | 30 | np = reallocarray(p, nelem, size); 31 | if (np == NULL || nelem <= oelem) 32 | return np; 33 | nlen = size*nelem; 34 | olen = size*oelem; 35 | memset(np + olen, 0, nlen - olen); 36 | 37 | return np; 38 | } 39 | 40 | #endif // USE_COMPAT 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 44ripd: An AMPRNet mesh maintenance daemon for BSD 2 | ================================================== 3 | 4 | This is 44ripd, a daemon for maintaining routes and tunnels on the 5 | AMPRNet amateur radio IP network (IPv4 network 44/9 and 44.128.0.0/10). 6 | 7 | This software implements a listener for RIPv2 packets containing route 8 | and tunnel information for gateways to APMRNet sub-networks as well as 9 | support for maintaining routes and IPENCAP tunnels. It runs on OpenBSD, 10 | but is likely portable to other BSD variants with fairly little work. 11 | The author current runs it on a Ubiquiti Networks EdgeRouter Lite 12 | running OpenBSD/Octeon. 13 | 14 | The software is released under the 2-clause BSD license. 15 | 16 | Author 17 | ------ 18 | 44ripd was written by Dan Cross, KZ2X. Reach me via email at 19 | crossd@gmail.com or find me on the web at http://pub.gajendra.net/ 20 | 21 | TODO 22 | ---- 23 | * Write a man page. 24 | * At startup, the daemon should probe the state of the system and 25 | use the existing routing table and interfaces to bootstrap its 26 | internal copies. 27 | * Logging and assertions could always be improved. 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, Dan Cross 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions 6 | are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /dat.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | typedef unsigned char octet; 6 | typedef struct Bitvec Bitvec; 7 | typedef struct IPMap IPMap; 8 | typedef struct RIPPacket RIPPacket; 9 | typedef struct RIPResponse RIPResponse; 10 | typedef struct Route Route; 11 | typedef struct Tunnel Tunnel; 12 | 13 | enum { 14 | MIN_RIP_PACKET_SIZE = 4, 15 | }; 16 | 17 | /* 18 | * We use a bit vector to keep track of allocated interfaces. 19 | */ 20 | struct Bitvec { 21 | uint64_t *words; 22 | size_t nwords; 23 | size_t firstclr; 24 | }; 25 | 26 | /* 27 | * A PATRICIA trie mapping CIDR network numbers to a datum. 28 | * The central data structure for maintaining lookup tables 29 | * of active routes and tunnels. 30 | */ 31 | struct IPMap { 32 | uint32_t key; 33 | size_t keylen; 34 | void *datum; 35 | IPMap *left; 36 | IPMap *right; 37 | }; 38 | 39 | struct RIPPacket { 40 | octet command; 41 | octet version; 42 | uint16_t nbz; 43 | size_t datalen; 44 | size_t nresponse; 45 | const octet *data; 46 | }; 47 | 48 | enum { 49 | RIP_RESPONSE_SIZE = 20, 50 | }; 51 | 52 | struct RIPResponse { 53 | uint16_t addrfamily; 54 | uint16_t routetag; 55 | uint32_t ipaddr; 56 | uint32_t subnetmask; 57 | uint32_t nexthop; 58 | uint32_t metric; 59 | }; 60 | 61 | struct Route { 62 | uint32_t ipnet; 63 | uint32_t subnetmask; 64 | uint32_t gateway; 65 | time_t expires; // Seconds. 66 | Route *rnext; 67 | Tunnel *tunnel; 68 | }; 69 | 70 | enum { 71 | MAX_TUN_IFNAME = 16, 72 | }; 73 | 74 | struct Tunnel { 75 | Route *routes; 76 | uint32_t local; 77 | uint32_t remote; 78 | int nref; 79 | char ifname[MAX_TUN_IFNAME]; 80 | unsigned int ifnum; 81 | }; 82 | -------------------------------------------------------------------------------- /amprroute.c: -------------------------------------------------------------------------------- 1 | /* 2 | * A program to manually add or remove tunnel routes. route(8) 3 | * is not sufficiently expressive to do this. 4 | */ 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include "dat.h" 21 | #include "fns.h" 22 | 23 | int 24 | main(int argc, char *argv[]) 25 | { 26 | Route route; 27 | Tunnel tunnel; 28 | struct in_addr addr; 29 | char *slash, *net, *ifname; 30 | unsigned int cidr; 31 | uint32_t netmask; 32 | int ch, rdomain; 33 | 34 | rdomain = 0; 35 | while ((ch = getopt(argc, argv, "D:?h")) != -1) { 36 | switch (ch) { 37 | case 'D': 38 | rdomain = strnum(optarg); 39 | break; 40 | case '?': 41 | case 'h': 42 | default: 43 | fatal("usage: amprroute network/cidr ifname"); 44 | break; 45 | } 46 | } 47 | argc -= optind; 48 | argv += optind; 49 | 50 | initlog(); 51 | initsys(rdomain); 52 | 53 | if (argc != 2) 54 | fatal("usage: amprroute network/cidr ifname"); 55 | net = argv[0]; 56 | ifname = argv[1]; 57 | 58 | slash = strchr(net, '/'); 59 | if (slash == NULL) 60 | fatal("network missing CIDR"); 61 | *slash++ = '\0'; 62 | cidr = strnum(slash); 63 | netmask = cidr2netmask(cidr); 64 | 65 | memset(&addr, 0, sizeof(addr)); 66 | if (inet_pton(AF_INET, net, &addr) <= 0) 67 | fatal("cannot parse network: %s", net); 68 | 69 | memset(&route, 0, sizeof(route)); 70 | route.subnetmask = netmask; 71 | route.ipnet = ntohl(addr.s_addr); 72 | 73 | memset(&tunnel, 0, sizeof(tunnel)); 74 | strlcpy(tunnel.ifname, ifname, sizeof(tunnel.ifname)); 75 | 76 | addroute(&route, &tunnel, rdomain); 77 | 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /uptunnel.c: -------------------------------------------------------------------------------- 1 | /* 2 | * A program to manually add or remove tunnel routes. route(8) 3 | * is not sufficiently expressive to do this. 4 | */ 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include "dat.h" 21 | #include "fns.h" 22 | 23 | int 24 | main(int argc, char *argv[]) 25 | { 26 | Tunnel tunnel; 27 | struct in_addr local, remote, local44; 28 | int ch, rdomain, tunneldomain; 29 | uint32_t local44addr; 30 | 31 | rdomain = 0; 32 | tunneldomain = 0; 33 | while ((ch = getopt(argc, argv, "D:T:?h")) != -1) { 34 | switch (ch) { 35 | case 'T': 36 | tunneldomain = strnum(optarg); 37 | break; 38 | case 'D': 39 | rdomain = strnum(optarg); 40 | break; 41 | break; 42 | case '?': 43 | case 'h': 44 | default: 45 | fatal("usage: uptunnel ifname local remote endpoint"); 46 | break; 47 | } 48 | } 49 | argc -= optind; 50 | argv += optind; 51 | 52 | initlog(); 53 | initsys(rdomain); 54 | 55 | if (argc != 4) 56 | fatal("usage: uptunnel ifname local remote endpoint"); 57 | 58 | memset(&local, 0, sizeof(local)); 59 | if (inet_pton(AF_INET, argv[1], &local) <= 0) 60 | fatal("cannot parse local: %s", argv[1]); 61 | 62 | memset(&remote, 0, sizeof(remote)); 63 | if (inet_pton(AF_INET, argv[2], &remote) <= 0) 64 | fatal("cannot parse remote: %s", argv[2]); 65 | 66 | memset(&local44, 0, sizeof(local44)); 67 | if (inet_pton(AF_INET, argv[3], &local44) <= 0) 68 | fatal("cannot parse local 44: %s", argv[3]); 69 | local44addr = ntohl(local44.s_addr); 70 | 71 | memset(&tunnel, 0, sizeof(tunnel)); 72 | strlcpy(tunnel.ifname, argv[0], sizeof(tunnel.ifname)); 73 | tunnel.local = ntohl(local.s_addr); 74 | tunnel.remote = ntohl(remote.s_addr); 75 | 76 | uptunnel(&tunnel, rdomain, tunneldomain, local44addr); 77 | 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | CC= cc 3 | FLAGS= -Wall -Werror -ansi -pedantic -std=c11 -I. -Iopenbsd # -DUSE_COMPAT 4 | CFLAGS= $(FLAGS) -g 5 | SRCS= main.c rip.c lib.c openbsd/sys.c compat.c 6 | OBJS= main.o rip.o lib.o openbsd/sys.o compat.o 7 | PROG= 44ripd 8 | PROGS= $(PROG) amprroute uptunnel 9 | TESTS= testbitvec testipmapfind testipmapnearest \ 10 | testisvalidnetmask testnetmask2cidr testrevbits 11 | DTESTS= testipmapinsert 12 | TOBJS= lib.o openbsd/sys.o compat.o testlib.o 13 | LIBS= 14 | 15 | all: $(PROGS) 16 | 17 | $(PROG): $(OBJS) 18 | $(CC) -o $(PROG) $(OBJS) $(LIBS) 19 | 20 | fast$(PROG): $(SRCS) dat.h fns.h Makefile 21 | $(CC) $(FLAGS) -Ofast -o fast$(PROG) $(SRCS) 22 | 23 | amprroute: $(OBJS) amprroute.o 24 | $(CC) -o amprroute amprroute.o lib.o openbsd/sys.o 25 | 26 | uptunnel: $(OBJS) uptunnel.o 27 | $(CC) -o uptunnel uptunnel.o lib.o openbsd/sys.o 28 | 29 | $(OBJS): dat.h fns.h openbsd/stdalign.h Makefile 30 | 31 | .c.o: 32 | $(CC) $(CFLAGS) -c -o $@ $< 33 | 34 | clean: 35 | rm -f $(PROGS) fast$(PROG) $(TESTS) $(DTESTS) openbsd/sys.o *.o 36 | 37 | tests: $(TESTS) $(DTESTS) 38 | for t in $(TESTS); do ./$$t; done 39 | ./testipmapinsert < testdata/testipmapinsert.data 40 | ./testipmapinsert < testdata/testipmapinsert.data2 41 | ./testipmapinsert < testdata/testipmapinsert.data3 42 | 43 | $(TOBJS): dat.h fns.h testfns.h openbsd/stdalign.h Makefile 44 | 45 | testbitvec: testbitvec.o $(TOBJS) 46 | $(CC) -o testbitvec testbitvec.o $(TOBJS) 47 | 48 | testipmapfind: testipmapfind.o $(TOBJS) 49 | $(CC) -o testipmapfind testipmapfind.o $(TOBJS) 50 | 51 | testipmapinsert: testipmapinsert.o $(TOBJS) 52 | $(CC) -o testipmapinsert testipmapinsert.o $(TOBJS) 53 | 54 | testipmapnearest: testipmapnearest.o $(TOBJS) 55 | $(CC) -o testipmapnearest testipmapnearest.o $(TOBJS) 56 | 57 | testisvalidnetmask: testisvalidnetmask.o $(TOBJS) 58 | $(CC) -o testisvalidnetmask testisvalidnetmask.o $(TOBJS) 59 | 60 | testnetmask2cidr: testnetmask2cidr.o $(TOBJS) 61 | $(CC) -o testnetmask2cidr testnetmask2cidr.o $(TOBJS) 62 | 63 | testrevbits: testrevbits.o $(TOBJS) 64 | $(CC) -o testrevbits testrevbits.o $(TOBJS) 65 | -------------------------------------------------------------------------------- /testipmapfind.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "dat.h" 9 | #include "fns.h" 10 | #include "testfns.h" 11 | 12 | IPMap root, a, b, c, d, e; 13 | const char *av = "a"; 14 | const char *bv = "b"; 15 | const char *cv = "c"; 16 | const char *dv = "d"; 17 | const char *ev = "e"; 18 | 19 | void 20 | setup(void) 21 | { 22 | memset(&root, 0, sizeof(root)); 23 | memset(&a, 0, sizeof(a)); 24 | memset(&b, 0, sizeof(b)); 25 | memset(&c, 0, sizeof(c)); 26 | memset(&d, 0, sizeof(d)); 27 | 28 | root.key = revbits(mkkey("44.0.0.0")); 29 | root.keylen = 8; 30 | root.datum = NULL; 31 | root.left = &a; 32 | root.right = &b; 33 | 34 | a.key = (revbits(mkkey("44.0.0.1")) >> 8); 35 | a.keylen = 24; 36 | a.datum = (void *)av; 37 | a.left = NULL; 38 | a.right = NULL; 39 | 40 | b.key = (revbits(mkkey("44.130.0.0")) >> 8); 41 | b.keylen = 8; 42 | b.datum = (void *)bv; 43 | b.left = &c; 44 | b.right = &d; 45 | 46 | c.key = (revbits(mkkey("44.130.24.0")) >> 16); 47 | c.keylen = 8; 48 | c.datum = (void *)cv; 49 | c.left = &e; 50 | c.right = NULL; 51 | 52 | d.key = (revbits(mkkey("44.130.130.0")) >> 16); 53 | d.keylen = 8; 54 | d.datum = (void *)dv; 55 | d.left = NULL; 56 | d.right = NULL; 57 | 58 | e.key = (revbits(mkkey("44.130.24.25")) >> 24); 59 | e.keylen = 8; 60 | e.datum = (void *)ev; 61 | e.left = NULL; 62 | e.right = NULL; 63 | } 64 | 65 | void 66 | test(const char *key, uint32_t keylen, const char *expected) 67 | { 68 | void *v = ipmapfind(&root, mkkey(key), keylen); 69 | if (v != expected) { 70 | const char *exp = expected ? expected : "(NULL)"; 71 | printf("ipmapnearest(&root, \"%s\", %d) != %s (%p)\n", 72 | key, keylen, exp, v); 73 | } 74 | } 75 | 76 | int 77 | main(void) 78 | { 79 | setup(); 80 | 81 | test("44.0.0.1", 24, NULL); 82 | test("44.0.0.1", 32, av); 83 | test("44.130.24.25", 32, ev); 84 | test("44.130.24.1", 32, NULL); 85 | test("44.188.0.1", 32, NULL); 86 | test("44.130.130.0", 24, dv); 87 | test("44.130.130.0", 27, NULL); 88 | test("44.130.131.0", 27, NULL); 89 | test("44.130.24.0", 24, cv); 90 | 91 | return 0; 92 | } 93 | -------------------------------------------------------------------------------- /rip.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "dat.h" 10 | #include "fns.h" 11 | 12 | int 13 | parserippkt(const octet *restrict data, size_t len, RIPPacket *restrict packet) 14 | { 15 | assert(data != NULL); 16 | assert(packet != NULL); 17 | if (len < MIN_RIP_PACKET_SIZE) 18 | return -1; 19 | packet->command = data[0]; 20 | packet->version = data[1]; 21 | packet->nbz = readnet16(data + 2); 22 | packet->datalen = len - MIN_RIP_PACKET_SIZE; 23 | packet->data = NULL; 24 | if (packet->datalen != 0) 25 | packet->data = data + 4; 26 | if ((packet->datalen % RIP_RESPONSE_SIZE) != 0) 27 | return -1; 28 | packet->nresponse = packet->datalen / RIP_RESPONSE_SIZE; 29 | 30 | return 0; 31 | } 32 | 33 | int 34 | verifyripauth(RIPPacket *restrict packet, const char *restrict password) 35 | { 36 | char packetpass[16 + 1]; 37 | 38 | assert(packet != NULL); 39 | assert(password != NULL); 40 | if (packet->datalen < RIP_RESPONSE_SIZE) 41 | return -1; 42 | if (readnet16(packet->data + 0) != 0xFFFF) 43 | return -1; 44 | if (readnet16(packet->data + 2) != 2) 45 | return -1; 46 | memmove(packetpass, (char *)packet->data + 4, 16); 47 | packetpass[16] = '\0'; 48 | if (strcmp(packetpass, password) != 0) 49 | return -1; 50 | --packet->nresponse; 51 | packet->data += RIP_RESPONSE_SIZE; 52 | packet->datalen -= RIP_RESPONSE_SIZE; 53 | 54 | return 0; 55 | } 56 | 57 | static int 58 | parseriprespocts(const octet *data, size_t len, RIPResponse *restrict response) 59 | { 60 | assert(data != NULL); 61 | assert(response != NULL); 62 | if (len < RIP_RESPONSE_SIZE) 63 | return -1; 64 | response->addrfamily = readnet16(data + 0); 65 | response->routetag = readnet16(data + 2); 66 | response->ipaddr = readnet32(data + 4); 67 | response->subnetmask = readnet32(data + 8); 68 | response->nexthop = readnet32(data + 12); 69 | response->metric = readnet32(data + 16); 70 | if (!isvalidnetmask(response->subnetmask)) 71 | return -1; 72 | 73 | return 0; 74 | } 75 | 76 | int 77 | parseripresponse(const RIPPacket *restrict packet, int k, 78 | RIPResponse *restrict response) 79 | { 80 | size_t offset; 81 | 82 | assert(packet != NULL); 83 | assert(response != NULL); 84 | offset = k*RIP_RESPONSE_SIZE; 85 | if (packet->datalen < offset) 86 | return -1; 87 | return parseriprespocts(packet->data + offset, 88 | packet->datalen - offset, response); 89 | } 90 | -------------------------------------------------------------------------------- /testipmapnearest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "dat.h" 9 | #include "fns.h" 10 | #include "testfns.h" 11 | 12 | IPMap root, rroot, a, b, c, d, e; 13 | const char *rv = "root"; 14 | const char *av = "a"; 15 | const char *bv = "b"; 16 | const char *cv = "c"; 17 | const char *dv = "d"; 18 | const char *ev = "e"; 19 | 20 | void 21 | setup(void) 22 | { 23 | memset(&root, 0, sizeof(root)); 24 | memset(&rroot, 0, sizeof(rroot)); 25 | memset(&a, 0, sizeof(a)); 26 | memset(&b, 0, sizeof(b)); 27 | memset(&c, 0, sizeof(c)); 28 | memset(&d, 0, sizeof(d)); 29 | 30 | root.key = 0; 31 | root.keylen = 0; 32 | root.datum = NULL; 33 | root.left = &rroot; 34 | root.right = NULL; 35 | 36 | rroot.key = revbits(mkkey("44.0.0.0")); 37 | rroot.keylen = 8; 38 | rroot.datum = (void *)rv; 39 | rroot.left = &a; 40 | rroot.right = &b; 41 | 42 | a.key = (revbits(mkkey("44.0.0.1")) >> 8); 43 | a.keylen = 24; 44 | a.datum = (void *)av; 45 | a.left = NULL; 46 | a.right = NULL; 47 | 48 | b.key = (revbits(mkkey("44.130.0.0")) >> 8); 49 | b.keylen = 8; 50 | b.datum = (void *)bv; 51 | b.left = &c; 52 | b.right = &d; 53 | 54 | c.key = (revbits(mkkey("44.130.24.0")) >> 16); 55 | c.keylen = 8; 56 | c.datum = (void *)cv; 57 | c.left = &e; 58 | c.right = NULL; 59 | 60 | d.key = (revbits(mkkey("44.130.130.0")) >> 16); 61 | d.keylen = 8; 62 | d.datum = (void *)dv; 63 | d.left = NULL; 64 | d.right = NULL; 65 | 66 | e.key = (revbits(mkkey("44.130.24.25")) >> 24); 67 | e.keylen = 8; 68 | e.datum = (void *)ev; 69 | e.left = NULL; 70 | e.right = NULL; 71 | } 72 | 73 | void 74 | test(const char *key, size_t keylen, const char *expected) 75 | { 76 | void *v = ipmapnearest(&root, mkkey(key), keylen); 77 | if (v != expected) { 78 | const char *exp = expected ? expected : "NULL"; 79 | printf("ipmapnearest(&root, \"%s\", %zu) != %s (%p -> %s)\n", 80 | key, keylen, exp, v, (v == NULL) ? "NULL" : (char *)v); 81 | } 82 | } 83 | 84 | int 85 | main(void) 86 | { 87 | setup(); 88 | 89 | test("130.0.0.1", 32, NULL); 90 | test("44.0.0.1", 24, rv); 91 | test("44.0.0.12", 32, rv); 92 | test("44.0.0.1", 32, av); 93 | test("44.130.24.25", 32, ev); 94 | test("44.130.24.1", 32, cv); 95 | test("44.188.0.1", 32, rv); 96 | test("44.130.130.0", 24, dv); 97 | test("44.130.130.0", 27, dv); 98 | test("44.130.131.0", 27, bv); 99 | test("44.130.24.0", 24, cv); 100 | 101 | return 0; 102 | } 103 | -------------------------------------------------------------------------------- /fns.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | uint32_t readnet32(const octet data[static 4]); 7 | uint16_t readnet16(const octet data[static 2]); 8 | int parserippkt(const octet *restrict data, size_t len, RIPPacket *restrict packet); 9 | int verifyripauth(RIPPacket *restrict packet, const char *restrict password); 10 | int parseripresponse(const RIPPacket *restrict pkt, int k, RIPResponse *restrict response); 11 | bool isvalidnetmask(uint32_t netmask); 12 | unsigned int netmask2cidr(uint32_t netmask); 13 | uint32_t cidr2netmask(unsigned int cidr); 14 | uint32_t revbits(uint32_t w); 15 | IPMap *mkipmap(void); 16 | void freeipmap(IPMap *map, void (*freedatum)(void *)); 17 | int ipmapdo_preorder(IPMap *map, int (*thunk)(uint32_t key, size_t keylen, void *datum, void *arg), void *arg); 18 | int ipmapdo_inorder(IPMap *map, int (*thunk)(uint32_t key, size_t keylen, void *datum, void *arg), void *arg); 19 | int ipmapdo_postorder(IPMap *map, int (*thunk)(uint32_t key, size_t keylen, void *datum, void *arg), void *arg); 20 | void ipmapdo(IPMap *map, void (*thunk)(uint32_t key, size_t keylen, void *datum, void *arg), void *arg); 21 | void *ipmapinsert(IPMap *map, uint32_t key, size_t keylen, void *datum); 22 | void *ipmapremove(IPMap *map, uint32_t key, size_t keylen); 23 | void *ipmapnearest(IPMap *map, uint32_t key, size_t keylen); 24 | void *ipmapfind(IPMap *map, uint32_t key, size_t keylen); 25 | int initsock(const char *restrict iface, const char *restrict group, int port, int rtable); 26 | void initsys(int rtable); 27 | int uptunnel(Tunnel *tunnel, int rdomain, int tunneldomain, uint32_t endpoint); 28 | int downtunnel(Tunnel *tunnel); 29 | int addroute(Route *route, Tunnel *tunnel, int rtable); 30 | int chroute(Route *route, Tunnel *tunnel, int rtable); 31 | int rmroute(Route *route, int rtable); 32 | void ipaddrstr(uint32_t addr, char buf[static INET_ADDRSTRLEN]); 33 | void routestr(Route *route, Tunnel *tunnel, char *buf, size_t size); 34 | Bitvec *mkbitvec(void); 35 | void freebitvec(Bitvec *bits); 36 | int bitget(Bitvec *bits, size_t bit); 37 | void bitset(Bitvec *bits, size_t bit); 38 | void bitclr(Bitvec *bits, size_t bit); 39 | size_t nextbit(Bitvec *bits); 40 | unsigned int strnum(const char *restrict str); 41 | 42 | void initlog(void); 43 | void debug(const char *restrict fmt, ...); 44 | void info(const char *restrict fmt, ...); 45 | void notice(const char *restrict fmt, ...); 46 | void error(const char *restrict fmt, ...); 47 | void fatal(const char *restrict fmt, ...); 48 | 49 | #ifdef USE_COMPAT 50 | void *reallocarray(void *p, size_t nelem, size_t size); 51 | void *recallocarray(void *p, size_t oelem, size_t nelem, size_t size); 52 | #endif // USE_COMPAT 53 | -------------------------------------------------------------------------------- /testnetmask2cidr.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "dat.h" 9 | #include "fns.h" 10 | 11 | void 12 | testn2c(const char *snetmask, int expected) 13 | { 14 | if (netmask2cidr(ntohl(inet_addr(snetmask))) != expected) 15 | printf("netmask2cidr(\"%s\") != %d\n", snetmask, expected); 16 | } 17 | 18 | void 19 | testc2n(int cidr, const char *expected) 20 | { 21 | if (cidr2netmask(cidr) != ntohl(inet_addr(expected))) { 22 | printf("cidr2netmask(%d) != \"%s\"\n", cidr, expected); 23 | printf("cidr2netmask(%d) = %x\n", cidr, cidr2netmask(cidr)); 24 | } 25 | } 26 | 27 | int 28 | main(void) 29 | { 30 | // Test all valid netmasks explicitly. 31 | testn2c("255.255.255.255", 32); 32 | testn2c("255.255.255.254", 31); 33 | testn2c("255.255.255.252", 30); 34 | testn2c("255.255.255.248", 29); 35 | testn2c("255.255.255.240", 28); 36 | testn2c("255.255.255.224", 27); 37 | testn2c("255.255.255.192", 26); 38 | testn2c("255.255.255.128", 25); 39 | testn2c("255.255.255.0", 24); 40 | testn2c("255.255.254.0", 23); 41 | testn2c("255.255.252.0", 22); 42 | testn2c("255.255.248.0", 21); 43 | testn2c("255.255.240.0", 20); 44 | testn2c("255.255.224.0", 19); 45 | testn2c("255.255.192.0", 18); 46 | testn2c("255.255.128.0", 17); 47 | testn2c("255.255.0.0", 16); 48 | testn2c("255.254.0.0", 15); 49 | testn2c("255.252.0.0", 14); 50 | testn2c("255.248.0.0", 13); 51 | testn2c("255.240.0.0", 12); 52 | testn2c("255.224.0.0", 11); 53 | testn2c("255.192.0.0", 10); 54 | testn2c("255.128.0.0", 9); 55 | testn2c("255.0.0.0", 8); 56 | testn2c("254.0.0.0", 7); 57 | testn2c("252.0.0.0", 6); 58 | testn2c("248.0.0.0", 5); 59 | testn2c("240.0.0.0", 4); 60 | testn2c("224.0.0.0", 3); 61 | testn2c("192.0.0.0", 2); 62 | testn2c("128.0.0.0", 1); 63 | testn2c("0.0.0.0", 0); 64 | 65 | testc2n(32, "255.255.255.255"); 66 | testc2n(31, "255.255.255.254"); 67 | testc2n(30, "255.255.255.252"); 68 | testc2n(29, "255.255.255.248"); 69 | testc2n(28, "255.255.255.240"); 70 | testc2n(27, "255.255.255.224"); 71 | testc2n(26, "255.255.255.192"); 72 | testc2n(25, "255.255.255.128"); 73 | testc2n(24, "255.255.255.0"); 74 | testc2n(23, "255.255.254.0"); 75 | testc2n(22, "255.255.252.0"); 76 | testc2n(21, "255.255.248.0"); 77 | testc2n(20, "255.255.240.0"); 78 | testc2n(19, "255.255.224.0"); 79 | testc2n(18, "255.255.192.0"); 80 | testc2n(17, "255.255.128.0"); 81 | testc2n(16, "255.255.0.0"); 82 | testc2n(15, "255.254.0.0"); 83 | testc2n(14, "255.252.0.0"); 84 | testc2n(13, "255.248.0.0"); 85 | testc2n(12, "255.240.0.0"); 86 | testc2n(11, "255.224.0.0"); 87 | testc2n(10, "255.192.0.0"); 88 | testc2n(9, "255.128.0.0"); 89 | testc2n(8, "255.0.0.0"); 90 | testc2n(7, "254.0.0.0"); 91 | testc2n(6, "252.0.0.0"); 92 | testc2n(5, "248.0.0.0"); 93 | testc2n(4, "240.0.0.0"); 94 | testc2n(3, "224.0.0.0"); 95 | testc2n(2, "192.0.0.0"); 96 | testc2n(1, "128.0.0.0"); 97 | testc2n(0, "0.0.0.0"); 98 | 99 | return 0; 100 | } 101 | -------------------------------------------------------------------------------- /testipmapinsert.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "dat.h" 11 | #include "fns.h" 12 | #include "testfns.h" 13 | 14 | typedef struct Entry Entry; 15 | struct Entry { 16 | Entry *next; 17 | uint32_t key; 18 | size_t keylen; 19 | void *datum; 20 | }; 21 | 22 | static void 23 | rdumptree(IPMap *map, int i) 24 | { 25 | char kb[33]; 26 | 27 | if (map == NULL) return; 28 | u32tobin(map->key, map->keylen, kb); 29 | printf("%-*sKey: %s/%zd Datum: %s\n", i, "", 30 | kb, map->keylen, (char *)map->datum); 31 | if (map->left != NULL) { 32 | printf("%-*sLeft:\n", i, ""); 33 | rdumptree(map->left, i + 1); 34 | } 35 | if (map->right != NULL) { 36 | printf("%-*sRight:\n", i, ""); 37 | rdumptree(map->right, i + 1); 38 | } 39 | } 40 | 41 | void 42 | dumptree(IPMap *root) 43 | { 44 | assert(root->datum == NULL); 45 | assert(root->key == 0U); 46 | assert(root->keylen == 0ULL); 47 | printf("Root (no key)\n"); 48 | if (root->left) { 49 | printf("Left:\n"); 50 | rdumptree(root->left, 1); 51 | } 52 | if (root->right) { 53 | printf("Right:\n"); 54 | rdumptree(root->right, 1); 55 | } 56 | } 57 | 58 | int 59 | main(void) 60 | { 61 | IPMap *root; 62 | Entry *entries, *entry, *prev; 63 | void *v, *datum; 64 | size_t keylen; 65 | uint32_t key; 66 | int c; 67 | char buf[256], kb[33]; 68 | 69 | c = 0; 70 | entries = NULL; 71 | root = mkipmap(); 72 | assert(root != NULL); 73 | while (fgets(buf, sizeof buf, stdin) != NULL) { 74 | char *bp = buf; 75 | char *ip = strsep(&bp, " \t\r\n"); 76 | char *subnetmask = strsep(&bp, " \t\r\n"); 77 | assert(ip != NULL); 78 | assert(subnetmask != NULL); 79 | key = mkkey(ip); 80 | keylen = mkkeylen(subnetmask); 81 | snprintf(buf, sizeof buf, "%d", ++c); 82 | datum = strdup(buf); 83 | assert(datum != NULL); 84 | ipmapinsert(root, key, keylen, datum); 85 | v = ipmapfind(root, key, keylen); 86 | if (v != datum) { 87 | u32tobin(revbits(key), keylen, kb); 88 | printf("entry %d.%d.%d.%d/%zd %s = %s expected %s\n", 89 | (key >> 24) & 0xFF, (key >> 16) & 0xFF, 90 | (key >> 8) & 0xFF, key & 0xFF, keylen, 91 | kb, (v == NULL) ? "NULL" : (char *)v, 92 | (datum == NULL) ? "NULL" : (char *)datum); 93 | dumptree(root); 94 | exit(EXIT_FAILURE); 95 | } 96 | entry = calloc(1, sizeof(*entry)); 97 | assert(entry != NULL); 98 | entry->key = key; 99 | entry->keylen = keylen; 100 | entry->datum = datum; 101 | entry->next = entries; 102 | entries = entry; 103 | } 104 | 105 | for (entry = entries; entry != NULL; entry = entry->next) { 106 | v = ipmapfind(root, entry->key, entry->keylen); 107 | datum = entry->datum; 108 | if (v != datum) { 109 | key = entry->key; 110 | u32tobin(revbits(key), entry->keylen, kb); 111 | printf("entry %d.%d.%d.%d/%zd %s = %s expected %s\n", 112 | (key >> 24) & 0xFF, (key >> 16) & 0xFF, 113 | (key >> 8) & 0xFF, key & 0xFF, entry->keylen, 114 | kb, (v == NULL) ? "NULL" : (char *)v, 115 | (datum == NULL) ? "NULL" : (char *)datum); 116 | dumptree(root); 117 | exit(EXIT_FAILURE); 118 | } 119 | } 120 | 121 | prev = NULL; 122 | entry = entries; 123 | while (entry != NULL) { 124 | Entry *current = entry; 125 | entry = entry->next; 126 | current->next = prev; 127 | prev = current; 128 | } 129 | entries = prev; 130 | entry = entries; 131 | while (entry != NULL) { 132 | Entry *tmp = entry; 133 | datum = entry->datum; 134 | v = ipmapremove(root, entry->key, entry->keylen); 135 | if (v != datum) { 136 | key = entry->key; 137 | u32tobin(revbits(key), entry->keylen, kb); 138 | printf("entry %d.%d.%d.%d/%zd %s = %s expected %s\n", 139 | (key >> 24) & 0xFF, (key >> 16) & 0xFF, 140 | (key >> 8) & 0xFF, key & 0xFF, entry->keylen, 141 | kb, (v == NULL) ? "NULL" : (char *)v, 142 | (datum == NULL) ? "NULL" : (char *)datum); 143 | dumptree(root); 144 | exit(EXIT_FAILURE); 145 | } 146 | entry = entry->next; 147 | free(datum); 148 | free(tmp); 149 | for (tmp = entry; tmp != NULL; tmp = tmp->next) { 150 | v = ipmapfind(root, tmp->key, tmp->keylen); 151 | datum = tmp->datum; 152 | if (v != datum) { 153 | key = tmp->key; 154 | u32tobin(revbits(key), tmp->keylen, kb); 155 | printf("entry %d.%d.%d.%d/%zd %s = %s " 156 | "expected %s\n", 157 | (key >> 24) & 0xFF, (key >> 16) & 0xFF, 158 | (key >> 8) & 0xFF, key & 0xFF, 159 | tmp->keylen, 160 | kb, (v == NULL) ? "NULL" : (char *)v, 161 | (datum == NULL) ? "NULL" : (char *)datum); 162 | dumptree(root); 163 | exit(EXIT_FAILURE); 164 | } 165 | } 166 | } 167 | freeipmap(root, free); 168 | 169 | return 0; 170 | } 171 | -------------------------------------------------------------------------------- /openbsd/sys.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "dat.h" 25 | #include "fns.h" 26 | 27 | static int ctlfd = -1; 28 | static int rtfd = -1; 29 | 30 | uint32_t hostmask; 31 | 32 | void 33 | initsys(int rtable) 34 | { 35 | struct in_addr addr; 36 | 37 | ctlfd = socket(AF_INET, SOCK_DGRAM, 0); 38 | if (ctlfd < 0) 39 | fatal("ctl socket: %m"); 40 | rtfd = socket(PF_ROUTE, SOCK_RAW, AF_INET); 41 | if (rtfd < 0) 42 | fatal("route socket: %m"); 43 | if (shutdown(rtfd, SHUT_RD) < 0) 44 | fatal("route shutdown read: %m"); 45 | if (0 && setsockopt(rtfd, SOL_SOCKET, SO_RTABLE, &rtable, sizeof(rtable)) < 0) 46 | fatal("setsockopt rtfd SO_RTABLE: %m"); 47 | 48 | // Create prototype tunnel netmask. 49 | memset(&addr, 0, sizeof(addr)); 50 | inet_pton(AF_INET, "255.255.255.255", &addr); 51 | hostmask = addr.s_addr; 52 | } 53 | 54 | int 55 | initsock(const char *restrict iface, const char *restrict group, int port, int rtable) 56 | { 57 | int sd, on; 58 | uint32_t ifaddr; 59 | struct sockaddr_in sin; 60 | struct ip_mreq mr; 61 | 62 | ifaddr = htonl(INADDR_ANY); 63 | if (strcmp(iface, "*") != 0) { 64 | struct in_addr addr; 65 | memset(&addr, 0, sizeof(addr)); 66 | if (inet_pton(AF_INET, iface, &addr) < 0) 67 | fatal("bad interface address: %m"); 68 | ifaddr = addr.s_addr; 69 | } 70 | 71 | sd = socket(AF_INET, SOCK_DGRAM, 0); 72 | if (sd < 0) 73 | fatal("socket: %m"); 74 | on = 1; 75 | if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) 76 | fatal("setsockopt SO_REUSEADDR: %m"); 77 | // On OpenBSD, we use the `route` command to set the listening rtable. 78 | if (0 && setsockopt(sd, SOL_SOCKET, SO_RTABLE, &rtable, sizeof(rtable)) < 0) 79 | fatal("setsockopt SO_RTABLE: %m"); 80 | memset(&sin, 0, sizeof(sin)); 81 | sin.sin_family = AF_INET; 82 | sin.sin_port = htons(port); 83 | sin.sin_addr.s_addr = ifaddr; 84 | if (bind(sd, (struct sockaddr *)&sin, sizeof(sin)) < 0) 85 | fatal("bind: %m"); 86 | memset(&mr, 0, sizeof(mr)); 87 | inet_pton(AF_INET, group, &mr.imr_multiaddr.s_addr); 88 | mr.imr_interface.s_addr = ifaddr; 89 | if (setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mr, sizeof(mr)) < 0) 90 | fatal("setsockopt IP_ADD_MEMBERSHIP: %m"); 91 | 92 | return sd; 93 | } 94 | 95 | /* 96 | * Bring a tunnel up in routing domain `rdomain`, with 97 | * the tunnel endpoints routing in `tunneldomain`. 98 | * 99 | * Note that the ordering of steps matters here. 100 | * In particular, we cannot configure IP until we 101 | * have marked the tunnel up and running. 102 | * 103 | * The steps to fully configure a new tunnel are, 104 | * in order: 105 | * 106 | * 1. Create the interface. 107 | * 2. Configure the tunnel interface. 108 | * 3. Set the tunnel routing domain. 109 | * 4. Set the interface routing domain. 110 | * 5. Configure the interface up and mark it running. 111 | * 6. Configure IP on the interface. 112 | */ 113 | int 114 | uptunnel(Tunnel *tunnel, int rdomain, int tunneldomain, uint32_t endpoint) 115 | { 116 | struct ifreq ifr; 117 | struct if_laddrreq tr; 118 | struct ifaliasreq ir; 119 | struct sockaddr_in addr; 120 | 121 | assert(tunnel != NULL); 122 | assert(ctlfd >= 0); 123 | 124 | // Zero everything. 125 | memset(&ifr, 0, sizeof(ifr)); 126 | memset(&tr, 0, sizeof(tr)); 127 | memset(&ir, 0, sizeof(ir)); 128 | memset(&addr, 0, sizeof(addr)); 129 | 130 | // Create the interface. 131 | strlcpy(ifr.ifr_name, tunnel->ifname, sizeof(ifr.ifr_name)); 132 | if (ioctl(ctlfd, SIOCIFCREATE, &ifr) < 0) 133 | fatal("create %s failed: %m", tunnel->ifname); 134 | 135 | // Initialize the tunnel. 136 | strlcpy(tr.iflr_name, tunnel->ifname, sizeof(tr.iflr_name)); 137 | 138 | addr.sin_len = sizeof(addr); 139 | addr.sin_family = AF_INET; 140 | addr.sin_addr.s_addr = htonl(tunnel->local); 141 | assert(sizeof(addr) <= sizeof(tr.addr)); 142 | memmove(&tr.addr, &addr, sizeof(addr)); 143 | 144 | addr.sin_addr.s_addr = htonl(tunnel->remote); 145 | assert(sizeof(addr) <= sizeof(tr.dstaddr)); 146 | memmove(&tr.dstaddr, &addr, sizeof(addr)); 147 | 148 | // Configure the tunnel. 149 | if (ioctl(ctlfd, SIOCSLIFPHYADDR, &tr) < 0) { 150 | char local[INET_ADDRSTRLEN], remote[INET_ADDRSTRLEN]; 151 | ipaddrstr(htonl(tunnel->local), local); 152 | ipaddrstr(htonl(tunnel->remote), remote); 153 | fatal("tunnel %s failed (local %s remote %s): %m", 154 | tunnel->ifname, local, remote); 155 | } 156 | 157 | // Set the tunnnel routing domain. 158 | ifr.ifr_rdomainid = tunneldomain; 159 | if (ioctl(ctlfd, SIOCSLIFPHYRTABLE, &ifr) < 0) 160 | fatal("cannot set tunnel routing table %s: %m", 161 | tunnel->ifname); 162 | 163 | // Set the interface routing domain. 164 | ifr.ifr_rdomainid = rdomain; 165 | if (ioctl(ctlfd, SIOCSIFRDOMAIN, &ifr) < 0) 166 | fatal("cannot set interface routing table %s: %m", 167 | tunnel->ifname); 168 | 169 | // Bring the interface up and mark running. 170 | // 171 | // Note that we cannot manually set multicast flags (e.g. 172 | // IFF_ALLMULTI|IFF_MULTICAST) as the kernel does not allow 173 | // userspace programs to modify those flags. 174 | if (ioctl(ctlfd, SIOCGIFFLAGS, &ifr) < 0) 175 | fatal("cannot get flags for %s: %m", tunnel->ifname); 176 | ifr.ifr_flags |= (IFF_UP | IFF_RUNNING); 177 | if (ioctl(ctlfd, SIOCSIFFLAGS, &ifr) < 0) 178 | fatal("cannot set flags for %s: %m", tunnel->ifname); 179 | 180 | // Configure IP on the interface. Ideally, this wouldn't be 181 | // necessary, but the default source address and source addresses 182 | // for ICMP errors are taken from the source side. So we configure 183 | // that with the local 44net address and the remote end with 0 as 184 | // a dummy. 185 | strlcpy(ir.ifra_name, tunnel->ifname, sizeof(ir.ifra_name)); 186 | addr.sin_addr.s_addr = htonl(endpoint); 187 | memmove(&ir.ifra_addr, &addr, sizeof(addr)); 188 | addr.sin_addr.s_addr = htonl(0xFFFFFFFF); 189 | memmove(&ir.ifra_mask, &addr, sizeof(addr)); 190 | if (ioctl(ctlfd, SIOCAIFADDR, &ir) < 0) 191 | fatal("dummy inet %s failed: %m", tunnel->ifname); 192 | 193 | return 0; 194 | } 195 | 196 | int 197 | downtunnel(Tunnel *tunnel) 198 | { 199 | struct ifreq ifr; 200 | 201 | assert(tunnel != NULL); 202 | assert(ctlfd >= 0); 203 | memset(&ifr, 0, sizeof(ifr)); 204 | strlcpy(ifr.ifr_name, tunnel->ifname, sizeof(ifr.ifr_name)); 205 | if (ioctl(ctlfd, SIOCIFDESTROY, &ifr) < 0) 206 | fatal("destroying %s failed: %m", tunnel->ifname); 207 | 208 | return 0; 209 | } 210 | 211 | typedef struct Routemsg Routemsg; 212 | struct Routemsg { 213 | alignas(long) struct rt_msghdr header; 214 | alignas(long) struct sockaddr_in dst; 215 | alignas(long) struct sockaddr_dl gw; 216 | alignas(long) struct sockaddr_in netmask; 217 | }; 218 | 219 | static size_t 220 | mkrtmsg(int cmd, Route *route, Tunnel *tunnel, int rtable, Routemsg *msg) 221 | { 222 | static int seqno = 0; 223 | struct rt_msghdr *header; 224 | struct sockaddr_in *dst, *netmask; 225 | struct sockaddr_dl *gw; 226 | 227 | assert(route != NULL); 228 | assert(rtable >= 0); 229 | assert(msg != NULL); 230 | 231 | memset(msg, 0, sizeof(*msg)); 232 | header = &msg->header; 233 | header->rtm_msglen = sizeof(*msg); 234 | header->rtm_version = RTM_VERSION; 235 | header->rtm_type = cmd; 236 | header->rtm_hdrlen = sizeof(*header); 237 | header->rtm_tableid = rtable; 238 | header->rtm_addrs = RTA_DST | RTA_NETMASK; 239 | if (cmd != RTM_DELETE) 240 | header->rtm_addrs |= RTA_GATEWAY; 241 | header->rtm_flags = RTF_UP | RTF_CLONING /* | RTF_LLINFO | RTF_CONNECTED*/; 242 | header->rtm_fmask = 0; 243 | header->rtm_pid = getpid(); 244 | header->rtm_seq = seqno++; 245 | if (seqno == INT_MAX) 246 | seqno = 0; 247 | 248 | dst = &msg->dst; 249 | dst->sin_len = sizeof(*dst); 250 | dst->sin_family = AF_INET; 251 | dst->sin_addr.s_addr = htonl(route->ipnet); 252 | 253 | // XXX: copy this into a manually aligned byte buffer. 254 | // This is surely undefined behavior. 255 | netmask = (struct sockaddr_in *)&msg->gw; 256 | if (cmd != RTM_DELETE) { 257 | netmask = &msg->netmask; 258 | gw = &msg->gw; 259 | gw->sdl_len = sizeof(*gw); 260 | gw->sdl_family = AF_LINK; 261 | gw->sdl_index = if_nametoindex(tunnel->ifname); 262 | } 263 | 264 | netmask->sin_len = sizeof(*netmask); 265 | netmask->sin_family = AF_INET; 266 | netmask->sin_addr.s_addr = htonl(route->subnetmask); 267 | 268 | if (cmd == RTM_DELETE) 269 | header->rtm_msglen -= sizeof(*gw); 270 | 271 | if (route->subnetmask == hostmask) 272 | header->rtm_flags |= RTF_HOST; 273 | 274 | return header->rtm_msglen; 275 | } 276 | 277 | int 278 | addroute(Route *route, Tunnel *tunnel, int rtable) 279 | { 280 | Routemsg rtmsg; 281 | size_t len; 282 | 283 | len = mkrtmsg(RTM_ADD, route, tunnel, rtable, &rtmsg); 284 | if (write(rtfd, &rtmsg, len) != len) { 285 | char proute[128]; 286 | routestr(route, tunnel, proute, sizeof(proute)); 287 | error("route add failure (%s): %m", proute); 288 | } 289 | 290 | return 0; 291 | } 292 | 293 | int 294 | chroute(Route *route, Tunnel *tunnel, int rtable) 295 | { 296 | Routemsg rtmsg; 297 | size_t len; 298 | 299 | len = mkrtmsg(RTM_CHANGE, route, tunnel, rtable, &rtmsg); 300 | if (write(rtfd, &rtmsg, len) != len) { 301 | if (errno == ESRCH) { 302 | rmroute(route, rtable); 303 | return addroute(route, tunnel, rtable); 304 | } 305 | char proute[128]; 306 | routestr(route, tunnel, proute, sizeof(proute)); 307 | error("route change failure (%s): %m", proute); 308 | } 309 | 310 | return 0; 311 | } 312 | 313 | int 314 | rmroute(Route *route, int rtable) 315 | { 316 | Routemsg rtmsg; 317 | size_t len; 318 | 319 | len = mkrtmsg(RTM_DELETE, route, NULL, rtable, &rtmsg); 320 | if (write(rtfd, &rtmsg, len) != len) 321 | if (errno != ESRCH) { 322 | char proute[128]; 323 | routestr(route, NULL, proute, sizeof(proute)); 324 | error("route remove failure (%s): %m", proute); 325 | } 326 | 327 | return 0; 328 | } 329 | 330 | void 331 | ipaddrstr(uint32_t addr, char buf[static INET_ADDRSTRLEN]) 332 | { 333 | addr = htonl(addr); 334 | inet_ntop(AF_INET, &addr, buf, INET_ADDRSTRLEN); 335 | } 336 | 337 | void 338 | routestr(Route *route, Tunnel *tunnel, char *buf, size_t size) 339 | { 340 | char gw[INET_ADDRSTRLEN], proute[INET_ADDRSTRLEN]; 341 | size_t cidr; 342 | 343 | assert(route != NULL); 344 | cidr = netmask2cidr(ntohl(route->subnetmask)); 345 | ipaddrstr(ntohl(route->ipnet), proute); 346 | ipaddrstr(ntohl(route->gateway), gw); 347 | 348 | assert(buf != NULL); 349 | snprintf(buf, size, "%s/%zu -> %s", proute, cidr, gw); 350 | if (tunnel != NULL) { 351 | assert(tunnel->ifname != NULL); 352 | strlcat(buf, " on ", size); 353 | strlcat(buf, tunnel->ifname, size); 354 | } 355 | } 356 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This is an OpenBSD daemon for a modified version of the RIPv2 3 | * protocol (RFC 2453). It is designed to handle route and 4 | * tunnel maintenance for the AMPR amateur radio network 5 | * (IPv4 44/8: http://www.ampr.org). Note that the AMPRNet is a 6 | * mesh: each site sets up IPENCAP tunnels to (almost) all other 7 | * sites. 8 | * 9 | * The daemon listens on a multicast socket for UDP datagrams 10 | * directed to the RIP port. It discards packets that are not 11 | * valid, authenticated RIP packets (though authentication is 12 | * simply string comparison against a plaintext password: it is 13 | * not particularly strong and could be trivially broken). It 14 | * maintains an internal copy of the AMPRNet routing table as 15 | * well as a set of active tunnels. 16 | * 17 | * After processing a RIP packet, the daemon walks through the 18 | * routing table, looking for routes to expire. If a route 19 | * expires it is noted for removal from the table. Expiration 20 | * time is much greater than the expected interval between 21 | * RIP broadcasts. 22 | * 23 | * Routes keep a reference to a tunnel. When a route is added 24 | * that refers to an non-existent tunnel, the tunnel is created 25 | * and set up. If a route referring to a tunnel is removed or 26 | * changed to a different tunnel, the tunnel's reference count 27 | * is decremented. If a tunnel's reference count drops to zero, 28 | * it is torn down and removed. 29 | * 30 | * Each tunnel corresponds to a virtual IP encapsulation 31 | * interface; see gif(4) for details. The daemon dynamically 32 | * creates and destroys these interfaces as required. A bitmap 33 | * of active interfaces is kept and the lowest unused interface 34 | * number is always allocated when a new tunnel is created. 35 | */ 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | 51 | #include "dat.h" 52 | #include "fns.h" 53 | 54 | int init(int argc, char *argv[]); 55 | void riptide(int sd); 56 | void ripresponse(RIPResponse *response, time_t now); 57 | Route *mkroute(uint32_t ipnet, uint32_t subnetmask, uint32_t gateway); 58 | Tunnel *mktunnel(uint32_t local, uint32_t remote); 59 | void alloctunif(Tunnel *tunnel, Bitvec *interfaces); 60 | void unlinkroute(Tunnel *tunnel, Route *route); 61 | void linkroute(Tunnel *tunnel, Route *route); 62 | void walkexpired(time_t now); 63 | void destroy(uint32_t key, size_t keylen, void *routep, void *unused); 64 | void collapse(Tunnel *tunnel); 65 | void expire(uint32_t key, size_t keylen, void *routep, void *statep); 66 | void usage(const char *restrict prog); 67 | 68 | enum { 69 | CIDR_HOST = 32, 70 | RIPV2_PORT = 520, 71 | DEFAULT_ROUTE_TABLE = 44, 72 | //TIMEOUT = 7*24*60*60, // 7 days 73 | TIMEOUT = 15*60, // 15 minutes. 74 | }; 75 | 76 | const char *DEFAULT_LOCAL_ADDRESS = "23.30.150.141"; 77 | const char *DEFAULT_LOCAL_44ADDRESS = "44.44.48.1"; 78 | const char *DEFAULT_GATEWAY_ADDRESS = "169.228.34.84"; 79 | const char *RIPV2_GROUP = "224.0.0.9"; 80 | const char *PASSWORD = "pLaInTeXtpAsSwD"; 81 | 82 | IPMap *ignoreroutes; 83 | IPMap *routes; 84 | IPMap *tunnels; 85 | Bitvec *interfaces; 86 | Bitvec *staticinterfaces; 87 | 88 | const char *prog; 89 | uint32_t localaddr; 90 | uint32_t local44addr; 91 | uint32_t defgwaddr; 92 | int routedomain; 93 | int tunneldomain; 94 | int lowgif; 95 | 96 | int 97 | main(int argc, char *argv[]) 98 | { 99 | int sd; 100 | 101 | sd = init(argc, argv); 102 | for (;;) 103 | riptide(sd); 104 | close(sd); 105 | 106 | return 0; 107 | } 108 | 109 | int 110 | init(int argc, char *argv[]) 111 | { 112 | const char *localip, *local44; 113 | char *iface = "*"; 114 | char *slash; 115 | int sd, ch, daemonize; 116 | struct in_addr addr; 117 | 118 | slash = strrchr(argv[0], '/'); 119 | prog = (slash == NULL) ? argv[0] : slash + 1; 120 | daemonize = 1; 121 | interfaces = mkbitvec(); 122 | staticinterfaces = mkbitvec(); 123 | routedomain = DEFAULT_ROUTE_TABLE; 124 | tunneldomain = DEFAULT_ROUTE_TABLE; 125 | local44 = DEFAULT_LOCAL_44ADDRESS; 126 | localip = DEFAULT_LOCAL_ADDRESS; 127 | routes = mkipmap(); 128 | tunnels = mkipmap(); 129 | while ((ch = getopt(argc, argv, "dD:T:L:i:I:s:")) != -1) { 130 | switch (ch) { 131 | case 'd': 132 | daemonize = 0; 133 | break; 134 | case 'T': 135 | tunneldomain = strnum(optarg); 136 | break; 137 | case 'D': 138 | routedomain = strnum(optarg); 139 | break; 140 | case 'l': 141 | local44 = optarg; 142 | break; 143 | case 'L': 144 | localip = optarg; 145 | break; 146 | case 'i': 147 | iface = optarg; 148 | break; 149 | case 'I': { 150 | static void *IGNORE = (void *)0x10; // Arbitrary. 151 | uint32_t iroute; 152 | size_t icidr; 153 | 154 | slash = strchr(optarg, '/'); 155 | if (slash == NULL) 156 | fatal("Bad route (use CIDR): %s\n", optarg); 157 | *slash++ = '\0'; 158 | iroute = strnum(optarg); 159 | icidr = strnum(slash); 160 | ipmapinsert(ignoreroutes, iroute, icidr, IGNORE); 161 | break; 162 | } 163 | case 's': { 164 | unsigned int ifnum = strnum(optarg); 165 | bitset(staticinterfaces, ifnum); 166 | bitset(interfaces, ifnum); 167 | break; 168 | } 169 | case '?': 170 | case 'h': 171 | default: 172 | usage(prog); 173 | } 174 | } 175 | initsys(routedomain); 176 | sd = initsock(iface, RIPV2_GROUP, RIPV2_PORT, routedomain); 177 | 178 | memset(&addr, 0, sizeof(addr)); 179 | inet_pton(AF_INET, localip, &addr); 180 | localaddr = ntohl(addr.s_addr); 181 | 182 | memset(&addr, 0, sizeof(addr)); 183 | inet_pton(AF_INET, local44, &addr); 184 | local44addr = ntohl(addr.s_addr); 185 | 186 | memset(&addr, 0, sizeof(addr)); 187 | inet_pton(AF_INET, DEFAULT_GATEWAY_ADDRESS, &addr); 188 | defgwaddr = ntohl(addr.s_addr); 189 | 190 | if (daemonize) { 191 | const int chdiryes = 0; 192 | const int closeyes = 0; 193 | daemon(chdiryes, closeyes); 194 | } 195 | initlog(); 196 | 197 | return sd; 198 | } 199 | 200 | void 201 | riptide(int sd) 202 | { 203 | struct sockaddr *rem; 204 | struct sockaddr_in remote; 205 | socklen_t remotelen; 206 | ssize_t n; 207 | time_t now; 208 | RIPPacket pkt; 209 | octet packet[IP_MAXPACKET]; 210 | 211 | memset(&remote, 0, sizeof(remote)); 212 | remotelen = 0; 213 | rem = (struct sockaddr *)&remote; 214 | n = recvfrom(sd, packet, sizeof(packet), 0, rem, &remotelen); 215 | if (n < 0) 216 | fatal("socket error"); 217 | memset(&pkt, 0, sizeof(pkt)); 218 | if (parserippkt(packet, n, &pkt) < 0) { 219 | error("packet parse error\n"); 220 | return; 221 | } 222 | if (verifyripauth(&pkt, PASSWORD) < 0) { 223 | error("packet authentication failed\n"); 224 | return; 225 | } 226 | now = time(NULL); 227 | for (int k = 0; k < pkt.nresponse; k++) { 228 | RIPResponse response; 229 | memset(&response, 0, sizeof(response)); 230 | if (parseripresponse(&pkt, k, &response) < 0) { 231 | notice("bad response, index %d\n", k); 232 | continue; 233 | } 234 | ripresponse(&response, now); 235 | } 236 | walkexpired(now); 237 | } 238 | 239 | void 240 | ripresponse(RIPResponse *response, time_t now) 241 | { 242 | Route *route; 243 | Tunnel *tunnel; 244 | size_t cidr; 245 | char proute[INET_ADDRSTRLEN], gw[INET_ADDRSTRLEN]; 246 | 247 | cidr = netmask2cidr(response->subnetmask); 248 | ipaddrstr(response->ipaddr, proute); 249 | ipaddrstr(response->nexthop, gw); 250 | if (response->ipaddr & ~response->subnetmask) 251 | error("route ipaddr %s has more bits than netmask, %zu", 252 | proute, cidr); 253 | response->ipaddr &= response->subnetmask; 254 | if (response->nexthop == localaddr) { 255 | notice("skipping route for %s/%zu to local address", 256 | proute, cidr); 257 | return; 258 | } 259 | if ((response->nexthop & response->ipaddr) == response->nexthop) { 260 | error("skipping gateway inside of subnet (%s/%zu -> %s)", 261 | proute, cidr, gw); 262 | return; 263 | } 264 | tunnel = ipmapfind(tunnels, response->nexthop, CIDR_HOST); 265 | if (tunnel == NULL && defgwaddr != response->nexthop) { 266 | tunnel = mktunnel(localaddr, response->nexthop); 267 | alloctunif(tunnel, interfaces); 268 | uptunnel(tunnel, routedomain, tunneldomain, local44addr); 269 | ipmapinsert(tunnels, response->nexthop, CIDR_HOST, tunnel); 270 | } 271 | route = ipmapfind(routes, response->ipaddr, cidr); 272 | if (route == NULL) { 273 | route = mkroute( 274 | response->ipaddr, 275 | response->subnetmask, 276 | response->nexthop); 277 | ipmapinsert(routes, route->ipnet, cidr, route); 278 | info("Added route %s/%zu -> %s", proute, cidr, gw); 279 | } 280 | // The route is new or moved to a different tunnel. 281 | if (route->tunnel != tunnel) { 282 | if (route->tunnel == NULL) 283 | addroute(route, tunnel, routedomain); 284 | else 285 | chroute(route, tunnel, routedomain); 286 | unlinkroute(tunnel, route); 287 | unlinkroute(route->tunnel, route); 288 | collapse(route->tunnel); 289 | linkroute(tunnel, route); 290 | } 291 | route->expires = now + TIMEOUT; 292 | debug("RIPv2 response: %s/%zu -> %s", proute, cidr, gw); 293 | } 294 | 295 | Route * 296 | mkroute(uint32_t ipnet, uint32_t subnetmask, uint32_t gateway) 297 | { 298 | Route *route; 299 | 300 | route = calloc(1, sizeof(*route)); 301 | if (route == NULL) 302 | fatal("malloc"); 303 | route->ipnet = ipnet; 304 | route->subnetmask = subnetmask; 305 | route->gateway = gateway; 306 | 307 | return route; 308 | } 309 | 310 | Tunnel * 311 | mktunnel(uint32_t local, uint32_t remote) 312 | { 313 | Tunnel *tunnel; 314 | 315 | tunnel = calloc(1, sizeof(*tunnel)); 316 | if (tunnel == NULL) 317 | fatal("malloc"); 318 | tunnel->local = local; 319 | tunnel->remote = remote; 320 | 321 | return tunnel; 322 | } 323 | 324 | void 325 | alloctunif(Tunnel *tunnel, Bitvec *interfaces) 326 | { 327 | size_t ifnum; 328 | 329 | ifnum = nextbit(interfaces); 330 | tunnel->ifnum = ifnum; 331 | snprintf(tunnel->ifname, sizeof(tunnel->ifname), "gif%zu", ifnum); 332 | bitset(interfaces, ifnum); 333 | info("Allocating tunnel interface %s", tunnel->ifname); 334 | } 335 | 336 | void 337 | unlinkroute(Tunnel *tunnel, Route *route) 338 | { 339 | if (tunnel == NULL) 340 | return; 341 | for (Route *prev = NULL, *tmp = tunnel->routes; 342 | tmp != NULL; 343 | prev = tmp, tmp = tmp->rnext) 344 | { 345 | if (route->ipnet == tmp->ipnet && 346 | route->subnetmask == tmp->subnetmask) 347 | { 348 | if (prev == NULL) 349 | tunnel->routes = tmp->rnext; 350 | else 351 | prev->rnext = tmp->rnext; 352 | route->gateway = 0; 353 | --tunnel->nref; 354 | break; 355 | } 356 | } 357 | } 358 | 359 | void 360 | linkroute(Tunnel *tunnel, Route *route) 361 | { 362 | route->rnext = tunnel->routes; 363 | tunnel->routes = route; 364 | route->tunnel = tunnel; 365 | route->gateway = tunnel->remote; 366 | ++tunnel->nref; 367 | } 368 | 369 | typedef struct WalkState WalkState; 370 | struct WalkState { 371 | time_t now; 372 | IPMap *deleting; 373 | }; 374 | 375 | void 376 | walkexpired(time_t now) 377 | { 378 | WalkState state = { now, NULL }; 379 | 380 | ipmapdo(routes, expire, &state); 381 | if (state.deleting != NULL) { 382 | ipmapdo(state.deleting, destroy, NULL); 383 | freeipmap(state.deleting, free); 384 | } 385 | } 386 | 387 | void 388 | expire(uint32_t key, size_t keylen, void *routep, void *statep) 389 | { 390 | Route *route = routep; 391 | WalkState *state = statep; 392 | size_t cidr; 393 | char proute[INET_ADDRSTRLEN], gw[INET_ADDRSTRLEN]; 394 | 395 | if (route->expires > state->now) 396 | return; 397 | 398 | if (state->deleting == NULL) 399 | state->deleting = mkipmap(); 400 | cidr = netmask2cidr(route->subnetmask); 401 | assert(cidr == keylen); 402 | ipaddrstr(route->ipnet, proute); 403 | ipaddrstr(route->gateway, gw); 404 | info("Expiring route %s/%zu -> %s", proute, cidr, gw); 405 | ipmapinsert(state->deleting, key, keylen, route); 406 | } 407 | 408 | void 409 | destroy(uint32_t key, size_t keylen, void *routep, void *unused) 410 | { 411 | Route *route = routep; 412 | Tunnel *tunnel; 413 | void *datum; 414 | size_t cidr; 415 | char proute[INET_ADDRSTRLEN], gw[INET_ADDRSTRLEN]; 416 | 417 | (void)unused; 418 | if (route == NULL) 419 | return; 420 | cidr = netmask2cidr(route->subnetmask); 421 | assert(cidr == keylen); 422 | ipaddrstr(route->ipnet, proute); 423 | ipaddrstr(route->gateway, gw); 424 | info("Destroying route %s/%zu -> %s", proute, cidr, gw); 425 | datum = ipmapremove(routes, key, keylen); 426 | assert(datum == route); 427 | tunnel = route->tunnel; 428 | assert(tunnel != NULL); 429 | unlinkroute(tunnel, route); 430 | rmroute(route, routedomain); 431 | collapse(tunnel); 432 | } 433 | 434 | void 435 | collapse(Tunnel *tunnel) 436 | { 437 | if (tunnel == NULL) 438 | return; 439 | assert(tunnel->nref >= 0); 440 | if (tunnel->nref == 0) { 441 | void *datum = ipmapremove(tunnels, tunnel->remote, CIDR_HOST); 442 | assert(datum == tunnel); 443 | info("Tearing down tunnel interface %s", tunnel->ifname); 444 | downtunnel(tunnel); 445 | bitclr(interfaces, tunnel->ifnum); 446 | free(tunnel); 447 | } 448 | } 449 | 450 | void 451 | usage(const char *restrict prog) 452 | { 453 | fprintf(stderr, 454 | "Usage: %s [ -d ] [ -T rtable ] [ -L local_ip ] " 455 | "[ -I ignore ] [ -s static_ifnum ]\n", 456 | prog); 457 | exit(EXIT_FAILURE); 458 | } 459 | -------------------------------------------------------------------------------- /lib.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "dat.h" 10 | #include "fns.h" 11 | 12 | uint32_t 13 | readnet32(const octet data[static 4]) 14 | { 15 | return data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; 16 | } 17 | 18 | uint16_t 19 | readnet16(const octet data[static 2]) 20 | { 21 | return data[0] << 8 | data[1]; 22 | } 23 | 24 | /* 25 | * If 'netmask' is a valid IPv4 network mask, then '(1 + ~netmask)' will 26 | * be a power of two. If 'p' is a power of two, then 'p & (p - 1)' will 27 | * be zero. If 'p' is '~netmask + 1' then 'p - 1' is simply '~netmask'. 28 | */ 29 | bool 30 | isvalidnetmask(uint32_t netmask) 31 | { 32 | return ((~netmask + 1) & ~netmask) == 0; 33 | } 34 | 35 | unsigned int 36 | netmask2cidr(uint32_t netmask) 37 | { 38 | int cidr = 32; 39 | 40 | if (!isvalidnetmask(netmask)) return -1; 41 | while (cidr > 0 && (netmask & 0x01) == 0) { 42 | netmask >>= 1; 43 | cidr--; 44 | } 45 | 46 | return cidr; 47 | } 48 | 49 | uint32_t 50 | cidr2netmask(unsigned int cidr) 51 | { 52 | if (cidr == 0) 53 | return 0; 54 | if (cidr > 32) 55 | return ~0U; 56 | 57 | return ~0U << (32 - cidr); 58 | } 59 | 60 | /* 61 | * Reverse the bits of an unsigned 32-bit integer. See Hacker's 62 | * Delight, second edition, for more details. 63 | */ 64 | uint32_t 65 | revbits(uint32_t w) 66 | { 67 | w = (w & 0x55555555) << 1 | ((w >> 1) & 0x55555555); 68 | w = (w & 0x33333333) << 2 | ((w >> 2) & 0x33333333); 69 | w = (w & 0x0F0F0F0F) << 4 | ((w >> 4) & 0x0F0F0F0F); 70 | w = w << 24 | (w & 0xFF00) << 8 | ((w >> 8) & 0xFF00) | w >> 24; 71 | return w; 72 | } 73 | 74 | void * 75 | ipmapnearest(IPMap *map, uint32_t key, size_t keylen) 76 | { 77 | uint32_t rkey = revbits(key); 78 | IPMap *parent = NULL; 79 | 80 | while (map != NULL && map->keylen <= keylen) { 81 | uint32_t rkeymask = (1 << map->keylen) - 1; 82 | uint32_t rkeyfrag = rkey & rkeymask; 83 | if (map->key != rkeyfrag) 84 | break; 85 | rkey >>= map->keylen; 86 | keylen -= map->keylen; 87 | if (map->datum != NULL) 88 | parent = map; 89 | if (keylen == 0) 90 | break; 91 | map = (rkey & 0x01) ? map->right : map->left; 92 | } 93 | if (parent == NULL) 94 | return NULL; 95 | 96 | return parent->datum; 97 | } 98 | 99 | void * 100 | ipmapfind(IPMap *map, uint32_t key, size_t keylen) 101 | { 102 | uint32_t rkey = revbits(key); 103 | 104 | while (map != NULL && map->keylen <= keylen) { 105 | uint32_t rkeymask = (1 << map->keylen) - 1; 106 | uint32_t rkeyfrag = rkey & rkeymask; 107 | if (map->key != rkeyfrag) 108 | break; 109 | rkey >>= map->keylen; 110 | keylen -= map->keylen; 111 | if (keylen == 0) 112 | return map->datum; 113 | map = (rkey & 0x01) ? map->right : map->left; 114 | } 115 | 116 | return NULL; 117 | } 118 | 119 | static IPMap * 120 | mknode(uint32_t key, size_t keylen, void *datum) 121 | { 122 | IPMap *newnode; 123 | 124 | newnode = calloc(1, sizeof(*newnode)); 125 | if (newnode == NULL) 126 | fatal("malloc failed"); 127 | newnode->key = key; 128 | newnode->keylen = keylen; 129 | newnode->datum = datum; 130 | newnode->left = NULL; 131 | newnode->right = NULL; 132 | 133 | return newnode; 134 | } 135 | 136 | // Return the number of common low-order bits in 'a' and 'b'. 137 | static size_t 138 | cprefix(size_t n, uint32_t a, uint32_t b) 139 | { 140 | size_t bits; 141 | 142 | bits = 0; 143 | while (n-- > 0 && (a & 0x01) == (b & 0x01)) { 144 | a >>= 1; 145 | b >>= 1; 146 | bits++; 147 | } 148 | 149 | return bits; 150 | } 151 | 152 | static inline size_t 153 | nmin(size_t a, size_t b) 154 | { 155 | return (a < b) ? a : b; 156 | } 157 | 158 | IPMap * 159 | mkipmap(void) 160 | { 161 | return mknode(0, 0, NULL); 162 | } 163 | 164 | void 165 | freeipmap(IPMap *map, void (*freedatum)(void *datum)) 166 | { 167 | if (map == NULL) return; 168 | freeipmap(map->left, freedatum); 169 | freeipmap(map->right, freedatum); 170 | if (map->datum != NULL) 171 | freedatum(map->datum); 172 | free(map); 173 | } 174 | 175 | void * 176 | ipmapinsert(IPMap *root, uint32_t key, size_t keylen, void *datum) 177 | { 178 | IPMap *map; 179 | uint32_t rkey = revbits(key); // Reverse key bits. 180 | 181 | map = root; 182 | while (map != NULL) { 183 | IPMap *node = NULL, *newchild = NULL; 184 | size_t nkcp = 0; // Common prefix bits. 185 | 186 | if (keylen == map->keylen && rkey == map->key) { 187 | if (map->datum == NULL) 188 | map->datum = datum; 189 | return map->datum; 190 | } 191 | nkcp = cprefix(nmin(keylen, map->keylen), rkey, map->key); 192 | if (nkcp == 0 || nkcp == map->keylen) { 193 | assert(nkcp < keylen); 194 | rkey >>= nkcp; 195 | keylen -= nkcp; 196 | node = ((rkey & 0x01) == 0) ? map->left : map->right; 197 | if (node != NULL) { 198 | map = node; 199 | continue; 200 | } 201 | if ((rkey & 0x01) == 0) { 202 | assert(map->left == NULL); 203 | map->left = mknode(rkey, keylen, datum); 204 | } else { 205 | assert(map->right == NULL); 206 | map->right = mknode(rkey, keylen, datum); 207 | } 208 | return datum; 209 | } 210 | if (nkcp == keylen) { 211 | uint32_t tkey = map->key >> keylen; 212 | assert(nkcp < map->keylen); 213 | node = mknode(tkey, map->keylen - keylen, map->datum); 214 | node->left = map->left; 215 | node->right = map->right; 216 | map->key = rkey; 217 | map->keylen = keylen; 218 | map->datum = datum; 219 | if ((tkey & 0x01) == 0) { 220 | map->left = node; 221 | map->right = NULL; 222 | } else { 223 | map->left = NULL; 224 | map->right = node; 225 | } 226 | return datum; 227 | } 228 | 229 | assert(nkcp < map->keylen); 230 | assert(nkcp < keylen); 231 | newchild = mknode(map->key >> nkcp, 232 | map->keylen - nkcp, 233 | map->datum); 234 | newchild->left = map->left; 235 | newchild->right = map->right; 236 | node = mknode(rkey >> nkcp, keylen - nkcp, datum); 237 | map->key = rkey & ((1 << nkcp) - 1); 238 | map->keylen = nkcp; 239 | map->datum = NULL; 240 | if (newchild->key & 0x01) { 241 | assert((node->key & 0x01) == 0); 242 | map->left = node; 243 | map->right = newchild; 244 | } else { 245 | assert((node->key & 0x01) == 1); 246 | map->left = newchild; 247 | map->right = node; 248 | } 249 | return datum; 250 | } 251 | 252 | return NULL; 253 | } 254 | 255 | void * 256 | ipmapremove(IPMap *root, uint32_t key, size_t akeylen) 257 | { 258 | IPMap *map, *parent, **pmap; 259 | uint32_t rkey = revbits(key); // Reverse key bits. 260 | size_t keylen = akeylen; 261 | char pkey[INET_ADDRSTRLEN]; 262 | 263 | ipaddrstr(key, pkey); 264 | pmap = NULL; 265 | parent = NULL; 266 | map = root; 267 | while (map != NULL) { 268 | size_t nkcp = 0; // Common prefix bits. 269 | 270 | if (keylen == map->keylen && rkey == map->key) { 271 | void *datum = map->datum; 272 | 273 | if (map->left != NULL && map->right != NULL) { 274 | map->datum = NULL; 275 | } else if (map->left == NULL && map->right == NULL) { 276 | IPMap *child; 277 | 278 | // If not root, nil our parent's pointer to us. 279 | if (pmap != NULL) 280 | *pmap = NULL; 281 | map->datum = NULL; 282 | 283 | // Don't free the root; it is stable. 284 | if (map != root) 285 | free(map); 286 | 287 | // If we are the root, or our parent has data, 288 | // skip the rest of the logic and return the 289 | // datum. 290 | if (parent == NULL || parent->datum != NULL) 291 | return datum; 292 | 293 | // We nil'ed ourself out of the parent, find 294 | // the parent's other (possibly-nil) child. 295 | child = (parent->left != NULL) ? 296 | parent->left : parent->right; 297 | 298 | // If it is nil, skip the rest of the logic. 299 | if (child == NULL) 300 | return datum; 301 | 302 | // Otherwise, pull the child into the parent: 303 | // Combine the keys, set datum to the child's 304 | // datum, and reset the left and right child 305 | // pointers to the child's. Finally, free 306 | // the child node. 307 | parent->key |= (child->key << parent->keylen); 308 | parent->keylen += child->keylen; 309 | parent->datum = child->datum; 310 | parent->left = child->left; 311 | parent->right = child->right; 312 | free(child); 313 | } else { 314 | IPMap *child = (map->left != NULL) ? 315 | map->left : map->right; 316 | assert(child != NULL); 317 | map->key |= (child->key << map->keylen); 318 | map->keylen += child->keylen; 319 | map->datum = child->datum; 320 | map->left = child->left; 321 | map->right = child->right; 322 | free(child); 323 | } 324 | 325 | return datum; 326 | } 327 | nkcp = cprefix(nmin(keylen, map->keylen), rkey, map->key); 328 | if (nkcp != 0 && nkcp != map->keylen) { 329 | notice("ipmapremove: divergent key for %s/%zu (nkcp = %zu, keylen = %zu)", 330 | pkey, akeylen, nkcp, map->keylen); 331 | return NULL; 332 | } 333 | assert(nkcp < keylen); 334 | rkey >>= nkcp; 335 | keylen -= nkcp; 336 | parent = map; 337 | if ((rkey & 0x01) == 0) { 338 | pmap = &map->left; 339 | map = map->left; 340 | } else { 341 | pmap = &map->right; 342 | map = map->right; 343 | } 344 | } 345 | notice("ipmapremove: key %s/%zu not found", pkey, akeylen); 346 | 347 | return NULL; 348 | } 349 | 350 | enum 351 | { 352 | IPMAP_PREORDER = -1, 353 | IPMAP_INORDER, 354 | IPMAP_POSTORDER, 355 | }; 356 | 357 | static inline int 358 | ipmapdorec(IPMap *map, int order, 359 | uint32_t key, size_t keylen, 360 | int (*thunk)(uint32_t key, size_t keylen, void *datum, void *arg), 361 | void *arg) 362 | { 363 | int r = 0; 364 | 365 | if (map == NULL) return r; 366 | key |= (map->key << keylen); 367 | keylen += map->keylen; 368 | if (order == IPMAP_PREORDER && map->datum != NULL) { 369 | r = thunk(revbits(key), keylen, map->datum, arg); 370 | if (r != 0) return r; 371 | } 372 | r = ipmapdorec(map->left, order, key, keylen, thunk, arg); 373 | if (r != 0) return r; 374 | if (order == IPMAP_INORDER && map->datum != NULL) { 375 | r = thunk(revbits(key), keylen, map->datum, arg); 376 | if (r != 0) return r; 377 | } 378 | r = ipmapdorec(map->right, order, key, keylen, thunk, arg); 379 | if (r != 0) return r; 380 | if (order == IPMAP_POSTORDER && map->datum != NULL) 381 | r = thunk(revbits(key), keylen, map->datum, arg); 382 | 383 | return r; 384 | } 385 | 386 | int 387 | ipmapdo_preorder(IPMap *map, 388 | int (*thunk)(uint32_t key, size_t keylen, void *datum, void *arg), 389 | void *arg) 390 | { 391 | return ipmapdorec(map, IPMAP_PREORDER, 0, 0, thunk, arg); 392 | } 393 | 394 | int 395 | ipmapdo_inorder(IPMap *map, 396 | int (*thunk)(uint32_t key, size_t keylen, void *datum, void *arg), 397 | void *arg) 398 | { 399 | return ipmapdorec(map, IPMAP_INORDER, 0, 0, thunk, arg); 400 | } 401 | 402 | int 403 | ipmapdo_postorder(IPMap *map, 404 | int (*thunk)(uint32_t key, size_t keylen, void *datum, void *arg), 405 | void *arg) 406 | { 407 | return ipmapdorec(map, IPMAP_POSTORDER, 0, 0, thunk, arg); 408 | } 409 | 410 | typedef struct TrampArg TrampArg; 411 | struct TrampArg { 412 | void (*thunk)(uint32_t key, size_t keylen, void *datum, void *arg); 413 | void *arg; 414 | }; 415 | 416 | static int 417 | trampthunk(uint32_t key, size_t keylen, void *datum, void *arg) 418 | { 419 | TrampArg *tramparg = arg; 420 | 421 | if (tramparg == NULL) 422 | return -1; 423 | tramparg->thunk(key, keylen, datum, tramparg->arg); 424 | 425 | return 0; 426 | } 427 | 428 | void 429 | ipmapdo(IPMap *map, 430 | void (*thunk)(uint32_t key, size_t keylen, void *datum, void *arg), 431 | void *arg) 432 | { 433 | TrampArg tramparg; 434 | 435 | memset(&tramparg, 0, sizeof tramparg); 436 | tramparg.thunk = thunk; 437 | tramparg.arg = arg; 438 | 439 | ipmapdo_inorder(map, trampthunk, &tramparg); 440 | } 441 | 442 | Bitvec * 443 | mkbitvec(void) 444 | { 445 | return calloc(1, sizeof(Bitvec)); 446 | } 447 | 448 | void 449 | freebitvec(Bitvec *bits) 450 | { 451 | assert(bits != NULL); 452 | free(bits->words); 453 | free(bits); 454 | } 455 | 456 | void 457 | bitset(Bitvec *bits, size_t bit) 458 | { 459 | uint64_t *words; 460 | size_t word; 461 | 462 | assert(bits != NULL); 463 | word = bit/64; 464 | if (word >= bits->nwords) { 465 | words = recallocarray(bits->words, bits->nwords, word + 1, sizeof(uint64_t)); 466 | if (words == NULL) 467 | fatal("malloc failed"); 468 | bits->words = words; 469 | bits->nwords = word + 1; 470 | } 471 | bits->words[word] |= (1ULL << (bit%64)); 472 | if (bit == bits->firstclr) { 473 | const uint64_t noclr = ~0ULL; 474 | while (word < bits->nwords && bits->words[word] == noclr) 475 | word++; 476 | bits->firstclr = word*64; 477 | } 478 | } 479 | 480 | void 481 | bitclr(Bitvec *bits, size_t bit) 482 | { 483 | size_t word; 484 | 485 | assert(bits != NULL); 486 | word = bit/64; 487 | if (word >= bits->nwords) 488 | return; 489 | bits->words[word] &= ~(1ULL << (bit%64)); 490 | if (bit < bits->firstclr) 491 | bits->firstclr = bit; 492 | } 493 | 494 | int 495 | bitget(Bitvec *bits, size_t bit) 496 | { 497 | size_t word; 498 | 499 | assert(bits != NULL); 500 | word = bit/64; 501 | if (word >= bits->nwords) 502 | return 0; 503 | return (bits->words[word] >> (bit%64)) & 0x01; 504 | } 505 | 506 | size_t 507 | nextbit(Bitvec *bits) 508 | { 509 | assert(bits != NULL); 510 | while (bitget(bits, bits->firstclr) == 1) 511 | ++bits->firstclr; 512 | return bits->firstclr; 513 | } 514 | 515 | enum { 516 | MAX_NUM = (1 << 20), 517 | }; 518 | 519 | unsigned int 520 | strnum(const char *restrict str) 521 | { 522 | char *ep; 523 | unsigned long r; 524 | 525 | ep = NULL; 526 | r = strtoul(str, &ep, 10); 527 | if (ep != NULL && *ep != '\0') 528 | fatal("bad unsigned integer: %s", str); 529 | if (r > MAX_NUM) 530 | fatal("integer range error: %s", str); 531 | 532 | return (unsigned int)r; 533 | } 534 | 535 | void 536 | initlog(void) 537 | { 538 | openlog("44ripd", LOG_CONS | LOG_PERROR | LOG_PID, LOG_LOCAL0); 539 | } 540 | 541 | void 542 | debug(const char *fmt, ...) 543 | { 544 | va_list ap; 545 | va_start(ap, fmt); 546 | vsyslog(LOG_DEBUG, fmt, ap); 547 | va_end(ap); 548 | } 549 | 550 | void 551 | info(const char *fmt, ...) 552 | { 553 | va_list ap; 554 | va_start(ap, fmt); 555 | vsyslog(LOG_INFO, fmt, ap); 556 | va_end(ap); 557 | } 558 | 559 | void 560 | notice(const char *fmt, ...) 561 | { 562 | va_list ap; 563 | va_start(ap, fmt); 564 | vsyslog(LOG_NOTICE, fmt, ap); 565 | va_end(ap); 566 | } 567 | 568 | void 569 | error(const char *fmt, ...) 570 | { 571 | va_list ap; 572 | va_start(ap, fmt); 573 | vsyslog(LOG_ERR, fmt, ap); 574 | va_end(ap); 575 | } 576 | 577 | void 578 | fatal(const char *fmt, ...) 579 | { 580 | va_list ap; 581 | va_start(ap, fmt); 582 | vsyslog(LOG_ERR, fmt, ap); 583 | va_end(ap); 584 | exit(EXIT_FAILURE); 585 | } 586 | -------------------------------------------------------------------------------- /testdata/testipmapinsert.data: -------------------------------------------------------------------------------- 1 | 44.10.0.0 255.255.255.224 2 | 44.10.192.0 255.255.255.0 3 | 44.10.192.1 255.255.255.255 4 | 44.102.1.0 255.255.255.0 5 | 44.102.100.0 255.255.255.0 6 | 44.102.104.0 255.255.255.0 7 | 44.102.128.0 255.255.255.0 8 | 44.102.132.0 255.255.255.0 9 | 44.102.134.0 255.255.255.0 10 | 44.102.166.0 255.255.255.0 11 | 44.102.168.0 255.255.255.0 12 | 44.102.170.0 255.255.254.0 13 | 44.102.172.0 255.255.252.0 14 | 44.102.176.0 255.255.255.0 15 | 44.102.200.0 255.255.252.0 16 | 44.102.216.0 255.255.254.0 17 | 44.102.238.0 255.255.255.0 18 | 44.102.24.0 255.255.255.0 19 | 44.102.48.0 255.255.255.0 20 | 44.102.56.0 255.255.255.0 21 | 44.108.180.0 255.255.255.0 22 | 44.116.3.64 255.255.255.224 23 | 44.118.5.0 255.255.255.248 24 | 44.12.3.128 255.255.255.248 25 | 44.12.3.136 255.255.255.248 26 | 44.12.3.96 255.255.255.224 27 | 44.125.2.0 255.255.255.0 28 | 44.127.192.0 255.255.255.0 29 | 44.129.128.0 255.255.255.0 30 | 44.129.16.0 255.255.255.0 31 | 44.130.0.0 255.255.0.0 32 | 44.130.224.0 255.255.255.240 33 | 44.130.224.32 255.255.255.224 34 | 44.130.240.2 255.255.255.255 35 | 44.130.240.6 255.255.255.255 36 | 44.131.11.0 255.255.255.248 37 | 44.131.121.0 255.255.255.0 38 | 44.131.128.0 255.255.240.0 39 | 44.131.144.0 255.255.252.0 40 | 44.131.151.0 255.255.255.240 41 | 44.131.152.1 255.255.255.255 42 | 44.131.152.2 255.255.255.255 43 | 44.131.156.0 255.255.255.252 44 | 44.131.156.103 255.255.255.255 45 | 44.131.160.0 255.255.255.0 46 | 44.131.161.0 255.255.255.0 47 | 44.131.162.0 255.255.255.0 48 | 44.131.168.128 255.255.255.248 49 | 44.131.170.0 255.255.255.252 50 | 44.131.170.8 255.255.255.248 51 | 44.131.176.0 255.255.255.224 52 | 44.131.182.0 255.255.255.0 53 | 44.131.189.0 255.255.255.248 54 | 44.131.189.8 255.255.255.248 55 | 44.131.210.0 255.255.255.0 56 | 44.131.210.0 255.255.255.255 57 | 44.131.218.0 255.255.255.0 58 | 44.131.218.0 255.255.255.248 59 | 44.131.220.36 255.255.255.252 60 | 44.131.240.0 255.255.255.0 61 | 44.131.241.0 255.255.255.0 62 | 44.131.242.0 255.255.255.0 63 | 44.131.243.0 255.255.255.0 64 | 44.131.244.0 255.255.255.0 65 | 44.131.56.0 255.255.255.248 66 | 44.131.56.8 255.255.255.248 67 | 44.131.68.32 255.255.255.248 68 | 44.131.7.0 255.255.255.0 69 | 44.131.8.0 255.255.255.0 70 | 44.131.8.32 255.255.255.224 71 | 44.131.91.0 255.255.255.0 72 | 44.131.96.32 255.255.255.248 73 | 44.133.128.0 255.255.128.0 74 | 44.133.17.50 255.255.255.255 75 | 44.133.28.155 255.255.255.255 76 | 44.133.3.39 255.255.255.255 77 | 44.133.32.11 255.255.255.255 78 | 44.133.47.10 255.255.255.255 79 | 44.133.47.6 255.255.255.255 80 | 44.133.8.13 255.255.255.255 81 | 44.134.0.0 255.255.240.0 82 | 44.134.128.0 255.255.224.0 83 | 44.134.160.0 255.255.240.0 84 | 44.134.177.0 255.255.255.0 85 | 44.134.178.0 255.255.255.0 86 | 44.134.180.0 255.255.255.0 87 | 44.134.181.0 255.255.255.0 88 | 44.134.185.0 255.255.255.0 89 | 44.134.189.0 255.255.255.0 90 | 44.134.190.0 255.255.254.0 91 | 44.134.192.0 255.255.240.0 92 | 44.134.208.0 255.255.240.0 93 | 44.134.224.0 255.255.240.0 94 | 44.134.240.0 255.255.240.0 95 | 44.134.32.0 255.255.255.0 96 | 44.134.32.233 255.255.255.255 97 | 44.134.32.240 255.255.255.255 98 | 44.134.33.0 255.255.255.0 99 | 44.134.33.71 255.255.255.255 100 | 44.134.34.0 255.255.255.0 101 | 44.134.48.0 255.255.255.0 102 | 44.134.64.0 255.255.224.0 103 | 44.134.96.0 255.255.240.0 104 | 44.135.103.128 255.255.255.252 105 | 44.135.104.128 255.255.255.128 106 | 44.135.105.0 255.255.255.0 107 | 44.135.124.0 255.255.255.0 108 | 44.135.147.0 255.255.255.0 109 | 44.135.156.0 255.255.255.0 110 | 44.135.16.0 255.255.252.0 111 | 44.135.160.40 255.255.255.255 112 | 44.135.186.0 255.255.255.0 113 | 44.135.188.0 255.255.252.0 114 | 44.135.192.160 255.255.255.248 115 | 44.135.192.32 255.255.255.248 116 | 44.135.192.80 255.255.255.248 117 | 44.135.192.96 255.255.255.248 118 | 44.135.193.0 255.255.255.0 119 | 44.135.195.0 255.255.255.0 120 | 44.135.32.0 255.255.255.0 121 | 44.135.43.0 255.255.255.248 122 | 44.135.48.0 255.255.255.0 123 | 44.135.49.0 255.255.255.224 124 | 44.135.50.0 255.255.255.192 125 | 44.135.52.0 255.255.255.0 126 | 44.135.55.0 255.255.255.248 127 | 44.135.56.0 255.255.255.0 128 | 44.135.62.0 255.255.255.192 129 | 44.135.68.0 255.255.255.240 130 | 44.135.71.0 255.255.255.0 131 | 44.135.74.0 255.255.255.240 132 | 44.135.82.0 255.255.255.0 133 | 44.135.83.21 255.255.255.255 134 | 44.135.83.22 255.255.255.255 135 | 44.135.83.23 255.255.255.255 136 | 44.135.83.24 255.255.255.255 137 | 44.135.84.16 255.255.255.240 138 | 44.135.85.0 255.255.255.0 139 | 44.135.85.56 255.255.255.255 140 | 44.135.86.0 255.255.255.0 141 | 44.135.88.0 255.255.255.0 142 | 44.135.89.192 255.255.255.192 143 | 44.135.90.0 255.255.255.0 144 | 44.135.90.128 255.255.255.128 145 | 44.135.90.2 255.255.255.255 146 | 44.135.90.3 255.255.255.255 147 | 44.135.90.42 255.255.255.255 148 | 44.135.91.0 255.255.255.0 149 | 44.135.92.0 255.255.255.0 150 | 44.135.92.128 255.255.255.248 151 | 44.135.93.0 255.255.255.240 152 | 44.135.94.0 255.255.254.0 153 | 44.135.96.64 255.255.255.192 154 | 44.136.0.0 255.255.248.0 155 | 44.136.126.0 255.255.255.0 156 | 44.136.142.240 255.255.255.240 157 | 44.136.16.0 255.255.255.0 158 | 44.136.204.0 255.255.255.0 159 | 44.136.209.0 255.255.255.0 160 | 44.136.224.32 255.255.255.255 161 | 44.136.224.34 255.255.255.255 162 | 44.136.224.44 255.255.255.252 163 | 44.136.227.0 255.255.255.0 164 | 44.136.72.0 255.255.252.0 165 | 44.136.83.0 255.255.255.0 166 | 44.136.83.144 255.255.255.240 167 | 44.136.9.0 255.255.255.0 168 | 44.136.92.0 255.255.255.0 169 | 44.136.96.0 255.255.255.0 170 | 44.137.0.0 255.255.0.0 171 | 44.137.0.49 255.255.255.255 172 | 44.137.1.160 255.255.255.240 173 | 44.137.1.208 255.255.255.240 174 | 44.137.1.80 255.255.255.240 175 | 44.137.24.1 255.255.255.255 176 | 44.137.24.147 255.255.255.255 177 | 44.137.24.242 255.255.255.255 178 | 44.137.24.5 255.255.255.255 179 | 44.137.27.112 255.255.255.240 180 | 44.137.27.193 255.255.255.255 181 | 44.137.31.64 255.255.255.224 182 | 44.137.32.50 255.255.255.255 183 | 44.137.33.16 255.255.255.240 184 | 44.137.33.32 255.255.255.240 185 | 44.137.33.48 255.255.255.240 186 | 44.137.37.192 255.255.255.240 187 | 44.137.40.1 255.255.255.255 188 | 44.137.40.10 255.255.255.255 189 | 44.137.40.2 255.255.255.255 190 | 44.137.40.20 255.255.255.255 191 | 44.137.41.128 255.255.255.240 192 | 44.138.0.16 255.255.255.240 193 | 44.138.1.0 255.255.255.0 194 | 44.138.2.0 255.255.255.0 195 | 44.138.3.0 255.255.255.248 196 | 44.139.11.0 255.255.255.0 197 | 44.139.39.0 255.255.255.0 198 | 44.139.44.0 255.255.255.128 199 | 44.14.0.1 255.255.255.255 200 | 44.14.0.16 255.255.255.248 201 | 44.14.0.2 255.255.255.255 202 | 44.14.0.8 255.255.255.248 203 | 44.141.122.0 255.255.255.0 204 | 44.142.0.0 255.255.0.0 205 | 44.143.0.0 255.255.0.0 206 | 44.144.120.0 255.255.255.0 207 | 44.144.121.0 255.255.255.0 208 | 44.144.46.240 255.255.255.240 209 | 44.144.47.0 255.255.255.240 210 | 44.144.5.0 255.255.255.0 211 | 44.147.200.160 255.255.255.252 212 | 44.147.210.0 255.255.255.0 213 | 44.147.86.16 255.255.255.248 214 | 44.150.1.0 255.255.255.0 215 | 44.150.1.48 255.255.255.255 216 | 44.151.1.44 255.255.255.255 217 | 44.151.1.5 255.255.255.255 218 | 44.151.17.10 255.255.255.255 219 | 44.151.17.55 255.255.255.255 220 | 44.151.178.0 255.255.255.0 221 | 44.151.20.1 255.255.255.255 222 | 44.151.219.0 255.255.255.224 223 | 44.151.22.1 255.255.255.255 224 | 44.151.22.2 255.255.255.255 225 | 44.151.24.1 255.255.255.255 226 | 44.151.24.3 255.255.255.255 227 | 44.151.24.5 255.255.255.255 228 | 44.151.240.16 255.255.255.255 229 | 44.151.240.66 255.255.255.255 230 | 44.151.29.1 255.255.255.255 231 | 44.151.37.1 255.255.255.255 232 | 44.151.38.55 255.255.255.255 233 | 44.151.44.55 255.255.255.255 234 | 44.151.44.69 255.255.255.255 235 | 44.151.5.1 255.255.255.255 236 | 44.151.5.2 255.255.255.255 237 | 44.151.50.19 255.255.255.255 238 | 44.151.54.2 255.255.255.255 239 | 44.151.54.29 255.255.255.255 240 | 44.151.57.32 255.255.255.255 241 | 44.151.57.57 255.255.255.255 242 | 44.151.59.1 255.255.255.255 243 | 44.151.59.2 255.255.255.255 244 | 44.151.6.9 255.255.255.255 245 | 44.151.67.100 255.255.255.255 246 | 44.151.68.100 255.255.255.255 247 | 44.151.69.52 255.255.255.255 248 | 44.151.73.4 255.255.255.255 249 | 44.151.74.102 255.255.255.255 250 | 44.151.75.15 255.255.255.255 251 | 44.151.78.130 255.255.255.255 252 | 44.151.91.12 255.255.255.255 253 | 44.151.91.13 255.255.255.255 254 | 44.151.91.7 255.255.255.255 255 | 44.151.92.10 255.255.255.255 256 | 44.151.92.21 255.255.255.255 257 | 44.151.92.22 255.255.255.255 258 | 44.151.95.29 255.255.255.255 259 | 44.152.0.0 255.255.0.0 260 | 44.153.0.0 255.255.254.0 261 | 44.153.52.0 255.255.255.0 262 | 44.153.54.0 255.255.255.240 263 | 44.153.54.128 255.255.255.128 264 | 44.153.54.16 255.255.255.252 265 | 44.153.54.20 255.255.255.255 266 | 44.153.54.21 255.255.255.255 267 | 44.153.54.22 255.255.255.255 268 | 44.153.54.23 255.255.255.255 269 | 44.153.54.24 255.255.255.252 270 | 44.153.54.28 255.255.255.252 271 | 44.153.54.32 255.255.255.224 272 | 44.153.54.64 255.255.255.192 273 | 44.153.55.0 255.255.255.0 274 | 44.153.56.0 255.255.254.0 275 | 44.153.72.13 255.255.255.255 276 | 44.153.81.0 255.255.255.0 277 | 44.154.0.0 255.255.192.0 278 | 44.154.64.0 255.255.255.0 279 | 44.154.65.0 255.255.255.0 280 | 44.154.66.0 255.255.255.0 281 | 44.155.6.0 255.255.255.0 282 | 44.155.8.0 255.255.255.0 283 | 44.156.64.0 255.255.255.0 284 | 44.158.144.0 255.255.252.0 285 | 44.158.152.0 255.255.254.0 286 | 44.16.0.0 255.255.255.248 287 | 44.16.2.32 255.255.255.224 288 | 44.16.3.0 255.255.255.0 289 | 44.16.4.32 255.255.255.248 290 | 44.16.5.0 255.255.255.224 291 | 44.16.9.1 255.255.255.255 292 | 44.161.0.0 255.255.0.0 293 | 44.161.204.0 255.255.255.0 294 | 44.161.205.0 255.255.255.0 295 | 44.161.222.0 255.255.255.128 296 | 44.161.222.128 255.255.255.128 297 | 44.161.223.0 255.255.255.128 298 | 44.161.223.128 255.255.255.128 299 | 44.161.230.0 255.255.255.0 300 | 44.161.239.0 255.255.255.192 301 | 44.161.239.128 255.255.255.192 302 | 44.161.239.192 255.255.255.192 303 | 44.161.239.64 255.255.255.192 304 | 44.161.252.0 255.255.252.0 305 | 44.163.144.0 255.255.240.0 306 | 44.163.144.32 255.255.255.240 307 | 44.163.22.0 255.255.255.0 308 | 44.163.32.0 255.255.248.0 309 | 44.165.100.0 255.255.255.0 310 | 44.165.104.0 255.255.255.0 311 | 44.165.108.0 255.255.255.0 312 | 44.165.111.0 255.255.255.240 313 | 44.165.129.0 255.255.255.0 314 | 44.165.145.0 255.255.255.0 315 | 44.165.15.0 255.255.255.0 316 | 44.165.152.0 255.255.255.0 317 | 44.165.2.0 255.255.255.128 318 | 44.165.25.0 255.255.255.0 319 | 44.165.32.0 255.255.255.0 320 | 44.165.33.0 255.255.255.0 321 | 44.165.44.0 255.255.255.0 322 | 44.165.51.0 255.255.255.0 323 | 44.165.53.0 255.255.255.0 324 | 44.165.64.0 255.255.255.0 325 | 44.165.68.0 255.255.255.0 326 | 44.165.69.0 255.255.255.0 327 | 44.165.80.0 255.255.255.0 328 | 44.165.81.0 255.255.255.240 329 | 44.168.12.0 255.255.252.0 330 | 44.168.16.0 255.255.240.0 331 | 44.168.254.12 255.255.255.252 332 | 44.168.254.140 255.255.255.252 333 | 44.168.254.160 255.255.255.248 334 | 44.168.254.168 255.255.255.252 335 | 44.168.254.32 255.255.255.252 336 | 44.168.254.36 255.255.255.252 337 | 44.168.254.40 255.255.255.248 338 | 44.168.254.72 255.255.255.248 339 | 44.168.254.80 255.255.255.248 340 | 44.168.254.96 255.255.255.240 341 | 44.168.40.0 255.255.255.0 342 | 44.168.44.0 255.255.255.0 343 | 44.168.50.0 255.255.255.0 344 | 44.168.51.0 255.255.255.224 345 | 44.17.0.128 255.255.255.254 346 | 44.170.0.0 255.255.0.0 347 | 44.174.27.0 255.255.255.0 348 | 44.174.3.0 255.255.255.0 349 | 44.174.43.0 255.255.255.0 350 | 44.174.6.0 255.255.255.0 351 | 44.174.77.10 255.255.255.255 352 | 44.177.10.10 255.255.255.255 353 | 44.177.10.253 255.255.255.255 354 | 44.177.10.254 255.255.255.255 355 | 44.177.11.0 255.255.255.240 356 | 44.178.224.0 255.255.255.0 357 | 44.178.224.0 255.255.255.248 358 | 44.178.74.0 255.255.255.248 359 | 44.18.0.185 255.255.255.255 360 | 44.18.0.208 255.255.255.240 361 | 44.18.44.0 255.255.255.0 362 | 44.180.0.0 255.255.255.252 363 | 44.182.20.0 255.255.255.0 364 | 44.182.21.0 255.255.255.0 365 | 44.182.21.2 255.255.255.254 366 | 44.182.30.0 255.255.255.0 367 | 44.182.60.0 255.255.255.248 368 | 44.182.62.0 255.255.255.0 369 | 44.182.69.0 255.255.255.0 370 | 44.182.83.0 255.255.255.0 371 | 44.185.1.0 255.255.255.0 372 | 44.185.10.0 255.255.255.0 373 | 44.185.11.0 255.255.255.0 374 | 44.185.185.0 255.255.255.0 375 | 44.185.2.64 255.255.255.192 376 | 44.185.4.0 255.255.255.0 377 | 44.185.44.0 255.255.255.252 378 | 44.185.5.0 255.255.255.0 379 | 44.185.66.0 255.255.255.0 380 | 44.185.69.0 255.255.255.0 381 | 44.185.80.0 255.255.255.0 382 | 44.185.92.0 255.255.255.0 383 | 44.185.96.0 255.255.255.0 384 | 44.188.1.1 255.255.255.255 385 | 44.188.128.0 255.255.240.0 386 | 44.188.192.221 255.255.255.255 387 | 44.188.192.222 255.255.255.255 388 | 44.2.10.0 255.255.255.248 389 | 44.2.14.0 255.255.255.248 390 | 44.2.2.0 255.255.255.0 391 | 44.2.5.0 255.255.255.128 392 | 44.2.50.0 255.255.255.248 393 | 44.2.9.0 255.255.255.248 394 | 44.20.1.0 255.255.255.0 395 | 44.20.100.0 255.255.255.248 396 | 44.20.2.0 255.255.254.0 397 | 44.20.42.0 255.255.255.0 398 | 44.208.0.0 255.255.0.0 399 | 44.208.58.0 255.255.255.240 400 | 44.22.128.0 255.255.255.0 401 | 44.224.0.0 255.254.0.0 402 | 44.24.0.0 255.255.240.0 403 | 44.24.10.0 255.255.255.0 404 | 44.24.125.0 255.255.255.0 405 | 44.24.172.64 255.255.255.192 406 | 44.24.194.0 255.255.255.0 407 | 44.24.24.8 255.255.255.255 408 | 44.26.0.160 255.255.255.252 409 | 44.26.1.32 255.255.255.248 410 | 44.26.1.40 255.255.255.248 411 | 44.34.255.0 255.255.255.192 412 | 44.36.0.0 255.255.255.0 413 | 44.36.8.0 255.255.255.240 414 | 44.4.10.40 255.255.255.255 415 | 44.4.12.0 255.255.255.0 416 | 44.4.138.0 255.255.255.240 417 | 44.4.140.0 255.255.255.0 418 | 44.4.2.152 255.255.255.248 419 | 44.4.38.27 255.255.255.255 420 | 44.4.39.0 255.255.255.248 421 | 44.4.4.64 255.255.255.224 422 | 44.4.50.1 255.255.255.255 423 | 44.4.50.10 255.255.255.255 424 | 44.4.50.11 255.255.255.255 425 | 44.4.50.12 255.255.255.255 426 | 44.4.50.13 255.255.255.255 427 | 44.4.50.14 255.255.255.255 428 | 44.4.50.16 255.255.255.252 429 | 44.4.50.2 255.255.255.255 430 | 44.4.50.20 255.255.255.252 431 | 44.4.50.24 255.255.255.252 432 | 44.4.50.28 255.255.255.252 433 | 44.4.50.3 255.255.255.255 434 | 44.4.50.32 255.255.255.252 435 | 44.4.50.36 255.255.255.252 436 | 44.4.50.4 255.255.255.255 437 | 44.4.50.5 255.255.255.255 438 | 44.4.50.6 255.255.255.255 439 | 44.4.50.9 255.255.255.255 440 | 44.40.1.40 255.255.255.248 441 | 44.40.128.0 255.255.255.0 442 | 44.40.64.0 255.255.255.240 443 | 44.42.128.0 255.255.255.0 444 | 44.44.10.0 255.255.255.248 445 | 44.44.107.0 255.255.255.0 446 | 44.44.6.32 255.255.255.248 447 | 44.44.7.128 255.255.255.248 448 | 44.44.7.144 255.255.255.248 449 | 44.46.0.11 255.255.255.255 450 | 44.46.128.0 255.255.255.0 451 | 44.46.32.0 255.255.255.0 452 | 44.46.64.0 255.255.255.0 453 | 44.48.0.40 255.255.255.248 454 | 44.48.12.0 255.255.255.0 455 | 44.48.128.0 255.255.255.0 456 | 44.48.15.0 255.255.255.248 457 | 44.48.16.0 255.255.255.0 458 | 44.48.17.0 255.255.255.252 459 | 44.48.18.0 255.255.255.192 460 | 44.48.5.0 255.255.255.248 461 | 44.48.6.0 255.255.255.248 462 | 44.48.8.0 255.255.252.0 463 | 44.50.0.69 255.255.255.255 464 | 44.50.192.0 255.255.255.224 465 | 44.50.192.128 255.255.255.248 466 | 44.52.11.0 255.255.255.240 467 | 44.56.192.0 255.255.255.0 468 | 44.56.193.0 255.255.255.0 469 | 44.56.53.0 255.255.255.240 470 | 44.56.6.0 255.255.255.240 471 | 44.56.6.16 255.255.255.240 472 | 44.58.128.0 255.255.255.0 473 | 44.60.0.0 255.255.255.248 474 | 44.60.0.8 255.255.255.248 475 | 44.60.44.0 255.255.255.0 476 | 44.62.1.48 255.255.255.248 477 | 44.62.1.8 255.255.255.248 478 | 44.62.4.0 255.255.255.224 479 | 44.64.0.0 255.255.0.0 480 | 44.64.255.224 255.255.255.224 481 | 44.68.100.0 255.255.255.248 482 | 44.68.112.0 255.255.255.224 483 | 44.68.20.0 255.255.255.248 484 | 44.68.220.0 255.255.255.240 485 | 44.68.41.0 255.255.255.0 486 | 44.68.64.0 255.255.255.0 487 | 44.68.84.0 255.255.255.248 488 | 44.68.88.0 255.255.255.224 489 | 44.70.4.0 255.255.255.224 490 | 44.70.4.32 255.255.255.224 491 | 44.70.6.0 255.255.255.224 492 | 44.71.16.0 255.255.255.224 493 | 44.72.26.0 255.255.255.0 494 | 44.72.26.0 255.255.255.192 495 | 44.72.73.0 255.255.255.192 496 | 44.73.0.0 255.255.192.0 497 | 44.73.120.0 255.255.248.0 498 | 44.73.64.0 255.255.224.0 499 | 44.74.0.128 255.255.255.240 500 | 44.74.12.0 255.255.255.248 501 | 44.76.1.80 255.255.255.248 502 | 44.76.1.88 255.255.255.248 503 | 44.76.11.0 255.255.255.248 504 | 44.76.2.0 255.255.255.0 505 | 44.8.1.16 255.255.255.240 506 | 44.8.2.0 255.255.255.0 507 | 44.8.64.0 255.255.255.0 508 | 44.80.44.0 255.255.255.0 509 | 44.88.0.0 255.255.255.224 510 | 44.88.0.200 255.255.255.255 511 | 44.88.0.201 255.255.255.255 512 | 44.88.4.0 255.255.255.240 513 | 44.88.8.0 255.255.255.248 514 | 44.88.8.32 255.255.255.240 515 | 44.90.128.0 255.255.255.0 516 | 44.92.21.0 255.255.255.128 517 | 44.92.21.128 255.255.255.128 518 | 44.92.250.1 255.255.255.255 519 | 44.92.35.0 255.255.255.248 520 | 44.92.35.16 255.255.255.240 521 | 44.94.0.0 255.255.0.0 522 | 44.94.10.8 255.255.255.248 523 | 44.94.11.0 255.255.255.0 524 | 44.94.14.65 255.255.255.255 525 | 44.94.15.0 255.255.255.0 526 | 44.98.16.0 255.255.255.224 527 | 44.98.16.248 255.255.255.248 528 | 44.98.24.0 255.255.255.240 529 | 44.98.24.48 255.255.255.240 530 | 44.98.28.16 255.255.255.248 531 | 44.98.41.0 255.255.255.248 532 | -------------------------------------------------------------------------------- /testdata/testipmapinsert.data2: -------------------------------------------------------------------------------- 1 | 44.224.0.0 255.254.0.0 2 | 44.208.58.0 255.255.255.240 3 | 44.208.0.0 255.255.0.0 4 | 44.188.192.222 255.255.255.255 5 | 44.188.192.221 255.255.255.255 6 | 44.188.128.0 255.255.240.0 7 | 44.188.1.1 255.255.255.255 8 | 44.185.185.0 255.255.255.0 9 | 44.185.96.0 255.255.255.0 10 | 44.185.92.0 255.255.255.0 11 | 44.185.80.0 255.255.255.0 12 | 44.185.69.0 255.255.255.0 13 | 44.185.66.0 255.255.255.0 14 | 44.185.44.0 255.255.255.252 15 | 44.185.11.0 255.255.255.0 16 | 44.185.10.0 255.255.255.0 17 | 44.185.5.0 255.255.255.0 18 | 44.185.4.0 255.255.255.0 19 | 44.185.2.64 255.255.255.192 20 | 44.185.1.0 255.255.255.0 21 | 44.182.83.0 255.255.255.0 22 | 44.182.69.0 255.255.255.0 23 | 44.182.62.0 255.255.255.0 24 | 44.182.60.0 255.255.255.248 25 | 44.182.30.0 255.255.255.0 26 | 44.182.21.2 255.255.255.254 27 | 44.182.21.0 255.255.255.0 28 | 44.182.20.0 255.255.255.0 29 | 44.180.0.0 255.255.255.252 30 | 44.178.224.0 255.255.255.248 31 | 44.178.224.0 255.255.255.0 32 | 44.178.74.0 255.255.255.248 33 | 44.177.11.0 255.255.255.240 34 | 44.177.10.254 255.255.255.255 35 | 44.177.10.253 255.255.255.255 36 | 44.177.10.10 255.255.255.255 37 | 44.174.77.10 255.255.255.255 38 | 44.174.43.0 255.255.255.0 39 | 44.174.27.0 255.255.255.0 40 | 44.174.6.0 255.255.255.0 41 | 44.174.3.0 255.255.255.0 42 | 44.170.0.0 255.255.0.0 43 | 44.168.254.168 255.255.255.252 44 | 44.168.254.160 255.255.255.248 45 | 44.168.254.140 255.255.255.252 46 | 44.168.254.96 255.255.255.240 47 | 44.168.254.80 255.255.255.248 48 | 44.168.254.72 255.255.255.248 49 | 44.168.254.40 255.255.255.248 50 | 44.168.254.36 255.255.255.252 51 | 44.168.254.32 255.255.255.252 52 | 44.168.254.12 255.255.255.252 53 | 44.168.51.0 255.255.255.224 54 | 44.168.50.0 255.255.255.0 55 | 44.168.44.0 255.255.255.0 56 | 44.168.40.0 255.255.255.0 57 | 44.168.16.0 255.255.240.0 58 | 44.168.12.0 255.255.252.0 59 | 44.165.152.0 255.255.255.0 60 | 44.165.145.0 255.255.255.0 61 | 44.165.129.0 255.255.255.0 62 | 44.165.111.0 255.255.255.240 63 | 44.165.108.0 255.255.255.0 64 | 44.165.104.0 255.255.255.0 65 | 44.165.100.0 255.255.255.0 66 | 44.165.81.0 255.255.255.240 67 | 44.165.80.0 255.255.255.0 68 | 44.165.69.0 255.255.255.0 69 | 44.165.68.0 255.255.255.0 70 | 44.165.64.0 255.255.255.0 71 | 44.165.53.0 255.255.255.0 72 | 44.165.51.0 255.255.255.0 73 | 44.165.44.0 255.255.255.0 74 | 44.165.33.0 255.255.255.0 75 | 44.165.32.0 255.255.255.0 76 | 44.165.25.0 255.255.255.0 77 | 44.165.15.0 255.255.255.0 78 | 44.165.2.0 255.255.255.128 79 | 44.163.144.32 255.255.255.240 80 | 44.163.144.0 255.255.240.0 81 | 44.163.32.0 255.255.248.0 82 | 44.163.22.0 255.255.255.0 83 | 44.161.252.0 255.255.252.0 84 | 44.161.239.192 255.255.255.192 85 | 44.161.239.128 255.255.255.192 86 | 44.161.239.64 255.255.255.192 87 | 44.161.239.0 255.255.255.192 88 | 44.161.230.0 255.255.255.0 89 | 44.161.223.128 255.255.255.128 90 | 44.161.223.0 255.255.255.128 91 | 44.161.222.128 255.255.255.128 92 | 44.161.222.0 255.255.255.128 93 | 44.161.205.0 255.255.255.0 94 | 44.161.204.0 255.255.255.0 95 | 44.161.0.0 255.255.0.0 96 | 44.158.152.0 255.255.254.0 97 | 44.158.144.0 255.255.252.0 98 | 44.156.64.0 255.255.255.0 99 | 44.155.8.0 255.255.255.0 100 | 44.155.6.0 255.255.255.0 101 | 44.154.66.0 255.255.255.0 102 | 44.154.65.0 255.255.255.0 103 | 44.154.64.0 255.255.255.0 104 | 44.154.0.0 255.255.192.0 105 | 44.153.81.0 255.255.255.0 106 | 44.153.72.13 255.255.255.255 107 | 44.153.56.0 255.255.254.0 108 | 44.153.55.0 255.255.255.0 109 | 44.153.54.128 255.255.255.128 110 | 44.153.54.64 255.255.255.192 111 | 44.153.54.32 255.255.255.224 112 | 44.153.54.28 255.255.255.252 113 | 44.153.54.24 255.255.255.252 114 | 44.153.54.23 255.255.255.255 115 | 44.153.54.22 255.255.255.255 116 | 44.153.54.21 255.255.255.255 117 | 44.153.54.20 255.255.255.255 118 | 44.153.54.16 255.255.255.252 119 | 44.153.54.0 255.255.255.240 120 | 44.153.52.0 255.255.255.0 121 | 44.153.0.0 255.255.254.0 122 | 44.152.0.0 255.255.0.0 123 | 44.151.240.66 255.255.255.255 124 | 44.151.240.16 255.255.255.255 125 | 44.151.219.0 255.255.255.224 126 | 44.151.178.0 255.255.255.0 127 | 44.151.95.29 255.255.255.255 128 | 44.151.92.22 255.255.255.255 129 | 44.151.92.21 255.255.255.255 130 | 44.151.92.10 255.255.255.255 131 | 44.151.91.13 255.255.255.255 132 | 44.151.91.12 255.255.255.255 133 | 44.151.91.7 255.255.255.255 134 | 44.151.78.130 255.255.255.255 135 | 44.151.75.15 255.255.255.255 136 | 44.151.74.102 255.255.255.255 137 | 44.151.73.4 255.255.255.255 138 | 44.151.69.52 255.255.255.255 139 | 44.151.68.100 255.255.255.255 140 | 44.151.67.100 255.255.255.255 141 | 44.151.59.2 255.255.255.255 142 | 44.151.59.1 255.255.255.255 143 | 44.151.57.57 255.255.255.255 144 | 44.151.57.32 255.255.255.255 145 | 44.151.54.29 255.255.255.255 146 | 44.151.54.2 255.255.255.255 147 | 44.151.50.19 255.255.255.255 148 | 44.151.44.69 255.255.255.255 149 | 44.151.44.55 255.255.255.255 150 | 44.151.38.55 255.255.255.255 151 | 44.151.37.1 255.255.255.255 152 | 44.151.29.1 255.255.255.255 153 | 44.151.24.5 255.255.255.255 154 | 44.151.24.3 255.255.255.255 155 | 44.151.24.1 255.255.255.255 156 | 44.151.22.2 255.255.255.255 157 | 44.151.22.1 255.255.255.255 158 | 44.151.20.1 255.255.255.255 159 | 44.151.17.55 255.255.255.255 160 | 44.151.17.10 255.255.255.255 161 | 44.151.6.9 255.255.255.255 162 | 44.151.5.2 255.255.255.255 163 | 44.151.5.1 255.255.255.255 164 | 44.151.1.44 255.255.255.255 165 | 44.151.1.5 255.255.255.255 166 | 44.150.1.48 255.255.255.255 167 | 44.150.1.0 255.255.255.0 168 | 44.147.210.0 255.255.255.0 169 | 44.147.200.160 255.255.255.252 170 | 44.147.86.16 255.255.255.248 171 | 44.144.121.0 255.255.255.0 172 | 44.144.120.0 255.255.255.0 173 | 44.144.47.0 255.255.255.240 174 | 44.144.46.240 255.255.255.240 175 | 44.144.5.0 255.255.255.0 176 | 44.143.0.0 255.255.0.0 177 | 44.142.0.0 255.255.0.0 178 | 44.141.122.0 255.255.255.0 179 | 44.139.44.0 255.255.255.128 180 | 44.139.39.0 255.255.255.0 181 | 44.139.11.0 255.255.255.0 182 | 44.138.3.0 255.255.255.248 183 | 44.138.2.0 255.255.255.0 184 | 44.138.1.0 255.255.255.0 185 | 44.138.0.16 255.255.255.240 186 | 44.137.41.128 255.255.255.240 187 | 44.137.40.20 255.255.255.255 188 | 44.137.40.10 255.255.255.255 189 | 44.137.40.2 255.255.255.255 190 | 44.137.40.1 255.255.255.255 191 | 44.137.37.192 255.255.255.240 192 | 44.137.33.48 255.255.255.240 193 | 44.137.33.32 255.255.255.240 194 | 44.137.33.16 255.255.255.240 195 | 44.137.32.50 255.255.255.255 196 | 44.137.31.64 255.255.255.224 197 | 44.137.27.193 255.255.255.255 198 | 44.137.27.112 255.255.255.240 199 | 44.137.24.242 255.255.255.255 200 | 44.137.24.147 255.255.255.255 201 | 44.137.24.5 255.255.255.255 202 | 44.137.24.1 255.255.255.255 203 | 44.137.1.208 255.255.255.240 204 | 44.137.1.160 255.255.255.240 205 | 44.137.1.80 255.255.255.240 206 | 44.137.0.49 255.255.255.255 207 | 44.137.0.0 255.255.0.0 208 | 44.136.227.0 255.255.255.0 209 | 44.136.224.44 255.255.255.252 210 | 44.136.224.34 255.255.255.255 211 | 44.136.224.32 255.255.255.255 212 | 44.136.209.0 255.255.255.0 213 | 44.136.204.0 255.255.255.0 214 | 44.136.142.240 255.255.255.240 215 | 44.136.126.0 255.255.255.0 216 | 44.136.96.0 255.255.255.0 217 | 44.136.92.0 255.255.255.0 218 | 44.136.83.144 255.255.255.240 219 | 44.136.83.0 255.255.255.0 220 | 44.136.72.0 255.255.252.0 221 | 44.136.16.0 255.255.255.0 222 | 44.136.9.0 255.255.255.0 223 | 44.136.0.0 255.255.248.0 224 | 44.135.195.0 255.255.255.0 225 | 44.135.193.0 255.255.255.0 226 | 44.135.192.160 255.255.255.248 227 | 44.135.192.96 255.255.255.248 228 | 44.135.192.80 255.255.255.248 229 | 44.135.192.32 255.255.255.248 230 | 44.135.188.0 255.255.252.0 231 | 44.135.186.0 255.255.255.0 232 | 44.135.160.40 255.255.255.255 233 | 44.135.156.0 255.255.255.0 234 | 44.135.147.0 255.255.255.0 235 | 44.135.124.0 255.255.255.0 236 | 44.135.105.0 255.255.255.0 237 | 44.135.104.128 255.255.255.128 238 | 44.135.103.128 255.255.255.252 239 | 44.135.96.64 255.255.255.192 240 | 44.135.94.0 255.255.254.0 241 | 44.135.93.0 255.255.255.240 242 | 44.135.92.128 255.255.255.248 243 | 44.135.92.0 255.255.255.0 244 | 44.135.91.0 255.255.255.0 245 | 44.135.90.128 255.255.255.128 246 | 44.135.90.42 255.255.255.255 247 | 44.135.90.3 255.255.255.255 248 | 44.135.90.2 255.255.255.255 249 | 44.135.90.0 255.255.255.0 250 | 44.135.89.192 255.255.255.192 251 | 44.135.88.0 255.255.255.0 252 | 44.135.86.0 255.255.255.0 253 | 44.135.85.56 255.255.255.255 254 | 44.135.85.0 255.255.255.0 255 | 44.135.84.16 255.255.255.240 256 | 44.135.83.24 255.255.255.255 257 | 44.135.83.23 255.255.255.255 258 | 44.135.83.22 255.255.255.255 259 | 44.135.83.21 255.255.255.255 260 | 44.135.82.0 255.255.255.0 261 | 44.135.74.0 255.255.255.240 262 | 44.135.71.0 255.255.255.0 263 | 44.135.68.0 255.255.255.240 264 | 44.135.62.0 255.255.255.192 265 | 44.135.56.0 255.255.255.0 266 | 44.135.55.0 255.255.255.248 267 | 44.135.52.0 255.255.255.0 268 | 44.135.50.0 255.255.255.192 269 | 44.135.49.0 255.255.255.224 270 | 44.135.48.0 255.255.255.0 271 | 44.135.43.0 255.255.255.248 272 | 44.135.32.0 255.255.255.0 273 | 44.135.16.0 255.255.252.0 274 | 44.134.240.0 255.255.240.0 275 | 44.134.224.0 255.255.240.0 276 | 44.134.208.0 255.255.240.0 277 | 44.134.192.0 255.255.240.0 278 | 44.134.190.0 255.255.254.0 279 | 44.134.189.0 255.255.255.0 280 | 44.134.185.0 255.255.255.0 281 | 44.134.181.0 255.255.255.0 282 | 44.134.180.0 255.255.255.0 283 | 44.134.178.0 255.255.255.0 284 | 44.134.177.0 255.255.255.0 285 | 44.134.160.0 255.255.240.0 286 | 44.134.128.0 255.255.224.0 287 | 44.134.96.0 255.255.240.0 288 | 44.134.64.0 255.255.224.0 289 | 44.134.48.0 255.255.255.0 290 | 44.134.34.0 255.255.255.0 291 | 44.134.33.71 255.255.255.255 292 | 44.134.33.0 255.255.255.0 293 | 44.134.32.240 255.255.255.255 294 | 44.134.32.233 255.255.255.255 295 | 44.134.32.0 255.255.255.0 296 | 44.134.0.0 255.255.240.0 297 | 44.133.128.0 255.255.128.0 298 | 44.133.47.10 255.255.255.255 299 | 44.133.47.6 255.255.255.255 300 | 44.133.32.11 255.255.255.255 301 | 44.133.28.155 255.255.255.255 302 | 44.133.17.50 255.255.255.255 303 | 44.133.8.13 255.255.255.255 304 | 44.133.3.39 255.255.255.255 305 | 44.131.244.0 255.255.255.0 306 | 44.131.243.0 255.255.255.0 307 | 44.131.242.0 255.255.255.0 308 | 44.131.241.0 255.255.255.0 309 | 44.131.240.0 255.255.255.0 310 | 44.131.220.36 255.255.255.252 311 | 44.131.218.0 255.255.255.248 312 | 44.131.218.0 255.255.255.0 313 | 44.131.210.0 255.255.255.255 314 | 44.131.210.0 255.255.255.0 315 | 44.131.189.8 255.255.255.248 316 | 44.131.189.0 255.255.255.248 317 | 44.131.182.0 255.255.255.0 318 | 44.131.176.0 255.255.255.224 319 | 44.131.170.8 255.255.255.248 320 | 44.131.170.0 255.255.255.252 321 | 44.131.168.128 255.255.255.248 322 | 44.131.162.0 255.255.255.0 323 | 44.131.161.0 255.255.255.0 324 | 44.131.160.0 255.255.255.0 325 | 44.131.156.103 255.255.255.255 326 | 44.131.156.0 255.255.255.252 327 | 44.131.152.2 255.255.255.255 328 | 44.131.152.1 255.255.255.255 329 | 44.131.151.0 255.255.255.240 330 | 44.131.144.0 255.255.252.0 331 | 44.131.128.0 255.255.240.0 332 | 44.131.121.0 255.255.255.0 333 | 44.131.96.32 255.255.255.248 334 | 44.131.91.0 255.255.255.0 335 | 44.131.68.32 255.255.255.248 336 | 44.131.56.8 255.255.255.248 337 | 44.131.56.0 255.255.255.248 338 | 44.131.11.0 255.255.255.248 339 | 44.131.8.32 255.255.255.224 340 | 44.131.8.0 255.255.255.0 341 | 44.131.7.0 255.255.255.0 342 | 44.130.240.6 255.255.255.255 343 | 44.130.240.2 255.255.255.255 344 | 44.130.224.32 255.255.255.224 345 | 44.130.224.0 255.255.255.240 346 | 44.130.0.0 255.255.0.0 347 | 44.129.128.0 255.255.255.0 348 | 44.129.16.0 255.255.255.0 349 | 44.127.192.0 255.255.255.0 350 | 44.125.2.0 255.255.255.0 351 | 44.118.5.0 255.255.255.248 352 | 44.116.3.64 255.255.255.224 353 | 44.108.180.0 255.255.255.0 354 | 44.102.238.0 255.255.255.0 355 | 44.102.216.0 255.255.254.0 356 | 44.102.200.0 255.255.252.0 357 | 44.102.176.0 255.255.255.0 358 | 44.102.172.0 255.255.252.0 359 | 44.102.170.0 255.255.254.0 360 | 44.102.168.0 255.255.255.0 361 | 44.102.166.0 255.255.255.0 362 | 44.102.134.0 255.255.255.0 363 | 44.102.132.0 255.255.255.0 364 | 44.102.128.0 255.255.255.0 365 | 44.102.104.0 255.255.255.0 366 | 44.102.100.0 255.255.255.0 367 | 44.102.56.0 255.255.255.0 368 | 44.102.48.0 255.255.255.0 369 | 44.102.24.0 255.255.255.0 370 | 44.102.1.0 255.255.255.0 371 | 44.98.41.0 255.255.255.248 372 | 44.98.28.16 255.255.255.248 373 | 44.98.24.48 255.255.255.240 374 | 44.98.24.0 255.255.255.240 375 | 44.98.16.248 255.255.255.248 376 | 44.98.16.0 255.255.255.224 377 | 44.94.15.0 255.255.255.0 378 | 44.94.14.65 255.255.255.255 379 | 44.94.11.0 255.255.255.0 380 | 44.94.10.8 255.255.255.248 381 | 44.94.0.0 255.255.0.0 382 | 44.92.250.1 255.255.255.255 383 | 44.92.35.16 255.255.255.240 384 | 44.92.35.0 255.255.255.248 385 | 44.92.21.128 255.255.255.128 386 | 44.92.21.0 255.255.255.128 387 | 44.90.128.0 255.255.255.0 388 | 44.88.8.32 255.255.255.240 389 | 44.88.8.0 255.255.255.248 390 | 44.88.4.0 255.255.255.240 391 | 44.88.0.201 255.255.255.255 392 | 44.88.0.200 255.255.255.255 393 | 44.88.0.0 255.255.255.224 394 | 44.80.44.0 255.255.255.0 395 | 44.76.11.0 255.255.255.248 396 | 44.76.2.0 255.255.255.0 397 | 44.76.1.88 255.255.255.248 398 | 44.76.1.80 255.255.255.248 399 | 44.74.12.0 255.255.255.248 400 | 44.74.0.128 255.255.255.240 401 | 44.73.120.0 255.255.248.0 402 | 44.73.64.0 255.255.224.0 403 | 44.73.0.0 255.255.192.0 404 | 44.72.73.0 255.255.255.192 405 | 44.72.26.0 255.255.255.192 406 | 44.72.26.0 255.255.255.0 407 | 44.71.16.0 255.255.255.224 408 | 44.70.6.0 255.255.255.224 409 | 44.70.4.32 255.255.255.224 410 | 44.70.4.0 255.255.255.224 411 | 44.68.220.0 255.255.255.240 412 | 44.68.112.0 255.255.255.224 413 | 44.68.100.0 255.255.255.248 414 | 44.68.88.0 255.255.255.224 415 | 44.68.84.0 255.255.255.248 416 | 44.68.64.0 255.255.255.0 417 | 44.68.41.0 255.255.255.0 418 | 44.68.20.0 255.255.255.248 419 | 44.64.255.224 255.255.255.224 420 | 44.64.0.0 255.255.0.0 421 | 44.62.4.0 255.255.255.224 422 | 44.62.1.48 255.255.255.248 423 | 44.62.1.8 255.255.255.248 424 | 44.60.44.0 255.255.255.0 425 | 44.60.0.8 255.255.255.248 426 | 44.60.0.0 255.255.255.248 427 | 44.58.128.0 255.255.255.0 428 | 44.56.193.0 255.255.255.0 429 | 44.56.192.0 255.255.255.0 430 | 44.56.53.0 255.255.255.240 431 | 44.56.6.16 255.255.255.240 432 | 44.56.6.0 255.255.255.240 433 | 44.52.11.0 255.255.255.240 434 | 44.50.192.128 255.255.255.248 435 | 44.50.192.0 255.255.255.224 436 | 44.50.0.69 255.255.255.255 437 | 44.48.128.0 255.255.255.0 438 | 44.48.18.0 255.255.255.192 439 | 44.48.17.0 255.255.255.252 440 | 44.48.16.0 255.255.255.0 441 | 44.48.15.0 255.255.255.248 442 | 44.48.12.0 255.255.255.0 443 | 44.48.8.0 255.255.252.0 444 | 44.48.6.0 255.255.255.248 445 | 44.48.5.0 255.255.255.248 446 | 44.48.0.40 255.255.255.248 447 | 44.46.128.0 255.255.255.0 448 | 44.46.64.0 255.255.255.0 449 | 44.46.32.0 255.255.255.0 450 | 44.46.0.11 255.255.255.255 451 | 44.44.107.0 255.255.255.0 452 | 44.44.10.0 255.255.255.248 453 | 44.44.7.144 255.255.255.248 454 | 44.44.7.128 255.255.255.248 455 | 44.44.6.32 255.255.255.248 456 | 44.42.128.0 255.255.255.0 457 | 44.40.128.0 255.255.255.0 458 | 44.40.64.0 255.255.255.240 459 | 44.40.1.40 255.255.255.248 460 | 44.36.8.0 255.255.255.240 461 | 44.36.0.0 255.255.255.0 462 | 44.34.255.0 255.255.255.192 463 | 44.26.1.40 255.255.255.248 464 | 44.26.1.32 255.255.255.248 465 | 44.26.0.160 255.255.255.252 466 | 44.24.194.0 255.255.255.0 467 | 44.24.172.64 255.255.255.192 468 | 44.24.125.0 255.255.255.0 469 | 44.24.24.8 255.255.255.255 470 | 44.24.10.0 255.255.255.0 471 | 44.24.0.0 255.255.240.0 472 | 44.22.128.0 255.255.255.0 473 | 44.20.100.0 255.255.255.248 474 | 44.20.42.0 255.255.255.0 475 | 44.20.2.0 255.255.254.0 476 | 44.20.1.0 255.255.255.0 477 | 44.18.44.0 255.255.255.0 478 | 44.18.0.208 255.255.255.240 479 | 44.18.0.185 255.255.255.255 480 | 44.17.0.128 255.255.255.254 481 | 44.16.9.1 255.255.255.255 482 | 44.16.5.0 255.255.255.224 483 | 44.16.4.32 255.255.255.248 484 | 44.16.3.0 255.255.255.0 485 | 44.16.2.32 255.255.255.224 486 | 44.16.0.0 255.255.255.248 487 | 44.14.0.16 255.255.255.248 488 | 44.14.0.8 255.255.255.248 489 | 44.14.0.2 255.255.255.255 490 | 44.14.0.1 255.255.255.255 491 | 44.12.3.136 255.255.255.248 492 | 44.12.3.128 255.255.255.248 493 | 44.12.3.96 255.255.255.224 494 | 44.10.192.1 255.255.255.255 495 | 44.10.192.0 255.255.255.0 496 | 44.10.0.0 255.255.255.224 497 | 44.8.64.0 255.255.255.0 498 | 44.8.2.0 255.255.255.0 499 | 44.8.1.16 255.255.255.240 500 | 44.4.140.0 255.255.255.0 501 | 44.4.138.0 255.255.255.240 502 | 44.4.50.36 255.255.255.252 503 | 44.4.50.32 255.255.255.252 504 | 44.4.50.28 255.255.255.252 505 | 44.4.50.24 255.255.255.252 506 | 44.4.50.20 255.255.255.252 507 | 44.4.50.16 255.255.255.252 508 | 44.4.50.14 255.255.255.255 509 | 44.4.50.13 255.255.255.255 510 | 44.4.50.12 255.255.255.255 511 | 44.4.50.11 255.255.255.255 512 | 44.4.50.10 255.255.255.255 513 | 44.4.50.9 255.255.255.255 514 | 44.4.50.6 255.255.255.255 515 | 44.4.50.5 255.255.255.255 516 | 44.4.50.4 255.255.255.255 517 | 44.4.50.3 255.255.255.255 518 | 44.4.50.2 255.255.255.255 519 | 44.4.50.1 255.255.255.255 520 | 44.4.39.0 255.255.255.248 521 | 44.4.38.27 255.255.255.255 522 | 44.4.12.0 255.255.255.0 523 | 44.4.10.40 255.255.255.255 524 | 44.4.4.64 255.255.255.224 525 | 44.4.2.152 255.255.255.248 526 | 44.2.50.0 255.255.255.248 527 | 44.2.14.0 255.255.255.248 528 | 44.2.10.0 255.255.255.248 529 | 44.2.9.0 255.255.255.248 530 | 44.2.5.0 255.255.255.128 531 | 44.2.2.0 255.255.255.0 532 | -------------------------------------------------------------------------------- /testdata/testipmapinsert.data3: -------------------------------------------------------------------------------- 1 | 44.98.41.0 255.255.255.248 2 | 44.98.28.16 255.255.255.248 3 | 44.98.24.48 255.255.255.240 4 | 44.98.24.0 255.255.255.240 5 | 44.98.16.248 255.255.255.248 6 | 44.98.16.0 255.255.255.224 7 | 44.94.15.0 255.255.255.0 8 | 44.94.14.65 255.255.255.255 9 | 44.94.11.0 255.255.255.0 10 | 44.94.10.8 255.255.255.248 11 | 44.94.0.0 255.255.0.0 12 | 44.92.35.16 255.255.255.240 13 | 44.92.35.0 255.255.255.248 14 | 44.92.250.1 255.255.255.255 15 | 44.92.21.128 255.255.255.128 16 | 44.92.21.0 255.255.255.128 17 | 44.90.128.0 255.255.255.0 18 | 44.88.8.32 255.255.255.240 19 | 44.88.8.0 255.255.255.248 20 | 44.88.4.0 255.255.255.240 21 | 44.88.0.201 255.255.255.255 22 | 44.88.0.200 255.255.255.255 23 | 44.88.0.0 255.255.255.224 24 | 44.80.44.0 255.255.255.0 25 | 44.8.64.0 255.255.255.0 26 | 44.8.2.0 255.255.255.0 27 | 44.8.1.16 255.255.255.240 28 | 44.76.2.0 255.255.255.0 29 | 44.76.11.0 255.255.255.248 30 | 44.76.1.88 255.255.255.248 31 | 44.76.1.80 255.255.255.248 32 | 44.74.12.0 255.255.255.248 33 | 44.74.0.128 255.255.255.240 34 | 44.73.64.0 255.255.224.0 35 | 44.73.120.0 255.255.248.0 36 | 44.73.0.0 255.255.192.0 37 | 44.72.73.0 255.255.255.192 38 | 44.72.26.0 255.255.255.192 39 | 44.72.26.0 255.255.255.0 40 | 44.71.16.0 255.255.255.224 41 | 44.70.6.0 255.255.255.224 42 | 44.70.4.32 255.255.255.224 43 | 44.70.4.0 255.255.255.224 44 | 44.68.88.0 255.255.255.224 45 | 44.68.84.0 255.255.255.248 46 | 44.68.64.0 255.255.255.0 47 | 44.68.41.0 255.255.255.0 48 | 44.68.220.0 255.255.255.240 49 | 44.68.20.0 255.255.255.248 50 | 44.68.112.0 255.255.255.224 51 | 44.68.100.0 255.255.255.248 52 | 44.64.255.224 255.255.255.224 53 | 44.64.0.0 255.255.0.0 54 | 44.62.4.0 255.255.255.224 55 | 44.62.1.8 255.255.255.248 56 | 44.62.1.48 255.255.255.248 57 | 44.60.44.0 255.255.255.0 58 | 44.60.0.8 255.255.255.248 59 | 44.60.0.0 255.255.255.248 60 | 44.58.128.0 255.255.255.0 61 | 44.56.6.16 255.255.255.240 62 | 44.56.6.0 255.255.255.240 63 | 44.56.53.0 255.255.255.240 64 | 44.56.193.0 255.255.255.0 65 | 44.56.192.0 255.255.255.0 66 | 44.52.11.0 255.255.255.240 67 | 44.50.192.128 255.255.255.248 68 | 44.50.192.0 255.255.255.224 69 | 44.50.0.69 255.255.255.255 70 | 44.48.8.0 255.255.252.0 71 | 44.48.6.0 255.255.255.248 72 | 44.48.5.0 255.255.255.248 73 | 44.48.18.0 255.255.255.192 74 | 44.48.17.0 255.255.255.252 75 | 44.48.16.0 255.255.255.0 76 | 44.48.15.0 255.255.255.248 77 | 44.48.128.0 255.255.255.0 78 | 44.48.12.0 255.255.255.0 79 | 44.48.0.40 255.255.255.248 80 | 44.46.64.0 255.255.255.0 81 | 44.46.32.0 255.255.255.0 82 | 44.46.128.0 255.255.255.0 83 | 44.46.0.11 255.255.255.255 84 | 44.44.7.144 255.255.255.248 85 | 44.44.7.128 255.255.255.248 86 | 44.44.6.32 255.255.255.248 87 | 44.44.107.0 255.255.255.0 88 | 44.44.10.0 255.255.255.248 89 | 44.42.128.0 255.255.255.0 90 | 44.40.64.0 255.255.255.240 91 | 44.40.128.0 255.255.255.0 92 | 44.40.1.40 255.255.255.248 93 | 44.4.50.9 255.255.255.255 94 | 44.4.50.6 255.255.255.255 95 | 44.4.50.5 255.255.255.255 96 | 44.4.50.4 255.255.255.255 97 | 44.4.50.36 255.255.255.252 98 | 44.4.50.32 255.255.255.252 99 | 44.4.50.3 255.255.255.255 100 | 44.4.50.28 255.255.255.252 101 | 44.4.50.24 255.255.255.252 102 | 44.4.50.20 255.255.255.252 103 | 44.4.50.2 255.255.255.255 104 | 44.4.50.16 255.255.255.252 105 | 44.4.50.14 255.255.255.255 106 | 44.4.50.13 255.255.255.255 107 | 44.4.50.12 255.255.255.255 108 | 44.4.50.11 255.255.255.255 109 | 44.4.50.10 255.255.255.255 110 | 44.4.50.1 255.255.255.255 111 | 44.4.4.64 255.255.255.224 112 | 44.4.39.0 255.255.255.248 113 | 44.4.38.27 255.255.255.255 114 | 44.4.2.152 255.255.255.248 115 | 44.4.140.0 255.255.255.0 116 | 44.4.138.0 255.255.255.240 117 | 44.4.12.0 255.255.255.0 118 | 44.4.10.40 255.255.255.255 119 | 44.36.8.0 255.255.255.240 120 | 44.36.0.0 255.255.255.0 121 | 44.34.255.0 255.255.255.192 122 | 44.26.1.40 255.255.255.248 123 | 44.26.1.32 255.255.255.248 124 | 44.26.0.160 255.255.255.252 125 | 44.24.24.8 255.255.255.255 126 | 44.24.194.0 255.255.255.0 127 | 44.24.172.64 255.255.255.192 128 | 44.24.125.0 255.255.255.0 129 | 44.24.10.0 255.255.255.0 130 | 44.24.0.0 255.255.240.0 131 | 44.224.0.0 255.254.0.0 132 | 44.22.128.0 255.255.255.0 133 | 44.208.58.0 255.255.255.240 134 | 44.208.0.0 255.255.0.0 135 | 44.20.42.0 255.255.255.0 136 | 44.20.2.0 255.255.254.0 137 | 44.20.100.0 255.255.255.248 138 | 44.20.1.0 255.255.255.0 139 | 44.2.9.0 255.255.255.248 140 | 44.2.50.0 255.255.255.248 141 | 44.2.5.0 255.255.255.128 142 | 44.2.2.0 255.255.255.0 143 | 44.2.14.0 255.255.255.248 144 | 44.2.10.0 255.255.255.248 145 | 44.188.192.222 255.255.255.255 146 | 44.188.192.221 255.255.255.255 147 | 44.188.128.0 255.255.240.0 148 | 44.188.1.1 255.255.255.255 149 | 44.185.96.0 255.255.255.0 150 | 44.185.92.0 255.255.255.0 151 | 44.185.80.0 255.255.255.0 152 | 44.185.69.0 255.255.255.0 153 | 44.185.66.0 255.255.255.0 154 | 44.185.5.0 255.255.255.0 155 | 44.185.44.0 255.255.255.252 156 | 44.185.4.0 255.255.255.0 157 | 44.185.2.64 255.255.255.192 158 | 44.185.185.0 255.255.255.0 159 | 44.185.11.0 255.255.255.0 160 | 44.185.10.0 255.255.255.0 161 | 44.185.1.0 255.255.255.0 162 | 44.182.83.0 255.255.255.0 163 | 44.182.69.0 255.255.255.0 164 | 44.182.62.0 255.255.255.0 165 | 44.182.60.0 255.255.255.248 166 | 44.182.30.0 255.255.255.0 167 | 44.182.21.2 255.255.255.254 168 | 44.182.21.0 255.255.255.0 169 | 44.182.20.0 255.255.255.0 170 | 44.180.0.0 255.255.255.252 171 | 44.18.44.0 255.255.255.0 172 | 44.18.0.208 255.255.255.240 173 | 44.18.0.185 255.255.255.255 174 | 44.178.74.0 255.255.255.248 175 | 44.178.224.0 255.255.255.248 176 | 44.178.224.0 255.255.255.0 177 | 44.177.11.0 255.255.255.240 178 | 44.177.10.254 255.255.255.255 179 | 44.177.10.253 255.255.255.255 180 | 44.177.10.10 255.255.255.255 181 | 44.174.77.10 255.255.255.255 182 | 44.174.6.0 255.255.255.0 183 | 44.174.43.0 255.255.255.0 184 | 44.174.3.0 255.255.255.0 185 | 44.174.27.0 255.255.255.0 186 | 44.170.0.0 255.255.0.0 187 | 44.17.0.128 255.255.255.254 188 | 44.168.51.0 255.255.255.224 189 | 44.168.50.0 255.255.255.0 190 | 44.168.44.0 255.255.255.0 191 | 44.168.40.0 255.255.255.0 192 | 44.168.254.96 255.255.255.240 193 | 44.168.254.80 255.255.255.248 194 | 44.168.254.72 255.255.255.248 195 | 44.168.254.40 255.255.255.248 196 | 44.168.254.36 255.255.255.252 197 | 44.168.254.32 255.255.255.252 198 | 44.168.254.168 255.255.255.252 199 | 44.168.254.160 255.255.255.248 200 | 44.168.254.140 255.255.255.252 201 | 44.168.254.12 255.255.255.252 202 | 44.168.16.0 255.255.240.0 203 | 44.168.12.0 255.255.252.0 204 | 44.165.81.0 255.255.255.240 205 | 44.165.80.0 255.255.255.0 206 | 44.165.69.0 255.255.255.0 207 | 44.165.68.0 255.255.255.0 208 | 44.165.64.0 255.255.255.0 209 | 44.165.53.0 255.255.255.0 210 | 44.165.51.0 255.255.255.0 211 | 44.165.44.0 255.255.255.0 212 | 44.165.33.0 255.255.255.0 213 | 44.165.32.0 255.255.255.0 214 | 44.165.25.0 255.255.255.0 215 | 44.165.2.0 255.255.255.128 216 | 44.165.152.0 255.255.255.0 217 | 44.165.15.0 255.255.255.0 218 | 44.165.145.0 255.255.255.0 219 | 44.165.129.0 255.255.255.0 220 | 44.165.111.0 255.255.255.240 221 | 44.165.108.0 255.255.255.0 222 | 44.165.104.0 255.255.255.0 223 | 44.165.100.0 255.255.255.0 224 | 44.163.32.0 255.255.248.0 225 | 44.163.22.0 255.255.255.0 226 | 44.163.144.32 255.255.255.240 227 | 44.163.144.0 255.255.240.0 228 | 44.161.252.0 255.255.252.0 229 | 44.161.239.64 255.255.255.192 230 | 44.161.239.192 255.255.255.192 231 | 44.161.239.128 255.255.255.192 232 | 44.161.239.0 255.255.255.192 233 | 44.161.230.0 255.255.255.0 234 | 44.161.223.128 255.255.255.128 235 | 44.161.223.0 255.255.255.128 236 | 44.161.222.128 255.255.255.128 237 | 44.161.222.0 255.255.255.128 238 | 44.161.205.0 255.255.255.0 239 | 44.161.204.0 255.255.255.0 240 | 44.161.0.0 255.255.0.0 241 | 44.16.9.1 255.255.255.255 242 | 44.16.5.0 255.255.255.224 243 | 44.16.4.32 255.255.255.248 244 | 44.16.3.0 255.255.255.0 245 | 44.16.2.32 255.255.255.224 246 | 44.16.0.0 255.255.255.248 247 | 44.158.152.0 255.255.254.0 248 | 44.158.144.0 255.255.252.0 249 | 44.156.64.0 255.255.255.0 250 | 44.155.8.0 255.255.255.0 251 | 44.155.6.0 255.255.255.0 252 | 44.154.66.0 255.255.255.0 253 | 44.154.65.0 255.255.255.0 254 | 44.154.64.0 255.255.255.0 255 | 44.154.0.0 255.255.192.0 256 | 44.153.81.0 255.255.255.0 257 | 44.153.72.13 255.255.255.255 258 | 44.153.56.0 255.255.254.0 259 | 44.153.55.0 255.255.255.0 260 | 44.153.54.64 255.255.255.192 261 | 44.153.54.32 255.255.255.224 262 | 44.153.54.28 255.255.255.252 263 | 44.153.54.24 255.255.255.252 264 | 44.153.54.23 255.255.255.255 265 | 44.153.54.22 255.255.255.255 266 | 44.153.54.21 255.255.255.255 267 | 44.153.54.20 255.255.255.255 268 | 44.153.54.16 255.255.255.252 269 | 44.153.54.128 255.255.255.128 270 | 44.153.54.0 255.255.255.240 271 | 44.153.52.0 255.255.255.0 272 | 44.153.0.0 255.255.254.0 273 | 44.152.0.0 255.255.0.0 274 | 44.151.95.29 255.255.255.255 275 | 44.151.92.22 255.255.255.255 276 | 44.151.92.21 255.255.255.255 277 | 44.151.92.10 255.255.255.255 278 | 44.151.91.7 255.255.255.255 279 | 44.151.91.13 255.255.255.255 280 | 44.151.91.12 255.255.255.255 281 | 44.151.78.130 255.255.255.255 282 | 44.151.75.15 255.255.255.255 283 | 44.151.74.102 255.255.255.255 284 | 44.151.73.4 255.255.255.255 285 | 44.151.69.52 255.255.255.255 286 | 44.151.68.100 255.255.255.255 287 | 44.151.67.100 255.255.255.255 288 | 44.151.6.9 255.255.255.255 289 | 44.151.59.2 255.255.255.255 290 | 44.151.59.1 255.255.255.255 291 | 44.151.57.57 255.255.255.255 292 | 44.151.57.32 255.255.255.255 293 | 44.151.54.29 255.255.255.255 294 | 44.151.54.2 255.255.255.255 295 | 44.151.50.19 255.255.255.255 296 | 44.151.5.2 255.255.255.255 297 | 44.151.5.1 255.255.255.255 298 | 44.151.44.69 255.255.255.255 299 | 44.151.44.55 255.255.255.255 300 | 44.151.38.55 255.255.255.255 301 | 44.151.37.1 255.255.255.255 302 | 44.151.29.1 255.255.255.255 303 | 44.151.240.66 255.255.255.255 304 | 44.151.240.16 255.255.255.255 305 | 44.151.24.5 255.255.255.255 306 | 44.151.24.3 255.255.255.255 307 | 44.151.24.1 255.255.255.255 308 | 44.151.22.2 255.255.255.255 309 | 44.151.22.1 255.255.255.255 310 | 44.151.219.0 255.255.255.224 311 | 44.151.20.1 255.255.255.255 312 | 44.151.178.0 255.255.255.0 313 | 44.151.17.55 255.255.255.255 314 | 44.151.17.10 255.255.255.255 315 | 44.151.1.5 255.255.255.255 316 | 44.151.1.44 255.255.255.255 317 | 44.150.1.48 255.255.255.255 318 | 44.150.1.0 255.255.255.0 319 | 44.147.86.16 255.255.255.248 320 | 44.147.210.0 255.255.255.0 321 | 44.147.200.160 255.255.255.252 322 | 44.144.5.0 255.255.255.0 323 | 44.144.47.0 255.255.255.240 324 | 44.144.46.240 255.255.255.240 325 | 44.144.121.0 255.255.255.0 326 | 44.144.120.0 255.255.255.0 327 | 44.143.0.0 255.255.0.0 328 | 44.142.0.0 255.255.0.0 329 | 44.141.122.0 255.255.255.0 330 | 44.14.0.8 255.255.255.248 331 | 44.14.0.2 255.255.255.255 332 | 44.14.0.16 255.255.255.248 333 | 44.14.0.1 255.255.255.255 334 | 44.139.44.0 255.255.255.128 335 | 44.139.39.0 255.255.255.0 336 | 44.139.11.0 255.255.255.0 337 | 44.138.3.0 255.255.255.248 338 | 44.138.2.0 255.255.255.0 339 | 44.138.1.0 255.255.255.0 340 | 44.138.0.16 255.255.255.240 341 | 44.137.41.128 255.255.255.240 342 | 44.137.40.20 255.255.255.255 343 | 44.137.40.2 255.255.255.255 344 | 44.137.40.10 255.255.255.255 345 | 44.137.40.1 255.255.255.255 346 | 44.137.37.192 255.255.255.240 347 | 44.137.33.48 255.255.255.240 348 | 44.137.33.32 255.255.255.240 349 | 44.137.33.16 255.255.255.240 350 | 44.137.32.50 255.255.255.255 351 | 44.137.31.64 255.255.255.224 352 | 44.137.27.193 255.255.255.255 353 | 44.137.27.112 255.255.255.240 354 | 44.137.24.5 255.255.255.255 355 | 44.137.24.242 255.255.255.255 356 | 44.137.24.147 255.255.255.255 357 | 44.137.24.1 255.255.255.255 358 | 44.137.1.80 255.255.255.240 359 | 44.137.1.208 255.255.255.240 360 | 44.137.1.160 255.255.255.240 361 | 44.137.0.49 255.255.255.255 362 | 44.137.0.0 255.255.0.0 363 | 44.136.96.0 255.255.255.0 364 | 44.136.92.0 255.255.255.0 365 | 44.136.9.0 255.255.255.0 366 | 44.136.83.144 255.255.255.240 367 | 44.136.83.0 255.255.255.0 368 | 44.136.72.0 255.255.252.0 369 | 44.136.227.0 255.255.255.0 370 | 44.136.224.44 255.255.255.252 371 | 44.136.224.34 255.255.255.255 372 | 44.136.224.32 255.255.255.255 373 | 44.136.209.0 255.255.255.0 374 | 44.136.204.0 255.255.255.0 375 | 44.136.16.0 255.255.255.0 376 | 44.136.142.240 255.255.255.240 377 | 44.136.126.0 255.255.255.0 378 | 44.136.0.0 255.255.248.0 379 | 44.135.96.64 255.255.255.192 380 | 44.135.94.0 255.255.254.0 381 | 44.135.93.0 255.255.255.240 382 | 44.135.92.128 255.255.255.248 383 | 44.135.92.0 255.255.255.0 384 | 44.135.91.0 255.255.255.0 385 | 44.135.90.42 255.255.255.255 386 | 44.135.90.3 255.255.255.255 387 | 44.135.90.2 255.255.255.255 388 | 44.135.90.128 255.255.255.128 389 | 44.135.90.0 255.255.255.0 390 | 44.135.89.192 255.255.255.192 391 | 44.135.88.0 255.255.255.0 392 | 44.135.86.0 255.255.255.0 393 | 44.135.85.56 255.255.255.255 394 | 44.135.85.0 255.255.255.0 395 | 44.135.84.16 255.255.255.240 396 | 44.135.83.24 255.255.255.255 397 | 44.135.83.23 255.255.255.255 398 | 44.135.83.22 255.255.255.255 399 | 44.135.83.21 255.255.255.255 400 | 44.135.82.0 255.255.255.0 401 | 44.135.74.0 255.255.255.240 402 | 44.135.71.0 255.255.255.0 403 | 44.135.68.0 255.255.255.240 404 | 44.135.62.0 255.255.255.192 405 | 44.135.56.0 255.255.255.0 406 | 44.135.55.0 255.255.255.248 407 | 44.135.52.0 255.255.255.0 408 | 44.135.50.0 255.255.255.192 409 | 44.135.49.0 255.255.255.224 410 | 44.135.48.0 255.255.255.0 411 | 44.135.43.0 255.255.255.248 412 | 44.135.32.0 255.255.255.0 413 | 44.135.195.0 255.255.255.0 414 | 44.135.193.0 255.255.255.0 415 | 44.135.192.96 255.255.255.248 416 | 44.135.192.80 255.255.255.248 417 | 44.135.192.32 255.255.255.248 418 | 44.135.192.160 255.255.255.248 419 | 44.135.188.0 255.255.252.0 420 | 44.135.186.0 255.255.255.0 421 | 44.135.160.40 255.255.255.255 422 | 44.135.16.0 255.255.252.0 423 | 44.135.156.0 255.255.255.0 424 | 44.135.147.0 255.255.255.0 425 | 44.135.124.0 255.255.255.0 426 | 44.135.105.0 255.255.255.0 427 | 44.135.104.128 255.255.255.128 428 | 44.135.103.128 255.255.255.252 429 | 44.134.96.0 255.255.240.0 430 | 44.134.64.0 255.255.224.0 431 | 44.134.48.0 255.255.255.0 432 | 44.134.34.0 255.255.255.0 433 | 44.134.33.71 255.255.255.255 434 | 44.134.33.0 255.255.255.0 435 | 44.134.32.240 255.255.255.255 436 | 44.134.32.233 255.255.255.255 437 | 44.134.32.0 255.255.255.0 438 | 44.134.240.0 255.255.240.0 439 | 44.134.224.0 255.255.240.0 440 | 44.134.208.0 255.255.240.0 441 | 44.134.192.0 255.255.240.0 442 | 44.134.190.0 255.255.254.0 443 | 44.134.189.0 255.255.255.0 444 | 44.134.185.0 255.255.255.0 445 | 44.134.181.0 255.255.255.0 446 | 44.134.180.0 255.255.255.0 447 | 44.134.178.0 255.255.255.0 448 | 44.134.177.0 255.255.255.0 449 | 44.134.160.0 255.255.240.0 450 | 44.134.128.0 255.255.224.0 451 | 44.134.0.0 255.255.240.0 452 | 44.133.8.13 255.255.255.255 453 | 44.133.47.6 255.255.255.255 454 | 44.133.47.10 255.255.255.255 455 | 44.133.32.11 255.255.255.255 456 | 44.133.3.39 255.255.255.255 457 | 44.133.28.155 255.255.255.255 458 | 44.133.17.50 255.255.255.255 459 | 44.133.128.0 255.255.128.0 460 | 44.131.96.32 255.255.255.248 461 | 44.131.91.0 255.255.255.0 462 | 44.131.8.32 255.255.255.224 463 | 44.131.8.0 255.255.255.0 464 | 44.131.7.0 255.255.255.0 465 | 44.131.68.32 255.255.255.248 466 | 44.131.56.8 255.255.255.248 467 | 44.131.56.0 255.255.255.248 468 | 44.131.244.0 255.255.255.0 469 | 44.131.243.0 255.255.255.0 470 | 44.131.242.0 255.255.255.0 471 | 44.131.241.0 255.255.255.0 472 | 44.131.240.0 255.255.255.0 473 | 44.131.220.36 255.255.255.252 474 | 44.131.218.0 255.255.255.248 475 | 44.131.218.0 255.255.255.0 476 | 44.131.210.0 255.255.255.255 477 | 44.131.210.0 255.255.255.0 478 | 44.131.189.8 255.255.255.248 479 | 44.131.189.0 255.255.255.248 480 | 44.131.182.0 255.255.255.0 481 | 44.131.176.0 255.255.255.224 482 | 44.131.170.8 255.255.255.248 483 | 44.131.170.0 255.255.255.252 484 | 44.131.168.128 255.255.255.248 485 | 44.131.162.0 255.255.255.0 486 | 44.131.161.0 255.255.255.0 487 | 44.131.160.0 255.255.255.0 488 | 44.131.156.103 255.255.255.255 489 | 44.131.156.0 255.255.255.252 490 | 44.131.152.2 255.255.255.255 491 | 44.131.152.1 255.255.255.255 492 | 44.131.151.0 255.255.255.240 493 | 44.131.144.0 255.255.252.0 494 | 44.131.128.0 255.255.240.0 495 | 44.131.121.0 255.255.255.0 496 | 44.131.11.0 255.255.255.248 497 | 44.130.240.6 255.255.255.255 498 | 44.130.240.2 255.255.255.255 499 | 44.130.224.32 255.255.255.224 500 | 44.130.224.0 255.255.255.240 501 | 44.130.0.0 255.255.0.0 502 | 44.129.16.0 255.255.255.0 503 | 44.129.128.0 255.255.255.0 504 | 44.127.192.0 255.255.255.0 505 | 44.125.2.0 255.255.255.0 506 | 44.12.3.96 255.255.255.224 507 | 44.12.3.136 255.255.255.248 508 | 44.12.3.128 255.255.255.248 509 | 44.118.5.0 255.255.255.248 510 | 44.116.3.64 255.255.255.224 511 | 44.108.180.0 255.255.255.0 512 | 44.102.56.0 255.255.255.0 513 | 44.102.48.0 255.255.255.0 514 | 44.102.24.0 255.255.255.0 515 | 44.102.238.0 255.255.255.0 516 | 44.102.216.0 255.255.254.0 517 | 44.102.200.0 255.255.252.0 518 | 44.102.176.0 255.255.255.0 519 | 44.102.172.0 255.255.252.0 520 | 44.102.170.0 255.255.254.0 521 | 44.102.168.0 255.255.255.0 522 | 44.102.166.0 255.255.255.0 523 | 44.102.134.0 255.255.255.0 524 | 44.102.132.0 255.255.255.0 525 | 44.102.128.0 255.255.255.0 526 | 44.102.104.0 255.255.255.0 527 | 44.102.100.0 255.255.255.0 528 | 44.102.1.0 255.255.255.0 529 | 44.10.192.1 255.255.255.255 530 | 44.10.192.0 255.255.255.0 531 | 44.10.0.0 255.255.255.224 532 | -------------------------------------------------------------------------------- /testisvalidnetmask.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "dat.h" 9 | #include "fns.h" 10 | 11 | void 12 | test(char *snetmask, int expected) 13 | { 14 | if (isvalidnetmask(ntohl(inet_addr(snetmask))) != expected) { 15 | printf("isvalidnetmask(\"%s\") != %d\n", snetmask, expected); 16 | } 17 | } 18 | 19 | int 20 | main(void) 21 | { 22 | // Test all valid netmasks explicitly. 23 | test("255.255.255.255", true); 24 | test("255.255.255.254", true); 25 | test("255.255.255.252", true); 26 | test("255.255.255.248", true); 27 | test("255.255.255.240", true); 28 | test("255.255.255.224", true); 29 | test("255.255.255.192", true); 30 | test("255.255.255.128", true); 31 | test("255.255.255.0", true); 32 | test("255.255.254.0", true); 33 | test("255.255.252.0", true); 34 | test("255.255.248.0", true); 35 | test("255.255.240.0", true); 36 | test("255.255.224.0", true); 37 | test("255.255.192.0", true); 38 | test("255.255.128.0", true); 39 | test("255.255.0.0", true); 40 | test("255.254.0.0", true); 41 | test("255.252.0.0", true); 42 | test("255.248.0.0", true); 43 | test("255.240.0.0", true); 44 | test("255.224.0.0", true); 45 | test("255.192.0.0", true); 46 | test("255.128.0.0", true); 47 | test("255.0.0.0", true); 48 | test("254.0.0.0", true); 49 | test("252.0.0.0", true); 50 | test("248.0.0.0", true); 51 | test("240.0.0.0", true); 52 | test("224.0.0.0", true); 53 | test("192.0.0.0", true); 54 | test("128.0.0.0", true); 55 | test("0.0.0.0", true); 56 | 57 | // Test all permutations of the last octet. 58 | test("255.255.255.1", false); 59 | test("255.255.255.2", false); 60 | test("255.255.255.3", false); 61 | test("255.255.255.4", false); 62 | test("255.255.255.5", false); 63 | test("255.255.255.6", false); 64 | test("255.255.255.7", false); 65 | test("255.255.255.8", false); 66 | test("255.255.255.9", false); 67 | test("255.255.255.10", false); 68 | test("255.255.255.11", false); 69 | test("255.255.255.12", false); 70 | test("255.255.255.13", false); 71 | test("255.255.255.14", false); 72 | test("255.255.255.15", false); 73 | test("255.255.255.16", false); 74 | test("255.255.255.17", false); 75 | test("255.255.255.18", false); 76 | test("255.255.255.19", false); 77 | test("255.255.255.20", false); 78 | test("255.255.255.21", false); 79 | test("255.255.255.22", false); 80 | test("255.255.255.23", false); 81 | test("255.255.255.24", false); 82 | test("255.255.255.25", false); 83 | test("255.255.255.26", false); 84 | test("255.255.255.27", false); 85 | test("255.255.255.28", false); 86 | test("255.255.255.29", false); 87 | test("255.255.255.30", false); 88 | test("255.255.255.31", false); 89 | test("255.255.255.32", false); 90 | test("255.255.255.33", false); 91 | test("255.255.255.34", false); 92 | test("255.255.255.35", false); 93 | test("255.255.255.36", false); 94 | test("255.255.255.37", false); 95 | test("255.255.255.38", false); 96 | test("255.255.255.39", false); 97 | test("255.255.255.40", false); 98 | test("255.255.255.41", false); 99 | test("255.255.255.42", false); 100 | test("255.255.255.43", false); 101 | test("255.255.255.44", false); 102 | test("255.255.255.45", false); 103 | test("255.255.255.46", false); 104 | test("255.255.255.47", false); 105 | test("255.255.255.48", false); 106 | test("255.255.255.49", false); 107 | test("255.255.255.50", false); 108 | test("255.255.255.51", false); 109 | test("255.255.255.52", false); 110 | test("255.255.255.53", false); 111 | test("255.255.255.54", false); 112 | test("255.255.255.55", false); 113 | test("255.255.255.56", false); 114 | test("255.255.255.57", false); 115 | test("255.255.255.58", false); 116 | test("255.255.255.59", false); 117 | test("255.255.255.60", false); 118 | test("255.255.255.61", false); 119 | test("255.255.255.62", false); 120 | test("255.255.255.63", false); 121 | test("255.255.255.64", false); 122 | test("255.255.255.65", false); 123 | test("255.255.255.66", false); 124 | test("255.255.255.67", false); 125 | test("255.255.255.68", false); 126 | test("255.255.255.69", false); 127 | test("255.255.255.70", false); 128 | test("255.255.255.71", false); 129 | test("255.255.255.72", false); 130 | test("255.255.255.73", false); 131 | test("255.255.255.74", false); 132 | test("255.255.255.75", false); 133 | test("255.255.255.76", false); 134 | test("255.255.255.77", false); 135 | test("255.255.255.78", false); 136 | test("255.255.255.79", false); 137 | test("255.255.255.80", false); 138 | test("255.255.255.81", false); 139 | test("255.255.255.82", false); 140 | test("255.255.255.83", false); 141 | test("255.255.255.84", false); 142 | test("255.255.255.85", false); 143 | test("255.255.255.86", false); 144 | test("255.255.255.87", false); 145 | test("255.255.255.88", false); 146 | test("255.255.255.89", false); 147 | test("255.255.255.90", false); 148 | test("255.255.255.91", false); 149 | test("255.255.255.92", false); 150 | test("255.255.255.93", false); 151 | test("255.255.255.94", false); 152 | test("255.255.255.95", false); 153 | test("255.255.255.96", false); 154 | test("255.255.255.97", false); 155 | test("255.255.255.98", false); 156 | test("255.255.255.99", false); 157 | test("255.255.255.100", false); 158 | test("255.255.255.101", false); 159 | test("255.255.255.102", false); 160 | test("255.255.255.103", false); 161 | test("255.255.255.104", false); 162 | test("255.255.255.105", false); 163 | test("255.255.255.106", false); 164 | test("255.255.255.107", false); 165 | test("255.255.255.108", false); 166 | test("255.255.255.109", false); 167 | test("255.255.255.110", false); 168 | test("255.255.255.111", false); 169 | test("255.255.255.112", false); 170 | test("255.255.255.113", false); 171 | test("255.255.255.114", false); 172 | test("255.255.255.115", false); 173 | test("255.255.255.116", false); 174 | test("255.255.255.117", false); 175 | test("255.255.255.118", false); 176 | test("255.255.255.119", false); 177 | test("255.255.255.120", false); 178 | test("255.255.255.121", false); 179 | test("255.255.255.122", false); 180 | test("255.255.255.123", false); 181 | test("255.255.255.124", false); 182 | test("255.255.255.125", false); 183 | test("255.255.255.126", false); 184 | test("255.255.255.127", false); 185 | test("255.255.255.129", false); 186 | test("255.255.255.130", false); 187 | test("255.255.255.131", false); 188 | test("255.255.255.132", false); 189 | test("255.255.255.133", false); 190 | test("255.255.255.134", false); 191 | test("255.255.255.135", false); 192 | test("255.255.255.136", false); 193 | test("255.255.255.137", false); 194 | test("255.255.255.138", false); 195 | test("255.255.255.139", false); 196 | test("255.255.255.140", false); 197 | test("255.255.255.141", false); 198 | test("255.255.255.142", false); 199 | test("255.255.255.143", false); 200 | test("255.255.255.144", false); 201 | test("255.255.255.145", false); 202 | test("255.255.255.146", false); 203 | test("255.255.255.147", false); 204 | test("255.255.255.148", false); 205 | test("255.255.255.149", false); 206 | test("255.255.255.150", false); 207 | test("255.255.255.151", false); 208 | test("255.255.255.152", false); 209 | test("255.255.255.153", false); 210 | test("255.255.255.154", false); 211 | test("255.255.255.155", false); 212 | test("255.255.255.156", false); 213 | test("255.255.255.157", false); 214 | test("255.255.255.158", false); 215 | test("255.255.255.159", false); 216 | test("255.255.255.160", false); 217 | test("255.255.255.161", false); 218 | test("255.255.255.162", false); 219 | test("255.255.255.163", false); 220 | test("255.255.255.164", false); 221 | test("255.255.255.165", false); 222 | test("255.255.255.166", false); 223 | test("255.255.255.167", false); 224 | test("255.255.255.168", false); 225 | test("255.255.255.169", false); 226 | test("255.255.255.170", false); 227 | test("255.255.255.171", false); 228 | test("255.255.255.172", false); 229 | test("255.255.255.173", false); 230 | test("255.255.255.174", false); 231 | test("255.255.255.175", false); 232 | test("255.255.255.176", false); 233 | test("255.255.255.177", false); 234 | test("255.255.255.178", false); 235 | test("255.255.255.179", false); 236 | test("255.255.255.180", false); 237 | test("255.255.255.181", false); 238 | test("255.255.255.182", false); 239 | test("255.255.255.183", false); 240 | test("255.255.255.184", false); 241 | test("255.255.255.185", false); 242 | test("255.255.255.186", false); 243 | test("255.255.255.187", false); 244 | test("255.255.255.188", false); 245 | test("255.255.255.189", false); 246 | test("255.255.255.190", false); 247 | test("255.255.255.191", false); 248 | test("255.255.255.193", false); 249 | test("255.255.255.194", false); 250 | test("255.255.255.195", false); 251 | test("255.255.255.196", false); 252 | test("255.255.255.197", false); 253 | test("255.255.255.198", false); 254 | test("255.255.255.199", false); 255 | test("255.255.255.200", false); 256 | test("255.255.255.201", false); 257 | test("255.255.255.202", false); 258 | test("255.255.255.203", false); 259 | test("255.255.255.204", false); 260 | test("255.255.255.205", false); 261 | test("255.255.255.206", false); 262 | test("255.255.255.207", false); 263 | test("255.255.255.208", false); 264 | test("255.255.255.209", false); 265 | test("255.255.255.210", false); 266 | test("255.255.255.211", false); 267 | test("255.255.255.212", false); 268 | test("255.255.255.213", false); 269 | test("255.255.255.214", false); 270 | test("255.255.255.215", false); 271 | test("255.255.255.216", false); 272 | test("255.255.255.217", false); 273 | test("255.255.255.218", false); 274 | test("255.255.255.219", false); 275 | test("255.255.255.220", false); 276 | test("255.255.255.221", false); 277 | test("255.255.255.222", false); 278 | test("255.255.255.223", false); 279 | test("255.255.255.225", false); 280 | test("255.255.255.226", false); 281 | test("255.255.255.227", false); 282 | test("255.255.255.228", false); 283 | test("255.255.255.229", false); 284 | test("255.255.255.230", false); 285 | test("255.255.255.231", false); 286 | test("255.255.255.232", false); 287 | test("255.255.255.233", false); 288 | test("255.255.255.234", false); 289 | test("255.255.255.235", false); 290 | test("255.255.255.236", false); 291 | test("255.255.255.237", false); 292 | test("255.255.255.238", false); 293 | test("255.255.255.239", false); 294 | test("255.255.255.241", false); 295 | test("255.255.255.242", false); 296 | test("255.255.255.243", false); 297 | test("255.255.255.244", false); 298 | test("255.255.255.245", false); 299 | test("255.255.255.246", false); 300 | test("255.255.255.247", false); 301 | test("255.255.255.249", false); 302 | test("255.255.255.250", false); 303 | test("255.255.255.251", false); 304 | test("255.255.255.253", false); 305 | test("255.255.255.255", true); 306 | 307 | // Probe a few other values. 308 | test("44.0.0.1", false); 309 | test("127.0.0.1", false); 310 | test("255.255.191.0", false); 311 | test("255.255.254.1", false); 312 | test("255.255.254.2", false); 313 | test("255.255.254.3", false); 314 | test("255.255.254.4", false); 315 | test("255.255.254.5", false); 316 | test("255.255.254.6", false); 317 | test("255.255.254.7", false); 318 | test("255.255.254.8", false); 319 | test("255.255.254.9", false); 320 | test("255.255.254.10", false); 321 | test("255.255.254.11", false); 322 | test("255.255.254.12", false); 323 | test("255.255.254.13", false); 324 | test("255.255.254.14", false); 325 | test("255.255.254.15", false); 326 | test("255.255.254.16", false); 327 | test("255.255.254.17", false); 328 | test("255.255.254.18", false); 329 | test("255.255.254.19", false); 330 | test("255.255.254.20", false); 331 | test("255.255.254.21", false); 332 | test("255.255.254.22", false); 333 | test("255.255.254.23", false); 334 | test("255.255.254.24", false); 335 | test("255.255.254.25", false); 336 | test("255.255.254.26", false); 337 | test("255.255.254.27", false); 338 | test("255.255.254.28", false); 339 | test("255.255.254.29", false); 340 | test("255.255.254.30", false); 341 | test("255.255.254.31", false); 342 | test("255.255.254.32", false); 343 | test("255.255.254.33", false); 344 | test("255.255.254.34", false); 345 | test("255.255.254.35", false); 346 | test("255.255.254.36", false); 347 | test("255.255.254.37", false); 348 | test("255.255.254.38", false); 349 | test("255.255.254.39", false); 350 | test("255.255.254.40", false); 351 | test("255.255.254.41", false); 352 | test("255.255.254.42", false); 353 | test("255.255.254.43", false); 354 | test("255.255.254.44", false); 355 | test("255.255.254.45", false); 356 | test("255.255.254.46", false); 357 | test("255.255.254.47", false); 358 | test("255.255.254.48", false); 359 | test("255.255.254.49", false); 360 | test("255.255.254.50", false); 361 | test("255.255.254.51", false); 362 | test("255.255.254.52", false); 363 | test("255.255.254.53", false); 364 | test("255.255.254.54", false); 365 | test("255.255.254.55", false); 366 | test("255.255.254.56", false); 367 | test("255.255.254.57", false); 368 | test("255.255.254.58", false); 369 | test("255.255.254.59", false); 370 | test("255.255.254.60", false); 371 | test("255.255.254.61", false); 372 | test("255.255.254.62", false); 373 | test("255.255.254.63", false); 374 | test("255.255.254.64", false); 375 | test("255.255.254.65", false); 376 | test("255.255.254.66", false); 377 | test("255.255.254.67", false); 378 | test("255.255.254.68", false); 379 | test("255.255.254.69", false); 380 | test("255.255.254.70", false); 381 | test("255.255.254.71", false); 382 | test("255.255.254.72", false); 383 | test("255.255.254.73", false); 384 | test("255.255.254.74", false); 385 | test("255.255.254.75", false); 386 | test("255.255.254.76", false); 387 | test("255.255.254.77", false); 388 | test("255.255.254.78", false); 389 | test("255.255.254.79", false); 390 | test("255.255.254.80", false); 391 | test("255.255.254.81", false); 392 | test("255.255.254.82", false); 393 | test("255.255.254.83", false); 394 | test("255.255.254.84", false); 395 | test("255.255.254.85", false); 396 | test("255.255.254.86", false); 397 | test("255.255.254.87", false); 398 | test("255.255.254.88", false); 399 | test("255.255.254.89", false); 400 | test("255.255.254.90", false); 401 | test("255.255.254.91", false); 402 | test("255.255.254.92", false); 403 | test("255.255.254.93", false); 404 | test("255.255.254.94", false); 405 | test("255.255.254.95", false); 406 | test("255.255.254.96", false); 407 | test("255.255.254.97", false); 408 | test("255.255.254.98", false); 409 | test("255.255.254.99", false); 410 | test("255.255.254.100", false); 411 | test("255.255.254.101", false); 412 | test("255.255.254.102", false); 413 | test("255.255.254.103", false); 414 | test("255.255.254.104", false); 415 | test("255.255.254.105", false); 416 | test("255.255.254.106", false); 417 | test("255.255.254.107", false); 418 | test("255.255.254.108", false); 419 | test("255.255.254.109", false); 420 | test("255.255.254.110", false); 421 | test("255.255.254.111", false); 422 | test("255.255.254.112", false); 423 | test("255.255.254.113", false); 424 | test("255.255.254.114", false); 425 | test("255.255.254.115", false); 426 | test("255.255.254.116", false); 427 | test("255.255.254.117", false); 428 | test("255.255.254.118", false); 429 | test("255.255.254.119", false); 430 | test("255.255.254.120", false); 431 | test("255.255.254.121", false); 432 | test("255.255.254.122", false); 433 | test("255.255.254.123", false); 434 | test("255.255.254.124", false); 435 | test("255.255.254.125", false); 436 | test("255.255.254.126", false); 437 | test("255.255.254.127", false); 438 | test("255.255.254.128", false); 439 | test("255.255.254.129", false); 440 | test("255.255.254.130", false); 441 | test("255.255.254.131", false); 442 | test("255.255.254.132", false); 443 | test("255.255.254.133", false); 444 | test("255.255.254.134", false); 445 | test("255.255.254.135", false); 446 | test("255.255.254.136", false); 447 | test("255.255.254.137", false); 448 | test("255.255.254.138", false); 449 | test("255.255.254.139", false); 450 | test("255.255.254.140", false); 451 | test("255.255.254.141", false); 452 | test("255.255.254.142", false); 453 | test("255.255.254.143", false); 454 | test("255.255.254.144", false); 455 | test("255.255.254.145", false); 456 | test("255.255.254.146", false); 457 | test("255.255.254.147", false); 458 | test("255.255.254.148", false); 459 | test("255.255.254.149", false); 460 | test("255.255.254.150", false); 461 | test("255.255.254.151", false); 462 | test("255.255.254.152", false); 463 | test("255.255.254.153", false); 464 | test("255.255.254.154", false); 465 | test("255.255.254.155", false); 466 | test("255.255.254.156", false); 467 | test("255.255.254.157", false); 468 | test("255.255.254.158", false); 469 | test("255.255.254.159", false); 470 | test("255.255.254.160", false); 471 | test("255.255.254.161", false); 472 | test("255.255.254.162", false); 473 | test("255.255.254.163", false); 474 | test("255.255.254.164", false); 475 | test("255.255.254.165", false); 476 | test("255.255.254.166", false); 477 | test("255.255.254.167", false); 478 | test("255.255.254.168", false); 479 | test("255.255.254.169", false); 480 | test("255.255.254.170", false); 481 | test("255.255.254.171", false); 482 | test("255.255.254.172", false); 483 | test("255.255.254.173", false); 484 | test("255.255.254.174", false); 485 | test("255.255.254.175", false); 486 | test("255.255.254.176", false); 487 | test("255.255.254.177", false); 488 | test("255.255.254.178", false); 489 | test("255.255.254.179", false); 490 | test("255.255.254.180", false); 491 | test("255.255.254.181", false); 492 | test("255.255.254.182", false); 493 | test("255.255.254.183", false); 494 | test("255.255.254.184", false); 495 | test("255.255.254.185", false); 496 | test("255.255.254.186", false); 497 | test("255.255.254.187", false); 498 | test("255.255.254.188", false); 499 | test("255.255.254.189", false); 500 | test("255.255.254.190", false); 501 | test("255.255.254.191", false); 502 | test("255.255.254.192", false); 503 | test("255.255.254.193", false); 504 | test("255.255.254.194", false); 505 | test("255.255.254.195", false); 506 | test("255.255.254.196", false); 507 | test("255.255.254.197", false); 508 | test("255.255.254.198", false); 509 | test("255.255.254.199", false); 510 | test("255.255.254.200", false); 511 | test("255.255.254.201", false); 512 | test("255.255.254.202", false); 513 | test("255.255.254.203", false); 514 | test("255.255.254.204", false); 515 | test("255.255.254.205", false); 516 | test("255.255.254.206", false); 517 | test("255.255.254.207", false); 518 | test("255.255.254.208", false); 519 | test("255.255.254.209", false); 520 | test("255.255.254.210", false); 521 | test("255.255.254.211", false); 522 | test("255.255.254.212", false); 523 | test("255.255.254.213", false); 524 | test("255.255.254.214", false); 525 | test("255.255.254.215", false); 526 | test("255.255.254.216", false); 527 | test("255.255.254.217", false); 528 | test("255.255.254.218", false); 529 | test("255.255.254.219", false); 530 | test("255.255.254.220", false); 531 | test("255.255.254.221", false); 532 | test("255.255.254.222", false); 533 | test("255.255.254.223", false); 534 | test("255.255.254.224", false); 535 | test("255.255.254.225", false); 536 | test("255.255.254.226", false); 537 | test("255.255.254.227", false); 538 | test("255.255.254.228", false); 539 | test("255.255.254.229", false); 540 | test("255.255.254.230", false); 541 | test("255.255.254.231", false); 542 | test("255.255.254.232", false); 543 | test("255.255.254.233", false); 544 | test("255.255.254.234", false); 545 | test("255.255.254.235", false); 546 | test("255.255.254.236", false); 547 | test("255.255.254.237", false); 548 | test("255.255.254.238", false); 549 | test("255.255.254.239", false); 550 | test("255.255.254.240", false); 551 | test("255.255.254.241", false); 552 | test("255.255.254.242", false); 553 | test("255.255.254.243", false); 554 | test("255.255.254.244", false); 555 | test("255.255.254.245", false); 556 | test("255.255.254.246", false); 557 | test("255.255.254.247", false); 558 | test("255.255.254.248", false); 559 | test("255.255.254.249", false); 560 | test("255.255.254.250", false); 561 | test("255.255.254.251", false); 562 | test("255.255.254.252", false); 563 | test("255.255.254.253", false); 564 | test("255.255.254.254", false); 565 | test("255.255.254.255", false); 566 | 567 | return 0; 568 | } 569 | --------------------------------------------------------------------------------