xref: /csrg-svn/sys/netiso/if_eon.c (revision 42321)
136382Ssklower /***********************************************************
236382Ssklower 		Copyright IBM Corporation 1987
336382Ssklower 
436382Ssklower                       All Rights Reserved
536382Ssklower 
636382Ssklower Permission to use, copy, modify, and distribute this software and its
736382Ssklower documentation for any purpose and without fee is hereby granted,
836382Ssklower provided that the above copyright notice appear in all copies and that
936382Ssklower both that copyright notice and this permission notice appear in
1036382Ssklower supporting documentation, and that the name of IBM not be
1136382Ssklower used in advertising or publicity pertaining to distribution of the
1236382Ssklower software without specific, written prior permission.
1336382Ssklower 
1436382Ssklower IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
1536382Ssklower ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
1636382Ssklower IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
1736382Ssklower ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
1836382Ssklower WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
1936382Ssklower ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
2036382Ssklower SOFTWARE.
2136382Ssklower 
2236382Ssklower ******************************************************************/
2336382Ssklower 
2436382Ssklower /*
2536382Ssklower  * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
2636382Ssklower  */
2736382Ssklower /*
2836382Ssklower  * $Header: if_eon.c,v 1.4 88/07/19 15:53:59 hagens Exp $
2936382Ssklower  * $Source: /usr/argo/sys/netiso/RCS/if_eon.c,v $
30*42321Ssklower  *	@(#)if_eon.c	7.9 (Berkeley) 05/24/90 *
3136382Ssklower  *
3236382Ssklower  *	EON rfc
3336382Ssklower  *  Layer between IP and CLNL
3436382Ssklower  *
3536382Ssklower  * TODO:
3636382Ssklower  * Put together a current rfc986 address format and get the right offset
3736382Ssklower  * for the nsel
3836382Ssklower  */
3936382Ssklower 
4036382Ssklower #ifndef lint
4136382Ssklower static char *rcsid = "$Header: if_eon.c,v 1.4 88/07/19 15:53:59 hagens Exp $";
4236382Ssklower #endif lint
4336382Ssklower 
4437469Ssklower #ifdef EON
4537469Ssklower #define NEON 1
4636382Ssklower 
4737469Ssklower 
4836382Ssklower #include "param.h"
4936382Ssklower #include "systm.h"
5036382Ssklower #include "types.h"
5136382Ssklower #include "mbuf.h"
5236382Ssklower #include "buf.h"
5336382Ssklower #include "protosw.h"
5436382Ssklower #include "socket.h"
5536382Ssklower #include "ioctl.h"
5636382Ssklower #include "errno.h"
5736382Ssklower #include "types.h"
5836382Ssklower 
5936382Ssklower #include "../net/if.h"
6039195Ssklower #include "../net/if_types.h"
6140778Ssklower #include "../net/if_dl.h"
6236382Ssklower #include "../net/netisr.h"
6336382Ssklower #include "../net/route.h"
6437518Smckusick #include "machine/mtpr.h"
6536382Ssklower 
6636382Ssklower #include "../netinet/in.h"
6736382Ssklower #include "../netinet/in_systm.h"
6840778Ssklower #include "../netinet/in_var.h"
6936382Ssklower #include "../netinet/ip.h"
7036382Ssklower #include "../netinet/ip_var.h"
7136382Ssklower #include "../netinet/if_ether.h"
7236382Ssklower 
7337469Ssklower #include "iso.h"
7437469Ssklower #include "iso_var.h"
7537469Ssklower #include "iso_snpac.h"
7637469Ssklower extern struct snpa_cache all_es, all_is;
7737469Ssklower #include "argo_debug.h"
7837469Ssklower #include "iso_errno.h"
7937469Ssklower #include "eonvar.h"
8039195Ssklower extern struct timeval time;
8136382Ssklower 
8236382Ssklower #define EOK 0
8336382Ssklower 
8436382Ssklower int						eoninput();
8536382Ssklower int						eonoutput();
8636382Ssklower int						eonioctl();
8736382Ssklower int						eonattach();
8836382Ssklower int						eoninit();
8940778Ssklower int						eonrtrequest();
9036382Ssklower extern 	int				ip_output();
9140778Ssklower struct ifnet			eonif[1];
9236382Ssklower 
9337469Ssklower eonprotoinit() {
9440778Ssklower 	(void) eonattach();
9537469Ssklower }
9640778Ssklower 
9740778Ssklower struct eon_llinfo eon_llinfo;
9837469Ssklower #define PROBE_OK 0;
9936382Ssklower 
10037469Ssklower 
10136382Ssklower /*
10236382Ssklower  * FUNCTION:		eonattach
10336382Ssklower  *
10436382Ssklower  * PURPOSE:			autoconf attach routine
10536382Ssklower  *
10636382Ssklower  * RETURNS:			void
10736382Ssklower  */
10836382Ssklower 
10940778Ssklower eonattach()
11036382Ssklower {
11140778Ssklower 	register struct ifnet *ifp = eonif;
11236382Ssklower 
11336382Ssklower 	IFDEBUG(D_EON)
11436382Ssklower 		printf("eonattach()\n");
11536382Ssklower 	ENDDEBUG
11640778Ssklower 	ifp->if_unit = 0;
11736382Ssklower 	ifp->if_name = "eon";
11836382Ssklower 	ifp->if_mtu = ETHERMTU;
11936382Ssklower 		/* since everything will go out over ether or token ring */
12036382Ssklower 
12136382Ssklower 	ifp->if_init = eoninit;
12237469Ssklower 	ifp->if_ioctl = eonioctl;
12336382Ssklower 	ifp->if_output = eonoutput;
12437469Ssklower 	ifp->if_type = IFT_EON;
12537469Ssklower 	ifp->if_addrlen = 5;
12637469Ssklower 	ifp->if_hdrlen = EONIPLEN;
12736382Ssklower 	ifp->if_flags = IFF_BROADCAST;
12836382Ssklower 	if_attach(ifp);
12940778Ssklower 	eonioctl(ifp, SIOCSIFADDR, (caddr_t)ifp->if_addrlist);
13040778Ssklower 	eon_llinfo.el_qhdr.link =
13140778Ssklower 		eon_llinfo.el_qhdr.rlink = &(eon_llinfo.el_qhdr);
13236382Ssklower 
13336382Ssklower 	IFDEBUG(D_EON)
13436382Ssklower 		printf("eonattach()\n");
13536382Ssklower 	ENDDEBUG
13636382Ssklower }
13736382Ssklower 
13836382Ssklower 
13936382Ssklower /*
14036382Ssklower  * FUNCTION:		eonioctl
14136382Ssklower  *
14236382Ssklower  * PURPOSE:			io controls - ifconfig
14336382Ssklower  *				need commands to
14436382Ssklower  *					link-UP (core addr) (flags: ES, IS)
14536382Ssklower  *					link-DOWN (core addr) (flags: ES, IS)
14636382Ssklower  *				must be callable from kernel or user
14736382Ssklower  *
14836382Ssklower  * RETURNS:			nothing
14936382Ssklower  */
15036382Ssklower eonioctl(ifp, cmd, data)
15136382Ssklower 	register struct ifnet *ifp;
15240778Ssklower 	int cmd;
15336382Ssklower 	register caddr_t data;
15436382Ssklower {
15540778Ssklower 	int s = splimp();
15636382Ssklower 	register int error = 0;
15736382Ssklower 
15836382Ssklower 	IFDEBUG(D_EON)
15936382Ssklower 		printf("eonioctl (cmd 0x%x) \n", cmd);
16036382Ssklower 	ENDDEBUG
16136382Ssklower 
16240778Ssklower 	switch (cmd) {
16340778Ssklower 		register struct ifaddr *ifa;
16441393Ssklower 		extern link_rtrequest();
16536382Ssklower 
16636382Ssklower 	case SIOCSIFADDR:
16740778Ssklower 		if (ifa = (struct ifaddr *)data) {
16840778Ssklower 			ifp->if_flags |= IFF_UP;
16941393Ssklower 			if (ifa->ifa_addr->sa_family != AF_LINK)
17041393Ssklower 				ifa->ifa_rtrequest = eonrtrequest;
17140778Ssklower 			ifa->ifa_llinfolen = sizeof(struct eon_llinfo);
17241393Ssklower 		}
17336382Ssklower 		break;
17436382Ssklower 	}
17536382Ssklower 	splx(s);
17636382Ssklower 	return(error);
17736382Ssklower }
17836382Ssklower 
17940778Ssklower 
18040778Ssklower eoniphdr(hdr, loc, ro, class, zero)
18140778Ssklower struct route *ro;
18240778Ssklower register struct eon_iphdr *hdr;
18340778Ssklower caddr_t loc;
18440778Ssklower {
18540778Ssklower 	struct mbuf mhead;
18640778Ssklower 	register struct sockaddr_in *sin = (struct sockaddr_in *)&ro->ro_dst;
18740778Ssklower 	if (zero) {
18840778Ssklower 		bzero((caddr_t)hdr, sizeof (*hdr));
18940778Ssklower 		bzero((caddr_t)ro, sizeof (*ro));
19040778Ssklower 	}
19140778Ssklower 	sin->sin_family = AF_INET;
19240778Ssklower 	sin->sin_len = sizeof (*sin);
19340778Ssklower 	bcopy(loc, (caddr_t)&sin->sin_addr, sizeof(struct in_addr));
19440778Ssklower 	hdr->ei_ip.ip_dst = sin->sin_addr;
19540778Ssklower 	hdr->ei_ip.ip_p = IPPROTO_EON;
19640778Ssklower 	hdr->ei_ip.ip_ttl = MAXTTL;
19740778Ssklower 	hdr->ei_eh.eonh_class = class;
19840778Ssklower 	hdr->ei_eh.eonh_vers = EON_VERSION;
19940778Ssklower 	hdr->ei_eh.eonh_csum = 0;
20040778Ssklower 	mhead.m_data = (caddr_t) &hdr->ei_eh;
20140778Ssklower 	mhead.m_len = sizeof(struct eon_hdr);
20240778Ssklower 	mhead.m_next = 0;
20340778Ssklower 	IFDEBUG(D_EON)
20440778Ssklower 		printf("eonoutput : gen csum (0x%x, offset %d, datalen %d)\n",
20540778Ssklower 			&mhead,
20640778Ssklower 			_offsetof(struct eon_hdr, eonh_csum), sizeof(struct eon_hdr));
20740778Ssklower 	ENDDEBUG
20840778Ssklower 	iso_gen_csum(&mhead,
20940778Ssklower 		_offsetof(struct eon_hdr, eonh_csum), sizeof(struct eon_hdr));
21040778Ssklower }
21136382Ssklower /*
21240778Ssklower  * FUNCTION:		eonrtrequest
21336382Ssklower  *
21440778Ssklower  * PURPOSE:			maintains list of direct eon recipients.
21540778Ssklower  *					sets up IP route for rest.
21636382Ssklower  *
21736382Ssklower  * RETURNS:			nothing
21836382Ssklower  */
21940778Ssklower eonrtrequest(cmd, rt, gate)
22040778Ssklower register struct rtentry *rt;
221*42321Ssklower register struct sockaddr *gate;
22240778Ssklower {
223*42321Ssklower 	unsigned long zerodst = 0;
224*42321Ssklower 	caddr_t	ipaddrloc = (caddr_t) &zerodst;
22540778Ssklower 	register struct eon_llinfo *el = (struct eon_llinfo *)rt->rt_llinfo;
22636382Ssklower 
22740778Ssklower 	if (el == 0)
22840778Ssklower 		panic("eonrtrequest");
22940778Ssklower 	/*
23040778Ssklower 	 * Common Housekeeping
23140778Ssklower 	 */
23240778Ssklower 	switch (cmd) {
23340778Ssklower 
23440778Ssklower 	case RTM_ADD:
23540778Ssklower 		insque(&(el->el_qhdr), &eon_llinfo.el_qhdr);
23640778Ssklower 		el->el_rt = rt;
23740778Ssklower 		break;
23840778Ssklower 
23940778Ssklower 	case RTM_DELETE:
24040778Ssklower 		remque(&(el->el_qhdr));
24140778Ssklower 		/* FALLTHROUGH */
24240778Ssklower 	case RTM_CHANGE:
24340778Ssklower 		el->el_flags &= ~RTF_UP;
244*42321Ssklower 		el->el_snpaoffset = 0;
245*42321Ssklower 		if (el->el_iproute.ro_rt)
246*42321Ssklower 			RTFREE(el->el_iproute.ro_rt);
24740778Ssklower 		if (cmd = RTM_DELETE)
24840778Ssklower 			return;
24940778Ssklower 	}
25040778Ssklower 	if (gate || (gate = rt->rt_gateway)) switch (gate->sa_family) {
25140778Ssklower 		case AF_LINK:
252*42321Ssklower #define SDL(x) ((struct sockaddr_dl *)x)
253*42321Ssklower 			if (SDL(gate)->sdl_alen = 1)
254*42321Ssklower 				el->el_snpaoffset = *(u_char *)LLADDR(SDL(gate));
255*42321Ssklower 			else
256*42321Ssklower 				ipaddrloc = LLADDR(SDL(gate));
25740778Ssklower 			break;
25840778Ssklower 		case AF_INET:
259*42321Ssklower #define SIN(x) ((struct sockaddr_in *)x)
260*42321Ssklower 			ipaddrloc = (caddr_t) &SIN(gate)->sin_addr;
26140778Ssklower 			break;
26240778Ssklower 		default:
26340778Ssklower 			return;
26440778Ssklower 	}
26540778Ssklower 	el->el_flags |= RTF_UP;
26641926Ssklower 	eoniphdr(&el->el_ei, ipaddrloc, &el->el_iproute, EON_NORMAL_ADDR, 0);
26736382Ssklower }
26836382Ssklower 
26936382Ssklower /*
27040778Ssklower  * FUNCTION:		eoninit
27136382Ssklower  *
27240778Ssklower  * PURPOSE:			initialization
27336382Ssklower  *
27436382Ssklower  * RETURNS:			nothing
27536382Ssklower  */
27636382Ssklower 
27740778Ssklower eoninit(unit)
27840778Ssklower 	int unit;
27936382Ssklower {
28040778Ssklower 	printf("eon driver-init eon%d\n", unit);
28136382Ssklower }
28236382Ssklower 
28336382Ssklower 
28436382Ssklower /*
28536382Ssklower  * FUNCTION:		eonoutput
28636382Ssklower  *
28736382Ssklower  * PURPOSE:			prepend an eon header and hand to IP
28836382Ssklower  * ARGUMENTS:	 	(ifp) is points to the ifnet structure for this unit/device
28936382Ssklower  *					(m)  is an mbuf *, *m is a CLNL packet
29036382Ssklower  *					(dst) is a destination address - have to interp. as
29136382Ssklower  *					multicast or broadcast or real address.
29236382Ssklower  *
29336382Ssklower  * RETURNS:			unix error code
29436382Ssklower  *
29536382Ssklower  * NOTES:
29636382Ssklower  *
29736382Ssklower  */
29840778Ssklower eonoutput(ifp, m, dst, rt)
29937469Ssklower 	struct ifnet 	*ifp;
30040778Ssklower 	register struct mbuf	*m;		/* packet */
30136382Ssklower 	struct sockaddr_iso		*dst;		/* destination addr */
30240778Ssklower 	struct rtentry *rt;
30336382Ssklower {
30440778Ssklower 	register struct eon_llinfo *el;
30540778Ssklower 	register struct eon_iphdr *ei;
30640778Ssklower 	struct route *ro;
30740778Ssklower 	int	datalen;
30840778Ssklower 	struct mbuf *mh;
30940778Ssklower 	int	error = 0;
31040778Ssklower 	caddr_t ippaddrloc;
31140778Ssklower 	static struct eon_iphdr eon_iphdr;
31240778Ssklower 	static struct route route;
31336382Ssklower 
31436382Ssklower 	IFDEBUG(D_EON)
31536382Ssklower 		printf("eonoutput \n" );
31636382Ssklower 	ENDDEBUG
31736382Ssklower 
31839195Ssklower 	ifp->if_lastchange = time;
31939195Ssklower 	ifp->if_opackets++;
32040778Ssklower 	if (rt == 0 || (el = (struct eon_llinfo *)rt->rt_llinfo) == 0) {
32140778Ssklower 		if (dst->siso_family == AF_LINK) {
32240778Ssklower 			register struct sockaddr_dl *sdl = (struct sockaddr_dl *)dst;
32340778Ssklower 			caddr_t ipaddrloc = LLADDR(sdl);
32440778Ssklower 			int class = (sdl->sdl_alen == 5) ? 4[(u_char *)ipaddrloc] : 0;
32540778Ssklower 
32640778Ssklower 			if (sdl->sdl_alen == 4 || sdl->sdl_alen == 5) {
32740778Ssklower 				ro = &route;
32840778Ssklower 				ei = &eon_iphdr;
32940778Ssklower 				eoniphdr(ei, ipaddrloc, ro, class, 1);
33040778Ssklower 				goto send;
33140778Ssklower 			}
33240778Ssklower 		}
33340778Ssklower einval:
33437469Ssklower 		error =  EINVAL;
33537469Ssklower 		goto flush;
33637469Ssklower 	}
33740778Ssklower 	if ((el->el_flags & RTF_UP) == 0) {
33840778Ssklower 		eonrtrequest(RTM_CHANGE, rt, (struct sockaddr *)0);
33940778Ssklower 		if ((el->el_flags & RTF_UP) == 0) {
34040778Ssklower 			error = EHOSTUNREACH;
34140778Ssklower 			goto flush;
34240778Ssklower 		}
34340778Ssklower 	}
34440778Ssklower 	if ((m->m_flags & M_PKTHDR) == 0) {
34537469Ssklower 		printf("eon: got non headered packet\n");
34637469Ssklower 		goto einval;
34737469Ssklower 	}
34840778Ssklower 	ei = &el->el_ei;
34940778Ssklower 	ro = &el->el_iproute;
350*42321Ssklower 	if (el->el_snpaoffset) {
351*42321Ssklower 		if (dst->siso_family == AF_ISO) {
352*42321Ssklower 			bcopy((caddr_t) &dst->siso_data[el->el_snpaoffset],
353*42321Ssklower 					(caddr_t) &ei->ei_ip.ip_dst, sizeof(ei->ei_ip.ip_dst));
354*42321Ssklower 		} else
355*42321Ssklower 			goto einval;
356*42321Ssklower 	}
35740778Ssklower send:
35840778Ssklower 	/* put an eon_hdr in the buffer, prepended by an ip header */
35940778Ssklower 	datalen = m->m_pkthdr.len + EONIPLEN;
36037469Ssklower 	MGETHDR(mh, M_DONTWAIT, MT_HEADER);
36137469Ssklower 	if(mh == (struct mbuf *)0)
36240778Ssklower 		goto flush;
36340778Ssklower 	mh->m_next = m;
36440778Ssklower 	m = mh;
36540778Ssklower 	MH_ALIGN(m, sizeof(struct eon_iphdr));
36640778Ssklower 	m->m_len = sizeof(struct eon_iphdr);
36739195Ssklower 	ifp->if_obytes +=
36840778Ssklower 		(ei->ei_ip.ip_len = (u_short)(m->m_pkthdr.len = datalen));
36940778Ssklower 	*mtod(m, struct eon_iphdr *) = *ei;
37036382Ssklower 
37136382Ssklower 	IFDEBUG(D_EON)
37240778Ssklower 		printf("eonoutput dst ip addr : %x\n",  ei->ei_ip.ip_dst.s_addr);
37340778Ssklower 		printf("eonoutput ip_output : eonip header:\n");
37440778Ssklower 		dump_buf(ei, sizeof(struct eon_iphdr));
37536382Ssklower 	ENDDEBUG
37636382Ssklower 
37740778Ssklower 	error = ip_output(m, (struct mbuf *)0, ro, 0);
37840778Ssklower 	m = 0;
37939195Ssklower 	if (error) {
38039195Ssklower 		ifp->if_oerrors++;
38139195Ssklower 		ifp->if_opackets--;
38240778Ssklower 		ifp->if_obytes -= datalen;
38339195Ssklower 	}
38440778Ssklower flush:
38540778Ssklower 	if (m)
38640778Ssklower 		m_freem(m);
38736382Ssklower 	return error;
38836382Ssklower }
38936382Ssklower 
39037469Ssklower eoninput(m, iphlen)
39136382Ssklower 	register struct mbuf	*m;
39237469Ssklower 	int iphlen;
39336382Ssklower {
39436382Ssklower 	register struct eon_hdr	*eonhdr;
39536382Ssklower 	register struct ip		*iphdr;
39636382Ssklower 	struct ifnet 			*eonifp;
39737469Ssklower 	int						s;
39836382Ssklower 
39936382Ssklower 	eonifp = &eonif[0]; /* kludge - really want to give CLNP
40036382Ssklower 						* the ifp for eon, not for the real device
40136382Ssklower 						*/
40236382Ssklower 
40336382Ssklower 	IFDEBUG(D_EON)
40437469Ssklower 		printf("eoninput() 0x%x m_data 0x%x m_len 0x%x dequeued\n",
40537469Ssklower 			m, m?m->m_data:0, m?m->m_len:0);
40636382Ssklower 	ENDDEBUG
40736382Ssklower 
40837469Ssklower 	if (m == 0)
40937469Ssklower 		return;
41037469Ssklower 	if (iphlen > sizeof (struct ip))
41137469Ssklower 		ip_stripoptions(m, (struct mbuf *)0);
41237469Ssklower 	if (m->m_len < EONIPLEN) {
41337469Ssklower 		if ((m = m_pullup(m, EONIPLEN)) == 0) {
41437469Ssklower 			IncStat(es_badhdr);
41537469Ssklower drop:
41637469Ssklower 			IFDEBUG(D_EON)
41737469Ssklower 				printf("eoninput: DROP \n" );
41837469Ssklower 			ENDDEBUG
41937469Ssklower 			eonifp->if_ierrors ++;
42037469Ssklower 			m_freem(m);
42137469Ssklower 			return;
42237469Ssklower 		}
42336382Ssklower 	}
42439195Ssklower 	eonif->if_ibytes += m->m_pkthdr.len;
42539195Ssklower 	eonif->if_lastchange = time;
42636382Ssklower 	iphdr = mtod(m, struct ip *);
42736382Ssklower 	/* do a few checks for debugging */
42836382Ssklower 	if( iphdr->ip_p != IPPROTO_EON ) {
42936382Ssklower 		IncStat(es_badhdr);
43036382Ssklower 		goto drop;
43136382Ssklower 	}
43237469Ssklower 	/* temporarily drop ip header from the mbuf */
43337469Ssklower 	m->m_data += sizeof(struct ip);
43436382Ssklower 	eonhdr = mtod(m, struct eon_hdr *);
43537469Ssklower 	if( iso_check_csum( m, sizeof(struct eon_hdr) )   != EOK ) {
43637469Ssklower 		IncStat(es_badcsum);
43737469Ssklower 		goto drop;
43837469Ssklower 	}
43937469Ssklower 	m->m_data -= sizeof(struct ip);
44037469Ssklower 
44136382Ssklower 	IFDEBUG(D_EON)
44237469Ssklower 		printf("eoninput csum ok class 0x%x\n", eonhdr->eonh_class );
44336382Ssklower 		printf("eoninput: eon header:\n");
44436382Ssklower 		dump_buf(eonhdr, sizeof(struct eon_hdr));
44536382Ssklower 	ENDDEBUG
44636382Ssklower 
44736382Ssklower 	/* checks for debugging */
44836382Ssklower 	if( eonhdr->eonh_vers != EON_VERSION) {
44936382Ssklower 		IncStat(es_badhdr);
45036382Ssklower 		goto drop;
45136382Ssklower 	}
45237469Ssklower 	m->m_flags &= ~(M_BCAST|M_MCAST);
45336382Ssklower 	switch( eonhdr->eonh_class) {
45436382Ssklower 		case EON_BROADCAST:
45536382Ssklower 			IncStat(es_in_broad);
45637469Ssklower 			m->m_flags |= M_BCAST;
45736382Ssklower 			break;
45836382Ssklower 		case EON_NORMAL_ADDR:
45936382Ssklower 			IncStat(es_in_normal);
46036382Ssklower 			break;
46136382Ssklower 		case EON_MULTICAST_ES:
46236382Ssklower 			IncStat(es_in_multi_es);
46337469Ssklower 			m->m_flags |= M_MCAST;
46436382Ssklower 			break;
46536382Ssklower 		case EON_MULTICAST_IS:
46636382Ssklower 			IncStat(es_in_multi_is);
46737469Ssklower 			m->m_flags |= M_MCAST;
46836382Ssklower 			break;
46936382Ssklower 	}
47039195Ssklower 	eonifp->if_ipackets++;
47136382Ssklower 
47236382Ssklower 	{
47336382Ssklower 		/* put it on the CLNP queue and set soft interrupt */
47436382Ssklower 		struct ifqueue 			*ifq;
47536382Ssklower 		extern struct ifqueue 	clnlintrq;
47636382Ssklower 
47737469Ssklower 		m->m_pkthdr.rcvif = eonifp; /* KLUDGE */
47836382Ssklower 		IFDEBUG(D_EON)
47936382Ssklower 			printf("eoninput to clnl IFQ\n");
48036382Ssklower 		ENDDEBUG
48136382Ssklower 		ifq = &clnlintrq;
48237469Ssklower 		s = splimp();
48336382Ssklower 		if (IF_QFULL(ifq)) {
48436382Ssklower 			IF_DROP(ifq);
48536382Ssklower 			m_freem(m);
48639195Ssklower 			eonifp->if_iqdrops++;
48739195Ssklower 			eonifp->if_ipackets--;
48836382Ssklower 			splx(s);
48936382Ssklower 			return;
49036382Ssklower 		}
49136382Ssklower 		IF_ENQUEUE(ifq, m);
49236382Ssklower 		IFDEBUG(D_EON)
49336382Ssklower 			printf(
49437469Ssklower 	"0x%x enqueued on clnp Q: m_len 0x%x m_type 0x%x m_data 0x%x\n",
49537469Ssklower 				m, m->m_len, m->m_type, m->m_data);
49636382Ssklower 			dump_buf(mtod(m, caddr_t), m->m_len);
49736382Ssklower 		ENDDEBUG
49837469Ssklower 		schednetisr(NETISR_ISO);
49937469Ssklower 		splx(s);
50036382Ssklower 	}
50136382Ssklower }
50236382Ssklower 
50336382Ssklower int
50436382Ssklower eonctlinput(cmd, sin)
50536382Ssklower 	int cmd;
50636382Ssklower 	struct sockaddr_in *sin;
50736382Ssklower {
50836382Ssklower 	extern u_char inetctlerrmap[];
50936382Ssklower 
51036382Ssklower 	IFDEBUG(D_EON)
51136382Ssklower 		printf("eonctlinput: cmd 0x%x addr: ", cmd);
51236382Ssklower 		dump_isoaddr(sin);
51336382Ssklower 		printf("\n");
51436382Ssklower 	ENDDEBUG
51536382Ssklower 
51636382Ssklower 	if (cmd < 0 || cmd > PRC_NCMDS)
51736382Ssklower 		return 0;
51836382Ssklower 
51936382Ssklower 	IncStat(es_icmp[cmd]);
52036382Ssklower 	switch (cmd) {
52136382Ssklower 
52237469Ssklower 		case	PRC_QUENCH:
52336382Ssklower 		case	PRC_QUENCH2:
52436382Ssklower 			/* TODO: set the dec bit */
52536382Ssklower 			break;
52636382Ssklower 		case	PRC_TIMXCEED_REASS:
52736382Ssklower 		case	PRC_ROUTEDEAD:
52836382Ssklower 		case	PRC_HOSTUNREACH:
52936382Ssklower 		case	PRC_UNREACH_NET:
53036382Ssklower 		case	PRC_IFDOWN:
53136382Ssklower 		case	PRC_UNREACH_HOST:
53236382Ssklower 		case	PRC_HOSTDEAD:
53336382Ssklower 		case	PRC_TIMXCEED_INTRANS:
53436382Ssklower 			/* TODO: mark the link down */
53536382Ssklower 			break;
53636382Ssklower 
53736382Ssklower 		case	PRC_UNREACH_PROTOCOL:
53836382Ssklower 		case	PRC_UNREACH_PORT:
53936382Ssklower 		case	PRC_UNREACH_SRCFAIL:
54036382Ssklower 		case	PRC_REDIRECT_NET:
54136382Ssklower 		case	PRC_REDIRECT_HOST:
54236382Ssklower 		case	PRC_REDIRECT_TOSNET:
54336382Ssklower 		case	PRC_REDIRECT_TOSHOST:
54436382Ssklower 		case	PRC_MSGSIZE:
54536382Ssklower 		case	PRC_PARAMPROB:
54636382Ssklower 			printf("eonctlinput: ICMP cmd 0x%x\n", cmd );
54736382Ssklower 		break;
54836382Ssklower 	}
54936382Ssklower 	return 0;
55036382Ssklower }
55136382Ssklower 
55237469Ssklower #endif
553