Exemplo n.º 1
0
/*
 *  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;
}
Exemplo n.º 2
0
Arquivo: ipifc.c Projeto: 7perl/akaros
/*
 *  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;
}
Exemplo n.º 3
0
Arquivo: ipifc.c Projeto: 7perl/akaros
char *ipifcaddpref6(struct Ipifc *ifc, char **argv, int argc)
{
	uint8_t onlink = 1;
	uint8_t autoflag = 1;
	uint64_t validlt = UINT64_MAX;
	uint64_t preflt = UINT64_MAX;
	uint64_t origint = NOW / 10 ^ 3;
	uint8_t prefix[IPaddrlen];
	int plen = 64;
	struct Iplifc *lifc;
	char addr[40], preflen[6];
	char *params[3];

	switch (argc) {
		case 7:
			preflt = atoi(argv[6]);
			/* fall through */
		case 6:
			validlt = atoi(argv[5]);
			/* fall through */
		case 5:
			autoflag = atoi(argv[4]);
			/* fall through */
		case 4:
			onlink = atoi(argv[3]);
			/* fall through */
		case 3:
			plen = atoi(argv[2]);
		case 2:
			break;
		default:
			return Ebadarg;
	}

	if ((parseip(prefix, argv[1]) != 6) ||
		(validlt < preflt) || (plen < 0) || (plen > 64) || (islinklocal(prefix))
		)
		return Ebadarg;

	lifc = kzmalloc(sizeof(struct Iplifc), 0);
	lifc->onlink = (onlink != 0);
	lifc->autoflag = (autoflag != 0);
	lifc->validlt = validlt;
	lifc->preflt = preflt;
	lifc->origint = origint;

	if (ifc->m->pref2addr != NULL)
		ifc->m->pref2addr(prefix, ifc->mac);
	else
		return Ebadarg;

	snprintf(addr, sizeof(addr), "%I", prefix);
	snprintf(preflen, sizeof(preflen), "/%d", plen);
	params[0] = "add";
	params[1] = addr;
	params[2] = preflen;

	return ipifcadd(ifc, params, 3, 0, lifc);
}
Exemplo n.º 4
0
Arquivo: ipifc.c Projeto: 7perl/akaros
/*
 *  non-standard control messages.
 *  called with c locked.
 */
static char *ipifcctl(struct conv *c, char **argv, int argc)
{
	struct Ipifc *ifc;
	int i;

	ifc = (struct Ipifc *)c->ptcl;
	if (strcmp(argv[0], "add") == 0)
		return ipifcadd(ifc, argv, argc, 0, NULL);
	else if (strcmp(argv[0], "bootp") == 0)
		return bootp(ifc);
	else if (strcmp(argv[0], "try") == 0)
		return ipifcadd(ifc, argv, argc, 1, NULL);
	else if (strcmp(argv[0], "remove") == 0)
		return ipifcrem(ifc, argv, argc);
	else if (strcmp(argv[0], "unbind") == 0)
		return ipifcunbind(ifc);
	else if (strcmp(argv[0], "joinmulti") == 0)
		return ipifcjoinmulti(ifc, argv, argc);
	else if (strcmp(argv[0], "leavemulti") == 0)
		return ipifcleavemulti(ifc, argv, argc);
	else if (strcmp(argv[0], "mtu") == 0)
		return ipifcsetmtu(ifc, argv, argc);
	else if (strcmp(argv[0], "reassemble") == 0) {
		ifc->reassemble = 1;
		return NULL;
	} else if (strcmp(argv[0], "iprouting") == 0) {
		i = 1;
		if (argc > 1)
			i = atoi(argv[1]);
		iprouting(c->p->f, i);
		return NULL;
	} else if (strcmp(argv[0], "addpref6") == 0)
		return ipifcaddpref6(ifc, argv, argc);
	else if (strcmp(argv[0], "setpar6") == 0)
		return ipifcsetpar6(ifc, argv, argc);
	else if (strcmp(argv[0], "sendra6") == 0)
		return ipifcsendra6(ifc, argv, argc);
	else if (strcmp(argv[0], "recvra6") == 0)
		return ipifcrecvra6(ifc, argv, argc);
	return "unsupported ctl";
}
Exemplo n.º 5
0
/*
 *  non-standard control messages.
 *  called with c->car locked.
 */
static char*
ipifcctl(Conv* c, char**argv, int argc)
{
	Ipifc *ifc;
	int i;

	ifc = (Ipifc*)c->ptcl;
	if(strcmp(argv[0], "add") == 0)
		return ipifcadd(ifc, argv, argc, 0, nil);
	else if(strcmp(argv[0], "try") == 0)
		return ipifcadd(ifc, argv, argc, 1, nil);
	else if(strcmp(argv[0], "remove") == 0)
		return ipifcrem(ifc, argv, argc);
	else if(strcmp(argv[0], "unbind") == 0)
		return ipifcunbind(ifc);
	else if(strcmp(argv[0], "joinmulti") == 0)
		return ipifcjoinmulti(ifc, argv, argc);
	else if(strcmp(argv[0], "leavemulti") == 0)
		return ipifcleavemulti(ifc, argv, argc);
	else if(strcmp(argv[0], "mtu") == 0)
		return ipifcsetmtu(ifc, argv, argc);
	else if(strcmp(argv[0], "reassemble") == 0){
		ifc->reassemble = 1;
		return nil;
	}
	else if(strcmp(argv[0], "iprouting") == 0){
		i = 1;
		if(argc > 1)
			i = atoi(argv[1]);
		iprouting(c->p->f, i);
		return nil;
	}
	else if(strcmp(argv[0], "add6") == 0)
		return ipifcadd6(ifc, argv, argc);
	else if(strcmp(argv[0], "ra6") == 0)
		return ipifcra6(ifc, argv, argc);
	return "unsupported ctl";
}
Exemplo n.º 6
0
char*
ipifcadd6(Ipifc *ifc, char**argv, int argc)
{
	int plen = 64;
	int32_t origint = NOW / 1000, preflt = ~0L, validlt = ~0L;
	char addr[Maxv6repr], preflen[6];
	char *params[3];
	uint8_t autoflag = 1, onlink = 1;
	uint8_t prefix[IPaddrlen];
	Iplifc *lifc;

	switch(argc) {
	case 7:
		preflt = atoi(argv[6]);
		/* fall through */
	case 6:
		validlt = atoi(argv[5]);
		/* fall through */
	case 5:
		autoflag = atoi(argv[4]);
		/* fall through */
	case 4:
		onlink = atoi(argv[3]);
		/* fall through */
	case 3:
		plen = atoi(argv[2]);
		/* fall through */
	case 2:
		break;
	default:
		return Ebadarg;
	}

	if (parseip(prefix, argv[1]) != 6)
		return "bad ipv6 address";
	if (validlt < preflt)
		return "valid ipv6 lifetime less than preferred lifetime";
	if (plen < 0)
		return "negative ipv6 prefix length";
	/* i think that this length limit is bogus - geoff */
//	if (plen > 64)
//		return "ipv6 prefix length greater than 64;
	if (islinklocal(prefix))
		return "ipv6 prefix is link-local";

	lifc = smalloc(sizeof(Iplifc));
	lifc->onlink = (onlink != 0);
	lifc->autoflag = (autoflag != 0);
	lifc->validlt = validlt;
	lifc->preflt = preflt;
	lifc->origint = origint;

	/* issue "add" ctl msg for v6 link-local addr and prefix len */
	if(!ifc->medium->pref2addr)
		return "no pref2addr on interface";
	ifc->medium->pref2addr(prefix, ifc->mac);	/* mac → v6 link-local addr */
	snprint(addr, sizeof addr, "%I", prefix);
	snprint(preflen, sizeof preflen, "/%d", plen);
	params[0] = "add";
	params[1] = addr;
	params[2] = preflen;

	return ipifcadd(ifc, params, 3, 0, lifc);
}
Exemplo n.º 7
0
Arquivo: dhcp.c Projeto: 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;
}