1254219Scy/* 2254219Scy * Copyright (C) 2012 by Darren Reed. 3254219Scy * 4254219Scy * See the IPFILTER.LICENCE file for details on licencing. 5254219Scy * 6254219Scy * $Id: parsewhoisline.c,v 1.2.2.5 2012/07/22 08:04:24 darren_r Exp $ 7254219Scy */ 8254219Scy#include "ipf.h" 9254219Scy 10254219Scy/* 11254219ScyMicrosoft Corp MICROSOFT19 (NET-198-136-97-0-1) 198.137.97.0 - 198.137.97.255 12254219ScyMicrosoft Corp SAVV-S233053-6 (NET-206-79-74-32-1) 206.79.74.32 - 206.79.74.47 13254219Scy */ 14254219Scyint 15254219Scyparsewhoisline(line, addrp, maskp) 16254219Scy char *line; 17254219Scy addrfamily_t *addrp; 18254219Scy addrfamily_t *maskp; 19254219Scy{ 20254219Scy struct in_addr a1, a2; 21254219Scy char *src = line; 22254219Scy char *s = NULL; 23254219Scy 24254219Scy if (line == NULL) 25254219Scy return -1; 26254219Scy 27254219Scy while (*src != '\0') { 28254219Scy s = strchr(src, '('); 29254219Scy if (s == NULL) 30254219Scy break; 31254219Scy 32254219Scy if (strncmp(s, "(NET", 4)) { 33254219Scy src = s + 1; 34254219Scy } 35254219Scy break; 36254219Scy } 37254219Scy 38254219Scy if (s == NULL) 39254219Scy return -1; 40254219Scy 41254219Scy memset(addrp, 0x00, sizeof(*maskp)); 42254219Scy memset(maskp, 0x00, sizeof(*maskp)); 43254219Scy 44254219Scy if (*(s + 4) == '6') { 45254219Scy#ifdef USE_INET6 46254219Scy i6addr_t a61, a62; 47254219Scy 48254219Scy s = strchr(s, ')'); 49254219Scy if (s == NULL || *++s != ' ') 50254219Scy return -1; 51254219Scy /* 52254219Scy * Parse the IPv6 53254219Scy */ 54254219Scy if (inet_pton(AF_INET6, s, &a61.in6) != 1) 55254219Scy return -1; 56254219Scy 57254219Scy s = strchr(s, ' '); 58254219Scy if (s == NULL || strncmp(s, " - ", 3)) 59254219Scy return -1; 60254219Scy 61254219Scy s += 3; 62254219Scy if (inet_pton(AF_INET6, s, &a62) != 1) 63254219Scy return -1; 64254219Scy 65254219Scy addrp->adf_addr = a61; 66254219Scy addrp->adf_family = AF_INET6; 67254219Scy addrp->adf_len = offsetof(addrfamily_t, adf_addr) + 68254219Scy sizeof(struct in6_addr); 69254219Scy 70254219Scy maskp->adf_addr.i6[0] = ~(a62.i6[0] ^ a61.i6[0]); 71254219Scy maskp->adf_addr.i6[1] = ~(a62.i6[1] ^ a61.i6[1]); 72254219Scy maskp->adf_addr.i6[2] = ~(a62.i6[2] ^ a61.i6[2]); 73254219Scy maskp->adf_addr.i6[3] = ~(a62.i6[3] ^ a61.i6[3]); 74254219Scy 75254219Scy /* 76254219Scy * If the mask that's been generated isn't a consecutive mask 77254219Scy * then we can't add it into a pool. 78254219Scy */ 79254219Scy if (count6bits(maskp->adf_addr.i6) == -1) 80254219Scy return -1; 81254219Scy 82254219Scy maskp->adf_family = AF_INET6; 83254219Scy maskp->adf_len = addrp->adf_len; 84254219Scy 85254219Scy if (IP6_MASKNEQ(&addrp->adf_addr.in6, &maskp->adf_addr.in6, 86254219Scy &addrp->adf_addr.in6)) { 87254219Scy return -1; 88254219Scy } 89254219Scy return 0; 90254219Scy#else 91254219Scy return -1; 92254219Scy#endif 93254219Scy } 94254219Scy 95254219Scy s = strchr(s, ')'); 96254219Scy if (s == NULL || *++s != ' ') 97254219Scy return -1; 98254219Scy 99254219Scy s++; 100254219Scy 101254219Scy if (inet_aton(s, &a1) != 1) 102254219Scy return -1; 103254219Scy 104254219Scy s = strchr(s, ' '); 105254219Scy if (s == NULL || strncmp(s, " - ", 3)) 106254219Scy return -1; 107254219Scy 108254219Scy s += 3; 109254219Scy if (inet_aton(s, &a2) != 1) 110254219Scy return -1; 111254219Scy 112254219Scy addrp->adf_addr.in4 = a1; 113254219Scy addrp->adf_family = AF_INET; 114254219Scy addrp->adf_len = offsetof(addrfamily_t, adf_addr) + 115254219Scy sizeof(struct in_addr); 116254219Scy maskp->adf_addr.in4.s_addr = ~(a2.s_addr ^ a1.s_addr); 117254219Scy 118254219Scy /* 119254219Scy * If the mask that's been generated isn't a consecutive mask then 120254219Scy * we can't add it into a pool. 121254219Scy */ 122254219Scy if (count4bits(maskp->adf_addr.in4.s_addr) == -1) 123254219Scy return -1; 124254219Scy 125254219Scy maskp->adf_family = AF_INET; 126254219Scy maskp->adf_len = addrp->adf_len; 127254219Scy bzero((char *)maskp + maskp->adf_len, sizeof(*maskp) - maskp->adf_len); 128254219Scy if ((addrp->adf_addr.in4.s_addr & maskp->adf_addr.in4.s_addr) != 129254219Scy addrp->adf_addr.in4.s_addr) 130254219Scy return -1; 131254219Scy return 0; 132254219Scy} 133