hg_add_hosts.c
上传用户:tjescc
上传日期:2021-02-23
资源大小:419k
文件大小:10k
源码类别:

Telnet服务器

开发平台:

Unix_Linux

  1. /* Hostloop2 -- the Hostloop Library, version 2.0
  2.  * Copyright (C) 1999 Renaud Deraison
  3.  *
  4.  * This library is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU Library General Public
  6.  * License as published by the Free Software Foundation; either
  7.  * version 2 of the License, or (at your option) any later version.
  8.  *
  9.  * This library is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12.  * Library General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU Library General Public
  15.  * License along with this library; if not, write to the Free
  16.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  */
  18. #include <includes.h>
  19. #include "hosts_gatherer.h"
  20. #include "hg_utils.h"
  21. #include "hg_filter.h"
  22. #include "hg_add_hosts.h"
  23. #include "hg_subnet.h"
  24. /*
  25.  * Add a host of the form
  26.  *
  27.  * 'hostname' or 'xx.xx.xx.xx' or 'hostname/netmask' 
  28.  * or 'xx.xx.xx.xx/netmask'
  29.  * or '[xx|xx-xx].[xx|xx-xx].[xx|xx-xx].[xx|xx-xx]' (by Alex Butcher, Articon-Integralis AG)
  30.  *
  31.  */
  32. #define OCTETRANGE "%3d%*1[-]%3d"
  33. #define OCTET "%3d"
  34. #define DOT "%*1[.]"
  35. #define COMP "%7[0-9-]"  
  36. #define REMINDER "%s"
  37. static int
  38. real_ip(char * s)
  39. {
  40.  int i;
  41.  int n = 0;
  42.  for(i=0;s[i];i++)
  43.  {
  44.   if(s[i] == '.') n ++;
  45.  }
  46.  
  47.  if(n == 3) 
  48.   return 1;
  49.  else 
  50.   return 0;
  51. }
  52. static int
  53. range(data, s, e)
  54.  char * data;
  55.  int * s;
  56.  int * e;
  57. {
  58.  int convs;
  59.  int first, last;
  60.  
  61.  convs=sscanf(data, OCTETRANGE, &first, &last);
  62.  if (convs != 2)
  63.  {
  64.   /* it didn't work out, so we try converting it as
  65.      an OCTET (xxx) */
  66.   convs=sscanf(data, OCTET, &first);
  67.   if (convs != 1)
  68.   {
  69.    /* that didn't work out either, so it's not a range */
  70.    return (-1);
  71.   }
  72.   else
  73.   {
  74.    /* we'll use these as loop ranges later */
  75.    last = first;
  76.   }
  77.  }
  78.  
  79.  if((first < 0) || (first > 255) ||
  80.     (last < 0 ) || (last  > 255))
  81.      return (-1);
  82.  
  83.  if(first > last)
  84.  {
  85.   /* swap the two vars */
  86.   first ^= last;
  87.   last  ^= first;
  88.   first ^= last;
  89.  }
  90.  
  91.  if(s)*s = first;
  92.  if(e)*e = last;
  93.  return 0;
  94. }
  95.  
  96. static int netmask_to_cidr_netmask(struct in_addr nm)
  97. {
  98.  int ret = 32;
  99.  
  100.  nm.s_addr = ntohl(nm.s_addr);
  101.  while(!(nm.s_addr & 1))
  102.  {
  103.   ret--;
  104.   nm.s_addr >>=1;
  105.  }
  106.  return ret;
  107. }
  108. int
  109. hg_add_host(globals, hostname)
  110.  struct hg_globals * globals;
  111.  char * hostname;
  112. {
  113.  int cidr_netmask = 32;
  114.  char * t;
  115.  char * q;
  116.  char * copy;
  117.  struct in_addr ip;
  118.  struct in_addr nm;
  119.  
  120.  int o1first,o1last; /* octet range boundaries */
  121.  int o2first,o2last;
  122.  int o3first,o3last;
  123.  int o4first,o4last;
  124.  int o1,o2,o3,o4; /* octet loop counters */
  125.  int convs; /* number of conversions made by sscanf */
  126.  char rangehost[20]; /* used to store string representation of ip */
  127.         
  128.  char comp1[8], comp2[8], comp3[8], comp4[8];
  129.  char * reminder;
  130.  int unquote = 0;
  131.  
  132.  *comp1 = *comp2 = *comp3 = *comp4 = '';
  133.  
  134.  t = strchr(hostname, '-');
  135.  if(t != NULL)
  136.  {
  137.   struct in_addr ip;
  138.   t[0] = '';
  139.   if((inet_aton(hostname, &ip) == 0) || !real_ip(hostname))
  140.   {
  141.    t[0] = '-';
  142.    goto next;
  143.   }
  144.   
  145.   if(real_ip(hostname) && 
  146.      real_ip(&(t[1])))
  147.      {
  148.       struct in_addr start, end;
  149.      
  150.       start = hg_resolv(hostname);
  151.       end = hg_resolv(&(t[1]));
  152.       
  153.       if ( globals->flags & HG_DISTRIBUTE )
  154.         {
  155.          int jump;
  156.          unsigned long diff;
  157.          int i, j;
  158.          
  159.          diff = ntohl(end.s_addr) - ntohl(start.s_addr);
  160.          if ( diff > 255 ) jump = 255;
  161.          else if ( diff > 128 ) jump = 10;
  162.          else jump = 1;
  163.          
  164.         
  165.          
  166.          for ( j = 0 ; j < jump ; j ++ )
  167.          {
  168.          for ( i = j ; i <= diff ; i += jump )
  169.          {
  170.           struct in_addr ia;
  171.           ia.s_addr = htonl(ntohl(start.s_addr) + i);
  172.           if ( ntohl(ia.s_addr) > ntohl(end.s_addr) )break;
  173.          
  174.           hg_add_host_with_options(globals, inet_ntoa(ia), ia, 1, 32, 1, &ia);
  175.          }
  176.         }
  177.        }
  178.       else
  179.         hg_add_host_with_options(globals, inet_ntoa(start), start, 1, 32, 1, &end);
  180.       return 0;
  181.      }
  182.    t[0] = '-';  
  183.  }
  184.  
  185. next:
  186.  reminder = malloc(strlen(hostname));
  187.           
  188.  if((hostname[0] == ''') &&
  189.     (hostname[strlen(hostname) - 1] == '''))
  190.  {
  191.  unquote++;
  192.  goto noranges;
  193.  }
  194.  
  195.  for (t = hostname; *t != ''; t ++)
  196.    if (! isdigit(*t) && *t != '-' && *t != '.')
  197.      break;
  198.  if (*t == '')
  199.  convs=sscanf(hostname, COMP DOT COMP DOT COMP DOT COMP REMINDER,
  200.   comp1, comp2, comp3, comp4, reminder);
  201.  else
  202.    convs = 0;
  203.  free(reminder);
  204.  if (convs != 4) goto noranges; /* there are definitely no ranges here, so
  205.                                    skip all this */
  206.  
  207.  /* try to convert components as OCTETRANGE (xxx-xxx) */
  208.  if(range(comp1, &o1first, &o1last) ||
  209.     range(comp2, &o2first, &o2last) ||
  210.     range(comp3, &o3first, &o3last) ||
  211.     range(comp4, &o4first, &o4last))
  212.      goto noranges;
  213.  
  214.  /* generate and add the range */
  215.  for(o1=o1first; o1<=o1last; o1++)
  216.  {
  217.   for(o2=o2first; o2<=o2last; o2++)
  218.   {
  219.    for(o3=o3first; o3<=o3last; o3++)
  220.    {
  221.     for(o4=o4first; o4<=o4last; o4++)
  222.     {
  223.      snprintf(rangehost,17,"%d.%d.%d.%d",o1,o2,o3,o4);
  224.      ip = hg_resolv(rangehost);
  225.      if(ip.s_addr != INADDR_NONE)
  226.      {
  227.       hg_add_host_with_options(globals, rangehost, ip, 0, 32,0,NULL);
  228.      }
  229.     }
  230.    }
  231.   }
  232.  }
  233.  return 0;
  234.  
  235. noranges:
  236.  if(unquote)
  237.  {
  238.  copy = malloc(strlen(hostname) - 1);
  239.  strncpy(copy, &(hostname[1]), strlen(&(hostname[1])) - 1);
  240.  }
  241.  else
  242.  {
  243.  copy = malloc(strlen(hostname)+1);
  244.  strncpy(copy, hostname, strlen(hostname)+1);
  245.  }
  246.  hostname = copy;
  247.  t = strchr(hostname, '/');
  248.  if(t){
  249.   t[0] = '';
  250.   if((atoi(t+1) > 32) &&
  251.      inet_aton(t+1, &nm))
  252.   {
  253.    cidr_netmask = netmask_to_cidr_netmask(nm);
  254.   }
  255.   else cidr_netmask = atoi(t+1);
  256.   if((cidr_netmask < 1) || (cidr_netmask > 32))cidr_netmask = 32;
  257.  }
  258.  ip.s_addr = INADDR_NONE;
  259.  q = strchr (hostname, '[');
  260.  if (q != NULL)
  261.  {
  262.   t = strchr (q, ']');
  263.   if (t != NULL)
  264.   {
  265.    t[0] = '';
  266.    ip = hg_resolv (&q [1]);
  267.    q[0] = '';
  268.   }
  269.  }
  270.  if (ip.s_addr == INADDR_NONE)
  271.  {
  272.   ip = hg_resolv (hostname);
  273.  }
  274.  if(ip.s_addr != INADDR_NONE)
  275.   {
  276. if(cidr_netmask == 32)
  277. {
  278.   hg_add_host_with_options(globals, hostname, ip, 0, cidr_netmask,0,NULL);
  279.   }
  280. else
  281. {
  282.  struct in_addr first = cidr_get_first_ip(ip, cidr_netmask);
  283.  struct in_addr last = cidr_get_last_ip(ip, cidr_netmask);
  284.  
  285.  if( (globals->flags & HG_DISTRIBUTE) != 0 && cidr_netmask <= 29 )
  286.  {
  287.   struct in_addr c_end;
  288.      struct in_addr c_start;
  289.   int addition;
  290.           
  291.           if ( cidr_netmask <= 21 ) addition = 8;
  292.           else if ( cidr_netmask <= 24 ) addition = 5;
  293.           else addition = 2;
  294.           
  295.   c_start = first;
  296.      c_end   = cidr_get_last_ip(c_start, cidr_netmask + addition);
  297.     
  298.      for(;;)
  299.   {
  300.    int dobreak = 0;
  301.    
  302.   
  303.    if(ntohl(c_end.s_addr) >= ntohl(last.s_addr)) dobreak++;
  304.         hg_get_name_from_ip(c_start, hostname, sizeof(hostname));
  305.            hg_add_host_with_options(globals, strdup(hostname), 
  306.   c_start, 1, 32, 1,
  307.   &c_end);
  308.        c_start.s_addr  = htonl(ntohl(c_end.s_addr) + 2);
  309.        c_end = cidr_get_last_ip(c_start, cidr_netmask + addition);
  310.    c_start.s_addr  = htonl(ntohl(c_start.s_addr) - 1);
  311.   if(dobreak) break;   
  312.     } 
  313. }
  314. else hg_add_host_with_options(globals, hostname, first, 1,32,1,&last);
  315.        }
  316.       }
  317.       else {
  318.        free(copy);
  319. return -1;
  320. }
  321.  free(copy);
  322.  return 0;
  323. }
  324.  
  325.  
  326. /*
  327.  * Add hosts of the form :
  328.  *
  329.  * host1/nm,host2/nm,xxx.xxx.xxx.xxx/xxx, ....
  330.  *
  331.  */
  332. int
  333. hg_add_comma_delimited_hosts(globals, limit)
  334.  struct hg_globals * globals;
  335.  int limit;
  336. {
  337.  char * p, *v;
  338.  int n = 0;
  339.  
  340.  p = globals->marker;
  341.  while(p)
  342.  {
  343.    int len;
  344.    if(limit > 0 && n > limit) /* Don't resolve more than 256 host names in a row */
  345.    {
  346.    globals->marker = p;
  347.    return 0;
  348.    } 
  349.   
  350.   while((*p == ' ')&&(p!=''))
  351.    p++;
  352.   
  353.   v = strchr(p+1, ',');
  354.   if( v == NULL )
  355.    v = strchr(p+1, ';');
  356.   
  357.   if( v != NULL )
  358.    v[0] = '';
  359.   len = strlen(p);
  360.   while(p[len-1]==' '){
  361.    p[len-1]='';
  362. len --;
  363. }
  364.   if(hg_add_host(globals, p) <  0)
  365.   {
  366.    if ( v != NULL )
  367. globals->marker = v + 1;
  368.    else
  369. globals->marker = NULL; 
  370.    return -1;
  371.   }
  372.   n ++;
  373.   if(v != NULL)
  374.    p = v+1;
  375.   else 
  376.    p = NULL;
  377.  }
  378.  
  379.  globals->marker = NULL;
  380.  return 0;
  381. }
  382. void
  383. hg_add_host_with_options(globals, hostname, ip, alive, netmask, use_max, ip_max)
  384.  struct hg_globals * globals;
  385.  char *  hostname;
  386.  struct in_addr ip;
  387.  int alive;
  388.  int netmask;
  389.  int use_max;
  390.  struct in_addr * ip_max;
  391. {
  392.  char * c_hostname;
  393.  struct hg_host * host;
  394.  int i;
  395.   c_hostname = strdup(hostname);
  396.   for(i=0;i<strlen(hostname);i++)c_hostname[i]=tolower(c_hostname[i]);
  397.   host = globals->host_list;
  398.   while(host->next)host = host->next;
  399.   host->next = malloc(sizeof(struct hg_host));
  400.   bzero(host->next, sizeof(struct hg_host));
  401.  
  402.   host->hostname = c_hostname;
  403.   host->domain = hostname ? hg_name_to_domain(c_hostname):"";
  404.   host->cidr_netmask = netmask;
  405.   if(netmask != 32)printf("Error ! Bad netmaskn");
  406.   host->tested = 0;
  407.   host->alive = alive;
  408.   host->addr = ip;
  409.   host->use_max = use_max?1:0;
  410.   if(ip_max){
  411.    host->max.s_addr = ip_max->s_addr;
  412. host->min = cidr_get_first_ip(ip, netmask);
  413. if(ntohl(host->max.s_addr) < ntohl(host->min.s_addr))
  414.  {
  415.  fprintf(stderr, "hg_add_host: error - ip_max < ip_min !n");
  416.  host->max.s_addr = host->min.s_addr;
  417.  }
  418. }
  419. }
  420.  
  421. void hg_add_domain(globals, domain)
  422.  struct hg_globals * globals;
  423.  char * domain;
  424. {
  425.  struct hg_host * list = globals->tested;
  426.  int len;
  427.  
  428.  while(list && list->next)list = list->next;
  429.  list->next = malloc(sizeof(struct hg_host));
  430.  bzero(list->next, sizeof(struct hg_host));
  431.  len = strlen(domain);
  432.  list->domain = malloc(len + 1);
  433.  strncpy(list->domain, domain, len + 1);
  434. }
  435. void hg_add_subnet(globals, ip, netmask)
  436.  struct hg_globals * globals;
  437.  struct in_addr ip;
  438.  int netmask;
  439. {
  440.  struct hg_host * list = globals->tested; 
  441.  while(list && list->next)list = list->next;
  442.  list->next = malloc(sizeof(struct hg_host));
  443.  bzero(list->next, sizeof(struct hg_host));
  444.  list->addr = ip;
  445.  list->cidr_netmask = netmask;
  446. }
  447.