示例#1
0
文件: devip.c 项目: 99years/plan9
static long
ipwrite(Chan* ch, void *v, long n, vlong off)
{
	Conv *c;
	Proto *x;
	char *p;
	Cmdbuf *cb;
	uchar ia[IPaddrlen], ma[IPaddrlen];
	Fs *f;
	char *a;
	ulong offset = off;

	a = v;
	f = ipfs[ch->dev];

	switch(TYPE(ch->qid)){
	default:
		error(Eperm);
	case Qdata:
		x = f->p[PROTO(ch->qid)];
		c = x->conv[CONV(ch->qid)];

		if(c->wq == nil)
			error(Eperm);

		qwrite(c->wq, a, n);
		break;
	case Qarp:
		return arpwrite(f, a, n);
	case Qiproute:
		return routewrite(f, ch, a, n);
	case Qlog:
		netlogctl(f, a, n);
		return n;
	case Qndb:
		return ndbwrite(f, a, offset, n);
		break;
	case Qctl:
		x = f->p[PROTO(ch->qid)];
		c = x->conv[CONV(ch->qid)];
		cb = parsecmd(a, n);

		qlock(c);
		if(waserror()) {
			qunlock(c);
			free(cb);
			nexterror();
		}
		if(cb->nf < 1)
			error("short control request");
		if(strcmp(cb->f[0], "connect") == 0)
			connectctlmsg(x, c, cb);
		else if(strcmp(cb->f[0], "announce") == 0)
			announcectlmsg(x, c, cb);
		else if(strcmp(cb->f[0], "bind") == 0)
			bindctlmsg(x, c, cb);
		else if(strcmp(cb->f[0], "ttl") == 0)
			ttlctlmsg(c, cb);
		else if(strcmp(cb->f[0], "tos") == 0)
			tosctlmsg(c, cb);
		else if(strcmp(cb->f[0], "ignoreadvice") == 0)
			c->ignoreadvice = 1;
		else if(strcmp(cb->f[0], "addmulti") == 0){
			if(cb->nf < 2)
				error("addmulti needs interface address");
			if(cb->nf == 2){
				if(!ipismulticast(c->raddr))
					error("addmulti for a non multicast address");
				if (parseip(ia, cb->f[1]) == -1)
					error(Ebadip);
				ipifcaddmulti(c, c->raddr, ia);
			} else {
				if (parseip(ia, cb->f[1]) == -1 ||
				    parseip(ma, cb->f[2]) == -1)
					error(Ebadip);
				if(!ipismulticast(ma))
					error("addmulti for a non multicast address");
				ipifcaddmulti(c, ma, ia);
			}
		} else if(strcmp(cb->f[0], "remmulti") == 0){
			if(cb->nf < 2)
				error("remmulti needs interface address");
			if(!ipismulticast(c->raddr))
				error("remmulti for a non multicast address");
			if (parseip(ia, cb->f[1]) == -1)
				error(Ebadip);
			ipifcremmulti(c, c->raddr, ia);
		} else if(strcmp(cb->f[0], "maxfragsize") == 0){
			if(cb->nf < 2)
				error("maxfragsize needs size");

			c->maxfragsize = (int)strtol(cb->f[1], nil, 0);

		} else if(x->ctl != nil) {
			p = x->ctl(c, cb->f, cb->nf);
			if(p != nil)
				error(p);
		} else
			error("unknown control request");
		qunlock(c);
		free(cb);
		poperror();
	}
	return n;
}
示例#2
0
文件: dhcp.c 项目: 8l/inferno
static char*
rbootp(Ipifc *ifc)
{
	int cfd, dfd, tries, n;
	char ia[5+3*16], im[16], *av[3];
	uchar nipaddr[4], ngwip[4], nipmask[4];
	char dir[Maxpath];
	static uchar vend_rfc1048[] = { 99, 130, 83, 99 };
	uchar *vend;

	/*
	 * broadcast bootp's till we get a reply,
	 * or fixed number of tries
	 */
	if(debug)
	    print("dhcp: bootp() called\n");
	tries = 0;
	av[1] = "0.0.0.0";
	av[2] = "0.0.0.0";
	ipifcadd(ifc, av, 3, 0, nil);

	cfd = kannounce("udp!*!68", dir);
	if(cfd < 0)
		return "dhcp announce failed";
	strcat(dir, "/data");
	if(kwrite(cfd, "headers", 7) < 0){
		kclose(cfd);
		return "dhcp ctl headers failed";
	}
	kwrite(cfd, "oldheaders", 10);
	dfd = kopen(dir, ORDWR);
	if(dfd < 0){
		kclose(cfd);
		return "dhcp open data failed";
	}
	kclose(cfd);
	
	while(tries<1){
		tries++;
		memset(sid, 0, 4);
		iplease=0;
		dhcpmsgtype=-2;
/* DHCPDISCOVER*/
		done = 0;
		recv = 0;
		kproc("rcvbootp", rcvbootp, (void*)dfd, KPDUPFDG);
		/* Prepare DHCPDISCOVER */	
		memset(&req, 0, sizeof(req));
		ipmove(req.raddr, IPv4bcast);
		hnputs(req.rport, 67);
		req.op = Bootrequest;
		req.htype = 1;			/* ethernet (all we know) */
		req.hlen = 6;			/* ethernet (all we know) */
		
		memmove(req.chaddr, ifc->mac, 6);	/* Hardware MAC address */
		//ipv4local(ifc, req.ciaddr);				/* Fill in the local IP address if we know it */
		memset(req.file, 0, sizeof(req.file));
		vend=req.vend;
		memmove(vend, vend_rfc1048, 4); vend+=4;
		*vend++=53; *vend++=1;*vend++=1;		/* dhcp msg type==3, dhcprequest */
		
		*vend++=61;*vend++=7;*vend++=1;
		memmove(vend, ifc->mac, 6);vend+=6;
		*vend=0xff;

		if(debug)
			dispvend(req.vend); 
		for(n=0;n<4;n++){
			if(kwrite(dfd, &req, sizeof(req))<0)	/* SEND DHCPDISCOVER */
				print("DHCPDISCOVER: %r");
		
			tsleep(&bootpr, return0, 0, 1000);	/* wait DHCPOFFER */
			if(debug)
				print("[DHCP] DISCOVER: msgtype = %d\n", dhcpmsgtype);

			if(dhcpmsgtype==2)		/* DHCPOFFER */
				break;
			else if(dhcpmsgtype==0)	/* bootp */
				return nil;
			else if(dhcpmsgtype== -2)	/* time out */
				continue;
			else
				break;
			
		}
		if(dhcpmsgtype!=2)
			continue;

/* DHCPREQUEST */	
		memset(req.vend, 0, sizeof(req.vend));
		vend=req.vend;
		memmove(vend, vend_rfc1048, 4);vend+=4;	

		*vend++=53; *vend++=1;*vend++=3;		/* dhcp msg type==3, dhcprequest */

		*vend++=50;	*vend++=4;				/* requested ip address */
		*vend++=(ipaddr >> 24)&0xff;
		*vend++=(ipaddr >> 16)&0xff;
		*vend++=(ipaddr >> 8) & 0xff;
		*vend++=ipaddr & 0xff;

		*vend++=51;*vend++=4;					/* lease time */
		*vend++=(iplease>>24)&0xff; *vend++=(iplease>>16)&0xff; *vend++=(iplease>>8)&0xff; *vend++=iplease&0xff;

		*vend++=54; *vend++=4;					/* server identifier */
		memmove(vend, sid, 4);	vend+=4;
	
		*vend++=61;*vend++=07;*vend++=01;		/* client identifier */
		memmove(vend, ifc->mac, 6);vend+=6;
		*vend=0xff;
		if(debug) 
			dispvend(req.vend); 
		if(kwrite(dfd, &req, sizeof(req))<0){
			print("DHCPREQUEST: %r");
			continue;
		}
		tsleep(&bootpr, return0, 0, 2000);
		if(dhcpmsgtype==5)		/* wait for DHCPACK */
			break;
		else
			continue;
		/* CHECK ARP */
		/* DHCPDECLINE */
	}
	kclose(dfd);
	done = 1;
	if(rcvprocp != nil){
		postnote(rcvprocp, 1, "timeout", 0);
		rcvprocp = nil;
	}

	av[1] = "0.0.0.0";
	av[2] = "0.0.0.0";
	ipifcrem(ifc, av, 3);

	hnputl(nipaddr, ipaddr);
	sprint(ia, "%V", nipaddr);
	hnputl(nipmask, ipmask);
	sprint(im, "%V", nipmask);
	av[1] = ia;
	av[2] = im;
	ipifcadd(ifc, av, 3, 0, nil);

	if(gwip != 0) {
		hnputl(ngwip, gwip);
		n = sprint(ia, "add 0.0.0.0 0.0.0.0 %V", ngwip);
		routewrite(ifc->conv->p->f, nil, ia, n);
	}
	return nil;
}