149268Sbostic /*- 249268Sbostic * Copyright (c) 1991 The Regents of the University of California. 349268Sbostic * All rights reserved. 449268Sbostic * 549268Sbostic * %sccs.include.redist.c% 649268Sbostic * 7*49616Ssklower * @(#)if_eon.c 7.15 (Berkeley) 05/09/91 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 5236382Ssklower #include "param.h" 5336382Ssklower #include "systm.h" 5436382Ssklower #include "types.h" 5536382Ssklower #include "mbuf.h" 5636382Ssklower #include "buf.h" 5736382Ssklower #include "protosw.h" 5836382Ssklower #include "socket.h" 5936382Ssklower #include "ioctl.h" 6036382Ssklower #include "errno.h" 6136382Ssklower #include "types.h" 6236382Ssklower 6336382Ssklower #include "../net/if.h" 6439195Ssklower #include "../net/if_types.h" 6540778Ssklower #include "../net/if_dl.h" 6636382Ssklower #include "../net/netisr.h" 6736382Ssklower #include "../net/route.h" 6837518Smckusick #include "machine/mtpr.h" 6936382Ssklower 7036382Ssklower #include "../netinet/in.h" 7136382Ssklower #include "../netinet/in_systm.h" 7240778Ssklower #include "../netinet/in_var.h" 7336382Ssklower #include "../netinet/ip.h" 7436382Ssklower #include "../netinet/ip_var.h" 7536382Ssklower #include "../netinet/if_ether.h" 7636382Ssklower 7737469Ssklower #include "iso.h" 7837469Ssklower #include "iso_var.h" 7937469Ssklower #include "iso_snpac.h" 8037469Ssklower #include "argo_debug.h" 8137469Ssklower #include "iso_errno.h" 8237469Ssklower #include "eonvar.h" 8339195Ssklower extern struct timeval time; 8436382Ssklower 8536382Ssklower #define EOK 0 8636382Ssklower 8736382Ssklower int eoninput(); 8836382Ssklower int eonoutput(); 8936382Ssklower int eonioctl(); 9036382Ssklower int eonattach(); 9136382Ssklower int eoninit(); 9240778Ssklower int eonrtrequest(); 9336382Ssklower extern int ip_output(); 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; 17340778Ssklower ifa->ifa_llinfolen = sizeof(struct eon_llinfo); 17441393Ssklower } 17536382Ssklower break; 17636382Ssklower } 17736382Ssklower splx(s); 17836382Ssklower return(error); 17936382Ssklower } 18036382Ssklower 18140778Ssklower 18240778Ssklower eoniphdr(hdr, loc, ro, class, zero) 18340778Ssklower struct route *ro; 18440778Ssklower register struct eon_iphdr *hdr; 18540778Ssklower caddr_t loc; 18640778Ssklower { 18740778Ssklower struct mbuf mhead; 18848751Ssklower extern struct ifnet loif; 18940778Ssklower register struct sockaddr_in *sin = (struct sockaddr_in *)&ro->ro_dst; 19040778Ssklower if (zero) { 19140778Ssklower bzero((caddr_t)hdr, sizeof (*hdr)); 19240778Ssklower bzero((caddr_t)ro, sizeof (*ro)); 19340778Ssklower } 19440778Ssklower sin->sin_family = AF_INET; 19540778Ssklower sin->sin_len = sizeof (*sin); 19640778Ssklower bcopy(loc, (caddr_t)&sin->sin_addr, sizeof(struct in_addr)); 19748751Ssklower /* 19848751Ssklower * If there is a cached route, 19948751Ssklower * check that it is to the same destination 20048751Ssklower * and is still up. If not, free it and try again. 20148751Ssklower */ 20248751Ssklower if (ro->ro_rt) { 20348751Ssklower struct sockaddr_in *dst = 20448751Ssklower (struct sockaddr_in *)rt_key(ro->ro_rt); 20548751Ssklower if ((ro->ro_rt->rt_flags & RTF_UP) == 0 || 20648751Ssklower sin->sin_addr.s_addr != dst->sin_addr.s_addr) { 20748751Ssklower RTFREE(ro->ro_rt); 20848751Ssklower ro->ro_rt = (struct rtentry *)0; 20948751Ssklower } 21048751Ssklower } 21148751Ssklower rtalloc(ro); 21248751Ssklower if (ro->ro_rt) 21348751Ssklower ro->ro_rt->rt_use++; 21440778Ssklower hdr->ei_ip.ip_dst = sin->sin_addr; 21540778Ssklower hdr->ei_ip.ip_p = IPPROTO_EON; 21640778Ssklower hdr->ei_ip.ip_ttl = MAXTTL; 21740778Ssklower hdr->ei_eh.eonh_class = class; 21840778Ssklower hdr->ei_eh.eonh_vers = EON_VERSION; 21940778Ssklower hdr->ei_eh.eonh_csum = 0; 22040778Ssklower mhead.m_data = (caddr_t) &hdr->ei_eh; 22140778Ssklower mhead.m_len = sizeof(struct eon_hdr); 22240778Ssklower mhead.m_next = 0; 22340778Ssklower IFDEBUG(D_EON) 22440778Ssklower printf("eonoutput : gen csum (0x%x, offset %d, datalen %d)\n", 22540778Ssklower &mhead, 22640778Ssklower _offsetof(struct eon_hdr, eonh_csum), sizeof(struct eon_hdr)); 22740778Ssklower ENDDEBUG 22840778Ssklower iso_gen_csum(&mhead, 22940778Ssklower _offsetof(struct eon_hdr, eonh_csum), sizeof(struct eon_hdr)); 23040778Ssklower } 23136382Ssklower /* 23240778Ssklower * FUNCTION: eonrtrequest 23336382Ssklower * 23440778Ssklower * PURPOSE: maintains list of direct eon recipients. 23540778Ssklower * sets up IP route for rest. 23636382Ssklower * 23736382Ssklower * RETURNS: nothing 23836382Ssklower */ 23940778Ssklower eonrtrequest(cmd, rt, gate) 24040778Ssklower register struct rtentry *rt; 24142321Ssklower register struct sockaddr *gate; 24240778Ssklower { 24342321Ssklower unsigned long zerodst = 0; 24442321Ssklower caddr_t ipaddrloc = (caddr_t) &zerodst; 24540778Ssklower register struct eon_llinfo *el = (struct eon_llinfo *)rt->rt_llinfo; 24636382Ssklower 24740778Ssklower /* 24840778Ssklower * Common Housekeeping 24940778Ssklower */ 25040778Ssklower switch (cmd) { 25143333Ssklower case RTM_DELETE: 25243333Ssklower if (el) { 25343333Ssklower remque(&(el->el_qhdr)); 25443333Ssklower if (el->el_iproute.ro_rt) 25543333Ssklower RTFREE(el->el_iproute.ro_rt); 25643333Ssklower Free(el); 25743333Ssklower rt->rt_llinfo = 0; 25843333Ssklower } 25943333Ssklower return; 26040778Ssklower 26148751Ssklower case RTM_ADD: 26243333Ssklower case RTM_RESOLVE: 26348751Ssklower rt->rt_rmx.rmx_mtu = loif.if_mtu; /* unless better below */ 26443333Ssklower R_Malloc(el, struct eon_llinfo *, sizeof(*el)); 26543333Ssklower rt->rt_llinfo = (caddr_t)el; 26643333Ssklower if (el == 0) 26743333Ssklower return; 26843333Ssklower Bzero(el, sizeof(*el)); 26940778Ssklower insque(&(el->el_qhdr), &eon_llinfo.el_qhdr); 27040778Ssklower el->el_rt = rt; 27140778Ssklower break; 27240778Ssklower } 27340778Ssklower if (gate || (gate = rt->rt_gateway)) switch (gate->sa_family) { 27440778Ssklower case AF_LINK: 27542321Ssklower #define SDL(x) ((struct sockaddr_dl *)x) 27642321Ssklower if (SDL(gate)->sdl_alen = 1) 27742321Ssklower el->el_snpaoffset = *(u_char *)LLADDR(SDL(gate)); 27842321Ssklower else 27942321Ssklower ipaddrloc = LLADDR(SDL(gate)); 28040778Ssklower break; 28140778Ssklower case AF_INET: 28242321Ssklower #define SIN(x) ((struct sockaddr_in *)x) 28342321Ssklower ipaddrloc = (caddr_t) &SIN(gate)->sin_addr; 28440778Ssklower break; 28540778Ssklower default: 28640778Ssklower return; 28740778Ssklower } 28840778Ssklower el->el_flags |= RTF_UP; 28941926Ssklower eoniphdr(&el->el_ei, ipaddrloc, &el->el_iproute, EON_NORMAL_ADDR, 0); 29048751Ssklower if (el->el_iproute.ro_rt) 291*49616Ssklower rt->rt_rmx.rmx_mtu = el->el_iproute.ro_rt->rt_rmx.rmx_mtu 29249572Ssklower - sizeof(el->el_ei); 29336382Ssklower } 29436382Ssklower 29536382Ssklower /* 29640778Ssklower * FUNCTION: eoninit 29736382Ssklower * 29840778Ssklower * PURPOSE: initialization 29936382Ssklower * 30036382Ssklower * RETURNS: nothing 30136382Ssklower */ 30236382Ssklower 30340778Ssklower eoninit(unit) 30440778Ssklower int unit; 30536382Ssklower { 30640778Ssklower printf("eon driver-init eon%d\n", unit); 30736382Ssklower } 30836382Ssklower 30936382Ssklower 31036382Ssklower /* 31136382Ssklower * FUNCTION: eonoutput 31236382Ssklower * 31336382Ssklower * PURPOSE: prepend an eon header and hand to IP 31436382Ssklower * ARGUMENTS: (ifp) is points to the ifnet structure for this unit/device 31536382Ssklower * (m) is an mbuf *, *m is a CLNL packet 31636382Ssklower * (dst) is a destination address - have to interp. as 31736382Ssklower * multicast or broadcast or real address. 31836382Ssklower * 31936382Ssklower * RETURNS: unix error code 32036382Ssklower * 32136382Ssklower * NOTES: 32236382Ssklower * 32336382Ssklower */ 32440778Ssklower eonoutput(ifp, m, dst, rt) 32537469Ssklower struct ifnet *ifp; 32640778Ssklower register struct mbuf *m; /* packet */ 32736382Ssklower struct sockaddr_iso *dst; /* destination addr */ 32840778Ssklower struct rtentry *rt; 32936382Ssklower { 33040778Ssklower register struct eon_llinfo *el; 33140778Ssklower register struct eon_iphdr *ei; 33240778Ssklower struct route *ro; 33340778Ssklower int datalen; 33440778Ssklower struct mbuf *mh; 33545896Ssklower int error = 0, class = 0, alen = 0; 33645896Ssklower caddr_t ipaddrloc; 33740778Ssklower static struct eon_iphdr eon_iphdr; 33840778Ssklower static struct route route; 33936382Ssklower 34036382Ssklower IFDEBUG(D_EON) 34136382Ssklower printf("eonoutput \n" ); 34236382Ssklower ENDDEBUG 34336382Ssklower 34439195Ssklower ifp->if_lastchange = time; 34539195Ssklower ifp->if_opackets++; 34640778Ssklower if (rt == 0 || (el = (struct eon_llinfo *)rt->rt_llinfo) == 0) { 34740778Ssklower if (dst->siso_family == AF_LINK) { 34840778Ssklower register struct sockaddr_dl *sdl = (struct sockaddr_dl *)dst; 34940778Ssklower 35045896Ssklower ipaddrloc = LLADDR(sdl); 35145896Ssklower alen = sdl->sdl_alen; 35245896Ssklower } else if (dst->siso_family == AF_ISO && dst->siso_data[0] == AFI_SNA) { 35345896Ssklower alen = dst->siso_nlen - 1; 35445896Ssklower ipaddrloc = (caddr_t) dst->siso_data + 1; 35540778Ssklower } 35645896Ssklower switch (alen) { 35745896Ssklower case 5: 35845896Ssklower class = 4[(u_char *)ipaddrloc]; 35945896Ssklower case 4: 36045896Ssklower ro = &route; 36145896Ssklower ei = &eon_iphdr; 36245896Ssklower eoniphdr(ei, ipaddrloc, ro, class, 1); 36345896Ssklower goto send; 36445896Ssklower } 36540778Ssklower einval: 36637469Ssklower error = EINVAL; 36737469Ssklower goto flush; 36837469Ssklower } 36940778Ssklower if ((el->el_flags & RTF_UP) == 0) { 37040778Ssklower eonrtrequest(RTM_CHANGE, rt, (struct sockaddr *)0); 37140778Ssklower if ((el->el_flags & RTF_UP) == 0) { 37240778Ssklower error = EHOSTUNREACH; 37340778Ssklower goto flush; 37440778Ssklower } 37540778Ssklower } 37640778Ssklower if ((m->m_flags & M_PKTHDR) == 0) { 37737469Ssklower printf("eon: got non headered packet\n"); 37837469Ssklower goto einval; 37937469Ssklower } 38040778Ssklower ei = &el->el_ei; 38140778Ssklower ro = &el->el_iproute; 38242321Ssklower if (el->el_snpaoffset) { 38342321Ssklower if (dst->siso_family == AF_ISO) { 38442321Ssklower bcopy((caddr_t) &dst->siso_data[el->el_snpaoffset], 38542321Ssklower (caddr_t) &ei->ei_ip.ip_dst, sizeof(ei->ei_ip.ip_dst)); 38642321Ssklower } else 38742321Ssklower goto einval; 38842321Ssklower } 38940778Ssklower send: 39040778Ssklower /* put an eon_hdr in the buffer, prepended by an ip header */ 39140778Ssklower datalen = m->m_pkthdr.len + EONIPLEN; 39237469Ssklower MGETHDR(mh, M_DONTWAIT, MT_HEADER); 39337469Ssklower if(mh == (struct mbuf *)0) 39440778Ssklower goto flush; 39540778Ssklower mh->m_next = m; 39640778Ssklower m = mh; 39740778Ssklower MH_ALIGN(m, sizeof(struct eon_iphdr)); 39840778Ssklower m->m_len = sizeof(struct eon_iphdr); 39939195Ssklower ifp->if_obytes += 40040778Ssklower (ei->ei_ip.ip_len = (u_short)(m->m_pkthdr.len = datalen)); 40140778Ssklower *mtod(m, struct eon_iphdr *) = *ei; 40236382Ssklower 40336382Ssklower IFDEBUG(D_EON) 40440778Ssklower printf("eonoutput dst ip addr : %x\n", ei->ei_ip.ip_dst.s_addr); 40540778Ssklower printf("eonoutput ip_output : eonip header:\n"); 40640778Ssklower dump_buf(ei, sizeof(struct eon_iphdr)); 40736382Ssklower ENDDEBUG 40836382Ssklower 40940778Ssklower error = ip_output(m, (struct mbuf *)0, ro, 0); 41040778Ssklower m = 0; 41139195Ssklower if (error) { 41239195Ssklower ifp->if_oerrors++; 41339195Ssklower ifp->if_opackets--; 41440778Ssklower ifp->if_obytes -= datalen; 41539195Ssklower } 41640778Ssklower flush: 41740778Ssklower if (m) 41840778Ssklower m_freem(m); 41936382Ssklower return error; 42036382Ssklower } 42136382Ssklower 42237469Ssklower eoninput(m, iphlen) 42336382Ssklower register struct mbuf *m; 42437469Ssklower int iphlen; 42536382Ssklower { 42636382Ssklower register struct eon_hdr *eonhdr; 42736382Ssklower register struct ip *iphdr; 42836382Ssklower struct ifnet *eonifp; 42937469Ssklower int s; 43036382Ssklower 43136382Ssklower eonifp = &eonif[0]; /* kludge - really want to give CLNP 43236382Ssklower * the ifp for eon, not for the real device 43336382Ssklower */ 43436382Ssklower 43536382Ssklower IFDEBUG(D_EON) 43637469Ssklower printf("eoninput() 0x%x m_data 0x%x m_len 0x%x dequeued\n", 43737469Ssklower m, m?m->m_data:0, m?m->m_len:0); 43836382Ssklower ENDDEBUG 43936382Ssklower 44037469Ssklower if (m == 0) 44137469Ssklower return; 44237469Ssklower if (iphlen > sizeof (struct ip)) 44337469Ssklower ip_stripoptions(m, (struct mbuf *)0); 44437469Ssklower if (m->m_len < EONIPLEN) { 44537469Ssklower if ((m = m_pullup(m, EONIPLEN)) == 0) { 44637469Ssklower IncStat(es_badhdr); 44737469Ssklower drop: 44837469Ssklower IFDEBUG(D_EON) 44937469Ssklower printf("eoninput: DROP \n" ); 45037469Ssklower ENDDEBUG 45137469Ssklower eonifp->if_ierrors ++; 45237469Ssklower m_freem(m); 45337469Ssklower return; 45437469Ssklower } 45536382Ssklower } 45639195Ssklower eonif->if_ibytes += m->m_pkthdr.len; 45739195Ssklower eonif->if_lastchange = time; 45836382Ssklower iphdr = mtod(m, struct ip *); 45936382Ssklower /* do a few checks for debugging */ 46036382Ssklower if( iphdr->ip_p != IPPROTO_EON ) { 46136382Ssklower IncStat(es_badhdr); 46236382Ssklower goto drop; 46336382Ssklower } 46437469Ssklower /* temporarily drop ip header from the mbuf */ 46537469Ssklower m->m_data += sizeof(struct ip); 46636382Ssklower eonhdr = mtod(m, struct eon_hdr *); 46737469Ssklower if( iso_check_csum( m, sizeof(struct eon_hdr) ) != EOK ) { 46837469Ssklower IncStat(es_badcsum); 46937469Ssklower goto drop; 47037469Ssklower } 47137469Ssklower m->m_data -= sizeof(struct ip); 47237469Ssklower 47336382Ssklower IFDEBUG(D_EON) 47437469Ssklower printf("eoninput csum ok class 0x%x\n", eonhdr->eonh_class ); 47536382Ssklower printf("eoninput: eon header:\n"); 47636382Ssklower dump_buf(eonhdr, sizeof(struct eon_hdr)); 47736382Ssklower ENDDEBUG 47836382Ssklower 47936382Ssklower /* checks for debugging */ 48036382Ssklower if( eonhdr->eonh_vers != EON_VERSION) { 48136382Ssklower IncStat(es_badhdr); 48236382Ssklower goto drop; 48336382Ssklower } 48437469Ssklower m->m_flags &= ~(M_BCAST|M_MCAST); 48536382Ssklower switch( eonhdr->eonh_class) { 48636382Ssklower case EON_BROADCAST: 48736382Ssklower IncStat(es_in_broad); 48837469Ssklower m->m_flags |= M_BCAST; 48936382Ssklower break; 49036382Ssklower case EON_NORMAL_ADDR: 49136382Ssklower IncStat(es_in_normal); 49236382Ssklower break; 49336382Ssklower case EON_MULTICAST_ES: 49436382Ssklower IncStat(es_in_multi_es); 49537469Ssklower m->m_flags |= M_MCAST; 49636382Ssklower break; 49736382Ssklower case EON_MULTICAST_IS: 49836382Ssklower IncStat(es_in_multi_is); 49937469Ssklower m->m_flags |= M_MCAST; 50036382Ssklower break; 50136382Ssklower } 50239195Ssklower eonifp->if_ipackets++; 50336382Ssklower 50436382Ssklower { 50536382Ssklower /* put it on the CLNP queue and set soft interrupt */ 50636382Ssklower struct ifqueue *ifq; 50736382Ssklower extern struct ifqueue clnlintrq; 50836382Ssklower 50937469Ssklower m->m_pkthdr.rcvif = eonifp; /* KLUDGE */ 51036382Ssklower IFDEBUG(D_EON) 51136382Ssklower printf("eoninput to clnl IFQ\n"); 51236382Ssklower ENDDEBUG 51336382Ssklower ifq = &clnlintrq; 51437469Ssklower s = splimp(); 51536382Ssklower if (IF_QFULL(ifq)) { 51636382Ssklower IF_DROP(ifq); 51736382Ssklower m_freem(m); 51839195Ssklower eonifp->if_iqdrops++; 51939195Ssklower eonifp->if_ipackets--; 52036382Ssklower splx(s); 52136382Ssklower return; 52236382Ssklower } 52336382Ssklower IF_ENQUEUE(ifq, m); 52436382Ssklower IFDEBUG(D_EON) 52536382Ssklower printf( 52637469Ssklower "0x%x enqueued on clnp Q: m_len 0x%x m_type 0x%x m_data 0x%x\n", 52737469Ssklower m, m->m_len, m->m_type, m->m_data); 52836382Ssklower dump_buf(mtod(m, caddr_t), m->m_len); 52936382Ssklower ENDDEBUG 53037469Ssklower schednetisr(NETISR_ISO); 53137469Ssklower splx(s); 53236382Ssklower } 53336382Ssklower } 53436382Ssklower 53536382Ssklower int 53636382Ssklower eonctlinput(cmd, sin) 53736382Ssklower int cmd; 53836382Ssklower struct sockaddr_in *sin; 53936382Ssklower { 54036382Ssklower extern u_char inetctlerrmap[]; 54136382Ssklower 54236382Ssklower IFDEBUG(D_EON) 54336382Ssklower printf("eonctlinput: cmd 0x%x addr: ", cmd); 54436382Ssklower dump_isoaddr(sin); 54536382Ssklower printf("\n"); 54636382Ssklower ENDDEBUG 54736382Ssklower 54836382Ssklower if (cmd < 0 || cmd > PRC_NCMDS) 54936382Ssklower return 0; 55036382Ssklower 55136382Ssklower IncStat(es_icmp[cmd]); 55236382Ssklower switch (cmd) { 55336382Ssklower 55437469Ssklower case PRC_QUENCH: 55536382Ssklower case PRC_QUENCH2: 55636382Ssklower /* TODO: set the dec bit */ 55736382Ssklower break; 55836382Ssklower case PRC_TIMXCEED_REASS: 55936382Ssklower case PRC_ROUTEDEAD: 56036382Ssklower case PRC_HOSTUNREACH: 56136382Ssklower case PRC_UNREACH_NET: 56236382Ssklower case PRC_IFDOWN: 56336382Ssklower case PRC_UNREACH_HOST: 56436382Ssklower case PRC_HOSTDEAD: 56536382Ssklower case PRC_TIMXCEED_INTRANS: 56636382Ssklower /* TODO: mark the link down */ 56736382Ssklower break; 56836382Ssklower 56936382Ssklower case PRC_UNREACH_PROTOCOL: 57036382Ssklower case PRC_UNREACH_PORT: 57136382Ssklower case PRC_UNREACH_SRCFAIL: 57236382Ssklower case PRC_REDIRECT_NET: 57336382Ssklower case PRC_REDIRECT_HOST: 57436382Ssklower case PRC_REDIRECT_TOSNET: 57536382Ssklower case PRC_REDIRECT_TOSHOST: 57636382Ssklower case PRC_MSGSIZE: 57736382Ssklower case PRC_PARAMPROB: 57845896Ssklower /* printf("eonctlinput: ICMP cmd 0x%x\n", cmd );*/ 57936382Ssklower break; 58036382Ssklower } 58136382Ssklower return 0; 58236382Ssklower } 58336382Ssklower 58437469Ssklower #endif 585