#include "pcdefs.h"
#include "shared.h"
#include "funcdef.h"

int memcmp(void const _far *, void const _far *, unsigned);

extern struct net_data shared;
int	ip_handle = 0;
int	arp_handle = 0;
static char iptype[2] = { 8, 0 };
static char arptype[2] = { 8, 6 };
static char pkt_label[9] = "PKT DRVR";

#define IC_ETHERNET	1
#define IC_SLIP		6
#define	IT_ANY		0xFFFF

#define set_rcv_mode(a,b)

static int locate_pkt_vector(int);

static int
locate_pkt_vector(vec)             /* search for the packet driver */
int	vec;
{
	u_char _far *vptr;
	int vector;

	if (vec == 0)
		vec = 0x60;
	else if (vec < 0x60 || vec > 0x7f)
		return 0;

	for (vector = vec; vector < 0x80; vector++) {
		vptr = *(u_char _far * _far *)(unsigned long)(vector << 2);
		if (!memcmp(vptr + 3, (u_char _far *)pkt_label, 8)) {
			patch_vec(vptr);
			return(vector);
		}
	}
	return 0;
}

/*
 *	pkopen()
 *	try and locate the packet driver,
 *	open ARP and IP handles.
 */
int
pkopen(ioaddr, address)
int	ioaddr;		/* packet int, or 0 */
unsigned	address;	/* address is packet class */
{
	int	i;

	if (ip_handle)
		return 0;	/* already open */

	if (locate_pkt_vector(ioaddr) == 0)
		return -1;

	if (driver_info(&shared.p))
		return -2;

	if (address && address != shared.p.packet_class)
		return -3;
	else
		address = shared.p.packet_class;

	if (shared.p.packet_class != IC_ETHERNET &&
	    shared.p.packet_class != IC_SLIP)
		return -4;

	shared.slip_mode = address == IC_SLIP;

	ip_handle = access_type(address, IT_ANY, 0, (u_char _far *)iptype,
		shared.slip_mode ? 0 : sizeof(iptype), pkt_receiver);
	if (ip_handle < 0) {
		ip_handle = 0;
		return -5;
	}
	set_rcv_mode(ip_handle, 3);
	if (!shared.slip_mode) {
		arp_handle = access_type(address, IT_ANY, 0,
			(u_char _far *)arptype, sizeof(arptype), arp_receiver);
		if (arp_handle < 0) {
			(void) release_type(ip_handle);
			ip_handle = 0;
			arp_handle = 0;
			return -6;
		}
		set_rcv_mode(arp_handle, 3);
	}
	if ((i = get_address(ip_handle, shared.myether, 6)) < 0) {
		(void) release_type(ip_handle);
		(void) release_type(arp_handle);
		ip_handle = 0;
		arp_handle = 0;
		return -7;
	}
	mbinit();
	arpinit();
	return 0;
}

void
pkclose()                     /* throw away our handles */
{

	if (!shared.slip_mode) {
		set_rcv_mode(arp_handle, 1);
		(void) release_type(arp_handle);
		arp_handle = 0;
	}
	set_rcv_mode(ip_handle, 1);
	(void) release_type(ip_handle);
	ip_handle = 0;
}
