xref: /csrg-svn/sys/netiso/if_eon.c (revision 40778)
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*40778Ssklower  *	@(#)if_eon.c	7.6 (Berkeley) 04/05/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"
61*40778Ssklower #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"
68*40778Ssklower #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();
89*40778Ssklower int						eonrtrequest();
9036382Ssklower extern 	int				ip_output();
91*40778Ssklower struct ifnet			eonif[1];
9236382Ssklower 
9337469Ssklower eonprotoinit() {
94*40778Ssklower 	(void) eonattach();
9537469Ssklower }
96*40778Ssklower 
97*40778Ssklower 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 
109*40778Ssklower eonattach()
11036382Ssklower {
111*40778Ssklower 	register struct ifnet *ifp = eonif;
11236382Ssklower 
11336382Ssklower 	IFDEBUG(D_EON)
11436382Ssklower 		printf("eonattach()\n");
11536382Ssklower 	ENDDEBUG
116*40778Ssklower 	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);
129*40778Ssklower 	eonioctl(ifp, SIOCSIFADDR, (caddr_t)ifp->if_addrlist);
130*40778Ssklower 	eon_llinfo.el_qhdr.link =
131*40778Ssklower 		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;
152*40778Ssklower 	int cmd;
15336382Ssklower 	register caddr_t data;
15436382Ssklower {
155*40778Ssklower 	int s = splimp();
15636382Ssklower 	register int error = 0;
15736382Ssklower 
15836382Ssklower 	IFDEBUG(D_EON)
15936382Ssklower 		printf("eonioctl (cmd 0x%x) \n", cmd);
16036382Ssklower 	ENDDEBUG
16136382Ssklower 
162*40778Ssklower 	switch (cmd) {
163*40778Ssklower 		register struct ifaddr *ifa;
16436382Ssklower 
16536382Ssklower 	case SIOCSIFADDR:
166*40778Ssklower 		if (ifa = (struct ifaddr *)data) {
167*40778Ssklower 			ifp->if_flags |= IFF_UP;
168*40778Ssklower 			ifa->ifa_rtrequest = eonrtrequest;
169*40778Ssklower 			ifa->ifa_llinfolen = sizeof(struct eon_llinfo);
170*40778Ssklower 	    }
17136382Ssklower 		break;
17236382Ssklower 	}
17336382Ssklower 	splx(s);
17436382Ssklower 	return(error);
17536382Ssklower }
17636382Ssklower 
177*40778Ssklower 
178*40778Ssklower eoniphdr(hdr, loc, ro, class, zero)
179*40778Ssklower struct route *ro;
180*40778Ssklower register struct eon_iphdr *hdr;
181*40778Ssklower caddr_t loc;
182*40778Ssklower {
183*40778Ssklower 	struct mbuf mhead;
184*40778Ssklower 	register struct sockaddr_in *sin = (struct sockaddr_in *)&ro->ro_dst;
185*40778Ssklower 	if (zero) {
186*40778Ssklower 		bzero((caddr_t)hdr, sizeof (*hdr));
187*40778Ssklower 		bzero((caddr_t)ro, sizeof (*ro));
188*40778Ssklower 	}
189*40778Ssklower 	sin->sin_family = AF_INET;
190*40778Ssklower 	sin->sin_len = sizeof (*sin);
191*40778Ssklower 	bcopy(loc, (caddr_t)&sin->sin_addr, sizeof(struct in_addr));
192*40778Ssklower 	hdr->ei_ip.ip_dst = sin->sin_addr;
193*40778Ssklower 	hdr->ei_ip.ip_p = IPPROTO_EON;
194*40778Ssklower 	hdr->ei_ip.ip_ttl = MAXTTL;
195*40778Ssklower 	hdr->ei_eh.eonh_class = class;
196*40778Ssklower 	hdr->ei_eh.eonh_vers = EON_VERSION;
197*40778Ssklower 	hdr->ei_eh.eonh_csum = 0;
198*40778Ssklower 	mhead.m_data = (caddr_t) &hdr->ei_eh;
199*40778Ssklower 	mhead.m_len = sizeof(struct eon_hdr);
200*40778Ssklower 	mhead.m_next = 0;
201*40778Ssklower 	IFDEBUG(D_EON)
202*40778Ssklower 		printf("eonoutput : gen csum (0x%x, offset %d, datalen %d)\n",
203*40778Ssklower 			&mhead,
204*40778Ssklower 			_offsetof(struct eon_hdr, eonh_csum), sizeof(struct eon_hdr));
205*40778Ssklower 	ENDDEBUG
206*40778Ssklower 	iso_gen_csum(&mhead,
207*40778Ssklower 		_offsetof(struct eon_hdr, eonh_csum), sizeof(struct eon_hdr));
208*40778Ssklower }
20936382Ssklower /*
210*40778Ssklower  * FUNCTION:		eonrtrequest
21136382Ssklower  *
212*40778Ssklower  * PURPOSE:			maintains list of direct eon recipients.
213*40778Ssklower  *					sets up IP route for rest.
21436382Ssklower  *
21536382Ssklower  * RETURNS:			nothing
21636382Ssklower  */
217*40778Ssklower eonrtrequest(cmd, rt, gate)
218*40778Ssklower register struct rtentry *rt;
219*40778Ssklower struct sockaddr *gate;
220*40778Ssklower {
221*40778Ssklower 	caddr_t	ipaddrloc = 0;
222*40778Ssklower 	register struct eon_llinfo *el = (struct eon_llinfo *)rt->rt_llinfo;
223*40778Ssklower 	register struct rtentry *iprt;
224*40778Ssklower 	register struct sockaddr_in sin;
22536382Ssklower 
226*40778Ssklower 	if (el == 0)
227*40778Ssklower 		panic("eonrtrequest");
228*40778Ssklower 	iprt = el->el_iproute.ro_rt;
229*40778Ssklower 	/*
230*40778Ssklower 	 * Common Housekeeping
231*40778Ssklower 	 */
232*40778Ssklower 	switch (cmd) {
233*40778Ssklower 
234*40778Ssklower 	case RTM_ADD:
235*40778Ssklower 		insque(&(el->el_qhdr), &eon_llinfo.el_qhdr);
236*40778Ssklower 		el->el_rt = rt;
237*40778Ssklower 		break;
238*40778Ssklower 
239*40778Ssklower 	case RTM_DELETE:
240*40778Ssklower 		remque(&(el->el_qhdr));
241*40778Ssklower 		/* FALLTHROUGH */
242*40778Ssklower 	case RTM_CHANGE:
243*40778Ssklower 		el->el_flags &= ~RTF_UP;
244*40778Ssklower 		if (iprt)
245*40778Ssklower 			RTFREE(iprt);
246*40778Ssklower 		if (cmd = RTM_DELETE)
247*40778Ssklower 			return;
248*40778Ssklower 	}
249*40778Ssklower 	if (gate || (gate = rt->rt_gateway)) switch (gate->sa_family) {
250*40778Ssklower 		case AF_LINK:
251*40778Ssklower 			ipaddrloc = LLADDR((struct sockaddr_dl *)gate);
252*40778Ssklower 			break;
253*40778Ssklower 		case AF_INET:
254*40778Ssklower 			ipaddrloc = (caddr_t) &((struct sockaddr_in *)gate)->sin_addr;
255*40778Ssklower 			break;
256*40778Ssklower 		default:
257*40778Ssklower 			return;
258*40778Ssklower 	}
259*40778Ssklower 	el->el_flags |= RTF_UP;
260*40778Ssklower 	eoniphdr(&el->el_ei, &el->el_iproute, ipaddrloc, EON_NORMAL_ADDR, 0);
26136382Ssklower }
26236382Ssklower 
26336382Ssklower /*
264*40778Ssklower  * FUNCTION:		eoninit
26536382Ssklower  *
266*40778Ssklower  * PURPOSE:			initialization
26736382Ssklower  *
26836382Ssklower  * RETURNS:			nothing
26936382Ssklower  */
27036382Ssklower 
271*40778Ssklower eoninit(unit)
272*40778Ssklower 	int unit;
27336382Ssklower {
274*40778Ssklower 	printf("eon driver-init eon%d\n", unit);
27536382Ssklower }
27636382Ssklower 
27736382Ssklower 
27836382Ssklower /*
27936382Ssklower  * FUNCTION:		eonoutput
28036382Ssklower  *
28136382Ssklower  * PURPOSE:			prepend an eon header and hand to IP
28236382Ssklower  * ARGUMENTS:	 	(ifp) is points to the ifnet structure for this unit/device
28336382Ssklower  *					(m)  is an mbuf *, *m is a CLNL packet
28436382Ssklower  *					(dst) is a destination address - have to interp. as
28536382Ssklower  *					multicast or broadcast or real address.
28636382Ssklower  *
28736382Ssklower  * RETURNS:			unix error code
28836382Ssklower  *
28936382Ssklower  * NOTES:
29036382Ssklower  *
29136382Ssklower  */
292*40778Ssklower eonoutput(ifp, m, dst, rt)
29337469Ssklower 	struct ifnet 	*ifp;
294*40778Ssklower 	register struct mbuf	*m;		/* packet */
29536382Ssklower 	struct sockaddr_iso		*dst;		/* destination addr */
296*40778Ssklower 	struct rtentry *rt;
29736382Ssklower {
298*40778Ssklower 	register struct eon_llinfo *el;
299*40778Ssklower 	register struct eon_iphdr *ei;
300*40778Ssklower 	struct route *ro;
301*40778Ssklower 	int	datalen;
302*40778Ssklower 	struct mbuf *mh;
303*40778Ssklower 	int	error = 0;
304*40778Ssklower 	caddr_t ippaddrloc;
305*40778Ssklower 	static struct eon_iphdr eon_iphdr;
306*40778Ssklower 	static struct route route;
30736382Ssklower 
30836382Ssklower 	IFDEBUG(D_EON)
30936382Ssklower 		printf("eonoutput \n" );
31036382Ssklower 	ENDDEBUG
31136382Ssklower 
31239195Ssklower 	ifp->if_lastchange = time;
31339195Ssklower 	ifp->if_opackets++;
314*40778Ssklower 	if (rt == 0 || (el = (struct eon_llinfo *)rt->rt_llinfo) == 0) {
315*40778Ssklower 		if (dst->siso_family == AF_LINK) {
316*40778Ssklower 			register struct sockaddr_dl *sdl = (struct sockaddr_dl *)dst;
317*40778Ssklower 			caddr_t ipaddrloc = LLADDR(sdl);
318*40778Ssklower 			int class = (sdl->sdl_alen == 5) ? 4[(u_char *)ipaddrloc] : 0;
319*40778Ssklower 
320*40778Ssklower 			if (sdl->sdl_alen == 4 || sdl->sdl_alen == 5) {
321*40778Ssklower 				ipaddrloc = LLADDR(sdl);
322*40778Ssklower 				ro = &route;
323*40778Ssklower 				ei = &eon_iphdr;
324*40778Ssklower 				eoniphdr(ei, ipaddrloc, ro, class, 1);
325*40778Ssklower 				goto send;
326*40778Ssklower 			}
327*40778Ssklower 		}
328*40778Ssklower einval:
32937469Ssklower 		error =  EINVAL;
33037469Ssklower 		goto flush;
33137469Ssklower 	}
332*40778Ssklower 	if ((el->el_flags & RTF_UP) == 0) {
333*40778Ssklower 		eonrtrequest(RTM_CHANGE, rt, (struct sockaddr *)0);
334*40778Ssklower 		if ((el->el_flags & RTF_UP) == 0) {
335*40778Ssklower 			error = EHOSTUNREACH;
336*40778Ssklower 			goto flush;
337*40778Ssklower 		}
338*40778Ssklower 	}
339*40778Ssklower 	if ((m->m_flags & M_PKTHDR) == 0) {
34037469Ssklower 		printf("eon: got non headered packet\n");
34137469Ssklower 		goto einval;
34237469Ssklower 	}
343*40778Ssklower 	ei = &el->el_ei;
344*40778Ssklower 	ro = &el->el_iproute;
345*40778Ssklower send:
346*40778Ssklower 	/* put an eon_hdr in the buffer, prepended by an ip header */
347*40778Ssklower 	datalen = m->m_pkthdr.len + EONIPLEN;
34837469Ssklower 	MGETHDR(mh, M_DONTWAIT, MT_HEADER);
34937469Ssklower 	if(mh == (struct mbuf *)0)
350*40778Ssklower 		goto flush;
351*40778Ssklower 	mh->m_next = m;
352*40778Ssklower 	m = mh;
353*40778Ssklower 	MH_ALIGN(m, sizeof(struct eon_iphdr));
354*40778Ssklower 	m->m_len = sizeof(struct eon_iphdr);
35539195Ssklower 	ifp->if_obytes +=
356*40778Ssklower 		(ei->ei_ip.ip_len = (u_short)(m->m_pkthdr.len = datalen));
357*40778Ssklower 	*mtod(m, struct eon_iphdr *) = *ei;
35836382Ssklower 
35936382Ssklower 	IFDEBUG(D_EON)
360*40778Ssklower 		printf("eonoutput dst ip addr : %x\n",  ei->ei_ip.ip_dst.s_addr);
361*40778Ssklower 		printf("eonoutput ip_output : eonip header:\n");
362*40778Ssklower 		dump_buf(ei, sizeof(struct eon_iphdr));
36336382Ssklower 	ENDDEBUG
36436382Ssklower 
365*40778Ssklower 	error = ip_output(m, (struct mbuf *)0, ro, 0);
366*40778Ssklower 	m = 0;
36739195Ssklower 	if (error) {
36839195Ssklower 		ifp->if_oerrors++;
36939195Ssklower 		ifp->if_opackets--;
370*40778Ssklower 		ifp->if_obytes -= datalen;
37139195Ssklower 	}
372*40778Ssklower flush:
373*40778Ssklower 	if (m)
374*40778Ssklower 		m_freem(m);
37536382Ssklower 	return error;
37636382Ssklower }
37736382Ssklower 
37837469Ssklower eoninput(m, iphlen)
37936382Ssklower 	register struct mbuf	*m;
38037469Ssklower 	int iphlen;
38136382Ssklower {
38236382Ssklower 	register struct eon_hdr	*eonhdr;
38336382Ssklower 	register struct ip		*iphdr;
38436382Ssklower 	struct ifnet 			*eonifp;
38537469Ssklower 	int						s;
38636382Ssklower 
38736382Ssklower 	eonifp = &eonif[0]; /* kludge - really want to give CLNP
38836382Ssklower 						* the ifp for eon, not for the real device
38936382Ssklower 						*/
39036382Ssklower 
39136382Ssklower 	IFDEBUG(D_EON)
39237469Ssklower 		printf("eoninput() 0x%x m_data 0x%x m_len 0x%x dequeued\n",
39337469Ssklower 			m, m?m->m_data:0, m?m->m_len:0);
39436382Ssklower 	ENDDEBUG
39536382Ssklower 
39637469Ssklower 	if (m == 0)
39737469Ssklower 		return;
39837469Ssklower 	if (iphlen > sizeof (struct ip))
39937469Ssklower 		ip_stripoptions(m, (struct mbuf *)0);
40037469Ssklower 	if (m->m_len < EONIPLEN) {
40137469Ssklower 		if ((m = m_pullup(m, EONIPLEN)) == 0) {
40237469Ssklower 			IncStat(es_badhdr);
40337469Ssklower drop:
40437469Ssklower 			IFDEBUG(D_EON)
40537469Ssklower 				printf("eoninput: DROP \n" );
40637469Ssklower 			ENDDEBUG
40737469Ssklower 			eonifp->if_ierrors ++;
40837469Ssklower 			m_freem(m);
40937469Ssklower 			return;
41037469Ssklower 		}
41136382Ssklower 	}
41239195Ssklower 	eonif->if_ibytes += m->m_pkthdr.len;
41339195Ssklower 	eonif->if_lastchange = time;
41436382Ssklower 	iphdr = mtod(m, struct ip *);
41536382Ssklower 	/* do a few checks for debugging */
41636382Ssklower 	if( iphdr->ip_p != IPPROTO_EON ) {
41736382Ssklower 		IncStat(es_badhdr);
41836382Ssklower 		goto drop;
41936382Ssklower 	}
42037469Ssklower 	/* temporarily drop ip header from the mbuf */
42137469Ssklower 	m->m_data += sizeof(struct ip);
42236382Ssklower 	eonhdr = mtod(m, struct eon_hdr *);
42337469Ssklower 	if( iso_check_csum( m, sizeof(struct eon_hdr) )   != EOK ) {
42437469Ssklower 		IncStat(es_badcsum);
42537469Ssklower 		goto drop;
42637469Ssklower 	}
42737469Ssklower 	m->m_data -= sizeof(struct ip);
42837469Ssklower 
42936382Ssklower 	IFDEBUG(D_EON)
43037469Ssklower 		printf("eoninput csum ok class 0x%x\n", eonhdr->eonh_class );
43136382Ssklower 		printf("eoninput: eon header:\n");
43236382Ssklower 		dump_buf(eonhdr, sizeof(struct eon_hdr));
43336382Ssklower 	ENDDEBUG
43436382Ssklower 
43536382Ssklower 	/* checks for debugging */
43636382Ssklower 	if( eonhdr->eonh_vers != EON_VERSION) {
43736382Ssklower 		IncStat(es_badhdr);
43836382Ssklower 		goto drop;
43936382Ssklower 	}
44037469Ssklower 	m->m_flags &= ~(M_BCAST|M_MCAST);
44136382Ssklower 	switch( eonhdr->eonh_class) {
44236382Ssklower 		case EON_BROADCAST:
44336382Ssklower 			IncStat(es_in_broad);
44437469Ssklower 			m->m_flags |= M_BCAST;
44536382Ssklower 			break;
44636382Ssklower 		case EON_NORMAL_ADDR:
44736382Ssklower 			IncStat(es_in_normal);
44836382Ssklower 			break;
44936382Ssklower 		case EON_MULTICAST_ES:
45036382Ssklower 			IncStat(es_in_multi_es);
45137469Ssklower 			m->m_flags |= M_MCAST;
45236382Ssklower 			break;
45336382Ssklower 		case EON_MULTICAST_IS:
45436382Ssklower 			IncStat(es_in_multi_is);
45537469Ssklower 			m->m_flags |= M_MCAST;
45636382Ssklower 			break;
45736382Ssklower 	}
45839195Ssklower 	eonifp->if_ipackets++;
45936382Ssklower 
46036382Ssklower 	{
46136382Ssklower 		/* put it on the CLNP queue and set soft interrupt */
46236382Ssklower 		struct ifqueue 			*ifq;
46336382Ssklower 		extern struct ifqueue 	clnlintrq;
46436382Ssklower 
46537469Ssklower 		m->m_pkthdr.rcvif = eonifp; /* KLUDGE */
46636382Ssklower 		IFDEBUG(D_EON)
46736382Ssklower 			printf("eoninput to clnl IFQ\n");
46836382Ssklower 		ENDDEBUG
46936382Ssklower 		ifq = &clnlintrq;
47037469Ssklower 		s = splimp();
47136382Ssklower 		if (IF_QFULL(ifq)) {
47236382Ssklower 			IF_DROP(ifq);
47336382Ssklower 			m_freem(m);
47439195Ssklower 			eonifp->if_iqdrops++;
47539195Ssklower 			eonifp->if_ipackets--;
47636382Ssklower 			splx(s);
47736382Ssklower 			return;
47836382Ssklower 		}
47936382Ssklower 		IF_ENQUEUE(ifq, m);
48036382Ssklower 		IFDEBUG(D_EON)
48136382Ssklower 			printf(
48237469Ssklower 	"0x%x enqueued on clnp Q: m_len 0x%x m_type 0x%x m_data 0x%x\n",
48337469Ssklower 				m, m->m_len, m->m_type, m->m_data);
48436382Ssklower 			dump_buf(mtod(m, caddr_t), m->m_len);
48536382Ssklower 		ENDDEBUG
48637469Ssklower 		schednetisr(NETISR_ISO);
48737469Ssklower 		splx(s);
48836382Ssklower 	}
48936382Ssklower }
49036382Ssklower 
49136382Ssklower int
49236382Ssklower eonctlinput(cmd, sin)
49336382Ssklower 	int cmd;
49436382Ssklower 	struct sockaddr_in *sin;
49536382Ssklower {
49636382Ssklower 	extern u_char inetctlerrmap[];
49736382Ssklower 
49836382Ssklower 	IFDEBUG(D_EON)
49936382Ssklower 		printf("eonctlinput: cmd 0x%x addr: ", cmd);
50036382Ssklower 		dump_isoaddr(sin);
50136382Ssklower 		printf("\n");
50236382Ssklower 	ENDDEBUG
50336382Ssklower 
50436382Ssklower 	if (cmd < 0 || cmd > PRC_NCMDS)
50536382Ssklower 		return 0;
50636382Ssklower 
50736382Ssklower 	IncStat(es_icmp[cmd]);
50836382Ssklower 	switch (cmd) {
50936382Ssklower 
51037469Ssklower 		case	PRC_QUENCH:
51136382Ssklower 		case	PRC_QUENCH2:
51236382Ssklower 			/* TODO: set the dec bit */
51336382Ssklower 			break;
51436382Ssklower 		case	PRC_TIMXCEED_REASS:
51536382Ssklower 		case	PRC_ROUTEDEAD:
51636382Ssklower 		case	PRC_HOSTUNREACH:
51736382Ssklower 		case	PRC_UNREACH_NET:
51836382Ssklower 		case	PRC_IFDOWN:
51936382Ssklower 		case	PRC_UNREACH_HOST:
52036382Ssklower 		case	PRC_HOSTDEAD:
52136382Ssklower 		case	PRC_TIMXCEED_INTRANS:
52236382Ssklower 			/* TODO: mark the link down */
52336382Ssklower 			break;
52436382Ssklower 
52536382Ssklower 		case	PRC_UNREACH_PROTOCOL:
52636382Ssklower 		case	PRC_UNREACH_PORT:
52736382Ssklower 		case	PRC_UNREACH_SRCFAIL:
52836382Ssklower 		case	PRC_REDIRECT_NET:
52936382Ssklower 		case	PRC_REDIRECT_HOST:
53036382Ssklower 		case	PRC_REDIRECT_TOSNET:
53136382Ssklower 		case	PRC_REDIRECT_TOSHOST:
53236382Ssklower 		case	PRC_MSGSIZE:
53336382Ssklower 		case	PRC_PARAMPROB:
53436382Ssklower 			printf("eonctlinput: ICMP cmd 0x%x\n", cmd );
53536382Ssklower 		break;
53636382Ssklower 	}
53736382Ssklower 	return 0;
53836382Ssklower }
53936382Ssklower 
54037469Ssklower #endif
541