Esempio n. 1
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);
}
Esempio n. 2
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);
    }
}
Esempio n. 3
0
/**
 * Plug an object interface into a new destination object interface
 *
 * @v intf		Object interface
 * @v dest		New destination object interface
 *
 * The reference to the existing destination interface is dropped, a
 * reference to the new destination interface is obtained, and the
 * interface is updated to point to the new destination interface.
 *
 * Note that there is no "unplug" call; instead you must plug the
 * interface into a null interface.
 */
void intf_plug ( struct interface *intf, struct interface *dest ) {
	DBGC ( INTF_COL ( intf ),
	       "INTF " INTF_INTF_FMT " replug to " INTF_FMT "\n",
	       INTF_INTF_DBG ( intf, intf->dest ), INTF_DBG ( dest ) );
	intf_get ( dest );
	intf_put ( intf->dest );
	intf->dest = dest;
}
Esempio n. 4
0
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);
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
/* 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;
}
Esempio n. 7
0
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);
}
Esempio n. 8
0
File: intf.c Progetto: tixxdz/nmap
/* Look up an interface from an index, such as a sockaddr_in6.sin6_scope_id. */
int
intf_get_index(intf_t *intf, struct intf_entry *entry, int af, unsigned int index)
{
	char namebuf[IFNAMSIZ];
	char *devname;

	/* af is ignored; only used in intf-win32.c. */
	devname = if_indextoname(index, namebuf);
	if (devname == NULL)
		return (-1);
	strlcpy(entry->intf_name, devname, sizeof(entry->intf_name));
	return intf_get(intf, entry);
}
Esempio n. 9
0
/**
 * Get object interface destination and operation method (without pass-through)
 *
 * @v intf		Object interface
 * @v type		Operation type
 * @ret dest		Destination interface
 * @ret func		Implementing method, or NULL
 */
void * intf_get_dest_op_no_passthru_untyped ( struct interface *intf,
					      void *type,
					      struct interface **dest ) {
	struct interface_descriptor *desc;
	struct interface_operation *op;
	unsigned int i;

	*dest = intf_get ( intf->dest );
	desc = (*dest)->desc;
	for ( i = desc->num_op, op = desc->op ; i ; i--, op++ ) {
		if ( op->type == type )
			return op->func;
	}

	return NULL;
}
Esempio n. 10
0
File: intf.c Progetto: OPSF/uClinux
int
intf_set(intf_t *intf, const struct intf_entry *entry)
{
    struct ifreq ifr;
    struct intf_entry *orig;
    struct addr bcast;
    u_char buf[BUFSIZ];

    orig = (struct intf_entry *)buf;
    orig->intf_len = sizeof(buf);
    strcpy(orig->intf_name, entry->intf_name);

    if (intf_get(intf, orig) < 0)
        return (-1);

    /* Delete any existing aliases. */
    if (_intf_delete_aliases(intf, orig) < 0)
        return (-1);

    /* Delete any existing addrs. */
    if (_intf_delete_addrs(intf, orig) < 0)
        return (-1);

    memset(&ifr, 0, sizeof(ifr));
    strlcpy(ifr.ifr_name, entry->intf_name, sizeof(ifr.ifr_name));

    /* Set interface MTU. */
    if (entry->intf_mtu != 0) {
        ifr.ifr_mtu = entry->intf_mtu;
#ifdef SIOCSIFMTU
        if (ioctl(intf->fd, SIOCSIFMTU, &ifr) < 0)
#endif
            return (-1);
    }
    /* Set interface address. */
    if (entry->intf_addr.addr_type == ADDR_TYPE_IP) {
#ifdef BSD
        /* XXX - why must this happen before SIOCSIFADDR? */
        if (addr_btos(entry->intf_addr.addr_bits,
                      &ifr.ifr_addr) == 0) {
            if (ioctl(intf->fd, SIOCSIFNETMASK, &ifr) < 0)
                return (-1);
        }
#endif
        if (addr_ntos(&entry->intf_addr, &ifr.ifr_addr) < 0)
            return (-1);
        if (ioctl(intf->fd, SIOCSIFADDR, &ifr) < 0 && errno != EEXIST)
            return (-1);

        if (addr_btos(entry->intf_addr.addr_bits, &ifr.ifr_addr) == 0
#ifdef __linux__
                && entry->intf_addr.addr_ip != 0
#endif
           ) {
            if (ioctl(intf->fd, SIOCSIFNETMASK, &ifr) < 0)
                return (-1);
        }
        if (addr_bcast(&entry->intf_addr, &bcast) == 0) {
            if (addr_ntos(&bcast, &ifr.ifr_broadaddr) == 0) {
                /* XXX - ignore error from non-broadcast ifs */
                ioctl(intf->fd, SIOCSIFBRDADDR, &ifr);
            }
        }
    }
    /* Set link-level address. */
    if (entry->intf_link_addr.addr_type == ADDR_TYPE_ETH &&
            addr_cmp(&entry->intf_link_addr, &orig->intf_link_addr) != 0) {
#if defined(SIOCSIFHWADDR)
        if (addr_ntos(&entry->intf_link_addr, &ifr.ifr_hwaddr) < 0)
            return (-1);
        if (ioctl(intf->fd, SIOCSIFHWADDR, &ifr) < 0)
            return (-1);
#elif defined (SIOCSIFLLADDR)
        memcpy(ifr.ifr_addr.sa_data, &entry->intf_link_addr.addr_eth,
               ETH_ADDR_LEN);
        ifr.ifr_addr.sa_len = ETH_ADDR_LEN;
        if (ioctl(intf->fd, SIOCSIFLLADDR, &ifr) < 0)
            return (-1);
#else
        eth_t *eth;

        if ((eth = eth_open(entry->intf_name)) == NULL)
            return (-1);
        if (eth_set(eth, &entry->intf_link_addr.addr_eth) < 0) {
            eth_close(eth);
            return (-1);
        }
        eth_close(eth);
#endif
    }
    /* Set point-to-point destination. */
    if (entry->intf_dst_addr.addr_type == ADDR_TYPE_IP) {
        if (addr_ntos(&entry->intf_dst_addr, &ifr.ifr_dstaddr) < 0)
            return (-1);
        if (ioctl(intf->fd, SIOCSIFDSTADDR, &ifr) < 0 &&
                errno != EEXIST)
            return (-1);
    }
    /* Add aliases. */
    if (_intf_add_aliases(intf, entry) < 0)
        return (-1);

    /* Set interface flags. */
    if (ioctl(intf->fd, SIOCGIFFLAGS, &ifr) < 0)
        return (-1);

    ifr.ifr_flags = intf_flags_to_iff(entry->intf_flags, ifr.ifr_flags);

    if (ioctl(intf->fd, SIOCSIFFLAGS, &ifr) < 0)
        return (-1);

    return (0);
}
Esempio n. 11
0
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);
}
Esempio n. 12
0
/* 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;
}