changelog shortlog tags branches changeset file revisions annotate raw help

Mercurial > hg > plan9front / sys/src/9/ip/ethermedium.c

revision 7228: 74d3b4699b3a
parent 6667: 6e2f7ef5b88f
child 7430: 88a2f67638e2
     1.1--- a/sys/src/9/ip/ethermedium.c
     1.2+++ b/sys/src/9/ip/ethermedium.c
     1.3@@ -122,32 +122,49 @@ static char *nbmsg = "nonblocking";
     1.4 static void
     1.5 etherbind(Ipifc *ifc, int argc, char **argv)
     1.6 {
     1.7-	Chan *mchan4, *cchan4, *achan, *mchan6, *cchan6, *schan;
     1.8-	char addr[Maxpath];	//char addr[2*KNAMELEN];
     1.9-	char dir[Maxpath];	//char dir[2*KNAMELEN];
    1.10-	char *buf;
    1.11+	char addr[Maxpath], dir[Maxpath];
    1.12+	Etherrock *er;
    1.13+	Chan *c;
    1.14 	int n;
    1.15-	char *ptr;
    1.16-	Etherrock *er;
    1.17 
    1.18 	if(argc < 2)
    1.19 		error(Ebadarg);
    1.20 
    1.21-	mchan4 = cchan4 = achan = mchan6 = cchan6 = nil;
    1.22-	buf = nil;
    1.23+	/*
    1.24+	 *  get mac address
    1.25+	 */
    1.26+	snprint(addr, sizeof(addr), "%s/addr", argv[2]);
    1.27+	c = namec(addr, Aopen, OREAD, 0);
    1.28 	if(waserror()){
    1.29-		if(mchan4 != nil)
    1.30-			cclose(mchan4);
    1.31-		if(cchan4 != nil)
    1.32-			cclose(cchan4);
    1.33-		if(achan != nil)
    1.34-			cclose(achan);
    1.35-		if(mchan6 != nil)
    1.36-			cclose(mchan6);
    1.37-		if(cchan6 != nil)
    1.38-			cclose(cchan6);
    1.39-		if(buf != nil)
    1.40-			free(buf);
    1.41+		cclose(c);
    1.42+		nexterror();
    1.43+	}
    1.44+	n = devtab[c->type]->read(c, addr, sizeof(addr)-1, 0);
    1.45+	if(n < 0)
    1.46+		error(Eio);
    1.47+	addr[n] = 0;
    1.48+	if(parsemac(ifc->mac, addr, sizeof(ifc->mac)) != 6)
    1.49+		error("could not find mac address");
    1.50+	cclose(c);
    1.51+	poperror();
    1.52+
    1.53+	er = smalloc(sizeof(*er));
    1.54+	er->read4p = er->read6p = er->arpp = (void*)-1;
    1.55+	er->mchan4 = er->cchan4 = er->mchan6 = er->cchan6 = er->achan = nil;
    1.56+	er->f = ifc->conv->p->f;
    1.57+
    1.58+	if(waserror()){
    1.59+		if(er->mchan4 != nil)
    1.60+			cclose(er->mchan4);
    1.61+		if(er->cchan4 != nil)
    1.62+			cclose(er->cchan4);
    1.63+		if(er->mchan6 != nil)
    1.64+			cclose(er->mchan6);
    1.65+		if(er->cchan6 != nil)
    1.66+			cclose(er->cchan6);
    1.67+		if(er->achan != nil)
    1.68+			cclose(er->achan);
    1.69+		free(er);
    1.70 		nexterror();
    1.71 	}
    1.72 
    1.73@@ -158,39 +175,12 @@ etherbind(Ipifc *ifc, int argc, char **a
    1.74 	 *  this device.
    1.75 	 */
    1.76 	snprint(addr, sizeof(addr), "%s!0x800", argv[2]);	/* ETIP4 */
    1.77-	mchan4 = chandial(addr, nil, dir, &cchan4);
    1.78+	er->mchan4 = chandial(addr, nil, dir, &er->cchan4);
    1.79 
    1.80 	/*
    1.81 	 *  make it non-blocking
    1.82 	 */
    1.83-	devtab[cchan4->type]->write(cchan4, nbmsg, strlen(nbmsg), 0);
    1.84-
    1.85-	/*
    1.86-	 *  get mac address and speed
    1.87-	 */
    1.88-	snprint(addr, sizeof(addr), "%s/stats", argv[2]);
    1.89-	buf = smalloc(512);
    1.90-	schan = namec(addr, Aopen, OREAD, 0);
    1.91-	if(waserror()){
    1.92-		cclose(schan);
    1.93-		nexterror();
    1.94-	}
    1.95-	n = devtab[schan->type]->read(schan, buf, 511, 0);
    1.96-	cclose(schan);
    1.97-	poperror();
    1.98-	buf[n] = 0;
    1.99-
   1.100-	ptr = strstr(buf, "addr: ");
   1.101-	if(!ptr)
   1.102-		error(Eio);
   1.103-	ptr += 6;
   1.104-	parsemac(ifc->mac, ptr, 6);
   1.105-
   1.106-	/*
   1.107- 	 *  open arp conversation
   1.108-	 */
   1.109-	snprint(addr, sizeof(addr), "%s!0x806", argv[2]);	/* ETARP */
   1.110-	achan = chandial(addr, nil, nil, nil);
   1.111+	devtab[er->cchan4->type]->write(er->cchan4, nbmsg, strlen(nbmsg), 0);
   1.112 
   1.113 	/*
   1.114 	 *  open ipv6 conversation
   1.115@@ -199,25 +189,22 @@ etherbind(Ipifc *ifc, int argc, char **a
   1.116 	 *  this device.
   1.117 	 */
   1.118 	snprint(addr, sizeof(addr), "%s!0x86DD", argv[2]);	/* ETIP6 */
   1.119-	mchan6 = chandial(addr, nil, dir, &cchan6);
   1.120+	er->mchan6 = chandial(addr, nil, dir, &er->cchan6);
   1.121 
   1.122 	/*
   1.123 	 *  make it non-blocking
   1.124 	 */
   1.125-	devtab[cchan6->type]->write(cchan6, nbmsg, strlen(nbmsg), 0);
   1.126+	devtab[er->cchan6->type]->write(er->cchan6, nbmsg, strlen(nbmsg), 0);
   1.127 
   1.128-	er = smalloc(sizeof(*er));
   1.129-	er->mchan4 = mchan4;
   1.130-	er->cchan4 = cchan4;
   1.131-	er->achan = achan;
   1.132-	er->mchan6 = mchan6;
   1.133-	er->cchan6 = cchan6;
   1.134-	er->f = ifc->conv->p->f;
   1.135+	/*
   1.136+ 	 *  open arp conversation
   1.137+	 */
   1.138+	snprint(addr, sizeof(addr), "%s!0x806", argv[2]);	/* ETARP */
   1.139+	er->achan = chandial(addr, nil, nil, nil);
   1.140+	poperror();
   1.141+
   1.142 	ifc->arg = er;
   1.143 
   1.144-	free(buf);
   1.145-	poperror();
   1.146-
   1.147 	kproc("etherread4", etherread4, ifc);
   1.148 	kproc("etherread6", etherread6, ifc);
   1.149 	kproc("recvarpproc", recvarpproc, ifc);
   1.150@@ -231,6 +218,10 @@ etherunbind(Ipifc *ifc)
   1.151 {
   1.152 	Etherrock *er = ifc->arg;
   1.153 
   1.154+	/* wait for readers to start */
   1.155+	while(er->arpp == (void*)-1 || er->read4p == (void*)-1 || er->read6p == (void*)-1)
   1.156+		tsleep(&up->sleep, return0, 0, 300);
   1.157+
   1.158 	if(er->read4p != nil)
   1.159 		postnote(er->read4p, 1, "unbind", 0);
   1.160 	if(er->read6p != nil)