#include #include #include #include /* * Network/Netmask to zone file converter * * Copyright (C) 2018 Rob van der Putten, Leiden, Holland, * rob at sput dot nl. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ /* Powers of two */ int pows[] = { 1, 2, 4, 8, 16, 32, 64, 128 }; /* Netmasks; 0000, 1000, 1100, 1110, etc */ int mask4[] = { 0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe }; int mask6[] = { 0, 0x08, 0x0c, 0x0e }; void proc4(int ip[], int mask, char *txt) { int divn, i, j, max, remn; i = 0; j = 0; max = 0; /* Per byte */ divn = mask / 8; remn = mask % 8; if (remn == 0) { if(divn > 3) printf("%d", ip[3]); else printf("*"); j = divn; while (j > 0) { printf(".%d", ip[j - 1]); j--; } printf("\tIN\tA\t127.0.0.2\n"); if(txt != NULL) printf("\t\tIN\tTXT\t\"https://www.spamhaus.org/sbl/query/%s\"\n", \ txt); } else { i = mask4[remn] & ip[divn]; /* In case they got it wrong */ max = pows[8 - remn] + i; while (i < max) { printf("*.%d", i); j = divn; while (j > 0) { printf(".%d", ip[j - 1]); j--; } printf("\tIN\tA\t127.0.0.2\n"); if(txt != NULL) printf("\t\tIN\tTXT\t\"https://www.spamhaus.org/sbl/query/%s\"\n", \ txt); i++; } } } void proc6(unsigned char nibs[], int mask, char *txt) { int divn, i, j, max, remn; i = 0; j = 0; max = 0; /* Per nibble */ divn = mask / 4; remn = mask % 4; if (remn == 0) { if(divn > 31) printf("%x", nibs[31]); else printf("*"); j = divn; while (j > 0) { printf(".%x", nibs[j - 1]); j--; } printf("\tIN\tA\t127.0.0.2\n"); if(txt != NULL) printf("\t\t\tIN\tTXT\t\"https://www.spamhaus.org/sbl/query/%s\"\n", \ txt); } else { i = mask6[remn] & nibs[divn]; /* In case they got it wrong */ max = pows[4 - remn] + i; while (i < max) { printf("*.%x", i); j = divn; while (j > 0) { printf(".%x", nibs[j - 1]); j--; } printf("\tIN\tA\t127.0.0.2\n"); if(txt != NULL) printf("\t\t\tIN\tTXT\t\"https://www.spamhaus.org/sbl/query/%s\"\n", \ txt); i++; } } } void hlp(void) { fprintf(stderr, "Usage: procdrop [-t]\n"); fprintf(stderr, "The '-t' option adds TXT records.\n\n"); fprintf(stderr, "Copyright (c) 2018 R.J. van der Putten, Leiden, Holland, "); fprintf(stderr, "rob at sput dot nl\n"); fprintf(stderr, "GNU GPL applies\n\n"); } int main(int argc, char **argv) { int i, ip[4], j, len, mask, tf; unsigned char ip6adr[16], nibs[32]; char ip6str[64], line[4096], txt[256]; /* * Translates network/netmask into dns zone file. */ i = 0; j = 0; len = 0; memset(ip, 0, sizeof(ip)); mask = 0; tf = 0; memset(ip6adr, 0, sizeof(ip6adr)); memset(ip6str, 0, sizeof(ip6str)); memset(line, 0, 4096); memset(nibs, 0, 32); memset(txt, 0, 256); if (argc > 2) { hlp(); exit(1); } if (argc > 1) { if (strcmp(argv[1], "-t") == 0) { tf = 1; } else { hlp(); exit(1); } } while (fgets(line, 4096, stdin)) { if (line[0] == ';' || (line[0] < '0' && line[0] > 0)) { printf("%s", line); continue; } if (sscanf(line, "%d.%d.%d.%d/%d ; %255s", \ &ip[0], &ip[1], &ip[2], &ip[3], &mask, txt) == 6) { if (ip[0] < 0 || ip[0] > 255 || \ ip[1] < 0 || ip[1] > 255 || \ ip[2] < 0 || ip[2] > 255 || ip[3] < 0 || ip[3] > 255) { printf("%s", line); continue; } if (mask < 0 || mask > 32) { printf("%s", line); continue; } printf("; %d.%d.%d.%d/%d\t%s\n", \ ip[0], ip[1], ip[2], ip[3], mask, txt); if (tf == 0) proc4(ip, mask, NULL); else proc4(ip, mask, txt); } else if (sscanf(line, "%63s ; %255s", ip6str, txt) == 2) { i = 0; len = strlen(ip6str); mask = -1; while (i < len) { if (ip6str[i] == '/') { ip6str[i] = 0 ; mask = atoi(ip6str + i + 1); break; } i++; } if (mask < 0 || mask > 128) { printf("%s", line); continue; } if (inet_pton(AF_INET6, ip6str, ip6adr) == 1) { printf("; %s/%d\t%s\n", ip6str, mask, txt); i = 0; j = 0; /* Translate bytes to nibbles */ while (i < 16) { nibs[j] = (ip6adr[i] >> 4); j++; nibs[j] = 0xf & ip6adr[i]; i++; j++; } if (tf == 0) proc6(nibs, mask, NULL); else proc6(nibs, mask, txt); } else { printf("%s", line); } } else { printf("%s", line); } } return(0); }