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