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(char *line, addrfamily_t *addrp, addrfamily_t *maskp) 16 { 17 struct in_addr a1, a2; 18 char *src = line; 19 char *s = NULL; 20 21 if (line == NULL) 22 return (-1); 23 24 while (*src != '\0') { 25 s = strchr(src, '('); 26 if (s == NULL) 27 break; 28 29 if (strncmp(s, "(NET", 4)) { 30 src = s + 1; 31 } 32 break; 33 } 34 35 if (s == NULL) 36 return (-1); 37 38 memset(addrp, 0x00, sizeof(*maskp)); 39 memset(maskp, 0x00, sizeof(*maskp)); 40 41 if (*(s + 4) == '6') { 42 #ifdef USE_INET6 43 i6addr_t a61, a62; 44 45 s = strchr(s, ')'); 46 if (s == NULL || *++s != ' ') 47 return (-1); 48 /* 49 * Parse the IPv6 50 */ 51 if (inet_pton(AF_INET6, s, &a61.in6) != 1) 52 return (-1); 53 54 s = strchr(s, ' '); 55 if (s == NULL || strncmp(s, " - ", 3)) 56 return (-1); 57 58 s += 3; 59 if (inet_pton(AF_INET6, s, &a62) != 1) 60 return (-1); 61 62 addrp->adf_addr = a61; 63 addrp->adf_family = AF_INET6; 64 addrp->adf_len = offsetof(addrfamily_t, adf_addr) + 65 sizeof(struct in6_addr); 66 67 maskp->adf_addr.i6[0] = ~(a62.i6[0] ^ a61.i6[0]); 68 maskp->adf_addr.i6[1] = ~(a62.i6[1] ^ a61.i6[1]); 69 maskp->adf_addr.i6[2] = ~(a62.i6[2] ^ a61.i6[2]); 70 maskp->adf_addr.i6[3] = ~(a62.i6[3] ^ a61.i6[3]); 71 72 /* 73 * If the mask that's been generated isn't a consecutive mask 74 * then we can't add it into a pool. 75 */ 76 if (count6bits(maskp->adf_addr.i6) == -1) 77 return (-1); 78 79 maskp->adf_family = AF_INET6; 80 maskp->adf_len = addrp->adf_len; 81 82 if (IP6_MASKNEQ(&addrp->adf_addr.in6, &maskp->adf_addr.in6, 83 &addrp->adf_addr.in6)) { 84 return (-1); 85 } 86 return (0); 87 #else 88 return (-1); 89 #endif 90 } 91 92 s = strchr(s, ')'); 93 if (s == NULL || *++s != ' ') 94 return (-1); 95 96 s++; 97 98 if (inet_aton(s, &a1) != 1) 99 return (-1); 100 101 s = strchr(s, ' '); 102 if (s == NULL || strncmp(s, " - ", 3)) 103 return (-1); 104 105 s += 3; 106 if (inet_aton(s, &a2) != 1) 107 return (-1); 108 109 addrp->adf_addr.in4 = a1; 110 addrp->adf_family = AF_INET; 111 addrp->adf_len = offsetof(addrfamily_t, adf_addr) + 112 sizeof(struct in_addr); 113 maskp->adf_addr.in4.s_addr = ~(a2.s_addr ^ a1.s_addr); 114 115 /* 116 * If the mask that's been generated isn't a consecutive mask then 117 * we can't add it into a pool. 118 */ 119 if (count4bits(maskp->adf_addr.in4.s_addr) == -1) 120 return (-1); 121 122 maskp->adf_family = AF_INET; 123 maskp->adf_len = addrp->adf_len; 124 bzero((char *)maskp + maskp->adf_len, sizeof(*maskp) - maskp->adf_len); 125 if ((addrp->adf_addr.in4.s_addr & maskp->adf_addr.in4.s_addr) != 126 addrp->adf_addr.in4.s_addr) 127 return (-1); 128 return (0); 129 } 130