#include "pcdefs.h"
#include "mbuf.h"
#include "protocol.h"
#include "data.h"
#include "config.h"
#include "funcdef.h"

/*
 *	mbinit()
 */
void near
mbinit()
{
	int	i;
	struct mbuf near *mp;
	struct ebuf near *ep;
#ifdef notdef
	u_char	buf[7];
#endif

	mbfree = NNULL;
	mbprocess = NNULL;
	mbnext = (struct mbuf near *)&mbprocess;
	mp = (struct mbuf near *)&mb[0];
	for (i = 0; i < NMBUFS; i++) {
		mp->next = mbfree;
		mbfree = mp++;
	}
#ifdef notdef
	buf[4] = '\r';
	buf[5] = '\n';
	buf[6] = 0;
	mp = mbfree;
	while (mp) {
		buf[0] = (((u_int)mp >> 12) & 0x0f) + 0x30;
		if (buf[0] > '9')
			buf[0] += 7;
		buf[1] = (((u_int)mp >> 8) & 0x0f) + 0x30;
		if (buf[1] > '9')
			buf[1] += 7;
		buf[2] = (((u_int)mp >> 4) & 0x0f) + 0x30;
		if (buf[2] > '9')
			buf[2] += 7;
		buf[3] = ((u_int)mp & 0x0f) + 0x30;
		if (buf[3] > '9')
			buf[3] += 7;
		dfputs(buf);
		mp = mp->next;
	}
#endif
	ep = (struct ebuf near *)&eb[0];
	ep->start_addr = &etherbuff[0];
	ep->count = RAWETHER;
/*
	ep++;
	(void) memset((u_char near *)ep, 0,
	    (NEBUFS - 1) * sizeof(struct ebuf));
*/
}

/*
*   for each new type of protocol, put an initialization call here.
*   There may be some requirement of order of initialization.
*/
void near
protinit()
{
	u_int	i;

	/* ethernet */
	(void) memcpy((u_char near *)blankd.dest, (u_char near *)etherall,
	    DADDLEN);
	(void) memcpy((u_char near *)blankd.me, (u_char near *)myether,
	    DADDLEN);	/* always from me */
	blankd.type = EIP;			/* mostly IP packets */

	/* arp */
	(void) memcpy((u_char near *)&arp.d, (u_char near *)&blankd, sizeof(struct ether));
	arp.d.type = EARP;		/* 0x0806 is ARP type */
	arp.hrd = htons(HTYPE);		/*  Ether = 1, swabbed  */
	arp.pro = htons(ARPPRO);	/* IP protocol = 0x0800, swabbed */
	arp.hln = DADDLEN;		/* Ethernet hardware length */
	arp.pln = 4;			/* IP length = 4 */
	arp.spa = Scon.myip;	/* sender's IP addr */
	(void) memcpy((u_char near *)arp.sha, (u_char near *)myether,
	    DADDLEN); /* sender's hardware addr */
	(void) memcpy((u_char near *)arp.tha, (u_char near *)etherall,
	    DADDLEN); /* target hardware addr */

#ifdef notdef
/*
*  initialize the ARP cache to 0 time, none are gateways to start
*/
should be already zeroed
	for (i = 0; i < NPORTS; i++) {
		arpc[i].tm = 0L;
		arpc[i].gate = 0;
	}
#endif

	/* ip */
/*
*  create a mask which can determine whether a machine is on the same wire
*  or not.  RFC950
*  Only set the mask if not previously set.
*  This mask may be replaced by a higher level request to set the subnet mask.
*/
	(void) memcpy((u_char near *)&blankip.d, (u_char near *)&blankd,
	    sizeof(struct ether));
	/* smallest header, version 4 */
	blankip.i.versionandhdrlen = 0x40 | sizeof(struct iph) >> 2;
	blankip.i.service = 0;			/* normal service */
	blankip.i.tlen = htons(576);		/* no data yet, maximum size */
	blankip.i.ident = 0;
	blankip.i.frags = 0;		/* not a fragment of a packet */
	blankip.i.ttl = 100;		/* 100 seconds should be enough */
	blankip.i.protocol = PROTUDP;	/* default to UDP */
	blankip.i.check = 0;		/* disable checksums for now */
	/* my return address */
	blankip.i.ipsource = Scon.myip;
	if (!Scon.flags) {
		if (Scon.snetmask)
		    nmask = Scon.snetmask;
		else
		    switch ((u_char)Scon.myip >> 6) {
			case 0:			/* class A */
			case 1:
			    nmask = 0x000000ffL;
			    break;
			case 2:			/* class B */
			    nmask = 0x0000ffffL;
			    break;
			case 3:			/* class C */
			    nmask = 0x00ffffffL;
		    }
		ipall = Scon.myip | ~Scon.snetmask;
	}
	blankip.i.ipdest = ipall;
	(void) memcpy((u_char near *)&ipout, (u_char near *)&blankip,
	    sizeof(struct ether) + sizeof(struct iph));

	/* portlist */
	for (i = 0; i < NPORTS; i++)
		portlist[i] = FNULL;		/* no ports open yet */
}
