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; }
/** 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; }
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; }