/* ARP header conversion routines
 * Copyright 1991 Phil Karn, KA9Q
 */
#include "global.h"
#include "mbuf.h"
#include "arp.h"

#if !defined(_lint)
static char rcsid[] OPTIONAL = "$Id: arphdr.c,v 1.8 1996/08/29 12:11:16 root Exp $";
#endif


/* Copy a host format arp structure into mbuf for transmission */
struct mbuf *
htonarp (arp)
register struct arp *arp;
{
struct mbuf *bp;
unsigned char *buf;

	if (arp == (struct arp *) NULL)
		return NULLBUF;

	if ((bp = alloc_mbuf (ARPLEN + 2 * uchar (arp->hwalen))) == NULLBUF)
		return NULLBUF;

	buf = bp->data;

	buf = put16 (buf, arp->hardware);
	buf = put16 (buf, arp->protocol);
	*buf++ = uchar(arp->hwalen);
	*buf++ = uchar(arp->pralen);
	buf = put16 (buf, arp->opcode);
	memcpy (buf, arp->shwaddr, (size_t) uchar (arp->hwalen));
	buf += arp->hwalen;
	buf = put32 (buf, arp->sprotaddr);
	memcpy (buf, arp->thwaddr, (size_t) uchar (arp->hwalen));
	buf += arp->hwalen;
	buf = put32 (buf, arp->tprotaddr);

	bp->cnt = (int16) ((unsigned char *) buf - bp->data);
	return bp;
}


/* Convert an incoming ARP packet into a host-format structure */
int
ntoharp (arp, bpp)
register struct arp *arp;
struct mbuf **bpp;
{
	if (arp == (struct arp *) NULL || bpp == NULLBUFP)
		return -1;

	arp->hardware = pull16 (bpp);
	arp->protocol = pull16 (bpp);
	arp->hwalen = (char) PULLCHAR (bpp);
	arp->pralen = (char) PULLCHAR (bpp);
	if (uchar (arp->hwalen) > MAXHWALEN || uchar (arp->pralen) != IPALEN)
		return -1;	/* n5knx: bad packet */
	arp->opcode = pull16 (bpp);
	(void) pullup (bpp, (unsigned char *) arp->shwaddr, (int16) uchar (arp->hwalen));
	arp->sprotaddr = pull32 (bpp);
	(void) pullup (bpp, (unsigned char *) arp->thwaddr, (int16) uchar (arp->hwalen));
	arp->tprotaddr = pull32 (bpp);

	/* Get rid of anything left over */
	if (bpp) {
		free_p (*bpp);
		*bpp = NULLBUF;
	}
	return 0;
}
