/* Stuff generic to all ARCnet controllers
 * Copyright 1990 Russ Nelson
 */
#ifdef MSDOS
#include "global.h"
#ifdef ARCNET
#include "mbuf.h"
#include "iface.h"
#include "arp.h"
#include "arcnet.h"

#if !defined(_lint)
static char rcsid[] OPTIONAL = "$Id: arcnet.c,v 1.6 1996/12/23 20:37:36 root Exp $";
#endif

uint8 ARC_bdcst[] = { 0 };

/* Convert ARCnet header in host form to network mbuf */
void
htonarc(
struct arc *arc,
struct mbuf **bpp
){
	uint8 *cp;

	(void) pushdown(*bpp,ARCLEN);

	cp = (*bpp)->data;

	memcpy(cp,arc->source,AADDR_LEN);
	cp += AADDR_LEN;
	memcpy(cp,arc->dest,AADDR_LEN);
	cp += AADDR_LEN;
	*cp++ = arc->type;
}
/* Extract ARCnet header */
int
ntoharc(arc,bpp)
struct arc *arc;
struct mbuf **bpp;
{
	(void) pullup(bpp,arc->source,AADDR_LEN);
	(void) pullup(bpp,arc->dest,AADDR_LEN);
	arc->type = uchar(PULLCHAR(bpp));
	return ARCLEN;
}

/* Format an ARCnet address into a printable ascii string */
char *
parc(out,addr)
char *out;
uint8 *addr;
{
	sprintf(out,"%02x", addr[0]);
	return  out;
}

/* Convert an ARCnet address from Hex/ASCII to binary */
int
garc(out,cp)
uint8 *out;
const char *cp;
{
	*out = (uint8) htoi(cp);
	return 0;
}
/* Send an IP datagram on ARCnet */
int
anet_send(
struct mbuf **bpp,	/* Buffer to send */
struct iface *iface,	/* Pointer to interface control block */
uint32 gateway,		/* IP address of next hop */
uint8 tos
){
	char *agate;

	agate = res_arp(iface,ARP_ARCNET,gateway,*bpp);
	if(agate != NULL)
		return (*iface->output)(iface,agate,iface->hwaddr,ARC_IP,*bpp);
	return 0;
}
/* Send a packet with ARCnet header */
int
anet_output(
struct iface *iface,	/* Pointer to interface control block */
uint8 *dest,		/* Destination ARCnet address */
uint8 *source,		/* Source ARCnet address */
uint type,		/* Type field */
struct mbuf **data	/* Data field */
){
	struct arc ap;

	memcpy(ap.dest,dest,AADDR_LEN);
	memcpy(ap.source,source,AADDR_LEN);
	ap.type = uchar(type);
	htonarc(&ap,data);
	return (*iface->raw)(iface,*data);
}
/* Process incoming ARCnet packets. Shared by all ARCnet drivers. */
void
aproc(
struct iface *iface,
struct mbuf *bp
){
	struct arc hdr;

	/* Remove ARCnet header and kick packet upstairs */
	(void) ntoharc(&hdr,&bp);
	switch(hdr.type){
	case ARC_ARP:
		arp_input(iface,bp);
		break;
	case ARC_IP:
		(void) ip_route(iface,bp,0);
		break;
	default:
		free_p(bp);
		break;
	}
}

#endif		/* ARCNET */
#endif		/* MSDOS */
