static int etherctl(Ether *e, Conn *c, char *buf) { uint8_t addr[Eaddrlen]; int t; deprint(2, "%s: etherctl: %s\n", argv0, buf); if(strncmp(buf, "connect ", 8) == 0){ t = atoi(buf+8); qlock(e); if(typeinuse(e, t)){ werrstr("type already in use"); qunlock(e); return -1; } c->type = atoi(buf+8); qunlock(e); return 0; } if(strncmp(buf, "nonblocking", 11) == 0){ if(buf[11] == '\n' || buf[11] == 0) e->nblock = 1; else e->nblock = atoi(buf + 12); deprint(2, "%s: nblock %d\n", argv0, e->nblock); return 0; } if(strncmp(buf, "promiscuous", 11) == 0){ if(c->prom == 0) incref(&e->prom); c->prom = 1; return prom(e, 1); } if(strncmp(buf, "headersonly", 11) == 0){ c->headersonly = 1; return 0; } if(strncmp(buf, "addmulti ", 9) == 0 || strncmp(buf, "remmulti ", 9) == 0){ if(parseaddr(addr, buf+9) < 0){ werrstr("bad address"); return -1; } if(e->multicast == nil) return 0; if(strncmp(buf, "add", 3) == 0){ e->nmcasts++; return e->multicast(e, addr, 1); }else{ e->nmcasts--; return e->multicast(e, addr, 0); } } if(e->ctl != nil) return e->ctl(e, buf); werrstr(Ebadctl); return -1; }
/* * the devxxx.c that calls us handles writing data, it knows best */ int32_t netifwrite(Netif *nif, Chan *c, void *a, int32_t n) { Proc *up = externup(); Netfile *f; int type, mtu; char *p, buf[64]; uint8_t binaddr[Nmaxaddr]; if(NETTYPE(c->qid.path) != Nctlqid) error(Eperm); if(n >= sizeof(buf)) n = sizeof(buf)-1; memmove(buf, a, n); buf[n] = 0; if(waserror()){ qunlock(&nif->q); nexterror(); } qlock(&nif->q); f = nif->f[NETID(c->qid.path)]; if((p = matchtoken(buf, "connect")) != 0){ qclose(f->iq); type = atoi(p); if(typeinuse(nif, type)) error(Einuse); f->type = type; if(f->type < 0) nif->all++; qreopen(f->iq); } else if(matchtoken(buf, "promiscuous")){ if(f->prom == 0){ if(nif->prom == 0 && nif->promiscuous != nil) nif->promiscuous(nif->arg, 1); f->prom = 1; nif->prom++; } } else if((p = matchtoken(buf, "scanbs")) != 0){ /* scan for base stations */ if(f->scan == 0){ type = atoi(p); if(type < 5) type = 5; if(nif->scanbs != nil) nif->scanbs(nif->arg, type); f->scan = type; nif->_scan++; } } else if((p = matchtoken(buf, "mtu")) != 0){ /* poor planning. */ if(!iseve()) error(Eperm); mtu = atoi(p); /* zero resets default. */ if(mtu != 0) if(mtu < nif->minmtu || mtu > nif->maxmtu) error(Ebadarg); if(nif->hwmtu) nif->mtu = nif->hwmtu(nif->arg, mtu); else nif->mtu = mtu; } else if(matchtoken(buf, "l2bridge")){ f->bridge |= 2; } else if(matchtoken(buf, "bridge")){ f->bridge |= 1; } else if(matchtoken(buf, "headersonly")){ f->headersonly = 1; } else if((p = matchtoken(buf, "addmulti")) != 0){ if(parseaddr(binaddr, p, nif->alen) < 0) error("bad address"); p = netmulti(nif, f, binaddr, 1); if(p) error(p); } else if((p = matchtoken(buf, "remmulti")) != 0){ if(parseaddr(binaddr, p, nif->alen) < 0) error("bad address"); p = netmulti(nif, f, binaddr, 0); if(p) error(p); } else n = -1; qunlock(&nif->q); poperror(); return n; }
/* * the devxxx.c that calls us handles writing data, it knows best */ long netifwrite(Netif *nif, Chan *c, void *a, long n) { Netfile *f; int type; char *p, buf[64]; uchar binaddr[Nmaxaddr]; if(NETTYPE(c->qid.path) != Nctlqid) error(Eperm); if(n >= sizeof(buf)) n = sizeof(buf)-1; memmove(buf, a, n); buf[n] = 0; if(waserror()){ qunlock(nif); nexterror(); } qlock(nif); f = nif->f[NETID(c->qid.path)]; if((p = matchtoken(buf, "connect")) != 0){ type = atoi(p); if(typeinuse(nif, type)) error(Einuse); f->type = type; if(f->type < 0) nif->all++; } else if(matchtoken(buf, "promiscuous")){ if(f->prom == 0){ if(nif->prom == 0 && nif->promiscuous != nil) nif->promiscuous(nif->arg, 1); f->prom = 1; nif->prom++; } } else if((p = matchtoken(buf, "scanbs")) != 0){ /* scan for base stations */ if(f->scan == 0){ type = atoi(p); if(type < 5) type = 5; if(nif->scanbs != nil) nif->scanbs(nif->arg, type); f->scan = type; nif->scan++; } } else if(matchtoken(buf, "bridge")){ f->bridge = 1; } else if(matchtoken(buf, "headersonly")){ f->headersonly = 1; } else if((p = matchtoken(buf, "addmulti")) != 0){ if(parseaddr(binaddr, p, nif->alen) < 0) error("bad address"); p = netmulti(nif, f, binaddr, 1); if(p) error(p); } else if((p = matchtoken(buf, "remmulti")) != 0){ if(parseaddr(binaddr, p, nif->alen) < 0) error("bad address"); p = netmulti(nif, f, binaddr, 0); if(p) error(p); } else n = -1; qunlock(nif); poperror(); return n; }
/* * the devxxx.c that calls us handles writing data, it knows best */ long netifwrite(struct ether *nif, struct chan *c, void *a, long n) { ERRSTACK(1); struct netfile *f; int type; char *p, buf[64]; uint8_t binaddr[Nmaxaddr]; if (NETTYPE(c->qid.path) != Nctlqid) error(EPERM, NULL); if (n >= sizeof(buf)) n = sizeof(buf) - 1; memmove(buf, a, n); buf[n] = 0; qlock(&nif->qlock); if (waserror()) { qunlock(&nif->qlock); nexterror(); } f = nif->f[NETID(c->qid.path)]; if ((p = matchtoken(buf, "connect")) != 0) { type = strtol(p, 0, 0); /* allows any base, though usually hex */ if (typeinuse(nif, type)) error(EBUSY, NULL); f->type = type; if (f->type < 0) nif->all++; } else if (matchtoken(buf, "promiscuous")) { if (f->prom == 0) { if (nif->prom == 0 && nif->promiscuous != NULL) nif->promiscuous(nif->arg, 1); f->prom = 1; nif->prom++; } } else if ((p = matchtoken(buf, "scanbs")) != 0) { /* scan for base stations */ if (f->scan == 0) { type = strtol(p, 0, 0); /* allows any base, though usually hex */ if (type < 5) type = 5; if (nif->scanbs != NULL) nif->scanbs(nif->arg, type); f->scan = type; nif->scan++; } } else if (matchtoken(buf, "bridge")) { f->bridge = 1; } else if (matchtoken(buf, "headersonly")) { f->headersonly = 1; } else if ((p = matchtoken(buf, "addmulti")) != 0) { if (parseaddr(binaddr, p, nif->alen) < 0) error(EFAIL, "bad address"); p = netmulti(nif, f, binaddr, 1); if (p) error(EFAIL, p); } else if ((p = matchtoken(buf, "remmulti")) != 0) { if (parseaddr(binaddr, p, nif->alen) < 0) error(EFAIL, "bad address"); p = netmulti(nif, f, binaddr, 0); if (p) error(EFAIL, p); } else n = -1; qunlock(&nif->qlock); poperror(); return n; }