Пример #1
0
int nozzle_set_mtu(nozzle_t nozzle, const int mtu)
{
	int err = 0, savederrno = 0;
	struct nozzle_ip *tmp_ip;
	struct ifreq ifr;

	if (!mtu) {
		errno = EINVAL;
		return -1;
	}

	savederrno = pthread_mutex_lock(&config_mutex);
	if (savederrno) {
		errno = savederrno;
		return -1;
	}

	if (!is_valid_nozzle(nozzle)) {
		savederrno = EINVAL;
		err = -1;
		goto out_clean;
	}

	err = nozzle->current_mtu = get_iface_mtu(nozzle);
	if (err < 0) {
		savederrno = errno;
		goto out_clean;
	}

	memset(&ifr, 0, sizeof(struct ifreq));
	strncpy(ifname, nozzle->name, IFNAMSIZ);
	ifr.ifr_mtu = mtu;

	err = ioctl(lib_cfg.ioctlfd, SIOCSIFMTU, &ifr);
	if (err) {
		savederrno = errno;
		goto out_clean;
	}

	if ((nozzle->current_mtu < 1280) && (mtu >= 1280)) {
		tmp_ip = nozzle->ip;
		while(tmp_ip) {
			if (tmp_ip->domain == AF_INET6) {
				err = _set_ip(nozzle, IP_ADD, tmp_ip->ipaddr, tmp_ip->prefix, 0);
				if (err) {
					savederrno = errno;
					err = -1;
					goto out_clean;
				}
			}
			tmp_ip = tmp_ip->next;
		}
	}

out_clean:
	pthread_mutex_unlock(&config_mutex);
	errno = savederrno;
	return err;
}
Пример #2
0
int nozzle_del_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix)
{
	int err = 0, savederrno = 0;
        int found = 0;
	struct nozzle_ip *ip = NULL, *ip_prev = NULL;

	if ((!ipaddr) || (!prefix)) {
		errno = EINVAL;
		return -1;
	}

	savederrno = pthread_mutex_lock(&config_mutex);
	if (savederrno) {
		errno = savederrno;
		return -1;
	}

	if (!is_valid_nozzle(nozzle)) {
		savederrno = EINVAL;
		err = -1;
		goto out_clean;
	}

	found = find_ip(nozzle, ipaddr, prefix, &ip, &ip_prev);
	if (!found) {
		goto out_clean;
	}

	/*
	 * if user asks for an IPv6 address, but MTU < 1280
	 * the IP might not be configured on the interface and we only need to
	 * remove it from our internal database
	 */
	if ((ip->domain == AF_INET6) && (get_iface_mtu(nozzle) < 1280)) {
		err = 0;
	} else {
		err = _set_ip(nozzle, IP_DEL, ipaddr, prefix, 0);
		savederrno = errno;
	}

	if (!err) {
		if (ip == ip_prev) {
			nozzle->ip = ip->next;
		} else {
			ip_prev->next = ip->next;
		}
		free(ip);
	}

out_clean:
	pthread_mutex_unlock(&config_mutex);
	errno = savederrno;
	return err;
}
Пример #3
0
int nozzle_get_mtu(const nozzle_t nozzle)
{
	int err = 0, savederrno = 0;

	savederrno = pthread_mutex_lock(&config_mutex);
	if (savederrno) {
		errno = savederrno;
		return -1;
	}

	if (!is_valid_nozzle(nozzle)) {
		savederrno = EINVAL;
		err = -1;
		goto out_clean;
	}

	err = get_iface_mtu(nozzle);
	savederrno = errno;

out_clean:
	pthread_mutex_unlock(&config_mutex);
	errno = savederrno;
	return err;
}
Пример #4
0
void get_hw_info(void)
{
   u_long ip;
   struct libnet_ether_addr *ea;
   bpf_u_int32 network, netmask;
   char pcap_errbuf[PCAP_ERRBUF_SIZE];
 
   /* dont touch the interface reading from file */
   if (!GBL_LNET->lnet || GBL_OPTIONS->read) {
      DEBUG_MSG("get_hw_info: skipping... (not initialized)");
      return;
   }
   
   DEBUG_MSG("get_hw_info");
  
   /* get the ip address */
   ip = libnet_get_ipaddr4(GBL_LNET->lnet);
   
   /* if ip is equal to -1 there was an error */
   if (ip != (u_long)~0) {

      /* the interface has an ip address */
      if (ip != 0)
         GBL_IFACE->configured = 1;
      
      /* save the ip address */
      ip_addr_init(&GBL_IFACE->ip, AF_INET, (char *)&ip);
      
      if (pcap_lookupnet(GBL_OPTIONS->iface, &network, &netmask, pcap_errbuf) == -1)
         ERROR_MSG("%s", pcap_errbuf);
      
      ip_addr_init(&GBL_IFACE->network, AF_INET, (char *)&network);

      /* the user has specified a different netmask, use it */
      if (GBL_OPTIONS->netmask) {
         struct in_addr net;
         /* sanity check */
         if (inet_aton(GBL_OPTIONS->netmask, &net) == 0)
            FATAL_ERROR("Invalid netmask %s", GBL_OPTIONS->netmask);

         ip_addr_init(&GBL_IFACE->netmask, AF_INET, (char *)&net);
      } else
         ip_addr_init(&GBL_IFACE->netmask, AF_INET, (char *)&netmask);
      
   } else
      DEBUG_MSG("get_hw_info: NO IP on %s", GBL_OPTIONS->iface);
   
   /* get the mac address */
   ea = libnet_get_hwaddr(GBL_LNET->lnet);

   if (ea != NULL)
      memcpy(GBL_IFACE->mac, ea->ether_addr_octet, MEDIA_ADDR_LEN);
   else
      DEBUG_MSG("get_hw_info: NO MAC for %s", GBL_OPTIONS->iface);

   /* get the MTU */
   GBL_IFACE->mtu = get_iface_mtu(GBL_OPTIONS->iface);
   
   /* check the mtu */
   if (GBL_IFACE->mtu > INT16_MAX)
      FATAL_ERROR("MTU too large");

   USER_MSG("%6s ->\t%s  ",  GBL_OPTIONS->iface,
            mac_addr_ntoa(GBL_IFACE->mac, pcap_errbuf));
   USER_MSG("%16s  ", ip_addr_ntoa(&GBL_IFACE->ip, pcap_errbuf));
   USER_MSG("%16s\n\n", ip_addr_ntoa(&GBL_IFACE->netmask, pcap_errbuf) );
   
   /* if not in bridged sniffing, return */
   if (GBL_SNIFF->type != SM_BRIDGED)
      return;
   
   ip = libnet_get_ipaddr4(GBL_LNET->lnet_bridge);

   /* if ip is equal to -1 there was an error */
   if (ip != (u_long)~0) {
      ip_addr_init(&GBL_BRIDGE->ip, AF_INET, (char *)&ip);
      
      if (pcap_lookupnet(GBL_OPTIONS->iface_bridge, &network, &netmask, pcap_errbuf) == -1)
         ERROR_MSG("%s", pcap_errbuf);
      
      ip_addr_init(&GBL_BRIDGE->network, AF_INET, (char *)&network);
      ip_addr_init(&GBL_BRIDGE->netmask, AF_INET, (char *)&netmask);
      
   } else
      DEBUG_MSG("get_hw_info: NO IP on %s", GBL_OPTIONS->iface_bridge);
   
   ea = libnet_get_hwaddr(GBL_LNET->lnet_bridge);

   if (ea != NULL)
      memcpy(GBL_BRIDGE->mac, ea->ether_addr_octet, MEDIA_ADDR_LEN);
   else
      DEBUG_MSG("get_hw_info: NO MAC for %s", GBL_OPTIONS->iface_bridge);
   
   /* get the MTU */
   GBL_BRIDGE->mtu = get_iface_mtu(GBL_OPTIONS->iface_bridge);
   
   if (GBL_BRIDGE->mtu > INT16_MAX)
      FATAL_ERROR("MTU too large");

   USER_MSG("%6s ->\t%s  ",  GBL_OPTIONS->iface_bridge,
            mac_addr_ntoa(GBL_BRIDGE->mac, pcap_errbuf));
   USER_MSG("%16s  ", ip_addr_ntoa(&GBL_BRIDGE->ip, pcap_errbuf));
   USER_MSG("%16s\n\n", ip_addr_ntoa(&GBL_BRIDGE->netmask, pcap_errbuf) );

   /* some sanity checks */
   if (GBL_BRIDGE->mtu != GBL_IFACE->mtu)
      FATAL_ERROR("The two interfaces must have the same MTU.");

   if (!memcmp(GBL_BRIDGE->mac, GBL_IFACE->mac, MEDIA_ADDR_LEN))
      FATAL_ERROR("The two bridged interfaces must be phisically different");
}
Пример #5
0
nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
{
	int savederrno = 0;
	nozzle_t nozzle = NULL;
	char *temp_mac = NULL;
#ifdef KNET_LINUX
	struct ifreq ifr;
#endif
#ifdef KNET_BSD
	uint16_t i;
	long int nozzlenum = 0;
	char curnozzle[IFNAMSIZ];
#endif

	if (devname == NULL) {
		errno = EINVAL;
		return NULL;
	}

	if (devname_size < IFNAMSIZ) {
		errno = EINVAL;
		return NULL;
	}

	if (strlen(devname) > IFNAMSIZ) {
		errno = E2BIG;
		return NULL;
	}

#ifdef KNET_BSD
	/*
	 * BSD does not support named devices like Linux
	 * but it is possible to force a nozzleX device number
	 * where X is 0 to 255.
	 */
	if (strlen(devname)) {
		if (strncmp(devname, "tap", 3)) {
			errno = EINVAL;
			return NULL;
		}
		errno = 0;
		nozzlenum = strtol(devname+3, NULL, 10);
		if (errno) {
			errno = EINVAL;
			return NULL;
		}
		if ((nozzlenum < 0) || (nozzlenum > 255)) {
			errno = EINVAL;
			return NULL;
		}
	}
#endif

	if (updownpath) {
		/* only absolute paths */
		if (updownpath[0] != '/') {
			errno = EINVAL;
			return NULL;
		}
		if (strlen(updownpath) >= UPDOWN_PATH_MAX) {
			errno = E2BIG;
			return NULL;
		}
	}

	savederrno = pthread_mutex_lock(&config_mutex);
	if (savederrno) {
		errno = savederrno;
		return NULL;
	}

	if (!lib_init) {
		lib_cfg.head = NULL;
#ifdef KNET_LINUX
		lib_cfg.nlsock = nl_socket_alloc();
		if (!lib_cfg.nlsock) {
			savederrno = errno;
			goto out_error;
		}
		if (nl_connect(lib_cfg.nlsock, NETLINK_ROUTE) < 0) {
			savederrno = EBUSY;
			goto out_error;
		}
		lib_cfg.ioctlfd = socket(AF_INET, SOCK_STREAM, 0);
#endif
#ifdef KNET_BSD
		lib_cfg.ioctlfd = socket(AF_LOCAL, SOCK_DGRAM, 0);
#endif
		if (lib_cfg.ioctlfd < 0) {
			savederrno = errno;
			goto out_error;
		}
		lib_init = 1;
	}

	nozzle = malloc(sizeof(struct nozzle_iface));
	if (!nozzle) {
		savederrno = ENOMEM;
		goto out_error;
	}

	memset(nozzle, 0, sizeof(struct nozzle_iface));

#ifdef KNET_BSD
	if (!strlen(devname)) {
		for (i = 0; i < 256; i++) {
			snprintf(curnozzle, sizeof(curnozzle) - 1, "/dev/tap%u", i);
			nozzle->fd = open(curnozzle, O_RDWR);
			savederrno = errno;
			if (nozzle->fd > 0) {
				break;
			}
		}
		snprintf(curnozzle, sizeof(curnozzle) -1 , "tap%u", i);
	} else {
		snprintf(curnozzle, sizeof(curnozzle) - 1, "/dev/%s", devname);
		nozzle->fd = open(curnozzle, O_RDWR);
		savederrno = errno;
		snprintf(curnozzle, sizeof(curnozzle) - 1, "%s", devname);
	}
	if (nozzle->fd < 0) {
		savederrno = EBUSY;
		goto out_error;
	}
	strncpy(devname, curnozzle, IFNAMSIZ);
	strncpy(nozzle->name, curnozzle, IFNAMSIZ);
#endif

#ifdef KNET_LINUX
	if ((nozzle->fd = open("/dev/net/tun", O_RDWR)) < 0) {
		savederrno = errno;
		goto out_error;
	}

	memset(&ifr, 0, sizeof(struct ifreq));
	memmove(ifname, devname, IFNAMSIZ);
	ifr.ifr_flags = IFF_TAP | IFF_NO_PI;

	if (ioctl(nozzle->fd, TUNSETIFF, &ifr) < 0) {
		savederrno = errno;
		goto out_error;
	}

	if ((strlen(devname) > 0) && (strcmp(devname, ifname) != 0)) {
		savederrno = EBUSY;
		goto out_error;
	}

	strncpy(devname, ifname, IFNAMSIZ);
	strncpy(nozzle->name, ifname, IFNAMSIZ);
#endif

	nozzle->default_mtu = get_iface_mtu(nozzle);
	if (nozzle->default_mtu < 0) {
		savederrno = errno;
		goto out_error;
	}

	if (get_iface_mac(nozzle, &temp_mac) < 0) {
		savederrno = errno;
		goto out_error;
	}

	strncpy(nozzle->default_mac, temp_mac, 18);
	free(temp_mac);

	if (updownpath) {
		int len = strlen(updownpath);

		strcpy(nozzle->updownpath, updownpath);
		if (nozzle->updownpath[len-1] != '/') {
			nozzle->updownpath[len] = '/';
		}
		nozzle->hasupdown = 1;
	}

	nozzle->next = lib_cfg.head;
	lib_cfg.head = nozzle;

	pthread_mutex_unlock(&config_mutex);
	errno = savederrno;
	return nozzle;

out_error:
	destroy_iface(nozzle);
	pthread_mutex_unlock(&config_mutex);
	errno = savederrno;
	return NULL;
}
Пример #6
0
int nozzle_add_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix)
{
	int err = 0, savederrno = 0;
	int found = 0;
	struct nozzle_ip *ip = NULL, *ip_prev = NULL, *ip_last = NULL;
	int secondary = 0;

	if ((!ipaddr) || (!prefix)) {
		errno = EINVAL;
		return -1;
	}

	savederrno = pthread_mutex_lock(&config_mutex);
	if (savederrno) {
		errno = savederrno;
		return -1;
	}

	if (!is_valid_nozzle(nozzle)) {
		savederrno = EINVAL;
		err = -1;
		goto out_clean;
	}

	found = find_ip(nozzle, ipaddr, prefix, &ip, &ip_prev);
	if (found) {
		goto out_clean;
	}

	ip = malloc(sizeof(struct nozzle_ip));
	if (!ip) {
		savederrno = errno;
		err = -1 ;
		goto out_clean;
	}

	memset(ip, 0, sizeof(struct nozzle_ip));
	strncpy(ip->ipaddr, ipaddr, IPADDR_CHAR_MAX);
	strncpy(ip->prefix, prefix, PREFIX_CHAR_MAX);
	if (!strchr(ip->ipaddr, ':')) {
		ip->domain = AF_INET;
	} else {
		ip->domain = AF_INET6;
	}

	/*
	 * if user asks for an IPv6 address, but MTU < 1280
	 * store the IP and bring it up later if and when MTU > 1280
	 */
	if ((ip->domain == AF_INET6) && (get_iface_mtu(nozzle) < 1280)) {
		err = 0;
	} else {
		if (nozzle->ip) {
			secondary = 1;
		}
		err = _set_ip(nozzle, IP_ADD, ipaddr, prefix, secondary);
		savederrno = errno;
	}

	if (err) {
		free(ip);
		goto out_clean;
	}

	if (nozzle->ip) {
		ip_last = nozzle->ip;
		while (ip_last->next != NULL) {
			ip_last = ip_last->next;
		}
		ip_last->next = ip;
	} else {
		nozzle->ip = ip;
	}

out_clean:
	pthread_mutex_unlock(&config_mutex);
	errno = savederrno;
	return err;
}