コード例 #1
0
ファイル: env.c プロジェクト: lacombar/netbsd-alc
int
getifflags(prop_dictionary_t env, prop_dictionary_t oenv,
    unsigned short *flagsp)
{
	struct ifreq ifr;
	const char *ifname;
	uint64_t ifflags;
	int s;

	if (prop_dictionary_get_uint64(env, "ifflags", &ifflags)) {
		*flagsp = (unsigned short)ifflags;
		return 0;
	}

	if ((s = getsock(AF_UNSPEC)) == -1)
		return -1;

	if ((ifname = getifname(env)) == NULL)
		return -1;

	memset(&ifr, 0, sizeof(ifr));
	estrlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
	if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1)
		return -1;

	*flagsp = (unsigned short)ifr.ifr_flags;

	prop_dictionary_set_uint64(oenv, "ifflags",
	    (unsigned short)ifr.ifr_flags);

	return 0;
}
コード例 #2
0
ファイル: env.c プロジェクト: lacombar/netbsd-alc
const char *
getifinfo(prop_dictionary_t env, prop_dictionary_t oenv, unsigned short *flagsp)
{
	if (getifflags(env, oenv, flagsp) == -1)
		return NULL;

	return getifname(env);
}
コード例 #3
0
void
print_link_addresses(prop_dictionary_t env, bool print_active_only)
{
	char hbuf[NI_MAXHOST];
	const char *ifname;
	int s;
	struct ifaddrs *ifa, *ifap;
	const struct sockaddr_dl *sdl;
	struct if_laddrreq iflr;

	if ((ifname = getifname(env)) == NULL)
		err(EXIT_FAILURE, "%s: getifname", __func__);

	if ((s = getsock(AF_LINK)) == -1)
		err(EXIT_FAILURE, "%s: getsock", __func__);

	if (getifaddrs(&ifap) == -1)
		err(EXIT_FAILURE, "%s: getifaddrs", __func__);

	memset(&iflr, 0, sizeof(iflr));

	strlcpy(iflr.iflr_name, ifname, sizeof(iflr.iflr_name));

	for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
		if (strcmp(ifname, ifa->ifa_name) != 0)
			continue;
		if (ifa->ifa_addr->sa_family != AF_LINK)
			continue;

		sdl = satocsdl(ifa->ifa_addr);

		memcpy(&iflr.addr, ifa->ifa_addr, MIN(ifa->ifa_addr->sa_len,
		    sizeof(iflr.addr)));
		iflr.flags = IFLR_PREFIX;
		iflr.prefixlen = sdl->sdl_alen * NBBY;

		if (prog_ioctl(s, SIOCGLIFADDR, &iflr) == -1)
			err(EXIT_FAILURE, "%s: ioctl", __func__);

		if (((iflr.flags & IFLR_ACTIVE) != 0) != print_active_only)
			continue;

		if (getnameinfo(ifa->ifa_addr, ifa->ifa_addr->sa_len,
			hbuf, sizeof(hbuf), NULL, 0,
			Nflag ? 0 : NI_NUMERICHOST) == 0 &&
		    hbuf[0] != '\0') {
			printf("\t%s %s\n",
			    print_active_only ? "address:" : "link", hbuf);
		}
	}
	freeifaddrs(ifap);
}
コード例 #4
0
int
direct_ioctl(prop_dictionary_t env, unsigned long cmd, void *data)
{
	const char *ifname;
	int s;

	if ((s = getsock(AF_UNSPEC)) == -1)
		err(EXIT_FAILURE, "getsock");

	if ((ifname = getifname(env)) == NULL)
		err(EXIT_FAILURE, "getifname");

	estrlcpy(data, ifname, IFNAMSIZ);

	return prog_ioctl(s, cmd, data);
}
コード例 #5
0
ファイル: addr.c プロジェクト: troglobit/mcjoin
/* Find IPv4 address of default outbound LAN interface */
int getaddr(char *iface, struct in_addr *ina)
{
	struct ifaddrs *ifaddr, *ifa;
	char ifname[17] = { 0 };
	char buf[20] = { 0 };
	int rc = -1;

	if (!iface)
		iface = getifname(ifname, sizeof(ifname));

	rc = getifaddrs(&ifaddr);
	if (rc)
		return -1;

	for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
		if (!ifa->ifa_addr)
			continue;

		if (ifa->ifa_flags & IFF_LOOPBACK)
			continue;

		if (!(ifa->ifa_flags & IFF_MULTICAST))
			continue;

		if (ifa->ifa_addr->sa_family != AF_INET)
			continue;

		if (iface && strcmp(iface, ifa->ifa_name))
			continue;

		rc = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in),
				 buf, sizeof(buf), NULL, 0, NI_NUMERICHOST);
		if (!rc) {
			if (!inet_aton(buf, ina))
				continue;
			if (!valid_addr(ina))
				continue;
			break;
		}
	}
	freeifaddrs(ifaddr);

	if (rc || IN_ZERONET(ntohl(ina->s_addr)))
		return -1;

	return 0;
}
コード例 #6
0
signed openchannel (struct channel * channel)

{

#if defined (__linux__)

	struct ifreq ifreq;
	struct sockaddr_ll sockaddr_ll =
	{
		PF_PACKET,
		0x0000,
		0x0000,
		ARPHRD_ETHER,
		PACKET_HOST,
		ETHER_ADDR_LEN,
		{
			0x00,
			0x00,
			0x00,
			0x00,
			0x00,
			0x00,
			0x00,
			0x00
		}
	};

/*
 *      raw packets require root privileges on linux; one does not have to be
 *      root when this program is installed setuid using 'chown root:root' and
 *      'chmod 4555';
 */

	if (geteuid ())
	{
		error (1, EPERM, ERROR_NOTROOT);
	}

	memset (&ifreq, 0, sizeof (ifreq));
	sockaddr_ll.sll_protocol = htons (channel->type);
	if ((channel->fd = socket (sockaddr_ll.sll_family, SOCK_RAW, sockaddr_ll.sll_protocol)) == -1)
	{
		error (1, errno, "%s", channel->ifname);
	}
	memcpy (ifreq.ifr_name, channel->ifname, sizeof (ifreq.ifr_name));
	if (ioctl (channel->fd, SIOCGIFINDEX, &ifreq) == -1)
	{
		error (1, errno, "%s", ifreq.ifr_name);
	}
	channel->ifindex = sockaddr_ll.sll_ifindex = ifreq.ifr_ifindex;
	if (ioctl (channel->fd, SIOCGIFHWADDR, &ifreq) == -1)
	{
		error (1, errno, "%s", ifreq.ifr_name);
	}
	memcpy (sockaddr_ll.sll_addr, ifreq.ifr_ifru.ifru_hwaddr.sa_data, sizeof (sockaddr_ll.sll_addr));
	if (bind (channel->fd, (struct sockaddr *) (&sockaddr_ll), sizeof (sockaddr_ll)) == -1)
	{
		error (1, errno, "%s", ifreq.ifr_name);
	}
	memcpy (channel->host, sockaddr_ll.sll_addr, sizeof (channel->host));
	if (ioctl (channel->fd, SIOCGIFFLAGS, &ifreq) == -1)
	{
		error (1, errno, "%s", ifreq.ifr_name);
	}
	channel->ifstate = ifreq.ifr_flags;
	_setbits (ifreq.ifr_flags, (IFF_UP | IFF_BROADCAST | IFF_MULTICAST));
	_clrbits (ifreq.ifr_flags, (IFF_ALLMULTI | IFF_PROMISC));
	if (ioctl (channel->fd, SIOCSIFFLAGS, &ifreq) == -1)
	{
		error (1, errno, "%s", ifreq.ifr_name);
	}

#else

	struct bpf_program bpf_program;
	static struct bpf_insn bpf_insn [] =
	{
		{
			BPF_LD + BPF_H + BPF_ABS,
			0,
			0,
			12
		},
		{
			BPF_JMP + BPF_JEQ + BPF_K,
			0,
			18,
			0
		},
		{
			BPF_LD + BPF_B + BPF_ABS,
			0,
			0,
			0
		},
		{
			BPF_JMP + BPF_JEQ + BPF_K,
			0,
			10,
			0
		},
		{
			BPF_LD + BPF_B + BPF_ABS,
			0,
			0,
			1
		},
		{
			BPF_JMP + BPF_JEQ + BPF_K,
			0,
			8,
			0
		},
		{
			BPF_LD + BPF_B + BPF_ABS,
			0,
			0,
			2
		},
		{
			BPF_JMP + BPF_JEQ + BPF_K,
			0,
			6,
			0
		},
		{
			BPF_LD + BPF_B + BPF_ABS,
			0,
			0,
			3
		},
		{
			BPF_JMP + BPF_JEQ + BPF_K,
			0,
			4,
			0
		},
		{
			BPF_LD + BPF_B + BPF_ABS,
			0,
			0,
			4
		},
		{
			BPF_JMP + BPF_JEQ + BPF_K,
			0,
			2,
			0
		},
		{
			BPF_LD + BPF_B + BPF_ABS,
			0,
			0,
			5
		},
		{
			BPF_JMP + BPF_JEQ + BPF_K,
			4,
			0,
			0
		},
		{
			BPF_LD + BPF_W + BPF_ABS,
			0,
			0,
			0
		},
		{
			BPF_JMP + BPF_JEQ + BPF_K,
			0,
			4,
			0xFFFFFFFF
		},
		{
			BPF_LD + BPF_H + BPF_ABS,
			0,
			0,
			4
		},
		{
			BPF_JMP + BPF_JEQ + BPF_K,
			0,
			2,
			0xFFFF
		},
		{
			BPF_LD + BPF_W + BPF_LEN,
			0,
			0,
			0
		},
		{
			BPF_RET + BPF_A,
			0,
			0,
			0
		},
		{
			BPF_RET + BPF_K,
			0,
			0,
			0
		}
	};

#if defined (__APPLE__) || defined (__OpenBSD__) || defined (__NetBSD__)

	struct ifreq ifreq;
	struct timeval timeval;
	struct bpf * bpf;
	char filename [sizeof (CHANNEL_BPFDEVICE) + 1];
	unsigned count;
	unsigned state;
	int stat_errno = 0;
	int open_errno = 0;
	for (count = 0; count < 100; count++)
	{
		struct stat st;
		snprintf (filename, sizeof (filename), CHANNEL_BPFDEVICE, count);
		if (stat(filename, &st) == -1)
		{
			stat_errno = errno;
			continue;
		}
		if ((channel->fd = open (filename, O_RDWR)) != -1)
		{
			break;
		}
		else
		{
			open_errno = errno;
		}
	}
	if (channel->fd == -1)
	{
		if (open_errno)
		{
			error (1, open_errno, "Could not open bpf device");
		}
		else
		{
			error (1, stat_errno, "No bpf device found");
		}
	}
	memcpy (ifreq.ifr_name, channel->ifname, sizeof (ifreq.ifr_name));
	if (ioctl (channel->fd, BIOCSETIF, &ifreq) == -1)
	{
		error (1, errno, "%s", ifreq.ifr_name);
	}
	channel->bpf = bpf = malloc (sizeof (* bpf));
	if (ioctl (channel->fd, BIOCGBLEN, &bpf->bpf_length) == -1)
	{
		error (1, errno, "Can't determine buffer length: %s", ifreq.ifr_name);
	}
	bpf->bpf_bp = bpf->bpf_buffer = malloc (bpf->bpf_length);
	if (bpf->bpf_buffer == NULL)
	{
		error (1, errno, "Can't allocate receive buffer");
	}

#if defined (__APPLE__) || defined (__NetBSD__)

	state = 0;
	if (ioctl (channel->fd, BIOCSSEESENT, &state) == -1)
	{
		error (1, errno, "Can't hide outgoing frames: %s", ifreq.ifr_name);
	}

#elif defined (__OpenBSD__)

	state = BPF_DIRECTION_OUT;
	if (ioctl (channel->fd, BIOCSDIRFILT, &state) == -1)
	{
		error (0, errno, "Can't hide outgoing frames");
	}

#else
#error "Abandon all hope"
#endif

	if (channel->capture > 1000)
	{
		timeval.tv_sec = channel->capture / 1000;
		timeval.tv_usec = 0;
	}
	else
	{

#if defined (__MAC_10_6)

/*
 *	accommodate known bug in BPF on MAC OS X 10.6; shorter times cause socket read
 *	operations to block indefinitely if no frames are waiting because tv_usec gets
 *      clobbered;
 */

		timeval.tv_sec = 1;
		timeval.tv_usec = 0;

#else

		timeval.tv_sec = 0;
		timeval.tv_usec = channel->capture * 1000;

#endif

	}
	if (ioctl (channel->fd, BIOCSRTIMEOUT, &timeval) == -1)
	{
		error (1, errno, "Can't set channel timeout: %s", ifreq.ifr_name);
	}
	state = 1;
	if (ioctl (channel->fd, BIOCIMMEDIATE, &state) == -1)
	{
		error (1, errno, "Can't set immediate mode: %s", ifreq.ifr_name);
	}

#if 1

	state = 1;
	if (ioctl (channel->fd, BIOCSHDRCMPLT, &state) == -1)
	{
		error (1, errno, "Can't set header complete mode: %s", ifreq.ifr_name);
	}

#endif

#if 1

	gethwaddr (channel->host, channel->ifname);

#else

	if (ioctl (channel->fd, SIOCGIFADDR, &ifreq) > 0)
	{
		error (1, errno, "%s", ifreq.ifr_name);
	}
	memcpy (channel->host, LLADDR (ifreq.ifr_ifru.ifru_addr), sizeof (channel->host));

#endif

	bpf_program.bf_len = sizeof (bpf_insn) / sizeof (struct bpf_insn);
	bpf_program.bf_insns = bpf_insn;
	if (channel->type == ETH_P_802_2)
	{
		bpf_insn [1].code = BPF_JMP + BPF_JGT + BPF_K;
		bpf_insn [1].jt = 18;
		bpf_insn [1].jf = 0;
		bpf_insn [1].k = ETHERMTU;
	}
	else
	{
		bpf_insn [1].code = BPF_JMP + BPF_JEQ + BPF_K;
		bpf_insn [1].jt = 0;
		bpf_insn [1].jf = 18;
		bpf_insn [1].k = channel->type;
	}
	bpf_insn [3].k = channel->host [0];
	bpf_insn [5].k = channel->host [1];
	bpf_insn [7].k = channel->host [2];
	bpf_insn [9].k = channel->host [3];
	bpf_insn [11].k = channel->host [4];
	bpf_insn [13].k = channel->host [5];
	if (ioctl (channel->fd, BIOCSETF, &bpf_program) == -1)
	{
		error (1, errno, "Can't store filter: %s", channel->ifname);
	}

#elif defined (WINPCAP) || defined (LIBPCAP)

	channel->ifname = getifname (channel->ifindex);
	gethwaddr (channel->host, channel->ifname);
	channel->socket = pcap_open_live (channel->ifname, 65536, 0, channel->capture, channel->errbuf);
	snprintf ((char *)(channel->ifname), strlen (channel->ifname), "nic%d", channel->ifindex);
	if (!channel->socket)
	{
		error (1, errno, "Can't open interface: %s", channel->ifname);
	}
	bpf_program.bf_len = sizeof (bpf_insn)/sizeof (struct bpf_insn);
	bpf_program.bf_insns = bpf_insn;
	if (channel->type == ETH_P_802_2)
	{
		bpf_insn [1].code = BPF_JMP + BPF_JGT + BPF_K;
		bpf_insn [1].jt = 18;
		bpf_insn [1].jf = 0;
		bpf_insn [1].k = ETHERMTU;
	}
	else
	{
		bpf_insn [1].code = BPF_JMP + BPF_JEQ + BPF_K;
		bpf_insn [1].jt = 0;
		bpf_insn [1].jf = 18;
		bpf_insn [1].k = channel->type;
	}
	bpf_insn [3].k = channel->host [0];
	bpf_insn [5].k = channel->host [1];
	bpf_insn [7].k = channel->host [2];
	bpf_insn [9].k = channel->host [3];
	bpf_insn [11].k = channel->host [4];
	bpf_insn [13].k = channel->host [5];
	if (pcap_setfilter (channel->socket, &bpf_program) < 0)
	{
		error (1, errno, "Can't store filter: %s", channel->ifname);
	}
	if (pcap_setmintocopy (channel->socket, ETHER_MIN_LEN) < 0)
	{
		error (1, errno, "Can't set pcap mintocopy: %s", channel->ifname);
	}

#else
#error "Unknown Environment"
#endif
#endif

	return (0);
}