Exemplo n.º 1
0
int
openlisten(char *net)
{
	int n, fd, cfd;
	char data[128], devdir[40];

//	sprint(data, "%s/udp!*!bootpc", net);
	sprint(data, "%s/udp!*!68", net);
	for(n = 0; ; n++) {
		cfd = announce(data, devdir);
		if(cfd >= 0)
			break;
		/* might be another client - wait and try again */
		fprint(2, "dhcpclient: can't announce %s: %r", data);
		sleep(1000);
		if(n > 10)
			myfatal("can't announce: giving up: %r");
	}

	if(fprint(cfd, "headers") < 0)
		myfatal("can't set header mode: %r");

	sprint(data, "%s/data", devdir);
	fd = open(data, ORDWR);
	if(fd < 0)
		myfatal("open %s: %r", data);
	close(cfd);
	return fd;
}
Exemplo n.º 2
0
void
dhcpsend(int type)
{
	int n;
	uint8_t *p;
	Bootp bp;
	Udphdr *up;

	memset(&bp, 0, sizeof bp);
	up = (Udphdr*)bp.udphdr;

	hnputs(up->rport, 67);
	bp.op = Bootrequest;
	hnputl(bp.xid, dhcp.xid);
	hnputs(bp.secs, time(0) - dhcp.starttime);
	hnputs(bp.flags, Fbroadcast);		/* reply must be broadcast */
	memmove(bp.optmagic, optmagic, 4);
	p = bp.optdata;
	p = optaddbyte(p, ODtype, type);
	p = optadd(p, ODclientid, dhcp.cid, strlen(dhcp.cid));
	switch(type) {
	default:
		myfatal("dhcpsend: unknown message type: %d", type);
	case Discover:
		ipmove(up->raddr, IPv4bcast);	/* broadcast */
		break;
	case Request:
		if(dhcp.state == Sbound || dhcp.state == Srenewing)
			ipmove(up->raddr, dhcp.server);
		else
			ipmove(up->raddr, IPv4bcast);	/* broadcast */
		p = optaddulong(p, ODlease, dhcp.lease);
		if(dhcp.state == Sselecting || dhcp.state == Srequesting) {
			p = optaddaddr(p, ODipaddr, dhcp.client);	/* mistake?? */
			p = optaddaddr(p, ODserverid, dhcp.server);
		} else
			v6tov4(bp.ciaddr, dhcp.client);
		break;
	case Release:
		ipmove(up->raddr, dhcp.server);
		v6tov4(bp.ciaddr, dhcp.client);
		p = optaddaddr(p, ODipaddr, dhcp.client);
		p = optaddaddr(p, ODserverid, dhcp.server);
		break;
	}

	*p++ = OBend;

	n = p - (uint8_t*)&bp;

	if(write(dhcp.fd, &bp, n) != n)
		myfatal("dhcpsend: write failed: %r");
}
Exemplo n.º 3
0
void
timerthread(void* v)
{
	for(;;) {
		sleep(1000);
		qlock(&dhcp.lk);
		if(--dhcp.timeout > 0) {
			qunlock(&dhcp.lk);
			continue;
		}

		switch(dhcp.state) {
		default:
			myfatal("timerthread: unknown state %d", dhcp.state);
		case Sinit:
			break;
		case Sselecting:
			dhcpsend(Discover);
			dhcp.timeout = 4;
			dhcp.resend++;
			if(dhcp.resend>5)
				myfatal("dhcp: giving up: selecting");
			break;
		case Srequesting:
			dhcpsend(Request);
			dhcp.timeout = 4;
			dhcp.resend++;
			if(dhcp.resend>5)
				myfatal("dhcp: giving up: requesting");
			break;
		case Srenewing:
			dhcpsend(Request);
			dhcp.timeout = 1;
			dhcp.resend++;
			if(dhcp.resend>3) {
				dhcp.state = Srebinding;
				dhcp.resend = 0;
			}
			break;
		case Srebinding:
			dhcpsend(Request);
			dhcp.timeout = 4;
			dhcp.resend++;
			if(dhcp.resend>5)
				myfatal("dhcp: giving up: rebinding");
			break;
		case Sbound:
			break;
		}
		qunlock(&dhcp.lk);
	}
}
Exemplo n.º 4
0
void *myrealloc(void *ptr, int size)
{
    assert(size >= 0 && ptr);
    void *p = realloc(ptr, size);
    if(!p) {
        myfatal("out of memory");
    }
    return p;
}
Exemplo n.º 5
0
void *mymalloc(int size)
{
    assert(size >= 0);
    void *p = malloc(size);
    if(!p) {
        myfatal("out of memory");
    }
    return p;
}
Exemplo n.º 6
0
uint32_t
thread(void(*f)(void*), void *a)
{
	int pid;

	pid = rfork(RFNOWAIT|RFMEM|RFPROC);
	if(pid < 0)
		myfatal("rfork failed: %r");
	if(pid != 0)
		return pid;
	(*f)(a);
	return 0;	/* never reaches here */
}
Exemplo n.º 7
0
void
dhcprecv(void)
{
	uint8_t buf[2000];
	Bootp *bp;
	int n, type;
	uint32_t lease;
	uint8_t mask[IPaddrlen];

	qunlock(&dhcp.lk);
	n = read(dhcp.fd, buf, sizeof(buf));
	qlock(&dhcp.lk);

	if(n <= 0)
		myfatal("dhcprecv: bad read: %r");

	bp = parse(buf, n);
	if(bp == 0)
		return;

if(1) {
fprint(2, "recved\n");
bootpdump(buf, n);
}

	type = optgetbyte(bp, ODtype);
	switch(type) {
	default:
		fprint(2, "dhcprecv: unknown type: %d\n", type);
		break;
	case Offer:
		if(dhcp.state != Sselecting)
			break;
		lease = optgetulong(bp, ODlease);
		if(lease == 0)
			myfatal("bad lease");
		if(!optgetaddr(bp, OBmask, mask))
			memset(mask, 0xff, sizeof(mask));
		v4tov6(dhcp.client, bp->yiaddr);
		if(!optgetaddr(bp, ODserverid, dhcp.server)) {
			fprint(2, "dhcprecv: Offer from server with invalid serverid\n");
			break;
		}

		dhcp.lease = lease;
		ipmove(dhcp.mask, mask);
		memmove(dhcp.sname, bp->sname, sizeof(dhcp.sname));
		dhcp.sname[sizeof(dhcp.sname)-1] = 0;

		dhcpsend(Request);
		dhcp.state = Srequesting;
		dhcp.resend = 0;
		dhcp.timeout = 4;
		break;
	case Ack:
		if(dhcp.state != Srequesting)
		if(dhcp.state != Srenewing)
		if(dhcp.state != Srebinding)
			break;
		lease = optgetulong(bp, ODlease);
		if(lease == 0)
			myfatal("bad lease");
		if(!optgetaddr(bp, OBmask, mask))
			memset(mask, 0xff, sizeof(mask));
		v4tov6(dhcp.client, bp->yiaddr);
		dhcp.lease = lease;
		ipmove(dhcp.mask, mask);
		dhcp.state = Sbound;
		break;
	case Nak:
		myfatal("recved nak");
		break;
	}

}