Example #1
0
struct irec *find_all_interfaces(struct iname *names,
				 struct iname *addrs,
				 int port)
{
  /* this code is adapted from Stevens, page 434. It finally
     destroyed my faith in the C/unix API */
  int len = 100 * sizeof(struct ifreq);
  int lastlen = 0;
  char *buf, *ptr;
  struct ifconf ifc;
  struct irec *ret = NULL;
  int fd = socket(PF_INET, SOCK_DGRAM, 0);
  
  if (fd == -1)
    die("cannot create socket to enumerate interfaces: %s", NULL);
        
  while (1)
    {
      buf = safe_malloc(len);
      ifc.ifc_len = len;
      ifc.ifc_buf = buf;
      if (ioctl(fd, SIOCGIFCONF, &ifc) < 0)
	{
	  if (errno != EINVAL || lastlen != 0)
	    die("ioctl error while enumerating interfaces: %s", NULL);
	}
      else
	{
	  if (ifc.ifc_len == lastlen)
	    break; /* got a big enough buffer now */
	  lastlen = ifc.ifc_len;
	}
      len += 10* sizeof(struct ifreq);
      safe_free(buf);
    }

  for (ptr = buf; ptr < buf + ifc.ifc_len; )
    {
      struct ifreq *ifr = (struct ifreq *) ptr;
      union mysockaddr addr;
#ifdef HAVE_SOCKADDR_SA_LEN
      ptr += ifr->ifr_addr.sa_len + IF_NAMESIZE;
#else
      ptr += sizeof(struct ifreq);
#endif

      /* copy address since getting flags overwrites */
      if (ifr->ifr_addr.sa_family == AF_INET)
	{
	  addr.in = *((struct sockaddr_in *) &ifr->ifr_addr);
	  addr.in.sin_port = htons(port);
	  
	  if (ioctl(fd, SIOCGIFFLAGS, ifr) < 0)
	    die ("ioctl error getting interface flags: %s", NULL);
	      	  
	  ret = add_iface(ret, ifr->ifr_flags, ifr->ifr_name, &addr, 
			  names, addrs);
	}
#ifdef HAVE_IPV6
      else if (ifr->ifr_addr.sa_family == AF_INET6)
	{
#ifdef HAVE_BROKEN_SOCKADDR_IN6
	  addr.in6 = *((struct my_sockaddr_in6 *) &ifr->ifr_addr);
#else
	  addr.in6 = *((struct sockaddr_in6 *) &ifr->ifr_addr);
#endif
	  addr.in6.sin6_port = htons(port);
	  addr.in6.sin6_flowinfo = htonl(0);
	  
	  if (ioctl(fd, SIOCGIFFLAGS, ifr) < 0)
	    die("ioctl error getting interface flags: %s", NULL);
	    	  
	  ret = add_iface(ret, ifr->ifr_flags, ifr->ifr_name, &addr, 
			      names, addrs);
	}
#endif /* IPV6 */
	
    }
  safe_free(buf);
  close(fd);
  
#if defined(HAVE_LINUX_IPV6_PROC) && defined(HAVE_IPV6)
  /* IPv6 addresses don't seem to work with SIOCGIFCONF. Barf */
  /* This code snarfed from net-tools 1.60 and certainly linux specific, though
     it shouldn't break on other Unices, and their SIOGIFCONF might work. */
  {
    FILE *f = fopen(IP6INTERFACES, "r");
    
    if (f)
      {
	union mysockaddr addr;
	unsigned int plen, scope, flags, if_idx;
	char devname[20], addrstring[32];
	
	while (fscanf(f, "%32s %02x %02x %02x %02x %20s\n",
		      addrstring, &if_idx, &plen, &scope, &flags, devname) != EOF) 
	  {
	    int i;
	    unsigned char *addr6p = (unsigned char *) &addr.in6.sin6_addr;
	    memset(&addr, 0, sizeof(addr));
	    addr.sa.sa_family = AF_INET6;
	    for (i=0; i<16; i++)
	      {
		unsigned int byte;
		sscanf(addrstring+i+i, "%02x", &byte);
		addr6p[i] = byte;
	      }
#ifdef HAVE_SOCKADDR_SA_LEN 
	    /* For completeness - should never be defined on Linux. */
	    addr.in6.sin6_len = sizeof(struct sockaddr_in6);
#endif
	    addr.in6.sin6_port = htons(port);
	    addr.in6.sin6_flowinfo = htonl(0);
	    addr.in6.sin6_scope_id = htonl(scope);
	    
	    ret = add_iface(ret, flags, devname, &addr, names, addrs);
	  }
	
	fclose(f);
      }
  }
#endif /* LINUX */

  /* if a whitelist provided, make sure the if names on it were OK */
  while(names)
    {
      if (!names->found)
	die("unknown interface %s", names->name);
      
      names = names->next;
    }
   
  while(addrs)
    {
      if (!addrs->found)
	{
#ifdef HAVE_IPV6
	  char addrbuff[INET6_ADDRSTRLEN];
#else
	  char addrbuff[INET_ADDRSTRLEN];
#endif
	  if (addrs->addr.sa.sa_family == AF_INET)
	    inet_ntop(AF_INET, &addrs->addr.in.sin_addr,
		      addrbuff, INET_ADDRSTRLEN);
#ifdef HAVE_IPV6
	  else
	    inet_ntop(AF_INET6, &addrs->addr.in6.sin6_addr,
		      addrbuff, INET6_ADDRSTRLEN);
#endif
	  die("no interface with address %s", addrbuff);
	}
      addrs = addrs->next;
    }
    
  return ret;
}
Example #2
0
int main(int argc, char *argv[])
{
	char errbuf[PCAP_ERRBUF_SIZE];
	char *dev;
	struct iface_config *ifc;
	int optind;
	int i;


	bzero(&cfg, sizeof(cfg));

	/* Default configuration */
//	cfg.ratelimit = 0;
	cfg.hashsize = 1;
//	cfg.quiet = 0;
	cfg.promisc_flag = 1;
//	cfg.ratelimit = 0;
//	cfg.sqlite_file = NULL;
//	cfg.uname = NULL;
	cfg.shm_data.size = DEFAULT_SHM_LOG_SIZE;
	cfg.shm_data.name = DEFAULT_SHM_LOG_NAME;
#if HAVE_LIBSQLITE3
	cfg.sqlite_table = PACKAGE;
#endif
	log_open(PACKAGE_NAME);
	argp_parse(&argp, argc, argv, 0, &optind, 0);

	if (!cfg.hostname) {
		cfg.hostname_len = sysconf(_SC_HOST_NAME_MAX);
		cfg.hostname = (char *)calloc(cfg.hostname_len, sizeof(char));
		gethostname(cfg.hostname, cfg.hostname_len);
	}

	daemonize();
	save_pid();

	libevent_init();


	if (cfg.ratelimit > 0)
		log_msg(LOG_DEBUG, "Ratelimiting duplicate entries to 1 per %d seconds", cfg.ratelimit);
	else if (cfg.ratelimit == -1)
		log_msg(LOG_DEBUG, "Duplicate entries supressed indefinitely");
	else
		log_msg(LOG_DEBUG, "Duplicate entries ratelimiting disabled");

	if (cfg.promisc_flag)
		log_msg(LOG_DEBUG, "PROMISC mode enabled");
	else
		log_msg(LOG_DEBUG, "PROMISC mode disabled");

	if (argc > optind) {
		for (i = optind; i < argc; i++)
			add_iface(argv[i]);
	} else {
		dev = pcap_lookupdev(errbuf);
		if (dev != NULL)
			add_iface(dev);
	}

	if (!cfg.interfaces)
		log_msg(LOG_ERR, "No suitable interfaces found!");

	if (cfg.uname)
		drop_root(cfg.uname);

	output_flatfile_init();
	output_sqlite_init();
	output_shm_init();

	/* main loop */
#if HAVE_LIBEVENT2
	event_base_dispatch(cfg.eb);
#else
	event_dispatch();
#endif

	output_shm_close();
	output_sqlite_close();
	output_flatfile_close();

	for (ifc = cfg.interfaces; ifc != NULL; ifc = del_iface(ifc));


	libevent_close();
	log_close();

	del_pid();
	blacklist_free();

	free(cfg.hostname);

	return 0;
}
Example #3
0
File: inarpd.c Project: ago/inarp
int main(int argc, char *argv[])
{
	int sock, devs = 0, ok, i;
	time_t last_xmit;
	device *dev;

	parse_args(argc, argv);

	read_ifaces();

	ok = 1;
	while(ifnum > 0) {
		if (add_iface(iflist[0], add_rt))
			ok = 0;
		else
			devs = 1;

		iflist++;
		ifnum--;
	}

	if (!ok)
		exit(1);

	if (!devs) {
		dev = first;
		while (dev) {
			dev->active = 1;
			dev->add_route = add_rt;
			dev = dev->next;
		}
	}

	dev = first;
	ok = 0;
	if (!dev) {
		error("inarpd: no network interfaces found\n");
		exit(1);
	}

	do {
		int ip4_cnt = 0, ip6_cnt = 0, peer = 0;

		if (!dev->active)
			continue;

		if (dev->has_name != 1) {
			error("Device %s has no name\n", dev->name);
			dev->active = 0;
			continue;
		}
		if ((dev->flags & IFF_POINTOPOINT) == 0) {
			if (verbose > 0 || devs)
				printf("Device %s is not point-to-point\n",
				       dev->name);
			dev->active = 0;
			continue;
		}
		if (dev->has_addr != 1) {
			if (verbose > 0 || devs)
				printf("Device %s has no hw address\n",
				       dev->name);
			dev->active = 0;
			continue;
		}
		if (dev->has_bcast != 1) {
			if (verbose > 0 || devs)
				printf("Device %s has no peer hw address\n",
				       dev->name);
			dev->active = 0;
			continue;
		}
		if (dev->ip_cnt == 0) {
			if (verbose > 0 || devs)
				printf("Device %s has no IP address\n",
				       dev->name);
			dev->active = 0;
			continue;
		}

		ok = 1;

		if (dev->type == ARPHRD_DLCI)
			memset(dev->addr, 0, dev->addr_len);

		if (!dev->add_route)
		continue;

		for (i = 0; (unsigned) i < dev->ip_cnt; i++) {
			if (dev->ip[i].family == AF_INET) {
				if (memcmp(dev->ip[i].addr, dev->ip[i].peer,
					   IP_ADDR_LEN) ||
				    dev->ip[i].bits != IP_ADDR_LEN * 8)
					peer = 1;
				ip4_cnt++;
			}
			if (dev->ip[i].family == AF_INET6) {
				if (memcmp(dev->ip[i].addr, dev->ip[i].peer,
					   IP6_ADDR_LEN) ||
				    dev->ip[i].bits != IP6_ADDR_LEN * 8)
					peer = 1;
				ip6_cnt++;
			}
		}

		if (ip4_cnt > 1 || ip6_cnt > 1) {
			if (verbose > 0 || devs)
				printf("Can't automatically add routes for"
				       " device %s having more than 1 IP"
				       " address\n", dev->name);
			dev->add_route = 0;
		} else if (peer) {
			if (verbose > 0 || devs)
				printf("Can't automatically add routes for"
				       " device %s with peer address\n",
				       dev->name);
			dev->add_route = 0;
		}
	}while ((dev = dev->next) != NULL);

	if (!ok) {
		error("inarpd: no usable interfaces found\n");
		exit(1);
	}

	if (verbose > 0) {
		dev = first;
		printf("Interfaces:\n");
		do {
			if (!dev->active)
				continue;
			printf("   %s%s", dev->name,
			       dev->add_route ? "(r)" : "");

			if (verbose <= 1) {
				putchar('\n');
				continue;
			}

			if (dev->type == ARPHRD_DLCI)
				printf(" [Q922 ");
			else {
				printf(" [");
				for (i = 0; (unsigned) i < dev->addr_len; i++)
					printf("%s%02X", i == 0 ? "" : ":",
					       dev->addr[i]);
				printf("->");
			}
			for (i = 0; (unsigned) i < dev->addr_len; i++)
				printf("%s%02X", i == 0 ? "" : ":",
				       dev->bcast[i]);
			printf("]");

			for (i = 0; (unsigned) i < dev->ip_cnt; i++) {
				putchar(' ');
				print_ip(dev->ip[i].family, dev->ip[i].addr);
				printf("->");
				print_ip(dev->ip[i].family, dev->ip[i].peer);
				printf("/%u", dev->ip[i].bits);
			}
			putchar('\n');
		}while ((dev = dev->next) != NULL);
	}


	if ((sock = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ARP))) == -1) {
		perror("inarpd: socket() failed");
		exit(-1);
	}

	if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0)
		perror("fcntl() failed");

	last_xmit = 0;
	while(1) {
		fd_set set;
                FD_ZERO(&set);
                FD_SET(sock, &set);
		time_t now = time(NULL);
		struct timeval tm;
		arp_packet buffer;
		struct sockaddr_ll addr;
		socklen_t addr_len = sizeof(addr);

		tm.tv_sec = last_xmit + INARP_DELAY - now;
		tm.tv_usec = 0;

 		if (tm.tv_sec <= 0) {
			send_requests(sock);
			last_xmit = now;
			continue;
		}

		expire_routes();
		if (verbose > 2)
			printf("calling select()\n");
		if (select(sock + 1, &set, NULL, NULL, &tm) < 0) {
                        perror("select() failed");
			continue;
		}

                if (!FD_ISSET(sock, &set))
			continue;

		if (verbose > 2)
			printf("calling recv()\n");

		int len = recvfrom(sock, &buffer, sizeof(buffer), 0,
				   (struct sockaddr*)&addr, &addr_len);
		dev = get_device(addr.sll_ifindex, GET_DEVICE_DONT_CREATE);
		if (!dev) {
			if (verbose > 1)
				printf("received packet on unknown device\n");
			continue;
		}
		inbound_inarp(sock, dev, &buffer, len);
	}
}