## diffname ip/netdevmedium.c 2000/0624 ## diff -e /dev/null /n/emeliedump/2000/0624/sys/src/9/ip/netdevmedium.c 0a #include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "../port/error.h" #include "ip.h" #include "kernel.h" static void netdevbind(Ipifc *ifc, int argc, char **argv); static void netdevunbind(Ipifc *ifc); static void netdevbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip); static void netdevread(void *a); typedef struct Netdevrock Netdevrock; struct Netdevrock { Fs *f; /* file system we belong to */ Proc *readp; /* reading process */ Chan *mchan; /* Data channel */ }; Medium netdevmedium = { .name= "netdev", .hsize= 14, //ZZZ what should these be? .minmtu= 60, .maxmtu= 1514, .maclen= 6, .bind= netdevbind, .unbind= netdevunbind, .bwrite= netdevbwrite, .unbindonclose= 0, }; /* * called to bind an IP ifc to a generic network device * called with ifc qlock'd */ static void netdevbind(Ipifc *ifc, int argc, char **argv) { int fd; Chan *mchan; Netdevrock *er; if(argc < 2) error(Ebadarg); fd = kopen(argv[2], ORDWR); if(fd < 0) error("fd open failed"); mchan = commonfdtochan(fd, ORDWR, 0, 1); kclose(fd); er = smalloc(sizeof(*er)); er->mchan = mchan; er->f = ifc->conv->p->f; ifc->arg = er; kproc("netdevread", netdevread, ifc); } /* * called with ifc wlock'd */ static void netdevunbind(Ipifc *ifc) { Netdevrock *er = ifc->arg; if(er->readp != nil) postnote(er->readp, 1, "unbind", 0); /* wait for readers to die */ while(er->readp != nil) tsleep(&up->sleep, return0, 0, 300); if(er->mchan != nil) cclose(er->mchan); free(er); } /* * called by ipoput with a single block to write */ static void netdevbwrite(Ipifc *ifc, Block *bp, int, uchar*) { Netdevrock *er = ifc->arg; if(bp->next) bp = concatblock(bp); if(BLEN(bp) < ifc->minmtu) bp = adjustblock(bp, ifc->minmtu); devtab[er->mchan->type]->bwrite(er->mchan, bp, 0); ifc->out++; } /* * process to read from the device */ static void netdevread(void *a) { Ipifc *ifc; Block *bp; Netdevrock *er; char *argv[1]; ifc = a; er = ifc->arg; er->readp = up; /* hide identity under a rock for unbind */ if(waserror()){ er->readp = nil; pexit("hangup", 1); } for(;;){ bp = devtab[er->mchan->type]->bread(er->mchan, ifc->maxmtu, 0); if(bp == nil){ /* * get here if mchan is a pipe and other side hangs up * clean up this interface & get out ZZZ is this a good idea? */ poperror(); er->readp = nil; argv[0] = "unbind"; if(!waserror()) ifc->conv->p->ctl(ifc->conv, argv, 1); pexit("hangup", 1); } if(!canrlock(ifc)){ freeb(bp); continue; } if(waserror()){ runlock(ifc); nexterror(); } ifc->in++; if(ifc->lifc == nil) freeb(bp); else ipiput(er->f, ifc->lifc->local, bp); runlock(ifc); poperror(); } } void netdevmediumlink(void) { addipmedium(&netdevmedium); } . ## diffname ip/netdevmedium.c 2000/0706 ## diff -e /n/emeliedump/2000/0624/sys/src/9/ip/netdevmedium.c /n/emeliedump/2000/0706/sys/src/9/ip/netdevmedium.c 27,30c .hsize= 0, .minmtu= 0, .maxmtu= 64000, .maclen= 0, . ## diffname ip/netdevmedium.c 2000/1111 ## diff -e /n/emeliedump/2000/0706/sys/src/9/ip/netdevmedium.c /n/emeliedump/2000/1111/sys/src/9/ip/netdevmedium.c 51,56c mchan = namec(argv[2], Aopen, ORDWR, 0); . 44d 9d ## diffname ip/netdevmedium.c 2001/0623 ## diff -e /n/emeliedump/2000/1111/sys/src/9/ip/netdevmedium.c /n/emeliedump/2001/0623/sys/src/9/ip/netdevmedium.c 143c ipiput(er->f, ifc, bp); . ## diffname ip/netdevmedium.c 2002/0507 ## diff -e /n/emeliedump/2001/0623/sys/src/9/ip/netdevmedium.c /n/emeliedump/2002/0507/sys/src/9/ip/netdevmedium.c 143c ipiput4(er->f, ifc, bp); . ## diffname ip/netdevmedium.c 2003/0209 ## diff -e /n/emeliedump/2002/0507/sys/src/9/ip/netdevmedium.c /n/emeliedump/2003/0209/sys/src/9/ip/netdevmedium.c 117c bp = devtab[er->mchan->type]->bread(er->mchan, ifc->maxtu, 0); . 91,92c if(BLEN(bp) < ifc->mintu) bp = adjustblock(bp, ifc->mintu); . 27,28c .mintu= 0, .maxtu= 64000, .