149268Sbostic /*-
263222Sbostic * Copyright (c) 1991, 1993
363222Sbostic * The Regents of the University of California. All rights reserved.
449268Sbostic *
549268Sbostic * %sccs.include.redist.c%
649268Sbostic *
7*68165Scgd * @(#)if_eon.c 8.2 (Berkeley) 01/09/95
849268Sbostic */
949268Sbostic
1036382Ssklower /***********************************************************
1136382Ssklower Copyright IBM Corporation 1987
1236382Ssklower
1336382Ssklower All Rights Reserved
1436382Ssklower
1536382Ssklower Permission to use, copy, modify, and distribute this software and its
1636382Ssklower documentation for any purpose and without fee is hereby granted,
1736382Ssklower provided that the above copyright notice appear in all copies and that
1836382Ssklower both that copyright notice and this permission notice appear in
1936382Ssklower supporting documentation, and that the name of IBM not be
2036382Ssklower used in advertising or publicity pertaining to distribution of the
2136382Ssklower software without specific, written prior permission.
2236382Ssklower
2336382Ssklower IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
2436382Ssklower ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
2536382Ssklower IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
2636382Ssklower ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
2736382Ssklower WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
2836382Ssklower ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
2936382Ssklower SOFTWARE.
3036382Ssklower
3136382Ssklower ******************************************************************/
3236382Ssklower
3336382Ssklower /*
3436382Ssklower * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
3536382Ssklower */
3636382Ssklower /*
3736382Ssklower * $Header: if_eon.c,v 1.4 88/07/19 15:53:59 hagens Exp $
3836382Ssklower * $Source: /usr/argo/sys/netiso/RCS/if_eon.c,v $
3936382Ssklower *
4036382Ssklower * EON rfc
4136382Ssklower * Layer between IP and CLNL
4236382Ssklower *
4336382Ssklower * TODO:
4436382Ssklower * Put together a current rfc986 address format and get the right offset
4536382Ssklower * for the nsel
4636382Ssklower */
4736382Ssklower
4837469Ssklower #ifdef EON
4937469Ssklower #define NEON 1
5036382Ssklower
5137469Ssklower
5256533Sbostic #include <sys/param.h>
5356533Sbostic #include <sys/systm.h>
5456533Sbostic #include <sys/mbuf.h>
5556533Sbostic #include <sys/buf.h>
5656533Sbostic #include <sys/protosw.h>
5756533Sbostic #include <sys/socket.h>
5856533Sbostic #include <sys/ioctl.h>
5956533Sbostic #include <sys/errno.h>
6056533Sbostic #include <sys/types.h>
6136382Ssklower
6256533Sbostic #include <net/if.h>
6356533Sbostic #include <net/if_types.h>
6456533Sbostic #include <net/if_dl.h>
6556533Sbostic #include <net/netisr.h>
6656533Sbostic #include <net/route.h>
6756533Sbostic #include <machine/mtpr.h>
6836382Ssklower
6956533Sbostic #include <netinet/in.h>
7056533Sbostic #include <netinet/in_systm.h>
7156533Sbostic #include <netinet/in_var.h>
7256533Sbostic #include <netinet/ip.h>
7356533Sbostic #include <netinet/ip_var.h>
7456533Sbostic #include <netinet/if_ether.h>
7536382Ssklower
7656533Sbostic #include <netiso/iso.h>
7756533Sbostic #include <netiso/iso_var.h>
7856533Sbostic #include <netiso/iso_snpac.h>
7956533Sbostic #include <netiso/argo_debug.h>
8056533Sbostic #include <netiso/iso_errno.h>
8156533Sbostic #include <netiso/eonvar.h>
8256533Sbostic
8339195Ssklower extern struct timeval time;
8450239Ssklower extern struct ifnet loif;
8536382Ssklower
8636382Ssklower #define EOK 0
8736382Ssklower
8836382Ssklower int eoninput();
8936382Ssklower int eonoutput();
9036382Ssklower int eonioctl();
9136382Ssklower int eonattach();
9236382Ssklower int eoninit();
9358989Ssklower void eonrtrequest();
9440778Ssklower struct ifnet eonif[1];
9536382Ssklower
eonprotoinit()9637469Ssklower eonprotoinit() {
9740778Ssklower (void) eonattach();
9837469Ssklower }
9940778Ssklower
10040778Ssklower struct eon_llinfo eon_llinfo;
10137469Ssklower #define PROBE_OK 0;
10236382Ssklower
10337469Ssklower
10436382Ssklower /*
10536382Ssklower * FUNCTION: eonattach
10636382Ssklower *
10736382Ssklower * PURPOSE: autoconf attach routine
10836382Ssklower *
10936382Ssklower * RETURNS: void
11036382Ssklower */
11136382Ssklower
eonattach()11240778Ssklower eonattach()
11336382Ssklower {
11440778Ssklower register struct ifnet *ifp = eonif;
11536382Ssklower
11636382Ssklower IFDEBUG(D_EON)
11736382Ssklower printf("eonattach()\n");
11836382Ssklower ENDDEBUG
11940778Ssklower ifp->if_unit = 0;
12036382Ssklower ifp->if_name = "eon";
12136382Ssklower ifp->if_mtu = ETHERMTU;
12236382Ssklower /* since everything will go out over ether or token ring */
12336382Ssklower
12436382Ssklower ifp->if_init = eoninit;
12537469Ssklower ifp->if_ioctl = eonioctl;
12636382Ssklower ifp->if_output = eonoutput;
12737469Ssklower ifp->if_type = IFT_EON;
12837469Ssklower ifp->if_addrlen = 5;
12937469Ssklower ifp->if_hdrlen = EONIPLEN;
13036382Ssklower ifp->if_flags = IFF_BROADCAST;
13136382Ssklower if_attach(ifp);
13240778Ssklower eonioctl(ifp, SIOCSIFADDR, (caddr_t)ifp->if_addrlist);
13340778Ssklower eon_llinfo.el_qhdr.link =
13440778Ssklower eon_llinfo.el_qhdr.rlink = &(eon_llinfo.el_qhdr);
13536382Ssklower
13636382Ssklower IFDEBUG(D_EON)
13736382Ssklower printf("eonattach()\n");
13836382Ssklower ENDDEBUG
13936382Ssklower }
14036382Ssklower
14136382Ssklower
14236382Ssklower /*
14336382Ssklower * FUNCTION: eonioctl
14436382Ssklower *
14536382Ssklower * PURPOSE: io controls - ifconfig
14636382Ssklower * need commands to
14736382Ssklower * link-UP (core addr) (flags: ES, IS)
14836382Ssklower * link-DOWN (core addr) (flags: ES, IS)
14936382Ssklower * must be callable from kernel or user
15036382Ssklower *
15136382Ssklower * RETURNS: nothing
15236382Ssklower */
eonioctl(ifp,cmd,data)15336382Ssklower eonioctl(ifp, cmd, data)
15436382Ssklower register struct ifnet *ifp;
155*68165Scgd u_long cmd;
15636382Ssklower register caddr_t data;
15736382Ssklower {
15840778Ssklower int s = splimp();
15936382Ssklower register int error = 0;
16036382Ssklower
16136382Ssklower IFDEBUG(D_EON)
16236382Ssklower printf("eonioctl (cmd 0x%x) \n", cmd);
16336382Ssklower ENDDEBUG
16436382Ssklower
16540778Ssklower switch (cmd) {
16640778Ssklower register struct ifaddr *ifa;
16736382Ssklower
16836382Ssklower case SIOCSIFADDR:
16940778Ssklower if (ifa = (struct ifaddr *)data) {
17040778Ssklower ifp->if_flags |= IFF_UP;
17141393Ssklower if (ifa->ifa_addr->sa_family != AF_LINK)
17241393Ssklower ifa->ifa_rtrequest = eonrtrequest;
17341393Ssklower }
17436382Ssklower break;
17536382Ssklower }
17636382Ssklower splx(s);
17736382Ssklower return(error);
17836382Ssklower }
17936382Ssklower
18040778Ssklower
18140778Ssklower eoniphdr(hdr, loc, ro, class, zero)
18240778Ssklower struct route *ro;
18340778Ssklower register struct eon_iphdr *hdr;
18440778Ssklower caddr_t loc;
18540778Ssklower {
18640778Ssklower struct mbuf mhead;
18740778Ssklower register struct sockaddr_in *sin = (struct sockaddr_in *)&ro->ro_dst;
18840778Ssklower if (zero) {
18940778Ssklower bzero((caddr_t)hdr, sizeof (*hdr));
19040778Ssklower bzero((caddr_t)ro, sizeof (*ro));
19140778Ssklower }
19240778Ssklower sin->sin_family = AF_INET;
19340778Ssklower sin->sin_len = sizeof (*sin);
19440778Ssklower bcopy(loc, (caddr_t)&sin->sin_addr, sizeof(struct in_addr));
19548751Ssklower /*
19648751Ssklower * If there is a cached route,
19748751Ssklower * check that it is to the same destination
19848751Ssklower * and is still up. If not, free it and try again.
19948751Ssklower */
20048751Ssklower if (ro->ro_rt) {
20148751Ssklower struct sockaddr_in *dst =
20248751Ssklower (struct sockaddr_in *)rt_key(ro->ro_rt);
20348751Ssklower if ((ro->ro_rt->rt_flags & RTF_UP) == 0 ||
20448751Ssklower sin->sin_addr.s_addr != dst->sin_addr.s_addr) {
20548751Ssklower RTFREE(ro->ro_rt);
20648751Ssklower ro->ro_rt = (struct rtentry *)0;
20748751Ssklower }
20848751Ssklower }
20948751Ssklower rtalloc(ro);
21048751Ssklower if (ro->ro_rt)
21148751Ssklower ro->ro_rt->rt_use++;
21240778Ssklower hdr->ei_ip.ip_dst = sin->sin_addr;
21340778Ssklower hdr->ei_ip.ip_p = IPPROTO_EON;
21440778Ssklower hdr->ei_ip.ip_ttl = MAXTTL;
21540778Ssklower hdr->ei_eh.eonh_class = class;
21640778Ssklower hdr->ei_eh.eonh_vers = EON_VERSION;
21740778Ssklower hdr->ei_eh.eonh_csum = 0;
21840778Ssklower mhead.m_data = (caddr_t) &hdr->ei_eh;
21940778Ssklower mhead.m_len = sizeof(struct eon_hdr);
22040778Ssklower mhead.m_next = 0;
22140778Ssklower IFDEBUG(D_EON)
22240778Ssklower printf("eonoutput : gen csum (0x%x, offset %d, datalen %d)\n",
22340778Ssklower &mhead,
22440778Ssklower _offsetof(struct eon_hdr, eonh_csum), sizeof(struct eon_hdr));
22540778Ssklower ENDDEBUG
22640778Ssklower iso_gen_csum(&mhead,
22740778Ssklower _offsetof(struct eon_hdr, eonh_csum), sizeof(struct eon_hdr));
22840778Ssklower }
22936382Ssklower /*
23040778Ssklower * FUNCTION: eonrtrequest
23136382Ssklower *
23240778Ssklower * PURPOSE: maintains list of direct eon recipients.
23340778Ssklower * sets up IP route for rest.
23436382Ssklower *
23536382Ssklower * RETURNS: nothing
23636382Ssklower */
23758989Ssklower void
eonrtrequest(cmd,rt,gate)23840778Ssklower eonrtrequest(cmd, rt, gate)
23940778Ssklower register struct rtentry *rt;
24042321Ssklower register struct sockaddr *gate;
24140778Ssklower {
24242321Ssklower unsigned long zerodst = 0;
24342321Ssklower caddr_t ipaddrloc = (caddr_t) &zerodst;
24440778Ssklower register struct eon_llinfo *el = (struct eon_llinfo *)rt->rt_llinfo;
24536382Ssklower
24640778Ssklower /*
24740778Ssklower * Common Housekeeping
24840778Ssklower */
24940778Ssklower switch (cmd) {
25043333Ssklower case RTM_DELETE:
25143333Ssklower if (el) {
25243333Ssklower remque(&(el->el_qhdr));
25343333Ssklower if (el->el_iproute.ro_rt)
25443333Ssklower RTFREE(el->el_iproute.ro_rt);
25543333Ssklower Free(el);
25643333Ssklower rt->rt_llinfo = 0;
25743333Ssklower }
25843333Ssklower return;
25940778Ssklower
26048751Ssklower case RTM_ADD:
26143333Ssklower case RTM_RESOLVE:
26248751Ssklower rt->rt_rmx.rmx_mtu = loif.if_mtu; /* unless better below */
26343333Ssklower R_Malloc(el, struct eon_llinfo *, sizeof(*el));
26443333Ssklower rt->rt_llinfo = (caddr_t)el;
26543333Ssklower if (el == 0)
26643333Ssklower return;
26743333Ssklower Bzero(el, sizeof(*el));
26840778Ssklower insque(&(el->el_qhdr), &eon_llinfo.el_qhdr);
26940778Ssklower el->el_rt = rt;
27040778Ssklower break;
27140778Ssklower }
27240778Ssklower if (gate || (gate = rt->rt_gateway)) switch (gate->sa_family) {
27340778Ssklower case AF_LINK:
27442321Ssklower #define SDL(x) ((struct sockaddr_dl *)x)
27552486Ssklower if (SDL(gate)->sdl_alen == 1)
27642321Ssklower el->el_snpaoffset = *(u_char *)LLADDR(SDL(gate));
27742321Ssklower else
27842321Ssklower ipaddrloc = LLADDR(SDL(gate));
27940778Ssklower break;
28040778Ssklower case AF_INET:
28142321Ssklower #define SIN(x) ((struct sockaddr_in *)x)
28242321Ssklower ipaddrloc = (caddr_t) &SIN(gate)->sin_addr;
28340778Ssklower break;
28440778Ssklower default:
28540778Ssklower return;
28640778Ssklower }
28740778Ssklower el->el_flags |= RTF_UP;
28841926Ssklower eoniphdr(&el->el_ei, ipaddrloc, &el->el_iproute, EON_NORMAL_ADDR, 0);
28948751Ssklower if (el->el_iproute.ro_rt)
29049616Ssklower rt->rt_rmx.rmx_mtu = el->el_iproute.ro_rt->rt_rmx.rmx_mtu
29149572Ssklower - sizeof(el->el_ei);
29236382Ssklower }
29336382Ssklower
29436382Ssklower /*
29540778Ssklower * FUNCTION: eoninit
29636382Ssklower *
29740778Ssklower * PURPOSE: initialization
29836382Ssklower *
29936382Ssklower * RETURNS: nothing
30036382Ssklower */
30136382Ssklower
eoninit(unit)30240778Ssklower eoninit(unit)
30340778Ssklower int unit;
30436382Ssklower {
30540778Ssklower printf("eon driver-init eon%d\n", unit);
30636382Ssklower }
30736382Ssklower
30836382Ssklower
30936382Ssklower /*
31036382Ssklower * FUNCTION: eonoutput
31136382Ssklower *
31236382Ssklower * PURPOSE: prepend an eon header and hand to IP
31336382Ssklower * ARGUMENTS: (ifp) is points to the ifnet structure for this unit/device
31436382Ssklower * (m) is an mbuf *, *m is a CLNL packet
31536382Ssklower * (dst) is a destination address - have to interp. as
31636382Ssklower * multicast or broadcast or real address.
31736382Ssklower *
31836382Ssklower * RETURNS: unix error code
31936382Ssklower *
32036382Ssklower * NOTES:
32136382Ssklower *
32236382Ssklower */
32340778Ssklower eonoutput(ifp, m, dst, rt)
32437469Ssklower struct ifnet *ifp;
32540778Ssklower register struct mbuf *m; /* packet */
32636382Ssklower struct sockaddr_iso *dst; /* destination addr */
32740778Ssklower struct rtentry *rt;
32836382Ssklower {
32940778Ssklower register struct eon_llinfo *el;
33040778Ssklower register struct eon_iphdr *ei;
33140778Ssklower struct route *ro;
33240778Ssklower int datalen;
33340778Ssklower struct mbuf *mh;
33445896Ssklower int error = 0, class = 0, alen = 0;
33545896Ssklower caddr_t ipaddrloc;
33640778Ssklower static struct eon_iphdr eon_iphdr;
33740778Ssklower static struct route route;
33836382Ssklower
33936382Ssklower IFDEBUG(D_EON)
34036382Ssklower printf("eonoutput \n" );
34136382Ssklower ENDDEBUG
34236382Ssklower
34339195Ssklower ifp->if_lastchange = time;
34439195Ssklower ifp->if_opackets++;
34540778Ssklower if (rt == 0 || (el = (struct eon_llinfo *)rt->rt_llinfo) == 0) {
34640778Ssklower if (dst->siso_family == AF_LINK) {
34740778Ssklower register struct sockaddr_dl *sdl = (struct sockaddr_dl *)dst;
34840778Ssklower
34945896Ssklower ipaddrloc = LLADDR(sdl);
35045896Ssklower alen = sdl->sdl_alen;
35145896Ssklower } else if (dst->siso_family == AF_ISO && dst->siso_data[0] == AFI_SNA) {
35245896Ssklower alen = dst->siso_nlen - 1;
35345896Ssklower ipaddrloc = (caddr_t) dst->siso_data + 1;
35440778Ssklower }
35545896Ssklower switch (alen) {
35645896Ssklower case 5:
35745896Ssklower class = 4[(u_char *)ipaddrloc];
35845896Ssklower case 4:
35945896Ssklower ro = &route;
36045896Ssklower ei = &eon_iphdr;
36145896Ssklower eoniphdr(ei, ipaddrloc, ro, class, 1);
36245896Ssklower goto send;
36345896Ssklower }
36440778Ssklower einval:
36537469Ssklower error = EINVAL;
36637469Ssklower goto flush;
36737469Ssklower }
36840778Ssklower if ((el->el_flags & RTF_UP) == 0) {
36940778Ssklower eonrtrequest(RTM_CHANGE, rt, (struct sockaddr *)0);
37040778Ssklower if ((el->el_flags & RTF_UP) == 0) {
37140778Ssklower error = EHOSTUNREACH;
37240778Ssklower goto flush;
37340778Ssklower }
37440778Ssklower }
37540778Ssklower if ((m->m_flags & M_PKTHDR) == 0) {
37637469Ssklower printf("eon: got non headered packet\n");
37737469Ssklower goto einval;
37837469Ssklower }
37940778Ssklower ei = &el->el_ei;
38040778Ssklower ro = &el->el_iproute;
38142321Ssklower if (el->el_snpaoffset) {
38242321Ssklower if (dst->siso_family == AF_ISO) {
38342321Ssklower bcopy((caddr_t) &dst->siso_data[el->el_snpaoffset],
38442321Ssklower (caddr_t) &ei->ei_ip.ip_dst, sizeof(ei->ei_ip.ip_dst));
38542321Ssklower } else
38642321Ssklower goto einval;
38742321Ssklower }
38840778Ssklower send:
38940778Ssklower /* put an eon_hdr in the buffer, prepended by an ip header */
39040778Ssklower datalen = m->m_pkthdr.len + EONIPLEN;
39137469Ssklower MGETHDR(mh, M_DONTWAIT, MT_HEADER);
39237469Ssklower if(mh == (struct mbuf *)0)
39340778Ssklower goto flush;
39440778Ssklower mh->m_next = m;
39540778Ssklower m = mh;
39640778Ssklower MH_ALIGN(m, sizeof(struct eon_iphdr));
39740778Ssklower m->m_len = sizeof(struct eon_iphdr);
39839195Ssklower ifp->if_obytes +=
39940778Ssklower (ei->ei_ip.ip_len = (u_short)(m->m_pkthdr.len = datalen));
40040778Ssklower *mtod(m, struct eon_iphdr *) = *ei;
40136382Ssklower
40236382Ssklower IFDEBUG(D_EON)
40340778Ssklower printf("eonoutput dst ip addr : %x\n", ei->ei_ip.ip_dst.s_addr);
40440778Ssklower printf("eonoutput ip_output : eonip header:\n");
40540778Ssklower dump_buf(ei, sizeof(struct eon_iphdr));
40636382Ssklower ENDDEBUG
40736382Ssklower
40861657Ssklower error = ip_output(m, (struct mbuf *)0, ro, 0, NULL);
40940778Ssklower m = 0;
41039195Ssklower if (error) {
41139195Ssklower ifp->if_oerrors++;
41239195Ssklower ifp->if_opackets--;
41340778Ssklower ifp->if_obytes -= datalen;
41439195Ssklower }
41540778Ssklower flush:
41640778Ssklower if (m)
41740778Ssklower m_freem(m);
41836382Ssklower return error;
41936382Ssklower }
42036382Ssklower
eoninput(m,iphlen)42137469Ssklower eoninput(m, iphlen)
42236382Ssklower register struct mbuf *m;
42337469Ssklower int iphlen;
42436382Ssklower {
42536382Ssklower register struct eon_hdr *eonhdr;
42636382Ssklower register struct ip *iphdr;
42736382Ssklower struct ifnet *eonifp;
42837469Ssklower int s;
42936382Ssklower
43036382Ssklower eonifp = &eonif[0]; /* kludge - really want to give CLNP
43136382Ssklower * the ifp for eon, not for the real device
43236382Ssklower */
43336382Ssklower
43436382Ssklower IFDEBUG(D_EON)
43537469Ssklower printf("eoninput() 0x%x m_data 0x%x m_len 0x%x dequeued\n",
43637469Ssklower m, m?m->m_data:0, m?m->m_len:0);
43736382Ssklower ENDDEBUG
43836382Ssklower
43937469Ssklower if (m == 0)
44037469Ssklower return;
44137469Ssklower if (iphlen > sizeof (struct ip))
44237469Ssklower ip_stripoptions(m, (struct mbuf *)0);
44337469Ssklower if (m->m_len < EONIPLEN) {
44437469Ssklower if ((m = m_pullup(m, EONIPLEN)) == 0) {
44537469Ssklower IncStat(es_badhdr);
44637469Ssklower drop:
44737469Ssklower IFDEBUG(D_EON)
44837469Ssklower printf("eoninput: DROP \n" );
44937469Ssklower ENDDEBUG
45037469Ssklower eonifp->if_ierrors ++;
45137469Ssklower m_freem(m);
45237469Ssklower return;
45337469Ssklower }
45436382Ssklower }
45539195Ssklower eonif->if_ibytes += m->m_pkthdr.len;
45639195Ssklower eonif->if_lastchange = time;
45736382Ssklower iphdr = mtod(m, struct ip *);
45836382Ssklower /* do a few checks for debugging */
45936382Ssklower if( iphdr->ip_p != IPPROTO_EON ) {
46036382Ssklower IncStat(es_badhdr);
46136382Ssklower goto drop;
46236382Ssklower }
46337469Ssklower /* temporarily drop ip header from the mbuf */
46437469Ssklower m->m_data += sizeof(struct ip);
46536382Ssklower eonhdr = mtod(m, struct eon_hdr *);
46637469Ssklower if( iso_check_csum( m, sizeof(struct eon_hdr) ) != EOK ) {
46737469Ssklower IncStat(es_badcsum);
46837469Ssklower goto drop;
46937469Ssklower }
47037469Ssklower m->m_data -= sizeof(struct ip);
47137469Ssklower
47236382Ssklower IFDEBUG(D_EON)
47337469Ssklower printf("eoninput csum ok class 0x%x\n", eonhdr->eonh_class );
47436382Ssklower printf("eoninput: eon header:\n");
47536382Ssklower dump_buf(eonhdr, sizeof(struct eon_hdr));
47636382Ssklower ENDDEBUG
47736382Ssklower
47836382Ssklower /* checks for debugging */
47936382Ssklower if( eonhdr->eonh_vers != EON_VERSION) {
48036382Ssklower IncStat(es_badhdr);
48136382Ssklower goto drop;
48236382Ssklower }
48337469Ssklower m->m_flags &= ~(M_BCAST|M_MCAST);
48436382Ssklower switch( eonhdr->eonh_class) {
48536382Ssklower case EON_BROADCAST:
48636382Ssklower IncStat(es_in_broad);
48737469Ssklower m->m_flags |= M_BCAST;
48836382Ssklower break;
48936382Ssklower case EON_NORMAL_ADDR:
49036382Ssklower IncStat(es_in_normal);
49136382Ssklower break;
49236382Ssklower case EON_MULTICAST_ES:
49336382Ssklower IncStat(es_in_multi_es);
49437469Ssklower m->m_flags |= M_MCAST;
49536382Ssklower break;
49636382Ssklower case EON_MULTICAST_IS:
49736382Ssklower IncStat(es_in_multi_is);
49837469Ssklower m->m_flags |= M_MCAST;
49936382Ssklower break;
50036382Ssklower }
50139195Ssklower eonifp->if_ipackets++;
50236382Ssklower
50336382Ssklower {
50436382Ssklower /* put it on the CLNP queue and set soft interrupt */
50536382Ssklower struct ifqueue *ifq;
50636382Ssklower extern struct ifqueue clnlintrq;
50736382Ssklower
50837469Ssklower m->m_pkthdr.rcvif = eonifp; /* KLUDGE */
50936382Ssklower IFDEBUG(D_EON)
51036382Ssklower printf("eoninput to clnl IFQ\n");
51136382Ssklower ENDDEBUG
51236382Ssklower ifq = &clnlintrq;
51337469Ssklower s = splimp();
51436382Ssklower if (IF_QFULL(ifq)) {
51536382Ssklower IF_DROP(ifq);
51636382Ssklower m_freem(m);
51739195Ssklower eonifp->if_iqdrops++;
51839195Ssklower eonifp->if_ipackets--;
51936382Ssklower splx(s);
52036382Ssklower return;
52136382Ssklower }
52236382Ssklower IF_ENQUEUE(ifq, m);
52336382Ssklower IFDEBUG(D_EON)
52436382Ssklower printf(
52537469Ssklower "0x%x enqueued on clnp Q: m_len 0x%x m_type 0x%x m_data 0x%x\n",
52637469Ssklower m, m->m_len, m->m_type, m->m_data);
52736382Ssklower dump_buf(mtod(m, caddr_t), m->m_len);
52836382Ssklower ENDDEBUG
52937469Ssklower schednetisr(NETISR_ISO);
53037469Ssklower splx(s);
53136382Ssklower }
53236382Ssklower }
53336382Ssklower
53436382Ssklower int
eonctlinput(cmd,sin)53536382Ssklower eonctlinput(cmd, sin)
53636382Ssklower int cmd;
53736382Ssklower struct sockaddr_in *sin;
53836382Ssklower {
53936382Ssklower extern u_char inetctlerrmap[];
54036382Ssklower
54136382Ssklower IFDEBUG(D_EON)
54236382Ssklower printf("eonctlinput: cmd 0x%x addr: ", cmd);
54336382Ssklower dump_isoaddr(sin);
54436382Ssklower printf("\n");
54536382Ssklower ENDDEBUG
54636382Ssklower
54736382Ssklower if (cmd < 0 || cmd > PRC_NCMDS)
54836382Ssklower return 0;
54936382Ssklower
55036382Ssklower IncStat(es_icmp[cmd]);
55136382Ssklower switch (cmd) {
55236382Ssklower
55337469Ssklower case PRC_QUENCH:
55436382Ssklower case PRC_QUENCH2:
55536382Ssklower /* TODO: set the dec bit */
55636382Ssklower break;
55736382Ssklower case PRC_TIMXCEED_REASS:
55836382Ssklower case PRC_ROUTEDEAD:
55936382Ssklower case PRC_HOSTUNREACH:
56036382Ssklower case PRC_UNREACH_NET:
56136382Ssklower case PRC_IFDOWN:
56236382Ssklower case PRC_UNREACH_HOST:
56336382Ssklower case PRC_HOSTDEAD:
56436382Ssklower case PRC_TIMXCEED_INTRANS:
56536382Ssklower /* TODO: mark the link down */
56636382Ssklower break;
56736382Ssklower
56836382Ssklower case PRC_UNREACH_PROTOCOL:
56936382Ssklower case PRC_UNREACH_PORT:
57036382Ssklower case PRC_UNREACH_SRCFAIL:
57136382Ssklower case PRC_REDIRECT_NET:
57236382Ssklower case PRC_REDIRECT_HOST:
57336382Ssklower case PRC_REDIRECT_TOSNET:
57436382Ssklower case PRC_REDIRECT_TOSHOST:
57536382Ssklower case PRC_MSGSIZE:
57636382Ssklower case PRC_PARAMPROB:
57745896Ssklower /* printf("eonctlinput: ICMP cmd 0x%x\n", cmd );*/
57836382Ssklower break;
57936382Ssklower }
58036382Ssklower return 0;
58136382Ssklower }
58236382Ssklower
58337469Ssklower #endif
584