1 /* 2 * Copyright (C) 2012 by Darren Reed. 3 * 4 * See the IPFILTER.LICENCE file for details on licencing. 5 * 6 * $Id: parsewhoisline.c,v 1.2.2.5 2012/07/22 08:04:24 darren_r Exp $ 7 */ 8 #include "ipf.h" 9 10 /* 11 Microsoft Corp MICROSOFT19 (NET-198-136-97-0-1) 198.137.97.0 - 198.137.97.255 12 Microsoft Corp SAVV-S233053-6 (NET-206-79-74-32-1) 206.79.74.32 - 206.79.74.47 13 */ 14 int 15 parsewhoisline(line, addrp, maskp) 16 char *line; 17 addrfamily_t *addrp; 18 addrfamily_t *maskp; 19 { 20 struct in_addr a1, a2; 21 char *src = line; 22 char *s = NULL; 23 24 if (line == NULL) 25 return -1; 26 27 while (*src != '\0') { 28 s = strchr(src, '('); 29 if (s == NULL) 30 break; 31 32 if (strncmp(s, "(NET", 4)) { 33 src = s + 1; 34 } 35 break; 36 } 37 38 if (s == NULL) 39 return -1; 40 41 memset(addrp, 0x00, sizeof(*maskp)); 42 memset(maskp, 0x00, sizeof(*maskp)); 43 44 if (*(s + 4) == '6') { 45 #ifdef USE_INET6 46 i6addr_t a61, a62; 47 48 s = strchr(s, ')'); 49 if (s == NULL || *++s != ' ') 50 return -1; 51 /* 52 * Parse the IPv6 53 */ 54 if (inet_pton(AF_INET6, s, &a61.in6) != 1) 55 return -1; 56 57 s = strchr(s, ' '); 58 if (s == NULL || strncmp(s, " - ", 3)) 59 return -1; 60 61 s += 3; 62 if (inet_pton(AF_INET6, s, &a62) != 1) 63 return -1; 64 65 addrp->adf_addr = a61; 66 addrp->adf_family = AF_INET6; 67 addrp->adf_len = offsetof(addrfamily_t, adf_addr) + 68 sizeof(struct in6_addr); 69 70 maskp->adf_addr.i6[0] = ~(a62.i6[0] ^ a61.i6[0]); 71 maskp->adf_addr.i6[1] = ~(a62.i6[1] ^ a61.i6[1]); 72 maskp->adf_addr.i6[2] = ~(a62.i6[2] ^ a61.i6[2]); 73 maskp->adf_addr.i6[3] = ~(a62.i6[3] ^ a61.i6[3]); 74 75 /* 76 * If the mask that's been generated isn't a consecutive mask 77 * then we can't add it into a pool. 78 */ 79 if (count6bits(maskp->adf_addr.i6) == -1) 80 return -1; 81 82 maskp->adf_family = AF_INET6; 83 maskp->adf_len = addrp->adf_len; 84 85 if (IP6_MASKNEQ(&addrp->adf_addr.in6, &maskp->adf_addr.in6, 86 &addrp->adf_addr.in6)) { 87 return -1; 88 } 89 return 0; 90 #else 91 return -1; 92 #endif 93 } 94 95 s = strchr(s, ')'); 96 if (s == NULL || *++s != ' ') 97 return -1; 98 99 s++; 100 101 if (inet_aton(s, &a1) != 1) 102 return -1; 103 104 s = strchr(s, ' '); 105 if (s == NULL || strncmp(s, " - ", 3)) 106 return -1; 107 108 s += 3; 109 if (inet_aton(s, &a2) != 1) 110 return -1; 111 112 addrp->adf_addr.in4 = a1; 113 addrp->adf_family = AF_INET; 114 addrp->adf_len = offsetof(addrfamily_t, adf_addr) + 115 sizeof(struct in_addr); 116 maskp->adf_addr.in4.s_addr = ~(a2.s_addr ^ a1.s_addr); 117 118 /* 119 * If the mask that's been generated isn't a consecutive mask then 120 * we can't add it into a pool. 121 */ 122 if (count4bits(maskp->adf_addr.in4.s_addr) == -1) 123 return -1; 124 125 maskp->adf_family = AF_INET; 126 maskp->adf_len = addrp->adf_len; 127 bzero((char *)maskp + maskp->adf_len, sizeof(*maskp) - maskp->adf_len); 128 if ((addrp->adf_addr.in4.s_addr & maskp->adf_addr.in4.s_addr) != 129 addrp->adf_addr.in4.s_addr) 130 return -1; 131 return 0; 132 } 133