Logo Search packages:      
Sourcecode: wflogs version File versions  Download package

preresolv.cc

/*
 * WallFire -- a comprehensive firewall administration tool.
 * 
 * Copyright (C) 2001 Hervé Eychenne <rv@wallfire.org>
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 * 
 */

using namespace std;

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <set>
#ifdef HAVE_LIBADNS
#include <adns.h>
#endif
#include <stdio.h> /* for stderr */
#include <arpa/inet.h>
#include <inttypes.h>
#include <errno.h> /* for ESRCH */

#include "preresolv.h"
#include "defs.h"


bool
preresolv(const wf_logentries& logentries, wf_dns* dns,
        bool resolve_srcip, bool resolve_dstip, unsigned char verbose) {
  set<uint32_t> Set;
  
  /* We insert all IP addresses first, because it eliminates duplicated
     entries. */
  {
    list<wf_logentry*>::const_iterator first = logentries.elems.begin(),
      last = logentries.elems.end();
    for (; first != last; ++first) {
      if (resolve_srcip)
      Set.insert((*first)->sipaddr.get());
      if (resolve_dstip)
      Set.insert((*first)->dipaddr.get());
    }
  }

  if (verbose)
    fprintf(stderr, _("Pre-resolving %i DNS addresses\n"), Set.size());

#ifdef HAVE_LIBADNS
  /* Now resolve asynchronously, so everything will be in the DNS cache. */

  adns_state adns;
  adns_query query;
  adns_answer *answer;
  int ret;

  if (adns_init(&adns, adns_if_eintr, 0)) {
    cerr << "adns_init" << endl;
    return false;
  }

  struct sockaddr_in addr;
  addr.sin_family = AF_INET;

  set<uint32_t>::const_iterator first = Set.begin(),
    last = Set.end();
  for (; first != last; ++first) {
    addr.sin_addr.s_addr = *first;

    if (verbose > 1)
      fprintf(stderr, _("Submitting %s\n"), inet_ntoa(addr.sin_addr));

    ret = adns_submit_reverse(adns, (const struct sockaddr*)&addr, adns_r_ptr,
                        adns_qf_owner, (void*)&*first, &query);
    if (ret) {
      cerr << "adns_submit_reverse" << endl;
      continue;
    }
  }

  int num = 0;

  for (;;) {
    uint32_t *addr;
    query = NULL;
    ret = adns_wait(adns, &query, &answer, (void**)&addr);
    if (ret == ESRCH)
      break;
    if (ret) {
      cerr << "adns_check: " << strerror(ret) << endl;
      return false;
    }

    wf_dns_entry* dns_entry = new wf_dns_entry();
    if (dns_entry == NULL)
      return false;

    wf_ipaddr ipaddr(*addr);
    dns_entry->ipaddr = ipaddr;

    if (answer->rrs.str != NULL) {
      dns_entry->name = answer->rrs.str[0];
      if (verbose > 1)
      fprintf(stderr, _("Resolved %s: %s\n"),
            ipaddr.tostr().c_str(), dns_entry->name.c_str());
    }
    else {
      /* If no name is found, we create the entry, but name will remain
       empty (""). */
      if (verbose > 1)
      fprintf(stderr, _("Resolving %s: no name found\n"),
            ipaddr.tostr().c_str());
    }

    dns->cache_add(dns_entry);  /* Add entry to cache. */
    num++;
  }
  //  cerr << num << endl;
#else
  /* Now resolve sequentially, so everything will be in the DNS cache. */
  wf_ipaddr ipaddr;
  set<uint32_t>::const_iterator first = Set.begin(), last = Set.end();
  for (; first != last; ++first) {
    ipaddr.set(*first);
    dns->resolv(ipaddr);
  }
#endif
  if (verbose)
    cerr << _("Pre-resolving of DNS addresses finished") << endl;
  return true;
}

Generated by  Doxygen 1.6.0   Back to index