Пример #1
0
int
interfaces_routing_enabled(struct lldpd *cfg) {
	(void)cfg;
	int f;
	char status;
	int rc;
	if ((f = priv_open("/proc/sys/net/ipv4/ip_forward")) >= 0) {
		if (read(f, &status, 1) == 1) {
			rc = (status == '1');
		} else rc = -1;
		close(f);
		return rc;
	}
	return -1;
}
Пример #2
0
/** start npppd_iface */
int
npppd_iface_start(npppd_iface *_this)
{
	int             x;
	char            buf[MAXPATHLEN];

	NPPPD_IFACE_ASSERT(_this != NULL);

	/* open device file */
	snprintf(buf, sizeof(buf), "/dev/%s", _this->ifname);
	if ((_this->devf = priv_open(buf, O_RDWR, 0600)) < 0) {
		npppd_iface_log(_this, LOG_ERR, "open(%s) failed: %m", buf);
		goto fail;
	}

	x = 1;
	if (ioctl(_this->devf, FIONBIO, &x) != 0) {
		npppd_iface_log(_this, LOG_ERR,
		    "ioctl(FIONBIO) failed in %s(): %m", __func__);
		goto fail;
	}

	if (_this->using_pppx == 0) {
		x = IFF_BROADCAST;
		if (ioctl(_this->devf, TUNSIFMODE, &x) != 0) {
			npppd_iface_log(_this, LOG_ERR,
			    "ioctl(TUNSIFMODE=IFF_BROADCAST) failed "
			    "in %s(): %m", __func__);
			goto fail;
		}
	}

	event_set(&_this->ev, _this->devf, EV_READ | EV_PERSIST,
	    npppd_iface_io_event_handler, _this);
	event_add(&_this->ev, NULL);

	if (_this->using_pppx == 0) {
		if (npppd_iface_setup_ip(_this) != 0)
			goto fail;
	}

#ifdef USE_NPPPD_PIPEX
	if (npppd_iface_pipex_enable(_this) != 0) {
		log_printf(LOG_WARNING,
		    "npppd_iface_pipex_enable() failed: %m");
	}
#else
	if (_this->using_pppx) {
		npppd_iface_log(_this, LOG_ERR,
		    "pipex is required when using pppx interface");
		goto fail;
	}
#endif /* USE_NPPPD_PIPEX */

	if (_this->using_pppx) {
		npppd_iface_log(_this, LOG_INFO, "Started pppx");
	} else {
		npppd_iface_log(_this, LOG_INFO, "Started ip4addr=%s",
			(npppd_iface_ip_is_ready(_this))?
			    inet_ntop(AF_INET, &_this->ip4addr, buf,
			    sizeof(buf)) : "(not assigned)");
	}
	_this->started = 1;

	return 0;
fail:
	if (_this->devf >= 0) {
		event_del(&_this->ev);
		close(_this->devf);
	}
	_this->devf = -1;

	return -1;
}
Пример #3
0
static int
pppoed_listener_start(pppoed_listener *_this, int restart)
{
	int i;
	int log_level;
	char buf[BUFSIZ];
	struct ifreq ifreq;
	int ival;
	int found;
	struct ifaddrs *ifa0, *ifa;
	struct sockaddr_dl *sdl;
	struct bpf_insn insns[] = {
	    /* check etyer type = PPPOEDESC or PPPOE */
		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETHERTYPE_PPPOEDISC, 2, 0),
		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETHERTYPE_PPPOE, 1, 0),
		BPF_STMT(BPF_RET+BPF_K, (u_int)0),
#ifndef	REJECT_FOREIGN_ADDRESS
		BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
#else
	/* to ff:ff:ff:ff:ff:ff */
		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 0),
		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0xffffffff, 0, 3),
		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 4),
		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0xffff, 0, 1),
		BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
	/* to self */
		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 0),
		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K,
		    ETHER_FIRST_INT(_this->ether_addr), 0, 3),
		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 4),
		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K,
		    ETHER_LAST_SHORT(_this->ether_addr), 0, 1),
		BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
		BPF_STMT(BPF_RET+BPF_K, (u_int)0),
#endif
	};
	struct bpf_program bf_filter = {
		.bf_len = countof(insns),
		.bf_insns = insns
	};
	pppoed *_pppoed;

	if (restart == 0)
		log_level = LOG_ERR;
	else
		log_level = LOG_INFO;

	_pppoed = _this->self;

	ifa0 = NULL;
	if (getifaddrs(&ifa0) != 0) {
		pppoed_log(_pppoed, log_level,
		    "getifaddrs() failed on %s(): %m", __func__);
		return -1;
	}
	found = 0;
	for (ifa = ifa0; ifa != NULL; ifa = ifa->ifa_next) {
		sdl = (struct sockaddr_dl *)ifa->ifa_addr;
		if (sdl->sdl_family != AF_LINK || sdl->sdl_type != IFT_ETHER ||
		    sdl->sdl_alen != ETHER_ADDR_LEN)
			continue;
		if (strcmp(ifa->ifa_name, _this->listen_ifname) == 0) {
			memcpy(_this->ether_addr,
			    (caddr_t)LLADDR(sdl), ETHER_ADDR_LEN);
			found = 1;
			break;
		}
	}
	freeifaddrs(ifa0);
	if (!found) {
		pppoed_log(_pppoed, log_level, "%s is not available.",
		    _this->listen_ifname);
		goto fail;
	}

	/* Open /dev/bpfXX */
	/* FIXME: /dev/bpf of NetBSD3.0 can simultaneity open */
	for (i = 0; i < 256; i++) {
		snprintf(buf, sizeof(buf), "/dev/bpf%d", i);
		if ((_this->bpf = priv_open(buf, O_RDWR, 0600)) >= 0) {
			break;
		} else if (errno == ENXIO || errno == ENOENT)
			break;	/* no more entries */
	}
	if (_this->bpf < 0) {
		pppoed_log(_pppoed, log_level, "Cannot open bpf");
		goto fail;
	}

	ival = BPF_CAPTURE_SIZ;
	if (ioctl(_this->bpf, BIOCSBLEN, &ival) != 0) {
		pppoed_log(_pppoed, log_level, "ioctl(bpf, BIOCSBLEN(%d)): %m",
		    ival);
		goto fail;
	}
	ival = 1;
	if (ioctl(_this->bpf, BIOCIMMEDIATE, &ival) != 0) {
		pppoed_log(_pppoed, log_level, "Cannot start bpf on %s: %m",
		    _this->listen_ifname);
		goto fail;
	}

	/* bind interface */
	memset(&ifreq, 0, sizeof(ifreq));
	strlcpy(ifreq.ifr_name, _this->listen_ifname, sizeof(ifreq.ifr_name));
	if (ioctl(_this->bpf, BIOCSETIF, &ifreq) != 0) {
		pppoed_log(_pppoed, log_level, "Cannot start bpf on %s: %m",
		    _this->listen_ifname);
		goto fail;
	}

	/* set linklocal address */
#ifdef	REJECT_FOREIGN_ADDRESS
	insns[10].k = ETHER_FIRST_INT(_this->ether_addr);
	insns[12].k = ETHER_LAST_SHORT(_this->ether_addr);
#endif

	/* set filter */
	if (ioctl(_this->bpf, BIOCSETF, &bf_filter) != 0) {
		pppoed_log(_pppoed, log_level, "ioctl(bpf, BIOCSETF()): %m");
		goto fail;
	}

	event_set(&_this->ev_bpf, _this->bpf, EV_READ | EV_PERSIST,
	    pppoed_io_event, _this);
	event_add(&_this->ev_bpf, NULL);

	pppoed_log(_pppoed, LOG_INFO, "Listening on %s (PPPoE) [%s] using=%s "
	    "address=%02x:%02x:%02x:%02x:%02x:%02x", _this->listen_ifname,
	    _this->tun_name, buf, _this->ether_addr[0], _this->ether_addr[1],
	    _this->ether_addr[2], _this->ether_addr[3], _this->ether_addr[4],
	    _this->ether_addr[5]);

	return 0;
fail:
	if (_this->bpf >= 0) {
		close(_this->bpf);
		_this->bpf = -1;
	}

	return 1;
}