Home | History | Annotate | Line # | Download | only in lib
      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 /*
     13 Microsoft Corp MICROSOFT19 (NET-198-136-97-0-1) 198.137.97.0 - 198.137.97.255
     14 Microsoft Corp SAVV-S233053-6 (NET-206-79-74-32-1) 206.79.74.32 - 206.79.74.47
     15  */
     16 int
     17 parsewhoisline(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