149268Sbostic /*- 249268Sbostic * Copyright (c) 1991 The Regents of the University of California. 349268Sbostic * All rights reserved. 449268Sbostic * 549268Sbostic * %sccs.include.redist.c% 649268Sbostic * 7*61657Ssklower * @(#)if_eon.c 7.21 (Berkeley) 06/05/93 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 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 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 */ 15336382Ssklower eonioctl(ifp, cmd, data) 15436382Ssklower register struct ifnet *ifp; 15540778Ssklower int 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 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 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 408*61657Ssklower 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 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 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