Пример #1
0
int
intf_loop(intf_t *intf, intf_handler callback, void *arg)
{
	struct intf_entry *entry;
	struct lifreq *lifr, *llifr, *plifr;
	char *p, ebuf[BUFSIZ];
	int ret;

	entry = (struct intf_entry *)ebuf;

	intf->lifc.lifc_buf = (caddr_t)intf->ifcbuf;
	intf->lifc.lifc_len = sizeof(intf->ifcbuf);
	
	if (ioctl(intf->fd, SIOCGLIFCONF, &intf->lifc) < 0)
		return (-1);

	llifr = (struct lifreq *)&intf->lifc.lifc_buf[intf->lifc.lifc_len];
	
	for (lifr = intf->lifc.lifc_req; lifr < llifr; lifr = NEXTLIFR(lifr)) {
		/* XXX - Linux, Solaris ifaliases */
		if ((p = strchr(lifr->lifr_name, ':')) != NULL)
			*p = '\0';
		
		for (plifr = intf->lifc.lifc_req; plifr < lifr; plifr = NEXTLIFR(lifr)) {
			if (strcmp(lifr->lifr_name, plifr->lifr_name) == 0)
				break;
		}
		if (lifr > intf->lifc.lifc_req && plifr < llifr)
			continue;

		memset(ebuf, 0, sizeof(ebuf));
		strlcpy(entry->intf_name, lifr->lifr_name,
		    sizeof(entry->intf_name));
		entry->intf_len = sizeof(ebuf);

		/* Repair the alias name back up */
		if (p) *p = ':';
		
		if (_intf_get_noalias(intf, entry) < 0)
			return (-1);
		if (_intf_get_aliases(intf, entry) < 0)
			return (-1);
		
		if ((ret = (*callback)(entry, arg)) != 0)
			return (ret);
	}
	return (0);
}
Пример #2
0
Файл: intf.c Проект: tixxdz/nmap
int
intf_loop(intf_t *intf, intf_handler callback, void *arg)
{
	struct intf_entry *entry;
	struct lifreq *lifr, *llifr, *plifr;
	char *p, ebuf[BUFSIZ];
	int ret;

	entry = (struct intf_entry *)ebuf;

	/* http://www.unix.com/man-page/opensolaris/7p/if_tcp */
	intf->lifc.lifc_family = AF_UNSPEC;
	intf->lifc.lifc_flags = 0;
#ifdef LIFC_UNDER_IPMP
	intf->lifc.lifc_flags |= LIFC_UNDER_IPMP;
#endif
	intf->lifc.lifc_buf = (caddr_t)intf->ifcbuf;
	intf->lifc.lifc_len = sizeof(intf->ifcbuf);
	
	if (ioctl(intf->fd, SIOCGLIFCONF, &intf->lifc) < 0)
		return (-1);

	llifr = (struct lifreq *)&intf->lifc.lifc_buf[intf->lifc.lifc_len];
	
	for (lifr = intf->lifc.lifc_req; lifr < llifr; lifr = NEXTLIFR(lifr)) {
		/* XXX - Linux, Solaris ifaliases */
		if ((p = strchr(lifr->lifr_name, ':')) != NULL)
			*p = '\0';
		
		for (plifr = intf->lifc.lifc_req; plifr < lifr; plifr = NEXTLIFR(lifr)) {
			if (strcmp(lifr->lifr_name, plifr->lifr_name) == 0)
				break;
		}
		if (lifr > intf->lifc.lifc_req && plifr < lifr)
			continue;

		memset(ebuf, 0, sizeof(ebuf));
		strlcpy(entry->intf_name, lifr->lifr_name,
		    sizeof(entry->intf_name));
		entry->intf_len = sizeof(ebuf);

		/* Repair the alias name back up */
		if (p) *p = ':';

		/* Ignore IPMP interfaces. These are virtual interfaces made up
		 * of physical interfaces. IPMP interfaces do not support things
		 * like packet sniffing; it is necessary to use one of the
		 * underlying physical interfaces instead. This works as long as
		 * the physical interface's test address is on the same subnet
		 * as the IPMP interface's address. */
		if (ioctl(intf->fd, SIOCGLIFFLAGS, lifr) >= 0)
			;
		else if (intf->fd6 != -1 && ioctl(intf->fd6, SIOCGLIFFLAGS, lifr) >= 0)
			;
		else
			return (-1);
		if (lifr->lifr_flags & IFF_IPMP) {
			continue;
		}
		
		if (_intf_get_noalias(intf, entry) < 0)
			return (-1);
		if (_intf_get_aliases(intf, entry) < 0)
			return (-1);
		
		if ((ret = (*callback)(entry, arg)) != 0)
			return (ret);
	}
	return (0);
}
Пример #3
0
Файл: intf.c Проект: tixxdz/nmap
static int
_intf_get_aliases(intf_t *intf, struct intf_entry *entry)
{
	struct lifreq *lifr, *llifr;
	struct lifreq tmplifr;
	struct addr *ap, *lap;
	char *p;
	
	if (intf->lifc.lifc_len < (int)sizeof(*lifr)) {
		errno = EINVAL;
		return (-1);
	}
	entry->intf_alias_num = 0;
	ap = entry->intf_alias_addrs;
	llifr = (struct lifreq *)intf->lifc.lifc_buf + 
	    (intf->lifc.lifc_len / sizeof(*llifr));
	lap = (struct addr *)((u_char *)entry + entry->intf_len);
	
	/* Get addresses for this interface. */
	for (lifr = intf->lifc.lifc_req; lifr < llifr && (ap + 1) < lap;
	    lifr = NEXTLIFR(lifr)) {
		/* XXX - Linux, Solaris ifaliases */
		if ((p = strchr(lifr->lifr_name, ':')) != NULL)
			*p = '\0';
		
		if (strcmp(lifr->lifr_name, entry->intf_name) != 0) {
			if (p) *p = ':';
			continue;
		}
		
		/* Fix the name back up */
		if (p) *p = ':';

		if (addr_ston((struct sockaddr *)&lifr->lifr_addr, ap) < 0)
			continue;
		
		/* XXX */
		if (ap->addr_type == ADDR_TYPE_ETH) {
			memcpy(&entry->intf_link_addr, ap, sizeof(*ap));
			continue;
		} else if (ap->addr_type == ADDR_TYPE_IP) {
			if (ap->addr_ip == entry->intf_addr.addr_ip ||
			    ap->addr_ip == entry->intf_dst_addr.addr_ip)
				continue;
			strlcpy(tmplifr.lifr_name, lifr->lifr_name, sizeof(tmplifr.lifr_name));
			if (ioctl(intf->fd, SIOCGIFNETMASK, &tmplifr) == 0)
				addr_stob((struct sockaddr *)&tmplifr.lifr_addr, &ap->addr_bits);
		} else if (ap->addr_type == ADDR_TYPE_IP6 && intf->fd6 != -1) {
			if (memcmp(&ap->addr_ip6, &entry->intf_addr.addr_ip6, IP6_ADDR_LEN) == 0 ||
			    memcmp(&ap->addr_ip6, &entry->intf_dst_addr.addr_ip6, IP6_ADDR_LEN) == 0)
				continue;
			strlcpy(tmplifr.lifr_name, lifr->lifr_name, sizeof(tmplifr.lifr_name));
			if (ioctl(intf->fd6, SIOCGLIFNETMASK, &tmplifr) == 0) {
				addr_stob((struct sockaddr *)&tmplifr.lifr_addr,
				    &ap->addr_bits);
			}
			else perror("SIOCGLIFNETMASK");
		}
		ap++, entry->intf_alias_num++;
	}
	entry->intf_len = (u_char *)ap - (u_char *)entry;
	
	return (0);
}