Esempio n. 1
0
/*
 * Send a packet and wait for a reply, with exponential backoff.
 *
 * The send routine must return the actual number of bytes written,
 * or -1 on error.
 *
 * The receive routine can indicate success by returning the number of
 * bytes read; it can return 0 to indicate EOF; it can return -1 with a
 * non-zero errno to indicate failure; finally, it can return -1 with a
 * zero errno to indicate it isn't done yet.
 */
ssize_t
sendrecv(struct iodesc *d,
	ssize_t (*sproc)(struct iodesc *, void *, size_t),
	void *sbuf, size_t ssize,
	ssize_t (*rproc)(struct iodesc *, void *, size_t, time_t),
	void *rbuf, size_t rsize)
{
	ssize_t cc;
	time_t t, tmo, tlast;
	long tleft;

#ifdef NET_DEBUG
	if (debug)
		printf("sendrecv: called\n");
#endif

	tmo = MINTMO;
	tlast = 0;
	tleft = 0;
	t = getsecs();
	for (;;) {
		if (tleft <= 0) {
			if (tmo >= MAXTMO) {
				errno = ETIMEDOUT;
				return -1;
			}
			cc = (*sproc)(d, sbuf, ssize);
			if (cc != -1 && cc < ssize)
				panic("sendrecv: short write! (%zd < %zd)",
				    cc, ssize);

			tleft = tmo;
			tmo += MINTMO;
			if (tmo > MAXTMO)
				tmo = MAXTMO;

			if (cc == -1) {
				/* Error on transmit; wait before retrying */
				while ((getsecs() - t) < tmo)
					;
				tleft = 0;
				continue;
			}

			tlast = t;
		}

		/* Try to get a packet and process it. */
		cc = (*rproc)(d, rbuf, rsize, tleft);
		/* Return on data, EOF or real error. */
		if (cc != -1 || errno != 0)
			return (cc);

		/* Timed out or didn't get the packet we're waiting for */
		t = getsecs();
		tleft -= t - tlast;
		tlast = t;
	}
}
Esempio n. 2
0
File: time.c Progetto: MarginC/kame
u_int
sleep(u_int i)
{
	register time_t t;

	/* loop for that number of seconds, polling BIOS,
	   so that it may handle interrupts */
	for (t = getsecs() + i; getsecs() < t; cnischar());

	return 0;
}
Esempio n. 3
0
int
le_get(struct iodesc *desc, void *pkt, size_t len, saseconds_t timeout)
{
	satime_t t;
	int cc;

	t = getsecs();
	do {
		cc = le_poll(desc, pkt, len);
	} while (cc == 0 && (getsecs() - t) < timeout);
	return cc;
}
Esempio n. 4
0
int
le_get(struct iodesc *desc, void *pkt, size_t len, saseconds_t timeout)
{
	satime_t t;
	int cc;

	t = getsecs();
	cc = 0;
	while (((getsecs() - t) < timeout) && !cc) {
		cc = le_poll(desc, pkt, len);
	}
	return cc;
}
Esempio n. 5
0
static int
ofwn_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout)
{
	time_t	t;
	int	length;

#if defined(NETIF_DEBUG)
	printf("netif_get: pkt=%p, maxlen=%d, timeout=%d\n", pkt, len,
	    timeout);
#endif

	t = getsecs();
	do {
		length = OF_read(netinstance, pkt, len);
	} while ((length == -2 || length == 0) &&
		(getsecs() - t < timeout));

#if defined(NETIF_DEBUG)
	printf("netif_get: received length=%d (%x)\n", length, length);
#endif

	if (length < 12)
		return -1;

#if defined(NETIF_VERBOSE_DEBUG)
	{
		char *ch = pkt;
		int i;

		for(i = 0; i < 96; i += 4) {
			printf("%02x%02x%02x%02x  ", ch[i], ch[i+1],
			    ch[i+2], ch[i+3]);
		}
		printf("\n");
	}
#endif

#if defined(NETIF_DEBUG)
	{
		struct ether_header *eh = pkt;

		printf("dst: %s ", ether_sprintf(eh->ether_dhost));
		printf("src: %s ", ether_sprintf(eh->ether_shost));
		printf("type: 0x%x\n", eh->ether_type & 0xffff);
	}
#endif

	return length;
}
Esempio n. 6
0
int
cfenet_get(struct iodesc *desc, void *pkt, size_t len, saseconds_t timeout)
{
    satime_t t;
    int cc;

    t = getsecs();
    cc = 0;
    while (((getsecs() - t) < timeout) && !cc) {
        cc = cfe_read(booted_dev_fd,pkt,len);
        if (cc < 0) break;
        break;
    }

    return cc;
}
Esempio n. 7
0
void
mii_dealan(struct local *l, unsigned timo)
{
	unsigned val, bound;

	val = (1U << 13) | (1U << 7) | 0x1f /* advertise all caps */;
	CSR_WRITE_4(l, P1CR4, val);
	bound = getsecs() + timo;
	do {
		val = CSR_READ_4(l, P1SR);
		if (val & (1U << 5)) /* link is found up */
			break;
		DELAY(10 * 1000);
	} while (getsecs() < bound);
	return;
}
Esempio n. 8
0
time_t
time(time_t *tloc)
{
    int secs = getsecs();
    if (tloc)
	*tloc = secs;
    return secs;
}
Esempio n. 9
0
static int
Xtime(void)
{
	time_t tt = getsecs();

	if (cmd.argc == 1)
		printf(ctime(&tt));

	return 0;
}
Esempio n. 10
0
/*
 * Given a pointer into a time zone string, extract a rule in the form
 * date[/time]. See POSIX section 8 for the format of "date" and "time".
 * If a valid rule is not found, return NULL.
 * Otherwise, return a pointer to the first character not part of the rule.
 */
static const char *
getrule(const char *strp, struct rule * rulep)
{
	if (*strp == 'J')
	{
		/*
		 * Julian day.
		 */
		rulep->r_type = JULIAN_DAY;
		++strp;
		strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
	}
	else if (*strp == 'M')
	{
		/*
		 * Month, week, day.
		 */
		rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
		++strp;
		strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
		if (strp == NULL)
			return NULL;
		if (*strp++ != '.')
			return NULL;
		strp = getnum(strp, &rulep->r_week, 1, 5);
		if (strp == NULL)
			return NULL;
		if (*strp++ != '.')
			return NULL;
		strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
	}
	else if (is_digit(*strp))
	{
		/*
		 * Day of year.
		 */
		rulep->r_type = DAY_OF_YEAR;
		strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
	}
	else
		return NULL;			/* invalid format */
	if (strp == NULL)
		return NULL;
	if (*strp == '/')
	{
		/*
		 * Time specified.
		 */
		++strp;
		strp = getsecs(strp, &rulep->r_time);
	}
	else
		rulep->r_time = 2 * SECSPERHOUR;		/* default = 2:00:00 */
	return strp;
}
Esempio n. 11
0
time_t
time(time_t *tloc)
{
	time_t rv;
	
	rv = getsecs();
	if (tloc != NULL)
		*tloc = rv;

	return (rv);
}
Esempio n. 12
0
/*
 * Receive a packet, including the ether header.
 * Return the total length received (or -1 on error).
 */
ssize_t
netif_get(struct iodesc *desc, void *pkt, size_t maxlen, time_t timo)
{
	struct romdev *pd;
	int tick0;
	ssize_t len;

	pd = (struct romdev *)desc->io_netif;

#ifdef NETIF_DEBUG
	if (netif_debug)
		printf("netif_get: pkt=0x%x, maxlen=%d, tmo=%d\n",
			   pkt, maxlen, timo);
#endif

	tick0 = getsecs();

	do {
		len = apcall_read(pd->fd, pkt, maxlen);
	} while ((len == 0) && ((getsecs() - tick0) < timo));

#ifdef NETIF_DEBUG
	if (netif_debug)
		printf("netif_get: received len=%d\n", len);
#endif

	if (len < 12)
		return -1;

#ifdef NETIF_DEBUG
	if (netif_debug) {
		struct ether_header *eh = pkt;

		printf("dst: %s ", ether_sprintf(eh->ether_dhost));
		printf("src: %s ", ether_sprintf(eh->ether_shost));
		printf("type: 0x%x\n", eh->ether_type & 0xFFFF);
	}
#endif

	return len;
}
Esempio n. 13
0
void
mii_dealan(struct local *l, unsigned timo)
{
	unsigned anar, bound;

	anar = ANAR_TX_FD | ANAR_TX | ANAR_10_FD | ANAR_10 | ANAR_CSMA;
	mii_write(l, l->phy, MII_ANAR, anar);
	mii_write(l, l->phy, MII_BMCR, BMCR_AUTOEN | BMCR_STARTNEG);
	l->anlpar = 0;
	bound = getsecs() + timo;
	do {
		l->bmsr = mii_read(l, l->phy, MII_BMSR) |
		   mii_read(l, l->phy, MII_BMSR); /* read twice */
		if ((l->bmsr & BMSR_LINK) && (l->bmsr & BMSR_ACOMP)) {
			l->anlpar = mii_read(l, l->phy, MII_ANLPAR);
			break;
		}
		DELAY(10 * 1000);
	} while (getsecs() < bound);
	return;
}
Esempio n. 14
0
/* Fetch required bootp information */
void
bootp(int sock)
{
	struct iodesc *d;
	struct bootp *bp;
	struct {
		u_char header[HEADER_SIZE];
		struct bootp wbootp;
	} wbuf;
	struct {
		u_char header[HEADER_SIZE];
		struct bootp rbootp;
	} rbuf;

#ifdef BOOTP_DEBUG
	if (debug)
		printf("bootp: socket=%d\n", sock);
#endif
	if (!bot)
		bot = getsecs();

	if (!(d = socktodesc(sock))) {
		printf("bootp: bad socket. %d\n", sock);
		return;
	}
#ifdef BOOTP_DEBUG
	if (debug)
		printf("bootp: d=%x\n", (u_int)d);
#endif

	bp = &wbuf.wbootp;
	bzero(bp, sizeof(*bp));

	bp->bp_op = BOOTREQUEST;
	bp->bp_htype = HTYPE_ETHERNET;	/* 10Mb Ethernet (48 bits) */
	bp->bp_hlen = 6;
	bp->bp_xid = htonl(d->xid);
	MACPY(d->myea, bp->bp_chaddr);
	bzero(bp->bp_file, sizeof(bp->bp_file));
	bcopy(vm_rfc1048, bp->bp_vend, sizeof(vm_rfc1048));

	d->myip = myip;
	d->myport = htons(IPPORT_BOOTPC);
	d->destip.s_addr = INADDR_BROADCAST;
	d->destport = htons(IPPORT_BOOTPS);

	(void)sendrecv(d,
	    bootpsend, bp, sizeof(*bp),
	    bootprecv, &rbuf.rbootp, sizeof(rbuf.rbootp));

	/* Bump xid so next request will be unique. */
	++d->xid;
}
Esempio n. 15
0
static int
net_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout)
{
	struct netif *nif = desc->io_netif;
	struct uboot_softc *sc = nif->nif_devdata;
	time_t t;
	int err, rlen;

#if defined(NETIF_DEBUG)
	printf("net_get: pkt %p, len %d, timeout %d\n", pkt, len, timeout);
#endif
	t = getsecs();
	do {
		err = ub_dev_recv(sc->sc_handle, sc->sc_rxbuf, len, &rlen);

		if (err != 0) {
			printf("net_get: ub_dev_recv() failed, error=%d\n",
			    err);
			rlen = 0;
			break;
		}
	} while ((rlen == -1 || rlen == 0) && (getsecs() - t < timeout));

#if defined(NETIF_DEBUG)
	printf("net_get: received len %d (%x)\n", rlen, rlen);
#endif

	if (rlen > 0) {
		memcpy(pkt, sc->sc_rxbuf, MIN(len, rlen));
		if (rlen != len) {
#if defined(NETIF_DEBUG)
			printf("net_get: len %x, rlen %x\n", len, rlen);
#endif
		}
		return (rlen);
	}

	return (-1);
}
Esempio n. 16
0
static int
cs_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout)
{
	time_t		t;
	int		rlen;
	int		i;
	u_int16_t	*p;

	t = getsecs();
	rlen = 0;
	while (getsecs() - t < timeout && rlen == 0) {
		if (!(CS_READ_PACKET_PAGE(PKTPG_RX_EVENT) & RX_EVENT_RX_OK))
			continue;

		/* drop status */
		CS_READ_2(PORT_RXTX_DATA);

		/* get frame length */
		rlen = CS_READ_2(PORT_RXTX_DATA);

		if (rlen > len) {
			CS_WRITE_PACKET_PAGE(PKTPG_RX_CFG, RX_CFG_SKIP);
			rlen = 0;
			continue;
		}

		p = pkt;
		for (i = rlen >> 1; i > 0; i--)
			*p++ = CS_READ_2(PORT_RXTX_DATA);
		if (rlen & 1)
			*((u_int8_t *) p + 1) = CS_READ_1(PORT_RXTX_DATA);

		/* exit while loop */
	}

	return rlen;
}
Esempio n. 17
0
static ssize_t
efinet_get(struct iodesc *desc, void **pkt, time_t timeout)
{
	struct netif *nif = desc->io_netif;
	EFI_SIMPLE_NETWORK *net;
	EFI_STATUS status;
	UINTN bufsz;
	time_t t;
	char *buf, *ptr;
	ssize_t ret = -1;

	net = nif->nif_devdata;
	if (net == NULL)
		return (ret);

	bufsz = net->Mode->MaxPacketSize + ETHER_HDR_LEN + ETHER_CRC_LEN;
	buf = malloc(bufsz + ETHER_ALIGN);
	if (buf == NULL)
		return (ret);
	ptr = buf + ETHER_ALIGN;

	t = getsecs();
	while ((getsecs() - t) < timeout) {
		status = net->Receive(net, NULL, &bufsz, ptr, NULL, NULL, NULL);
		if (status == EFI_SUCCESS) {
			*pkt = buf;
			ret = (ssize_t)bufsz;
			break;
		}
		if (status != EFI_NOT_READY)
			break;
	}

	if (ret == -1)
		free(buf);
	return (ret);
}
Esempio n. 18
0
static const char *getoffset(register const char *strp, long *const offsetp)
{
	register int neg = 0;

	if (*strp == '-') {
		neg = 1;
		++strp;
	} else if (*strp == '+')
		++strp;
	strp = getsecs(strp, offsetp);
	if (strp == NULL)
		return NULL;			/* illegal time */
	if (neg)
		*offsetp = -*offsetp;
	return strp;
}
Esempio n. 19
0
/* send request, expect first block (or error) */
int
tftp_makereq(struct tftp_handle *h)
{
	struct {
		u_char header[HEADER_SIZE];
		struct tftphdr  t;
		u_char space[FNAME_SIZE + 6];
	} wbuf;
	char           *wtail;
	int             l;
	ssize_t         res;
	struct tftphdr *t;

	bzero(&wbuf, sizeof(wbuf));

	wbuf.t.th_opcode = htons((u_short) RRQ);
	wtail = wbuf.t.th_stuff;
	l = strlen(h->path);
	bcopy(h->path, wtail, l + 1);
	wtail += l + 1;
	bcopy("octet", wtail, 6);
	wtail += 6;

	t = &h->lastdata.t;

	/* h->iodesc->myport = htons(--tftpport); */
	h->iodesc->myport = htons(tftpport + (getsecs() & 0x3ff));
	h->iodesc->destport = htons(IPPORT_TFTP);
	h->iodesc->xid = 1;	/* expected block */

	res = sendrecv(h->iodesc, sendudp, &wbuf.t, wtail - (char *) &wbuf.t,
	    recvtftp, t, sizeof(*t) + RSPACE);

	if (res == -1)
		return errno;

	h->currblock = 1;
	h->validsize = res;
	h->islastblock = 0;
	if (res < SEGSIZE)
		h->islastblock = 1;	/* very short file */
	return 0;
}
Esempio n. 20
0
/* Transmit a bootp request */
static ssize_t
bootpsend(struct iodesc *d, void *pkt, size_t len)
{
	struct bootp *bp;

#ifdef BOOTP_DEBUG
	if (debug)
		printf("bootpsend: d=%lx called.\n", (long)d);
#endif

	bp = pkt;
	bp->bp_secs = htons((u_short)(getsecs() - bot));

#ifdef BOOTP_DEBUG
	if (debug)
		printf("bootpsend: calling sendudp\n");
#endif

	return (sendudp(d, pkt, len));
}
Esempio n. 21
0
File: tgets.c Progetto: MarginC/kame
int
tgets(char *buf)
{
	int c, i;
	char *p, *lp = buf;
	time_t seconds1, seconds2;

	seconds1 = getsecs();
	for (i = 10; i > 0; ) {
		c = tgetchar() & 0177;
		if (c) {
			for (;;) {
				switch (c) {
				case '\n':
				case '\r':
					*lp = '\0';
					putchar('\n');
					return (1);

				case '\b':
				case '\177':
					if (lp > buf) {
						lp--;
						putchar('\b');
						putchar(' ');
						putchar('\b');
					}
					break;

				case '#':
					if (lp > buf)
						--lp;
					break;

				case 'r'&037:
					putchar('\n');
					for (p = buf; p < lp; ++p)
						putchar(*p);
					break;

				case '@':
				case 'u'&037:
				case 'w'&037:
					lp = buf;
					putchar('\n');
					break;

				default:
					*lp++ = c;
					putchar(c);
				}
				c = getchar() & 0177;
			}
		}
		if ((seconds2 = getsecs()) != seconds1) {
			seconds1 = seconds2;
			i--;
		}
	}
	return (0);
}
Esempio n. 22
0
/* send request, expect first block (or error) */
static int
tftp_makereq(struct tftp_handle *h)
{
	struct {
		u_char header[HEADER_SIZE];
		struct tftphdr  t;
		u_char space[FNAME_SIZE + 6];
	} __packed __aligned(4) wbuf;
	char           *wtail;
	int             l;
	ssize_t         res;
	struct tftphdr *t;
	char *tftp_blksize = NULL;
	int blksize_l;
	unsigned short rtype = 0;

	/*
	 * Allow overriding default TFTP block size by setting
	 * a tftp.blksize environment variable.
	 */
	if ((tftp_blksize = getenv("tftp.blksize")) != NULL) {
		tftp_set_blksize(h, tftp_blksize);
	}

	wbuf.t.th_opcode = htons((u_short) RRQ);
	wtail = wbuf.t.th_stuff;
	l = strlen(h->path);
#ifdef TFTP_PREPEND_PATH
	if (l > FNAME_SIZE - (sizeof(TFTP_PREPEND_PATH) - 1))
		return (ENAMETOOLONG);
	bcopy(TFTP_PREPEND_PATH, wtail, sizeof(TFTP_PREPEND_PATH) - 1);
	wtail += sizeof(TFTP_PREPEND_PATH) - 1;
#else
	if (l > FNAME_SIZE)
		return (ENAMETOOLONG);
#endif
	bcopy(h->path, wtail, l + 1);
	wtail += l + 1;
	bcopy("octet", wtail, 6);
	wtail += 6;
	bcopy("blksize", wtail, 8);
	wtail += 8;
	blksize_l = sprintf(wtail, "%d", h->tftp_blksize);
	wtail += blksize_l + 1;
	bcopy("tsize", wtail, 6);
	wtail += 6;
	bcopy("0", wtail, 2);
	wtail += 2;

	t = &h->lastdata.t;

	/* h->iodesc->myport = htons(--tftpport); */
	h->iodesc->myport = htons(tftpport + (getsecs() & 0x3ff));
	h->iodesc->destport = htons(IPPORT_TFTP);
	h->iodesc->xid = 1;	/* expected block */

	h->currblock = 0;
	h->islastblock = 0;
	h->validsize = 0;

	res = sendrecv_tftp(h, &sendudp, &wbuf.t, wtail - (char *) &wbuf.t,
		       &recvtftp, t, sizeof(*t) + h->tftp_blksize, &rtype);

	if (rtype == OACK)
		return (tftp_getnextblock(h));

	/* Server ignored our blksize request, revert to TFTP default. */
	h->tftp_blksize = SEGSIZE;

	switch (rtype) {
		case DATA: {
			h->currblock = 1;
			h->validsize = res;
			h->islastblock = 0;
			if (res < h->tftp_blksize) {
				h->islastblock = 1;	/* very short file */
				tftp_sendack(h);
			}
			return (0);
		}
		case ERROR:
		default:
			return (errno);
	}

}
Esempio n. 23
0
/* Fetch required bootp infomation */
void
bootp(int sock, int flag)
{
	struct iodesc *d;
	struct bootp *bp;
	struct {
		u_char header[HEADER_SIZE];
		struct bootp wbootp;
	} wbuf;
	struct {
		u_char header[HEADER_SIZE];
		struct bootp rbootp;
	} rbuf;

#ifdef BOOTP_DEBUG
 	if (debug)
		printf("bootp: socket=%d\n", sock);
#endif
	if (!bot)
		bot = getsecs();
	
	if (!(d = socktodesc(sock))) {
		printf("bootp: bad socket. %d\n", sock);
		return;
	}
#ifdef BOOTP_DEBUG
 	if (debug)
		printf("bootp: d=%lx\n", (long)d);
#endif

	bp = &wbuf.wbootp;
	bzero(bp, sizeof(*bp));

	bp->bp_op = BOOTREQUEST;
	bp->bp_htype = 1;		/* 10Mb Ethernet (48 bits) */
	bp->bp_hlen = 6;
	bp->bp_xid = htonl(d->xid);
	MACPY(d->myea, bp->bp_chaddr);
	strncpy(bp->bp_file, bootfile, sizeof(bp->bp_file));
	bcopy(vm_rfc1048, bp->bp_vend, sizeof(vm_rfc1048));
#ifdef SUPPORT_DHCP
	bp->bp_vend[4] = TAG_DHCP_MSGTYPE;
	bp->bp_vend[5] = 1;
	bp->bp_vend[6] = DHCPDISCOVER;

	/*
	 * If we are booting from PXE, we want to send the string
	 * 'PXEClient' to the DHCP server so you have the option of
	 * only responding to PXE aware dhcp requests.
	 */
	if (flag & BOOTP_PXE) {
		bp->bp_vend[7] = TAG_CLASSID;
		bp->bp_vend[8] = 9;
		bcopy("PXEClient", &bp->bp_vend[9], 9);
		bp->bp_vend[18] = TAG_PARAM_REQ;
		bp->bp_vend[19] = 7;
		bp->bp_vend[20] = TAG_ROOTPATH;
		bp->bp_vend[21] = TAG_HOSTNAME;
		bp->bp_vend[22] = TAG_SWAPSERVER;
		bp->bp_vend[23] = TAG_GATEWAY;
		bp->bp_vend[24] = TAG_SUBNET_MASK;
		bp->bp_vend[25] = TAG_INTF_MTU;
		bp->bp_vend[26] = TAG_SERVERID;
		bp->bp_vend[27] = TAG_END;
	} else
		bp->bp_vend[7] = TAG_END;
#else
	bp->bp_vend[4] = TAG_END;
#endif

	d->myip.s_addr = INADDR_ANY;
	d->myport = htons(IPPORT_BOOTPC);
	d->destip.s_addr = INADDR_BROADCAST;
	d->destport = htons(IPPORT_BOOTPS);

#ifdef SUPPORT_DHCP
	expected_dhcpmsgtype = DHCPOFFER;
	dhcp_ok = 0;
#endif

	if(sendrecv(d,
		    bootpsend, bp, sizeof(*bp),
		    bootprecv, &rbuf.rbootp, sizeof(rbuf.rbootp))
	   == -1) {
	    printf("bootp: no reply\n");
	    return;
	}

#ifdef SUPPORT_DHCP
	if(dhcp_ok) {
		u_int32_t leasetime;
		bp->bp_vend[6] = DHCPREQUEST;
		bp->bp_vend[7] = TAG_REQ_ADDR;
		bp->bp_vend[8] = 4;
		bcopy(&rbuf.rbootp.bp_yiaddr, &bp->bp_vend[9], 4);
		bp->bp_vend[13] = TAG_SERVERID;
		bp->bp_vend[14] = 4;
		bcopy(&dhcp_serverip.s_addr, &bp->bp_vend[15], 4);
		bp->bp_vend[19] = TAG_LEASETIME;
		bp->bp_vend[20] = 4;
		leasetime = htonl(300);
		bcopy(&leasetime, &bp->bp_vend[21], 4);
		if (flag & BOOTP_PXE) {
			bp->bp_vend[25] = TAG_CLASSID;
			bp->bp_vend[26] = 9;
			bcopy("PXEClient", &bp->bp_vend[27], 9);
			bp->bp_vend[36] = TAG_END;
		} else
			bp->bp_vend[25] = TAG_END;

		expected_dhcpmsgtype = DHCPACK;

		if(sendrecv(d,
			    bootpsend, bp, sizeof(*bp),
			    bootprecv, &rbuf.rbootp, sizeof(rbuf.rbootp))
		   == -1) {
			printf("DHCPREQUEST failed\n");
			return;
		}
	}
#endif

	myip = d->myip = rbuf.rbootp.bp_yiaddr;
	servip = rbuf.rbootp.bp_siaddr;
	if(rootip.s_addr == INADDR_ANY) rootip = servip;
	bcopy(rbuf.rbootp.bp_file, bootfile, sizeof(bootfile));
	bootfile[sizeof(bootfile) - 1] = '\0';

	if (!netmask) {
		if (IN_CLASSA(ntohl(myip.s_addr)))
			netmask = htonl(IN_CLASSA_NET);
		else if (IN_CLASSB(ntohl(myip.s_addr)))
			netmask = htonl(IN_CLASSB_NET);
		else
			netmask = htonl(IN_CLASSC_NET);
#ifdef BOOTP_DEBUG
		if (debug)
			printf("'native netmask' is %s\n", intoa(netmask));
#endif
	}

#ifdef BOOTP_DEBUG
	if (debug)
		printf("mask: %s\n", intoa(netmask));
#endif

	/* We need a gateway if root is on a different net */
	if (!SAMENET(myip, rootip, netmask)) {
#ifdef BOOTP_DEBUG
		if (debug)
			printf("need gateway for root ip\n");
#endif
	}

	/* Toss gateway if on a different net */
	if (!SAMENET(myip, gateip, netmask)) {
#ifdef BOOTP_DEBUG
		if (debug)
			printf("gateway ip (%s) bad\n", inet_ntoa(gateip));
#endif
		gateip.s_addr = 0;
	}

	/* Bump xid so next request will be unique. */
	++d->xid;
}
Esempio n. 24
0
/* Fetch required bootp infomation */
void
bootp(int sock)
{
	void *pkt;
	struct iodesc *d;
	struct bootp *bp;
	struct {
		uchar_t header[HEADER_SIZE];
		struct bootp wbootp;
	} wbuf;
	struct bootp *rbootp;

#ifdef BOOTP_DEBUG
	if (debug)
		printf("bootp: socket=%d\n", sock);
#endif
	if (!bot)
		bot = getsecs();

	if (!(d = socktodesc(sock))) {
		printf("bootp: bad socket. %d\n", sock);
		return;
	}
#ifdef BOOTP_DEBUG
	if (debug)
		printf("bootp: d=%lx\n", (long)d);
#endif

	bp = &wbuf.wbootp;
	bzero(bp, sizeof (*bp));

	bp->bp_op = BOOTREQUEST;
	bp->bp_htype = 1;		/* 10Mb Ethernet (48 bits) */
	bp->bp_hlen = 6;
	bp->bp_xid = htonl(d->xid);
	MACPY(d->myea, bp->bp_chaddr);
	strncpy(bp->bp_file, bootfile, sizeof (bp->bp_file));
	bcopy(vm_rfc1048, bp->bp_vend, sizeof (vm_rfc1048));
#ifdef SUPPORT_DHCP
	bp->bp_vend[4] = TAG_DHCP_MSGTYPE;
	bp->bp_vend[5] = 1;
	bp->bp_vend[6] = DHCPDISCOVER;
	bootp_fill_request(&bp->bp_vend[7]);
#else
	bp->bp_vend[4] = TAG_END;
#endif

	d->myip.s_addr = INADDR_ANY;
	d->myport = htons(IPPORT_BOOTPC);
	d->destip.s_addr = INADDR_BROADCAST;
	d->destport = htons(IPPORT_BOOTPS);

#ifdef SUPPORT_DHCP
	expected_dhcpmsgtype = DHCPOFFER;
	dhcp_ok = 0;
#endif

	if (sendrecv(d, bootpsend, bp, sizeof (*bp),
	    bootprecv, &pkt, (void **)&rbootp, NULL) == -1) {
		printf("bootp: no reply\n");
		return;
	}

#ifdef SUPPORT_DHCP
	if (dhcp_ok) {
		uint32_t leasetime;
		bp->bp_vend[6] = DHCPREQUEST;
		bp->bp_vend[7] = TAG_REQ_ADDR;
		bp->bp_vend[8] = 4;
		bcopy(&rbootp->bp_yiaddr, &bp->bp_vend[9], 4);
		bp->bp_vend[13] = TAG_SERVERID;
		bp->bp_vend[14] = 4;
		bcopy(&dhcp_serverip.s_addr, &bp->bp_vend[15], 4);
		bp->bp_vend[19] = TAG_LEASETIME;
		bp->bp_vend[20] = 4;
		leasetime = htonl(300);
		bcopy(&leasetime, &bp->bp_vend[21], 4);
		bootp_fill_request(&bp->bp_vend[25]);

		expected_dhcpmsgtype = DHCPACK;

		free(pkt);
		if (sendrecv(d, bootpsend, bp, sizeof (*bp),
		    bootprecv, &pkt, (void **)&rbootp, NULL) == -1) {
			printf("DHCPREQUEST failed\n");
			return;
		}
	}
#endif

	myip = d->myip = rbootp->bp_yiaddr;
	servip = rbootp->bp_siaddr;
	if (rootip.s_addr == INADDR_ANY)
		rootip = servip;
	bcopy(rbootp->bp_file, bootfile, sizeof (bootfile));
	bootfile[sizeof (bootfile) - 1] = '\0';

	if (!netmask) {
		if (IN_CLASSA(ntohl(myip.s_addr)))
			netmask = htonl(IN_CLASSA_NET);
		else if (IN_CLASSB(ntohl(myip.s_addr)))
			netmask = htonl(IN_CLASSB_NET);
		else
			netmask = htonl(IN_CLASSC_NET);
#ifdef BOOTP_DEBUG
		if (debug)
			printf("'native netmask' is %s\n", intoa(netmask));
#endif
	}

#ifdef BOOTP_DEBUG
	if (debug)
		printf("mask: %s\n", intoa(netmask));
#endif

	/* We need a gateway if root is on a different net */
	if (!SAMENET(myip, rootip, netmask)) {
#ifdef BOOTP_DEBUG
		if (debug)
			printf("need gateway for root ip\n");
#endif
	}

	/* Toss gateway if on a different net */
	if (!SAMENET(myip, gateip, netmask)) {
#ifdef BOOTP_DEBUG
		if (debug)
			printf("gateway ip (%s) bad\n", inet_ntoa(gateip));
#endif
		gateip.s_addr = 0;
	}

	/* Bump xid so next request will be unique. */
	++d->xid;
	free(pkt);
}
Esempio n. 25
0
/* Fetch required bootp information */
void
bootp(int sock)
{
	struct iodesc *d;
	struct bootp *bp;
	struct {
		u_char header[UDP_TOTAL_HEADER_SIZE];
		struct bootp wbootp;
	} wbuf;
	struct {
		u_char header[UDP_TOTAL_HEADER_SIZE];
		struct bootp rbootp;
	} rbuf;
	unsigned int index;

#ifdef BOOTP_DEBUG
 	if (debug)
		printf("bootp: socket=%d\n", sock);
#endif
	if (!bot)
		bot = getsecs();

	if (!(d = socktodesc(sock))) {
		printf("bootp: bad socket. %d\n", sock);
		return;
	}
#ifdef BOOTP_DEBUG
 	if (debug)
		printf("bootp: d=%lx\n", (long)d);
#endif

	bp = &wbuf.wbootp;
	(void)memset(bp, 0, sizeof(*bp));

	bp->bp_op = BOOTREQUEST;
	bp->bp_htype = 1;		/* 10Mb Ethernet (48 bits) */
	bp->bp_hlen = 6;
	bp->bp_xid = htonl(d->xid);
	MACPY(d->myea, bp->bp_chaddr);
	(void)strncpy((char *)bp->bp_file, bootfile, sizeof(bp->bp_file));
	(void)memcpy(bp->bp_vend, vm_rfc1048, sizeof(vm_rfc1048));
	index = 4;
#ifdef SUPPORT_DHCP
	bp->bp_vend[index++] = TAG_DHCP_MSGTYPE;
	bp->bp_vend[index++] = 1;
	bp->bp_vend[index++] = DHCPDISCOVER;
#endif
	bootp_addvend(&bp->bp_vend[index]);

	d->myip.s_addr = INADDR_ANY;
	d->myport = htons(IPPORT_BOOTPC);
	d->destip.s_addr = INADDR_BROADCAST;
	d->destport = htons(IPPORT_BOOTPS);

#ifdef SUPPORT_DHCP
	expected_dhcpmsgtype = DHCPOFFER;
	dhcp_ok = 0;
#endif

	if (sendrecv(d,
		    bootpsend, bp, sizeof(*bp),
		    bootprecv, &rbuf.rbootp, sizeof(rbuf.rbootp))
	   == -1) {
		printf("bootp: no reply\n");
		return;
	}

#ifdef SUPPORT_DHCP
	if (dhcp_ok) {
		u_int32_t leasetime;
		index = 6;
		bp->bp_vend[index++] = DHCPREQUEST;
		bp->bp_vend[index++] = TAG_REQ_ADDR;
		bp->bp_vend[index++] = 4;
		(void)memcpy(&bp->bp_vend[9], &rbuf.rbootp.bp_yiaddr, 4);
		index += 4;
		bp->bp_vend[index++] = TAG_SERVERID;
		bp->bp_vend[index++] = 4;
		(void)memcpy(&bp->bp_vend[index], &dhcp_serverip.s_addr, 4);
		index += 4;
		bp->bp_vend[index++] = TAG_LEASETIME;
		bp->bp_vend[index++] = 4;
		leasetime = htonl(300);
		(void)memcpy(&bp->bp_vend[index], &leasetime, 4);
		index += 4;
		bootp_addvend(&bp->bp_vend[index]);

		expected_dhcpmsgtype = DHCPACK;

		if (sendrecv(d,
			    bootpsend, bp, sizeof(*bp),
			    bootprecv, &rbuf.rbootp, sizeof(rbuf.rbootp))
		   == -1) {
			printf("DHCPREQUEST failed\n");
			return;
		}
	}
#endif

	myip = d->myip = rbuf.rbootp.bp_yiaddr;
	servip = rbuf.rbootp.bp_siaddr;
	if (rootip.s_addr == INADDR_ANY)
		rootip = servip;
	(void)memcpy(bootfile, rbuf.rbootp.bp_file, sizeof(bootfile));
	bootfile[sizeof(bootfile) - 1] = '\0';

	if (IN_CLASSA(myip.s_addr))
		nmask = IN_CLASSA_NET;
	else if (IN_CLASSB(myip.s_addr))
		nmask = IN_CLASSB_NET;
	else
		nmask = IN_CLASSC_NET;
#ifdef BOOTP_DEBUG
	if (debug)
		printf("'native netmask' is %s\n", intoa(nmask));
#endif

	/* Get subnet (or natural net) mask */
	netmask = nmask;
	if (smask)
		netmask = smask;
#ifdef BOOTP_DEBUG
	if (debug)
		printf("mask: %s\n", intoa(netmask));
#endif

	/* We need a gateway if root is on a different net */
	if (!SAMENET(myip, rootip, netmask)) {
#ifdef BOOTP_DEBUG
		if (debug)
			printf("need gateway for root ip\n");
#endif
	}

	/* Toss gateway if on a different net */
	if (!SAMENET(myip, gateip, netmask)) {
#ifdef BOOTP_DEBUG
		if (debug)
			printf("gateway ip (%s) bad\n", inet_ntoa(gateip));
#endif
		gateip.s_addr = 0;
	}

#ifdef BOOTP_DEBUG
	if (debug) {
		printf("client addr: %s\n", inet_ntoa(myip));
		if (smask)
			printf("subnet mask: %s\n", intoa(smask));
		if (gateip.s_addr != 0)
			printf("net gateway: %s\n", inet_ntoa(gateip));
		printf("server addr: %s\n", inet_ntoa(rootip));
		if (rootpath[0] != '\0')
			printf("server path: %s\n", rootpath);
		if (bootfile[0] != '\0')
			printf("file name: %s\n", bootfile);
	}
#endif

	/* Bump xid so next request will be unique. */
	++d->xid;
}
Esempio n. 26
0
static int
readline(char *buf, size_t n, int to)
{
#ifdef DEBUG
	extern int debug;
#endif
	char *p = buf, ch;

	/* Only do timeout if greater than 0 */
	if (to > 0) {
		u_long i = 0;
		time_t tt = getsecs() + to;
#ifdef DEBUG
		if (debug > 2)
			printf ("readline: timeout(%d) at %u\n", to, tt);
#endif
		/* check for timeout expiration less often
		   (for some very constrained archs) */
		while (!cnischar())
			if (!(i++ % 1000) && (getsecs() >= tt))
				break;

		if (!cnischar()) {
			strlcpy(buf, "boot", 5);
			putchar('\n');
			return strlen(buf);
		}
	} else
		while (!cnischar())
			;

	/* User has typed something.  Turn off timeouts. */
	cmd.timeout = 0;

	while (1) {
		switch ((ch = getchar())) {
		case CTRL('u'):
			while (p > buf) {
				putchar('\177');
				p--;
			}
			continue;
		case '\n':
		case '\r':
			p[1] = *p = '\0';
			break;
		case '\b':
		case '\177':
			if (p > buf) {
				putchar('\177');
				p--;
			}
			continue;
		default:
			if (p - buf < n-1)
				*p++ = ch;
			else {
				putchar('\007');
				putchar('\177');
			}
			continue;
		}
		break;
	}

	return p - buf;
}