/* rcsid[] = "$Header: if_ether.h,v 820.1 86/12/04 19:51:19 root Exp $" */
/* sccsid[] = "%W% %Y% %Q% %G%" */
/*	if_ether.h	6.2	83/09/26	*/

/*
 * Structure of a 10Mb/s Ethernet header.
 */

struct ether_header
    {
    u_char destAddr[6];		/* Destination address */
    u_char sourceAddr[6];	/* Source address */
    u_short etherType;		/* Packet type */
    };

#define	ETHERTYPE_PUP		0x0200	/* PUP protocol */
#define	ETHERTYPE_NS		0x0600	/* XEROX NS protocol */
#define	ETHERTYPE_IP		0x0800	/* Darpa IP protocol */
#define ETHERTYPE_ARP		0x0806	/* Addr. resolution protocol */
#define ETHERTYPE_VALID		0x1600	/* VALID homogeneous network */
#define ETHERTYPE_DECnet	0x6003	/* DECnet routing */

#define	ETHERMIN	(64-18)		/* Minimum packet size (46) */
#define	ETHERMTU	(1518-18)	/* Maximum packet size (1500) */

/*
 * LOCAL NETWORK TRAILER PROTOCOL
 *
 * This protocol puts header information at the end of a local network
 * packet.  This is to keep from having to copy the packet data to make
 * room for header information on the transmitting end.  On the receiving
 * end, since the data starts at the beginning of the packet it doesn't
 * need to be shuffled down after the routing layer header has been
 * extracted.  The packet is just truncated after the header has been
 * processed.
 *
 * The Ethernet packet types from ETHERTYPE_TRAILER to ETHERTYPE_TRAILER +
 * NUM_TRAILER denote a trailer protocol packet.  Data in the
 * packet must be a multiple of 512 bytes.  The data length is encoded
 * in the packet type (i.e., type = (length/512) + ETHERTYPE_TRAILER).
 * The actual packet type is embedded in the trailing header along with
 * a length of the variable size header.
 *
 * NOTE: This implementation (see ec.c) of the trailer protocol does not
 * allow for packets of zero length (i.e., type = ETHERTYPE_TRAILER).  It is
 * also not clear how much this protocol really saves (it may actually
 * reduce net throughput) because of the way the packets are received and
 * transmitted from the controller.
 *
 * The following is the packet format for packet type ETHERTYPE_TRAILER+N :
 *
 *	.----------------+----------------.
 *	|				  |
 *	/         Data (N * 512)          /
 *	|				  |
 *	|----------------+----------------|
 *	|	 Real packet type	  |
 *	|----------------+----------------|
 *	|         Header Length           |
 *	|----------------+----------------|
 *	|                                 |
 *	/            Header               /
 *	|				  |
 *	`---------------------------------'
 */

#define	ETHERTYPE_TRAILER	0x1000		/* Base trailer packet type */
#define	NUM_TRAILER		16		/* Number of trailer types */

/*
 * Ethernet Address Resolution Protocol.
 *
 * See RFC 826 for protocol description.  Structure below is adapted
 * to resolving internet addresses.  Field names used correspond to 
 * RFC 826.
 */
struct	ether_arp {
	u_short	arp_hrd;	/* format of hardware address */
#define ARPHRD_ETHER 	1	/* ethernet hardware address */
	u_short	arp_pro;	/* format of proto. address (ETHERPUP_IPTYPE) */
	u_char	arp_hln;	/* length of hardware address (6) */
	u_char	arp_pln;	/* length of protocol address (4) */
	u_short	arp_op;
#define	ARPOP_REQUEST	1	/* request to resolve address */
#define	ARPOP_REPLY	2	/* response to previous request */
	u_char	arp_sha[6];	/* sender hardware address */
	u_char	arp_spa[4];	/* sender protocol address */
	u_char	arp_tha[6];	/* target hardware address */
	u_char	arp_tpa[4];	/* target protocol address */
};

/*
 * Structure shared between the ethernet driver modules and
 * the address resolution code.  For example, each ec_softc or il_softc
 * begins with this structure.
 */
struct	arpcom {
	struct 	ifnet ac_if;	/* network-visible interface */
	u_char	ac_enaddr[6];	/* ethernet hardware address */
	struct	arpcom *ac_ac;	/* link to next ether driver */
};

/*  A set of macros to pack and unpack shorts & longs into unsigned character
 *  arrays for machine independent transmission over the network.
 *
 *  machine:	shorts:		longs:
 *  --------	-------		------
 *  Vax:	<0> <1>		<0> <1> <2> <3>
 *  68000:	<1> <0>		<3> <2> <1> <0>
 *  Ethernet:	<1> <0>		<3> <2> <1> <0>
 *
 *  <0> = least significant byte
 *  <1> = most significant byte
 */

#define short2unpk(c,s) \
	*(u_char*)(c + 0) = (s >> 8) & 0xFF; \
	*(u_char*)(c + 1) = (s >> 0) & 0xFF;

#define long2unpk(c,l) \
	*(u_char*)(c + 0) = (l >> 24) & 0xFF; \
	*(u_char*)(c + 1) = (l >> 16) & 0xFF; \
	*(u_char*)(c + 2) = (l >>  8) & 0xFF; \
	*(u_char*)(c + 3) = (l >>  0) & 0xFF;

#define long2ea(c,l) \
	*(u_char*)(c + 0) = (l >> 16) & 0xFF; \
	*(u_char*)(c + 1) = (l >>  8) & 0xFF; \
	*(u_char*)(c + 2) = (l >>  0) & 0xFF;

#define unpk2short(c,s) \
	s = *(u_char*)(c+0)<<8 | *(u_char*)(c+1);

#define unpk2long(c,l) \
	l = *(u_char*)(c+0)<<24 | *(u_char*)(c+1)<<16 | \
	*(u_char*)(c+2)<<8 | *(u_char*)(c+3);

#define ea2long(c,l) \
	l = *(u_char*)(c+0)<<16 | *(u_char*)(c+1)<<8 | *(u_char*)(c+2);

#ifdef	KERNEL
u_char etherbroadcastaddr[6];			/* 6 bytes of 0xFF */
struct	in_addr arpmyaddr();
struct	arptab *arptnew();
#endif
