/* * associate an address with the interface. This wipes out any previous * addresses. This is a macro that means, remove all the old interfaces * and add a new one. */ static char* ipifcconnect(Conv* c, char **argv, int argc) { Proc *up = externup(); char *err; Ipifc *ifc; ifc = (Ipifc*)c->ptcl; if(ifc->medium == nil) return "ipifc not yet bound to device"; if(waserror()){ wunlock(ifc); nexterror(); } wlock(ifc); while(ifc->lifc){ err = ipifcremlifc(ifc, ifc->lifc); if(err) error(err); } wunlock(ifc); poperror(); err = ipifcadd(ifc, argv, argc, 0, nil); if(err) return err; Fsconnected(c, nil); return nil; }
/* * associate an address with the interface. This wipes out any previous * addresses. This is a macro that means, remove all the old interfaces * and add a new one. */ static char *ipifcconnect(struct conv *c, char **argv, int argc) { ERRSTACK(1); char *err; struct Ipifc *ifc; ifc = (struct Ipifc *)c->ptcl; if (ifc->m == NULL) return "ipifc not yet bound to device"; if (waserror()) { wunlock(&ifc->rwlock); nexterror(); } wlock(&ifc->rwlock); while (ifc->lifc) { err = ipifcremlifc(ifc, ifc->lifc); if (err) error(err); } wunlock(&ifc->rwlock); poperror(); err = ipifcadd(ifc, argv, argc, 0, NULL); if (err) return err; Fsconnected(c, NULL); return NULL; }
/* * detach a device from an interface, close the interface * called with ifc->conv closed */ static char* ipifcunbind(Ipifc *ifc) { Proc *up = externup(); char *err; if(waserror()){ wunlock(ifc); nexterror(); } wlock(ifc); /* dissociate routes */ if(ifc->medium != nil && ifc->medium->unbindonclose == 0) ifc->conv->inuse--; ifc->ifcid++; /* disassociate logical interfaces (before zeroing ifc->arg) */ while(ifc->lifc){ err = ipifcremlifc(ifc, ifc->lifc); /* * note: err non-zero means lifc not found, * which can't happen in this case. */ if(err) error(err); } /* disassociate device */ if(ifc->medium && ifc->medium->unbind) (*ifc->medium->unbind)(ifc); memset(ifc->dev, 0, sizeof(ifc->dev)); ifc->arg = nil; ifc->reassemble = 0; /* close queues to stop queuing of packets */ qclose(ifc->conv->rq); qclose(ifc->conv->wq); qclose(ifc->conv->sq); ifc->medium = nil; wunlock(ifc); poperror(); return nil; }
/* * detach a device from an interface, close the interface * called with ifc->conv closed */ static char *ipifcunbind(struct Ipifc *ifc) { ERRSTACK(1); char *err; if (waserror()) { wunlock(&ifc->rwlock); nexterror(); } wlock(&ifc->rwlock); /* dissociate routes */ if (ifc->m != NULL && ifc->m->unbindonclose == 0) ifc->conv->inuse--; ifc->ifcid++; /* disassociate device */ if (ifc->m != NULL && ifc->m->unbind) (*ifc->m->unbind) (ifc); memset(ifc->dev, 0, sizeof(ifc->dev)); ifc->arg = NULL; ifc->reassemble = 0; /* close queues to stop queuing of packets */ qclose(ifc->conv->rq); qclose(ifc->conv->wq); qclose(ifc->conv->sq); /* disassociate logical interfaces */ while (ifc->lifc) { err = ipifcremlifc(ifc, ifc->lifc); if (err) error(err); } ifc->m = NULL; wunlock(&ifc->rwlock); poperror(); return NULL; }
/* * remove an address from an interface. * called with c->car locked */ char* ipifcrem(Ipifc *ifc, char **argv, int argc) { char *rv; uint8_t ip[IPaddrlen], mask[IPaddrlen], rem[IPaddrlen]; Iplifc *lifc; if(argc < 3) return Ebadarg; if (parseip(ip, argv[1]) == -1) return Ebadip; parseipmask(mask, argv[2]); if(argc < 4) maskip(ip, mask, rem); else if (parseip(rem, argv[3]) == -1) return Ebadip; wlock(ifc); /* * find address on this interface and remove from chain. * for pt to pt we actually specify the remote address as the * addresss to remove. */ for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next) { if (memcmp(ip, lifc->local, IPaddrlen) == 0 && memcmp(mask, lifc->mask, IPaddrlen) == 0 && memcmp(rem, lifc->remote, IPaddrlen) == 0) break; } rv = ipifcremlifc(ifc, lifc); wunlock(ifc); return rv; }