コード例 #1
0
void open_devices(void) {

    i = intf_open();

    if ( i == NULL ) {
      perror("intf open error");
      exit(-1);
    }
    strncpy(ie.intf_name, iface, 60);
    if ( intf_get(i, &ie) == -1 ) {
      perror("intf get error");
      exit(-1);
    }

    mha = ie.intf_link_addr;
    if ( addr_ntop(&mha, mhw, 32) == NULL ){
      exit(-1);
    }
    mad = ie.intf_addr;
    if ( addr_ntop(&mad, mip, 32) == NULL ){
      exit(-1);
    }
    rmslash(mip);
  
    e = eth_open(iface);
    if ( e == NULL ) {
      perror("eth open error");
      exit(-1);
    }
    p = pcap_open_live(iface, 20000, 1, 500, ebuf);
    if ( p == NULL ) {
      perror(ebuf);
      exit(-1);
    }
}
コード例 #2
0
ファイル: arpd.c プロジェクト: MagicalTux/farpd
static void
arpd_init(char *dev, int naddresses, char **addresses)
{
	struct bpf_program fcode;
	char filter[1024], ebuf[PCAP_ERRBUF_SIZE], *dst;
	intf_t *intf;
	
	dst = arpd_expandips(naddresses, addresses);

	if ((arpd_arp = arp_open()) == NULL)
		err(1, "arp_open");

	if ((intf = intf_open()) == NULL)
		err(1, "intf_open");

	if (dev == NULL) {
		if ((dev = pcap_lookupdev(ebuf)) == NULL)
			errx(1, "pcap_lookupdev: %s", ebuf);
	}
	arpd_ifent.intf_len = sizeof(arpd_ifent);
	strncpy(arpd_ifent.intf_name, dev, sizeof(arpd_ifent.intf_name) - 1);
	arpd_ifent.intf_name[sizeof(arpd_ifent.intf_name) - 1] = '\0';
	
	if (intf_get(intf, &arpd_ifent) < 0)
		err(1, "intf_get");

	if (arpd_ifent.intf_addr.addr_type != ADDR_TYPE_IP ||
	    arpd_ifent.intf_link_addr.addr_type != ADDR_TYPE_ETH)
		errx(1, "bad interface configuration: not IP or Ethernet");
	arpd_ifent.intf_addr.addr_bits = IP_ADDR_BITS;
	
	snprintf(filter, sizeof(filter), "arp %s%s%s and not ether src %s",
	    dst ? "and (" : "", dst ? dst : "", dst ? ")" : "",
	    addr_ntoa(&arpd_ifent.intf_link_addr));
	
	if ((arpd_pcap = pcap_open_live(dev, 128, 0, 500, ebuf)) == NULL)
		errx(1, "pcap_open_live: %s", ebuf);
	
	if (pcap_compile(arpd_pcap, &fcode, filter, 1, 0) < 0 ||
	    pcap_setfilter(arpd_pcap, &fcode) < 0)
		errx(1, "bad pcap filter: %s", pcap_geterr(arpd_pcap));
#if defined(BSD) && defined(BIOCIMMEDIATE)
	{
		int on = 1;
		if (ioctl(pcap_fileno(arpd_pcap), BIOCIMMEDIATE, &on) < 0)
			err(1, "BIOCIMMEDIATE");
	}
#endif
	if ((arpd_eth = eth_open(dev)) == NULL)
		errx(1, "eth_open");

#ifndef LOG_PERROR
#define LOG_PERROR	0
#endif
	openlog("arpd", LOG_PERROR|LOG_PID|LOG_CONS, LOG_DAEMON);
	syslog(LOG_INFO, "listening on %s: %s", dev, filter);
}
コード例 #3
0
ファイル: eth-win32.c プロジェクト: jwilkins/nmap
eth_t *
eth_open(const char *device)
{
	eth_t *eth;
	intf_t *intf;
	struct intf_entry ifent;
	eth_addr_t ea;
	char *p, *buf;
	ULONG len;

	/* Get interface entry. */
	memset(&ifent, 0, sizeof(ifent));
	if ((intf = intf_open()) != NULL) {
		strlcpy(ifent.intf_name, device, sizeof(ifent.intf_name));
		intf_get(intf, &ifent);
		intf_close(intf);
	}
	if (ifent.intf_link_addr.addr_type != ADDR_TYPE_ETH)
		return (NULL);

	/* Get Packet driver adapter name/desc lists. */
	buf = NULL;
	PacketGetAdapterNames(buf, &len);
	if (len > 0 && (buf = malloc(len)) != NULL) {
		if (!PacketGetAdapterNames(buf, &len)) {
			free(buf);
			buf = NULL;
		}
	}
	if (buf == NULL)
		return (NULL);
	
	/* XXX - find adapter with matching interface MAC address. */
	if ((eth = calloc(1, sizeof(*eth))) == NULL) {
		free(buf);
		return (NULL);
	}
	for (p = buf; *p != '\0'; p += strlen(p) + 1) {
		if ((eth->lpa = PacketOpenAdapter(p)) != NULL) {
			if (eth->lpa->hFile != INVALID_HANDLE_VALUE &&
			    eth_get(eth, &ea) == 0 &&
			    memcmp(&ea, &ifent.intf_link_addr.addr_eth,
				ETH_ADDR_LEN) == 0) {
				PacketSetBuff(eth->lpa, 512000);
				eth->pkt = PacketAllocatePacket();
				break;
			}
			PacketCloseAdapter(eth->lpa);
		}
	}
	free(buf);
	if (eth->pkt == NULL)
		eth = eth_close(eth);
	
	return (eth);
}
コード例 #4
0
ファイル: eth-win32.c プロジェクト: jwilkins/nmap
/* Converts a dnet interface name (ifname) to its pcap equivalent, which is stored in
pcapdev (up to a length of pcapdevlen).  Returns 0 and fills in pcapdev if successful. */
int eth_get_pcap_devname(const char *ifname, char *pcapdev, int pcapdevlen) {
	intf_t *intf;
	struct intf_entry ie;
	pcap_if_t *pcapdevs;
	pcap_if_t *pdev;
	char pname[128];

	if ((intf = intf_open()) == NULL)
		return -1;
	
	pname[0] = '\0';
	memset(&ie, 0, sizeof(ie));
	strlcpy(ie.intf_name, ifname, sizeof(ie.intf_name));
	if (intf_get(intf, &ie) != 0) {
		intf_close(intf);
		return -1;
	}
	intf_close(intf);
	
	/* Next we must find the pcap device name corresponding to the device.
	   The device description used to be compared with those from PacketGetAdapterNames(), but
	   that was unrelaible because dnet and pcap sometimes give different descriptions.  For example, 
	   dnet gave me "AMD PCNET Family PCI Ethernet Adapter - Packet Scheduler Miniport" for one of my 
	   adapters (in vmware), while pcap described it as "VMware Accelerated AMD PCNet Adapter (Microsoft's
	   Packet Scheduler)". Then IP addresses used to be compared, but that proved to be unreliable
           as well.  Now we compare hardware addresses much like eth_open() does */
	if (pcap_findalldevs(&pcapdevs, NULL) == -1)
		return -1;

	if (pname[0] == '\0' && ie.intf_link_addr.addr_type == ADDR_TYPE_ETH) {
		for(pdev=pcapdevs; pdev && !pname[0]; pdev = pdev->next) {
			eth_t eth;
			eth_addr_t ea;

			eth.lpa = PacketOpenAdapter(pdev->name);
			if (eth.lpa == NULL)
				continue;
			if (eth.lpa->hFile != INVALID_HANDLE_VALUE &&
			    eth_get(&eth, &ea) == 0 &&
			    memcmp(&ea, &ie.intf_link_addr.addr_eth,
			        ETH_ADDR_LEN) == 0) {
				/* Found it -- Yay! */
				strlcpy(pname, pdev->name, sizeof(pname));
			}
			PacketCloseAdapter(eth.lpa);
		}
	}

	pcap_freealldevs(pcapdevs);
	if (pname[0]) {
		strlcpy(pcapdev, pname, pcapdevlen);
		return 0;
	}
	return -1;
}
コード例 #5
0
ファイル: 7520.c プロジェクト: 0x24bin/exploit-database
int
main(int argc, char **argv)
{
    ip_t *sock;
    intf_t *intf;
    struct addr dst;
    struct ip_hdr *ip;
    struct udp_hdr *udp;
    struct intf_entry entry;
    int len = IP_HDR_LEN + UDP_HDR_LEN;
    char buf[len];
 
    if (argc < 2 || addr_aton(argv[1], &dst)) {  
        printf("error: please specify a target ip address\n");
        return 1;
    }
 
    memset(buf, 0, sizeof(buf));
 
    ip = (struct ip_hdr *) buf;
    ip->ip_v = 4;
    ip->ip_hl = 5;
    ip->ip_tos = 0;
    ip->ip_off = 0;
    ip->ip_sum = 0;
    ip->ip_ttl = IP_TTL_MAX;
    ip->ip_p = IP_PROTO_UDP;
    ip->ip_id = htons(0xdead);
    ip->ip_len = htons(len);
 
    udp = (struct udp_hdr *) (buf + IP_HDR_LEN);
    
    udp->uh_sum = 0;
    udp->uh_sport = htons(0);
    udp->uh_dport = htons(5353);
    udp->uh_ulen = htons(UDP_HDR_LEN);
 
    intf = intf_open();
    intf_get_dst(intf, &entry, &dst);
    intf_close(intf);
 
    ip->ip_src = entry.intf_addr.addr_ip;
    ip->ip_dst = dst.addr_ip;
    ip_checksum(buf, len);
 
    sock = ip_open();
    if (!sock) {
        printf("error: root privileges needed for raw socket\n");
        return 1;
    }
    ip_send(sock, buf, len);
    ip_close(sock);
 
    return 0;
}
コード例 #6
0
ファイル: tun-bsd.c プロジェクト: 0x00evil/nmap
tun_t *
tun_open(struct addr *src, struct addr *dst, int mtu)
{
	struct intf_entry ifent;
	tun_t *tun;
	char dev[128];
	int i;

	if (src->addr_type != ADDR_TYPE_IP || dst->addr_type != ADDR_TYPE_IP ||
	    src->addr_bits != IP_ADDR_BITS || dst->addr_bits != IP_ADDR_BITS) {
		errno = EINVAL;
		return (NULL);
	}
	if ((tun = calloc(1, sizeof(*tun))) == NULL)
		return (NULL);

	if ((tun->intf = intf_open()) == NULL)
		return (tun_close(tun));

	memset(&ifent, 0, sizeof(ifent));
	ifent.intf_len = sizeof(ifent);
	
	for (i = 0; i < MAX_DEVS; i++) {
		snprintf(dev, sizeof(dev), "/dev/tun%d", i);
		strlcpy(ifent.intf_name, dev + 5, sizeof(ifent.intf_name));
		tun->save = ifent;
		
		if ((tun->fd = open(dev, O_RDWR, 0)) != -1 &&
		    intf_get(tun->intf, &tun->save) == 0) {
			route_t *r;
			struct route_entry entry;
			
			ifent.intf_flags = INTF_FLAG_UP|INTF_FLAG_POINTOPOINT;
			ifent.intf_addr = *src;
			ifent.intf_dst_addr = *dst;	
			ifent.intf_mtu = mtu;
			
			if (intf_set(tun->intf, &ifent) < 0)
				tun = tun_close(tun);

			/* XXX - try to ensure our route got set */
			if ((r = route_open()) != NULL) {
				entry.route_dst = *dst;
				entry.route_gw = *src;
				route_add(r, &entry);
				route_close(r);
			}
			break;
		}
	}
	if (i == MAX_DEVS)
		tun = tun_close(tun);
	return (tun);
}
コード例 #7
0
END_TEST

START_TEST(test_intf_get)
{
	struct intf_entry ifent;
	intf_t *i;

	i = intf_open();
	memset(&ifent, 0, sizeof(ifent));
	fail_unless(intf_get(i, &ifent) < 0, "didn't fail on empty request");
	ifent.intf_len = sizeof(ifent);
	fail_unless(intf_get(i, &ifent) < 0, "didn't fail on empty name");
	intf_close(i);
}
コード例 #8
0
/* Converts a libdnet interface name to its pcap equivalent. The pcap name is
   stored in pcapdev up to a length of pcapdevlen, including the terminating
   '\0'. Returns -1 on error. */
int
intf_get_pcap_devname(const char *intf_name, char *pcapdev, int pcapdevlen)
{
	IP_ADAPTER_ADDRESSES *a;
	pcap_if_t *pcapdevs;
	pcap_if_t *pdev, *selected;
	intf_t *intf;

	if ((intf = intf_open()) == NULL)
		return (-1);
	if (_refresh_tables(intf) < 0) {
		intf_close(intf);
		return (-1);
	}
	a = _find_adapter_address(intf, intf_name);

	if (a == NULL) {
		intf_close(intf);
		return (-1);
	}

	if (pcap_findalldevs(&pcapdevs, NULL) == -1) {
		intf_close(intf);
		return (-1);
	}

	/* Loop through all the pcap devices until we find a match. */
	selected = NULL;
	for (pdev = pcapdevs; pdev != NULL; pdev = pdev->next) {
		char *name;

		if (pdev->name == NULL)
			continue;
		name = strchr(pdev->name, '{');
		if (name == NULL)
			continue;
		if (strcmp(name, a->AdapterName) == 0)
			break;
	}
	if (pdev != NULL)
		strlcpy(pcapdev, pdev->name, pcapdevlen);
	intf_close(intf);
	pcap_freealldevs(pcapdevs);
	if (pdev == NULL)
		return -1;
	else
		return 0;
}
コード例 #9
0
ファイル: Networkmodule.c プロジェクト: Sudoka/base
static PyObject *
interfaces(PyObject *self, PyObject *args)
{
	intf_t *intf;
	PyObject *dict;
	struct intf_entry *entry = NULL;

	dict = PyDict_New();
	if (!dict) return NULL;

	intf = intf_open();
	intf_loop( intf, interfaces_callback, (void*) dict );
	intf_close(intf);

	if (!dict) myerror("Could not read any net interfaces");

	return dict;
}
コード例 #10
0
ファイル: arp-ioctl.c プロジェクト: MCKapur/mesh-networking
arp_t *
arp_open(void)
{
	arp_t *a;
	
	if ((a = calloc(1, sizeof(*a))) != NULL) {
#ifdef HAVE_STREAMS_MIB2
		if ((a->fd = open(IP_DEV_NAME, O_RDWR)) < 0)
#elif defined(HAVE_STREAMS_ROUTE)
		if ((a->fd = open("/dev/route", O_WRONLY, 0)) < 0)
#else
		if ((a->fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
#endif
			return (arp_close(a));
#ifdef HAVE_ARPREQ_ARP_DEV
		if ((a->intf = intf_open()) == NULL)
			return (arp_close(a));
#endif
	}
	return (a);
}
コード例 #11
0
ファイル: intf.c プロジェクト: LindyLo/CrossCompileLibrary
int
intf_main(int argc, char *argv[])
{
	struct intf_entry *entry;
	struct addr *ap, addr;
	char *cmd, buf[1024];
	
	if (argc < 2)
		usage();

	cmd = argv[1];
	
	entry = (struct intf_entry *)buf;
	memset(entry, 0, sizeof(*entry));
	entry->intf_len = sizeof(buf);

	if ((intf = intf_open()) == NULL)
		err(1, "intf_open");

	if (strcmp(cmd, "show") == 0) {
		if (intf_loop(intf, print_intf, NULL) < 0)
			err(1, "intf_loop");
	} else if (strcmp(cmd, "get") == 0) {
		if (argc < 3)
			usage();
		strlcpy(entry->intf_name, argv[2], sizeof(entry->intf_name));
		if (intf_get(intf, entry) < 0)
			err(1, "intf_get");
		print_intf(entry, NULL);
	} else if (strcmp(cmd, "src") == 0) {
		if (argc < 3 || addr_aton(argv[2], &addr) < 0)
			usage();
		if (intf_get_src(intf, entry, &addr) < 0)
			err(1, "intf_get_src");
		print_intf(entry, NULL);
	} else if (strcmp(cmd, "dst") == 0) {
		if (argc < 3 || addr_aton(argv[2], &addr) < 0)
			usage();
		if (intf_get_dst(intf, entry, &addr) < 0)
			err(1, "intf_get_dst");
		print_intf(entry, NULL);
	} else if (strcmp(cmd, "set") == 0) {
		if (argc < 4)
			usage();
		
		strlcpy(entry->intf_name, argv[2], sizeof(entry->intf_name));

		for (argv += 3, argc -= 3; argc > 1; argv += 2, argc -= 2) {
			if (strcmp(argv[0], "alias") == 0) {
				ap = &entry->intf_alias_addrs
				    [entry->intf_alias_num++];
			} else if (strcmp(argv[0], "dst") == 0) {
				ap = &entry->intf_dst_addr;
			} else if (strcmp(argv[0], "inet") == 0) {
				ap = &entry->intf_addr;
			} else if (strcmp(argv[0], "link") == 0) {
				ap = &entry->intf_link_addr;
			} else
				break;
			
			if (addr_pton(argv[1], ap) < 0)
				err(1, "invalid address: %s", argv[1]);
		}
		for ( ; argc > 0; argv++, argc--) {
			if (strcmp(argv[0], "up") == 0)
				entry->intf_flags |= INTF_FLAG_UP;
			else if (strcmp(argv[0], "down") == 0)
				entry->intf_flags &= ~INTF_FLAG_UP;
			else if (strcmp(argv[0], "arp") == 0)
				entry->intf_flags &= ~INTF_FLAG_NOARP;
			else if (strcmp(argv[0], "noarp") == 0)
				entry->intf_flags |= INTF_FLAG_NOARP;
			else
				usage();
		}
		if (intf_set(intf, entry) < 0)
			err(1, "intf_set");
	} else
		usage();
	
	intf_close(intf);

	exit(0);
}
コード例 #12
0
ファイル: fragtest.c プロジェクト: stsi/fragroute-ipv6
int
main(int argc, char *argv[])
{
	struct intf_entry ifent;
	intf_t *intf;
	int i, tests;
	char *cmd;
	
	if (argc < 3)
		usage();

	for (tests = 0, i = 1; i < argc - 1; i++) {
		cmd = argv[i];
		
		if (strcmp(cmd, "all") == 0)
			tests = ~0;
		else if (strcmp(cmd, "ping") == 0)
			tests |= TEST_PING;
		else if (strcmp(cmd, "ip-opt") == 0)
			tests |= TEST_IP_OPT;
		else if (strcmp(cmd, "ip-tracert") == 0)
			tests |= TEST_IP_TRACERT;
		else if (strcmp(cmd, "frag") == 0)
			tests |= TEST_FRAG;
		else if (strcmp(cmd, "frag-new") == 0)
			tests |= TEST_FRAG_NEW;
		else if (strcmp(cmd, "frag-old") == 0)
			tests |= TEST_FRAG_OLD;
		else if (strcmp(cmd, "frag-timeout") == 0)
			tests |= TEST_FRAG_TIMEOUT;
		else
			usage();
	}
	if (addr_aton(argv[i], &ctx.dst) < 0)
		err(1, "invalid host %s", argv[i]);

	if ((intf = intf_open()) == NULL)
		err(1, "couldn't open interface handle");

	ifent.intf_len = sizeof(ifent);
	
	if (intf_get_dst(intf, &ifent, &ctx.dst) < 0)
		err(1, "couldn't find interface for %s", addr_ntoa(&ctx.dst));
	
	memcpy(&ctx.src, &ifent.intf_addr, sizeof(ctx.src));
	ctx.src.addr_bits = IP_ADDR_BITS;
	
	intf_close(intf);
	
	if ((ctx.ip = ip_open()) == NULL)
		err(1, "couldn't open raw IP interface");

	if ((ctx.pcap = pcap_open(ifent.intf_name)) == NULL)
		err(1, "couldn't open %s for sniffing", ifent.intf_name);
	
	if ((ctx.dloff = pcap_dloff(ctx.pcap)) < 0)
		err(1, "couldn't determine link layer offset");
	
	ctx.rnd = rand_open();
	pkt_init(16);
	TAILQ_INIT(&ctx.pktq);

	ping = pkt_new();
	ip_pack_hdr(ping->pkt_ip, 0, IP_HDR_LEN + 8 + 24, 666, 0,
	    IP_TTL_DEFAULT, IP_PROTO_ICMP, ctx.src.addr_ip, ctx.dst.addr_ip);
	icmp_pack_hdr_echo(ping->pkt_icmp, ICMP_ECHO, ICMP_CODE_NONE,
	    666, 1, "AAAAAAAABBBBBBBBCCCCCCCC", 24);
	ping->pkt_end = ping->pkt_eth_data + IP_HDR_LEN + 8 + 24;
	pkt_decorate(ping);
	
	if ((tests & TEST_PING) != 0)
		test_ping();
	if ((tests & TEST_IP_OPT) != 0)
		test_ip_opt();
	if ((tests & TEST_IP_TRACERT) != 0)
		test_ip_tracert();
	if ((tests & TEST_FRAG) != 0)
		test_frag(NULL, 0);
	if ((tests & TEST_FRAG_NEW) != 0)
		test_frag("new", 0);
	if ((tests & TEST_FRAG_OLD) != 0)
		test_frag("old", 0);
	if ((tests & TEST_FRAG_TIMEOUT) != 0)
		test_frag(NULL, 1);

	rand_close(ctx.rnd);
	pcap_close(ctx.pcap);
	ip_close(ctx.ip);
	
	exit(0);
}
コード例 #13
0
ファイル: fragroute.c プロジェクト: ajkeeton/fragroute
static void
fragroute_init(const char *dst, const char *outfile)
{
    struct arp_entry arpent;
    struct intf_entry ifent;
    struct route_entry rtent;
#ifdef WIN32
    WSADATA wsdata;
    
    if (WSAStartup(MAKEWORD(2, 2), &wsdata) != 0)
        err(1, "couldn't initialize Winsock");

    SetConsoleCtrlHandler(fragroute_signal, TRUE);
#else
    signal(SIGINT, fragroute_signal);
    signal(SIGTERM, fragroute_signal);
#endif
    if (addr_aton(dst, &ctx.dst) < 0)
        err(1, "destination address invalid");
    
    if (ctx.dst.addr_bits != IP_ADDR_BITS)
        errx(1, "only /32 destinations supported at this time");
    
    pkt_init(128);
    
    event_init();
    // event_sigcb = fragroute_close;
    
    if ((ctx.arp = arp_open()) == NULL ||
        (ctx.intf = intf_open()) == NULL ||
        (ctx.route = route_open()) == NULL)
        err(1, "couldn't open kernel networking interfaces");
    
    /* Find outgoing interface, addresses, and MTU. */
    ifent.intf_len = sizeof(ifent);
    if (intf_get_dst(ctx.intf, &ifent, &ctx.dst) < 0)
        err(1, "couldn't determine outgoing interface");
    
    memcpy(&ctx.src, &ifent.intf_addr, sizeof(ctx.src));
    ctx.src.addr_bits = IP_ADDR_BITS;
    memcpy(&ctx.smac, &ifent.intf_link_addr, sizeof(ctx.smac));
    ctx.mtu = ifent.intf_mtu;
    
    /* Open outgoing interface for sending. */
    if ((ctx.eth = eth_open(ifent.intf_name)) == NULL)
        err(1, "couldn't open %s for sending", ifent.intf_name);
    
    /* Find destination MAC address. */
    memcpy(&arpent.arp_pa, &ctx.dst, sizeof(arpent.arp_pa));
    
    if (arp_get(ctx.arp, &arpent) < 0) {
        memcpy(&rtent.route_dst, &ctx.dst, sizeof(rtent.route_dst));
        
        if (route_get(ctx.route, &rtent) < 0)
            err(1, "no route to %s", addr_ntoa(&rtent.route_dst));
        
        memcpy(&arpent.arp_pa, &rtent.route_gw, sizeof(arpent.arp_pa));
        
        if (arp_get(ctx.arp, &arpent) < 0)
            err(1, "no ARP entry for %s",
                addr_ntoa(&arpent.arp_pa));
    }
    memcpy(&ctx.dmac, &arpent.arp_ha, sizeof(ctx.dmac));
    
    /* Setup our tunnel. */
    if ((ctx.tun = tun_open(&ctx.src, &ctx.dst, ctx.mtu)) == NULL)
        err(1, "couldn't initialize tunnel interface");

    ctx.dfile = NULL;

    if (outfile && ((ctx.dfile = pcap_dump_open(ctx.tun->pcap, outfile)) == NULL)) 
        err(1, "couldn't open pcap dump file");
    
    tun_register(ctx.tun, fragroute_process, &ctx);
}
コード例 #14
0
ファイル: intf-win32.c プロジェクト: OPSF/uClinux
/* Converts a dnet interface name (ifname) to its pcap equivalent, which is stored in
pcapdev (up to a length of pcapdevlen).  Returns 0 and fills in pcapdev if successful. */
int intf_get_pcap_devname(const char *ifname, char *pcapdev, int pcapdevlen) {
	int i;
	intf_t *intf;
	struct intf_entry ie;
	pcap_if_t *pcapdevs;
	pcap_if_t *pdev;
	char pname[128];
	struct sockaddr_in devip;
	pcap_addr_t *pa;

	if ((intf = intf_open()) == NULL)
		return -1;
	
	pname[0] = '\0';
	memset(&ie, 0, sizeof(ie));
	strlcpy(ie.intf_name, ifname, sizeof(ie.intf_name));
	if (intf_get(intf, &ie) != 0) {
		intf_close(intf);
		return -1;
	}
	intf_close(intf);
	
	/* Find the first IPv4 address for ie */
	if (ie.intf_addr.addr_type == ADDR_TYPE_IP) {
		addr_ntos(&ie.intf_addr, (struct sockaddr *) &devip);
	} else {
		for(i=0; i < (int) ie.intf_alias_num; i++) {
			if (ie.intf_alias_addrs[i].addr_type == ADDR_TYPE_IP) {
				addr_ntos(&ie.intf_alias_addrs[i], (struct sockaddr *) &devip);
				break;
			}
		}
		if (i == ie.intf_alias_num)
			return -1; // Failed to find IPv4 address, which is currently a requirement
	}

	/* Next we must find the pcap device name corresponding to the device.
	   The device description used to be compared with those from PacketGetAdapterNames(), but
	   that was unrelaible because dnet and pcap sometimes give different descriptions.  For example, 
	   dnet gave me "AMD PCNET Family PCI Ethernet Adapter - Packet Scheduler Miniport" for one of my 
	   adapters (in vmware), while pcap described it as "VMware Accelerated AMD PCNet Adapter (Microsoft's
	   Packet Scheduler)". Plus,  Packet* functions aren't really supported for external use by the 
	   WinPcap folks.  So I have rewritten this to compare interface addresses (which has its own 
	   problems -- what if you want to listen an an interface with no IP address set?) --Fyodor */
	if (pcap_findalldevs(&pcapdevs, NULL) == -1)
		return -1;

	for(pdev=pcapdevs; pdev && !pname[0]; pdev = pdev->next) {
		for (pa=pdev->addresses; pa && !pname[0]; pa = pa->next) {
			if (pa->addr->sa_family != AF_INET)
				continue;
			if (((struct sockaddr_in *)pa->addr)->sin_addr.s_addr == devip.sin_addr.s_addr) {
				strlcpy(pname, pdev->name, sizeof(pname)); /* Found it -- Yay! */
			break;
	}
		}
	}

	pcap_freealldevs(pcapdevs);
	if (pname[0]) {
		strlcpy(pcapdev, pname, pcapdevlen);
		return 0;
	}
	return -1;
}