示例#1
0
文件: intf.c 项目: boundary/libdnet
int
intf_loop(intf_t *intf, intf_handler callback, void *arg)
{
	struct intf_entry *entry;
	struct ifreq *ifr, *lifr, *pifr;
	char *p, ebuf[BUFSIZ];
	int ret;

	entry = (struct intf_entry *)ebuf;

	intf->ifc.ifc_buf = (caddr_t)intf->ifcbuf;
	intf->ifc.ifc_len = sizeof(intf->ifcbuf);

	if (ioctl(intf->fd, SIOCGIFCONF, &intf->ifc) < 0)
		return (-1);

	pifr = NULL;
	lifr = (struct ifreq *)&intf->ifc.ifc_buf[intf->ifc.ifc_len];

	for (ifr = intf->ifc.ifc_req; ifr < lifr; ifr = NEXTIFR(ifr)) {
		/* XXX - Linux, Solaris ifaliases */
		if ((p = strchr(ifr->ifr_name, ':')) != NULL)
			*p = '\0';

		if (pifr != NULL && strcmp(ifr->ifr_name, pifr->ifr_name) == 0) {
			if (p) *p = ':';
			continue;
		}

		memset(ebuf, 0, sizeof(ebuf));
		strlcpy(entry->intf_name, ifr->ifr_name,
		    sizeof(entry->intf_name));
		strlcpy(entry->os_intf_name, ifr->ifr_name,
			sizeof(entry->os_intf_name));
		strlcpy(entry->pcap_intf_name, ifr->ifr_name,
			sizeof(entry->pcap_intf_name));
		intf_get_drv_info(intf, entry);
		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);

		pifr = ifr;
	}
	return (0);
}
示例#2
0
文件: intf.c 项目: OPSF/uClinux
static int
_intf_get_aliases(intf_t *intf, struct intf_entry *entry)
{
    struct ifreq *ifr, *lifr;
    struct ifreq tmpifr;
    struct addr *ap, *lap;
    char *p;

    if (intf->ifc.ifc_len < (int)sizeof(*ifr)) {
        errno = EINVAL;
        return (-1);
    }
    entry->intf_alias_num = 0;
    ap = entry->intf_alias_addrs;
    lifr = (struct ifreq *)intf->ifc.ifc_buf +
           (intf->ifc.ifc_len / sizeof(*lifr));
    lap = (struct addr *)((u_char *)entry + entry->intf_len);

    /* Get addresses for this interface. */
    for (ifr = intf->ifc.ifc_req; ifr < lifr && (ap + 1) < lap;
            ifr = NEXTIFR(ifr)) {
        /* XXX - Linux, Solaris ifaliases */
        if ((p = strchr(ifr->ifr_name, ':')) != NULL)
            *p = '\0';

        if (strcmp(ifr->ifr_name, entry->intf_name) != 0) {
            if (p) *p = ':';
            continue;
        }

        if (p) *p = ':'; /* Fix the name back up */
        if (addr_ston(&ifr->ifr_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(tmpifr.ifr_name, ifr->ifr_name,
                    sizeof(tmpifr.ifr_name));
            if (ioctl(intf->fd, SIOCGIFNETMASK, &tmpifr) == 0)
                addr_stob(&tmpifr.ifr_addr, &ap->addr_bits);

        }
#ifdef SIOCGIFNETMASK_IN6
        else if (ap->addr_type == ADDR_TYPE_IP6 && intf->fd6 != -1) {
            struct in6_ifreq ifr6;

            /* XXX - sizeof(ifr) < sizeof(ifr6) */
            memcpy(&ifr6, ifr, sizeof(ifr6));

            if (ioctl(intf->fd6, SIOCGIFNETMASK_IN6, &ifr6) == 0) {
                addr_stob((struct sockaddr *)&ifr6.ifr_addr,
                          &ap->addr_bits);
            }
            else perror("SIOCGIFNETMASK_IN6");
        }
#endif
        ap++, entry->intf_alias_num++;
    }
    entry->intf_len = (u_char *)ap - (u_char *)entry;

    return (0);
}
int
libnet_ifaddrlist(register struct libnet_ifaddr_list **ipaddrp, int8_t *dev,
register int8_t *errbuf)
{
    register struct libnet_ifaddr_list *al;
    struct ifreq *ifr, *lifr, *pifr, nifr;
    int8_t device[sizeof(nifr.ifr_name)];
    static struct libnet_ifaddr_list ifaddrlist[MAX_IPADDR];
    
    char *p;
    struct ifconf ifc;
    struct ifreq ibuf[MAX_IPADDR];
    register int fd, nipaddr;
    
#ifdef HAVE_LINUX_PROCFS
    FILE *fp;
    char buf[2048];
#endif
    
    fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (fd < 0)
    {
	snprintf(errbuf, LIBNET_ERRBUF_SIZE, "%s(): socket error: %s\n",
                __func__, strerror(errno));
	return (-1);
    }

#ifdef HAVE_LINUX_PROCFS
    if ((fp = fopen(PROC_DEV_FILE, "r")) == NULL)
    {
	snprintf(errbuf, LIBNET_ERRBUF_SIZE,
                "%s(): fopen(proc_dev_file) failed: %s\n",  __func__,
                strerror(errno));
	return (-1);
    }
#endif

    memset(&ifc, 0, sizeof(ifc));
    ifc.ifc_len = sizeof(ibuf);
    ifc.ifc_buf = (caddr_t)ibuf;

    if(ioctl(fd, SIOCGIFCONF, &ifc) < 0)
    {
	snprintf(errbuf, LIBNET_ERRBUF_SIZE,
                "%s(): ioctl(SIOCGIFCONF) error: %s\n", 
                __func__, strerror(errno));
	return(-1);
    }

    pifr = NULL;
    lifr = (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len];
    
    al = ifaddrlist;
    nipaddr = 0;

#ifdef HAVE_LINUX_PROCFS
    while (fgets(buf, sizeof(buf), fp))
    {
	if ((p = strchr(buf, ':')) == NULL)
        {
            continue;
        }
        *p = '\0';
        for(p = buf; *p == ' '; p++) ;
	
        strncpy(nifr.ifr_name, p, sizeof(nifr.ifr_name) - 1);
        nifr.ifr_name[sizeof(nifr.ifr_name) - 1] = '\0';
	
#else /* !HAVE_LINUX_PROCFS */

    for (ifr = ifc.ifc_req; ifr < lifr; ifr = NEXTIFR(ifr))
    {
	/* XXX LINUX SOLARIS ifalias */
	if((p = strchr(ifr->ifr_name, ':')))
        {
            *p='\0';
        }
	if (pifr && strcmp(ifr->ifr_name, pifr->ifr_name) == 0)
        {
            continue;
        }
	strncpy(nifr.ifr_name, ifr->ifr_name, sizeof(nifr.ifr_name) - 1);
	nifr.ifr_name[sizeof(nifr.ifr_name) - 1] = '\0';
#endif

        /* save device name */
        strncpy(device, nifr.ifr_name, sizeof(device) - 1);
        device[sizeof(device) - 1] = '\0';

        if (ioctl(fd, SIOCGIFFLAGS, &nifr) < 0)
        {
            pifr = ifr;
            continue;
	}
        if ((nifr.ifr_flags & IFF_UP) == 0)
	{
            pifr = ifr;
            continue;	
	}

        if (dev == NULL && LIBNET_ISLOOPBACK(&nifr))
	{
            pifr = ifr;
            continue;
	}
	
        strncpy(nifr.ifr_name, device, sizeof(device) - 1);
        nifr.ifr_name[sizeof(nifr.ifr_name) - 1] = '\0';
        if (ioctl(fd, SIOCGIFADDR, (int8_t *)&nifr) < 0)
        {
            if (errno != EADDRNOTAVAIL)
            {
                snprintf(errbuf, LIBNET_ERRBUF_SIZE,
                        "%s(): SIOCGIFADDR: dev=%s: %s\n", __func__, device,
                        strerror(errno));
                close(fd);
                return (-1);
	    }
            else /* device has no IP address => set to 0 */
            {
                al->addr = 0;
            }
        }
        else
        {
            al->addr = ((struct sockaddr_in *)&nifr.ifr_addr)->sin_addr.s_addr;
        }

        if ((al->device = strdup(device)) == NULL)
        {
            snprintf(errbuf, LIBNET_ERRBUF_SIZE, 
                    "%s(): strdup not enough memory\n", __func__);
            return(-1);
        }

        ++al;
        ++nipaddr;

#ifndef HAVE_LINUX_PROCFS
        pifr = ifr;
#endif

    } /* while|for */
	
#ifdef HAVE_LINUX_PROCFS
    if (ferror(fp))
    {
        snprintf(errbuf, LIBNET_ERRBUF_SIZE,
                "%s(): ferror: %s\n", __func__, strerror(errno));
	return (-1);
    }
    fclose(fp);
#endif

    *ipaddrp = ifaddrlist;
    return (nipaddr);
}
#else
/* From tcptraceroute, convert a numeric IP address to a string */
#define IPTOSBUFFERS    12
static int8_t *iptos(u_int32_t in)
{
    static int8_t output[IPTOSBUFFERS][ 3 * 4 + 3 + 1];
    static int16_t which;
    u_int8_t *p;

    p = (u_int8_t *)&in;
    which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);
    snprintf(output[which], IPTOSBUFFERS, "%d.%d.%d.%d", 
            p[0], p[1], p[2], p[3]);
    return output[which];
}

int
libnet_ifaddrlist(register struct libnet_ifaddr_list **ipaddrp, int8_t *dev,
register int8_t *errbuf)
{
    int nipaddr = 0;    int i = 0;

    static struct libnet_ifaddr_list ifaddrlist[MAX_IPADDR];
    pcap_if_t *alldevs;
    pcap_if_t *d;
    int8_t err[PCAP_ERRBUF_SIZE];

    /* Retrieve the interfaces list */
    if (pcap_findalldevs(&alldevs, err) == -1)
    {
        snprintf(errbuf, LIBNET_ERRBUF_SIZE, 
                "%s(): error in pcap_findalldevs: %s\n", __func__, err);
        return (-1);
    }

    /* Scan the list printing every entry */
	for (d = alldevs; d; d = d->next)
    {
		if((!d->addresses) || (d->addresses->addr->sa_family != AF_INET))
            continue;
        if(d->flags & PCAP_IF_LOOPBACK)
            continue;
    
		/* XXX - strdup */
        ifaddrlist[i].device = strdup(d->name);
        ifaddrlist[i].addr = (u_int32_t)
                strdup(iptos(((struct sockaddr_in *)
                d->addresses->addr)->sin_addr.s_addr));
        ++i;
        ++nipaddr;
    }

    *ipaddrp = ifaddrlist;
    return (nipaddr);
}
示例#4
0
文件: intf.c 项目: tixxdz/nmap
static int
_intf_get_aliases(intf_t *intf, struct intf_entry *entry)
{
	struct ifreq *ifr, *lifr;
	struct ifreq tmpifr;
	struct addr *ap, *lap;
	char *p;
	
	if (intf->ifc.ifc_len < (int)sizeof(*ifr)) {
		errno = EINVAL;
		return (-1);
	}
	entry->intf_alias_num = 0;
	ap = entry->intf_alias_addrs;
	lifr = (struct ifreq *)intf->ifc.ifc_buf + 
	    (intf->ifc.ifc_len / sizeof(*lifr));
	lap = (struct addr *)((u_char *)entry + entry->intf_len);
	
	/* Get addresses for this interface. */
	for (ifr = intf->ifc.ifc_req; ifr < lifr && (ap + 1) < lap;
	    ifr = NEXTIFR(ifr)) {
		/* XXX - Linux, Solaris ifaliases */
		if ((p = strchr(ifr->ifr_name, ':')) != NULL)
			*p = '\0';
		
		if (strcmp(ifr->ifr_name, entry->intf_name) != 0) {
			if (p) *p = ':';
			continue;
		}
		
		/* Fix the name back up */
		if (p) *p = ':';

		if (addr_ston(&ifr->ifr_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(tmpifr.ifr_name, ifr->ifr_name, sizeof(tmpifr.ifr_name));
			if (ioctl(intf->fd, SIOCGIFNETMASK, &tmpifr) == 0)
				addr_stob(&tmpifr.ifr_addr, &ap->addr_bits);
		}
#ifdef SIOCGIFNETMASK_IN6
		else if (ap->addr_type == ADDR_TYPE_IP6 && intf->fd6 != -1) {
			struct in6_ifreq ifr6;

			/* XXX - sizeof(ifr) < sizeof(ifr6) */
			memcpy(&ifr6, ifr, sizeof(ifr6));
			
			if (ioctl(intf->fd6, SIOCGIFNETMASK_IN6, &ifr6) == 0) {
				addr_stob((struct sockaddr *)&ifr6.ifr_addr,
				    &ap->addr_bits);
			}
			else perror("SIOCGIFNETMASK_IN6");
		}
#else
#ifdef SIOCGIFNETMASK6
		else if (ap->addr_type == ADDR_TYPE_IP6 && intf->fd6 != -1) {
			struct in6_ifreq ifr6;

			/* XXX - sizeof(ifr) < sizeof(ifr6) */
			memcpy(&ifr6, ifr, sizeof(ifr6));
			
			if (ioctl(intf->fd6, SIOCGIFNETMASK6, &ifr6) == 0) {
				/* For some reason this is 0 after the ioctl. */
				ifr6.ifr_Addr.sin6_family = AF_INET6;
				addr_stob((struct sockaddr *)&ifr6.ifr_Addr,
				    &ap->addr_bits);
			}
			else perror("SIOCGIFNETMASK6");
		}
#endif
#endif
		ap++, entry->intf_alias_num++;
	}
#ifdef HAVE_LINUX_PROCFS
#define PROC_INET6_FILE	"/proc/net/if_inet6"
	{
		FILE *f;
		char buf[256], s[8][5], name[INTF_NAME_LEN];
		u_int idx, bits, scope, flags;
		
		if ((f = fopen(PROC_INET6_FILE, "r")) != NULL) {
			while (ap < lap &&
			       fgets(buf, sizeof(buf), f) != NULL) {
				sscanf(buf, "%04s%04s%04s%04s%04s%04s%04s%04s %x %02x %02x %02x %32s\n",
				    s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7],
				    &idx, &bits, &scope, &flags, name);
				if (strcmp(name, entry->intf_name) == 0) {
					snprintf(buf, sizeof(buf), "%s:%s:%s:%s:%s:%s:%s:%s/%d",
					    s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], bits);
					addr_aton(buf, ap);
					ap++, entry->intf_alias_num++;
				}
			}
			fclose(f);
		}
	}
#endif
	entry->intf_len = (u_char *)ap - (u_char *)entry;
	
	return (0);
}