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*48751Ssklower * @(#)if_eon.c 7.12 (Berkeley) 04/26/91 * 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 #include "argo_debug.h" 7737469Ssklower #include "iso_errno.h" 7837469Ssklower #include "eonvar.h" 7939195Ssklower extern struct timeval time; 8036382Ssklower 8136382Ssklower #define EOK 0 8236382Ssklower 8336382Ssklower int eoninput(); 8436382Ssklower int eonoutput(); 8536382Ssklower int eonioctl(); 8636382Ssklower int eonattach(); 8736382Ssklower int eoninit(); 8840778Ssklower int eonrtrequest(); 8936382Ssklower extern int ip_output(); 9040778Ssklower struct ifnet eonif[1]; 9136382Ssklower 9237469Ssklower eonprotoinit() { 9340778Ssklower (void) eonattach(); 9437469Ssklower } 9540778Ssklower 9640778Ssklower struct eon_llinfo eon_llinfo; 9737469Ssklower #define PROBE_OK 0; 9836382Ssklower 9937469Ssklower 10036382Ssklower /* 10136382Ssklower * FUNCTION: eonattach 10236382Ssklower * 10336382Ssklower * PURPOSE: autoconf attach routine 10436382Ssklower * 10536382Ssklower * RETURNS: void 10636382Ssklower */ 10736382Ssklower 10840778Ssklower eonattach() 10936382Ssklower { 11040778Ssklower register struct ifnet *ifp = eonif; 11136382Ssklower 11236382Ssklower IFDEBUG(D_EON) 11336382Ssklower printf("eonattach()\n"); 11436382Ssklower ENDDEBUG 11540778Ssklower ifp->if_unit = 0; 11636382Ssklower ifp->if_name = "eon"; 11736382Ssklower ifp->if_mtu = ETHERMTU; 11836382Ssklower /* since everything will go out over ether or token ring */ 11936382Ssklower 12036382Ssklower ifp->if_init = eoninit; 12137469Ssklower ifp->if_ioctl = eonioctl; 12236382Ssklower ifp->if_output = eonoutput; 12337469Ssklower ifp->if_type = IFT_EON; 12437469Ssklower ifp->if_addrlen = 5; 12537469Ssklower ifp->if_hdrlen = EONIPLEN; 12636382Ssklower ifp->if_flags = IFF_BROADCAST; 12736382Ssklower if_attach(ifp); 12840778Ssklower eonioctl(ifp, SIOCSIFADDR, (caddr_t)ifp->if_addrlist); 12940778Ssklower eon_llinfo.el_qhdr.link = 13040778Ssklower eon_llinfo.el_qhdr.rlink = &(eon_llinfo.el_qhdr); 13136382Ssklower 13236382Ssklower IFDEBUG(D_EON) 13336382Ssklower printf("eonattach()\n"); 13436382Ssklower ENDDEBUG 13536382Ssklower } 13636382Ssklower 13736382Ssklower 13836382Ssklower /* 13936382Ssklower * FUNCTION: eonioctl 14036382Ssklower * 14136382Ssklower * PURPOSE: io controls - ifconfig 14236382Ssklower * need commands to 14336382Ssklower * link-UP (core addr) (flags: ES, IS) 14436382Ssklower * link-DOWN (core addr) (flags: ES, IS) 14536382Ssklower * must be callable from kernel or user 14636382Ssklower * 14736382Ssklower * RETURNS: nothing 14836382Ssklower */ 14936382Ssklower eonioctl(ifp, cmd, data) 15036382Ssklower register struct ifnet *ifp; 15140778Ssklower int cmd; 15236382Ssklower register caddr_t data; 15336382Ssklower { 15440778Ssklower int s = splimp(); 15536382Ssklower register int error = 0; 15636382Ssklower 15736382Ssklower IFDEBUG(D_EON) 15836382Ssklower printf("eonioctl (cmd 0x%x) \n", cmd); 15936382Ssklower ENDDEBUG 16036382Ssklower 16140778Ssklower switch (cmd) { 16240778Ssklower register struct ifaddr *ifa; 16336382Ssklower 16436382Ssklower case SIOCSIFADDR: 16540778Ssklower if (ifa = (struct ifaddr *)data) { 16640778Ssklower ifp->if_flags |= IFF_UP; 16741393Ssklower if (ifa->ifa_addr->sa_family != AF_LINK) 16841393Ssklower ifa->ifa_rtrequest = eonrtrequest; 16940778Ssklower ifa->ifa_llinfolen = sizeof(struct eon_llinfo); 17041393Ssklower } 17136382Ssklower break; 17236382Ssklower } 17336382Ssklower splx(s); 17436382Ssklower return(error); 17536382Ssklower } 17636382Ssklower 17740778Ssklower 17840778Ssklower eoniphdr(hdr, loc, ro, class, zero) 17940778Ssklower struct route *ro; 18040778Ssklower register struct eon_iphdr *hdr; 18140778Ssklower caddr_t loc; 18240778Ssklower { 18340778Ssklower struct mbuf mhead; 184*48751Ssklower extern struct ifnet loif; 18540778Ssklower register struct sockaddr_in *sin = (struct sockaddr_in *)&ro->ro_dst; 18640778Ssklower if (zero) { 18740778Ssklower bzero((caddr_t)hdr, sizeof (*hdr)); 18840778Ssklower bzero((caddr_t)ro, sizeof (*ro)); 18940778Ssklower } 19040778Ssklower sin->sin_family = AF_INET; 19140778Ssklower sin->sin_len = sizeof (*sin); 19240778Ssklower bcopy(loc, (caddr_t)&sin->sin_addr, sizeof(struct in_addr)); 193*48751Ssklower /* 194*48751Ssklower * If there is a cached route, 195*48751Ssklower * check that it is to the same destination 196*48751Ssklower * and is still up. If not, free it and try again. 197*48751Ssklower */ 198*48751Ssklower if (ro->ro_rt) { 199*48751Ssklower struct sockaddr_in *dst = 200*48751Ssklower (struct sockaddr_in *)rt_key(ro->ro_rt); 201*48751Ssklower if ((ro->ro_rt->rt_flags & RTF_UP) == 0 || 202*48751Ssklower sin->sin_addr.s_addr != dst->sin_addr.s_addr) { 203*48751Ssklower RTFREE(ro->ro_rt); 204*48751Ssklower ro->ro_rt = (struct rtentry *)0; 205*48751Ssklower } 206*48751Ssklower } 207*48751Ssklower rtalloc(ro); 208*48751Ssklower if (ro->ro_rt) 209*48751Ssklower ro->ro_rt->rt_use++; 21040778Ssklower hdr->ei_ip.ip_dst = sin->sin_addr; 21140778Ssklower hdr->ei_ip.ip_p = IPPROTO_EON; 21240778Ssklower hdr->ei_ip.ip_ttl = MAXTTL; 21340778Ssklower hdr->ei_eh.eonh_class = class; 21440778Ssklower hdr->ei_eh.eonh_vers = EON_VERSION; 21540778Ssklower hdr->ei_eh.eonh_csum = 0; 21640778Ssklower mhead.m_data = (caddr_t) &hdr->ei_eh; 21740778Ssklower mhead.m_len = sizeof(struct eon_hdr); 21840778Ssklower mhead.m_next = 0; 21940778Ssklower IFDEBUG(D_EON) 22040778Ssklower printf("eonoutput : gen csum (0x%x, offset %d, datalen %d)\n", 22140778Ssklower &mhead, 22240778Ssklower _offsetof(struct eon_hdr, eonh_csum), sizeof(struct eon_hdr)); 22340778Ssklower ENDDEBUG 22440778Ssklower iso_gen_csum(&mhead, 22540778Ssklower _offsetof(struct eon_hdr, eonh_csum), sizeof(struct eon_hdr)); 22640778Ssklower } 22736382Ssklower /* 22840778Ssklower * FUNCTION: eonrtrequest 22936382Ssklower * 23040778Ssklower * PURPOSE: maintains list of direct eon recipients. 23140778Ssklower * sets up IP route for rest. 23236382Ssklower * 23336382Ssklower * RETURNS: nothing 23436382Ssklower */ 23540778Ssklower eonrtrequest(cmd, rt, gate) 23640778Ssklower register struct rtentry *rt; 23742321Ssklower register struct sockaddr *gate; 23840778Ssklower { 23942321Ssklower unsigned long zerodst = 0; 24042321Ssklower caddr_t ipaddrloc = (caddr_t) &zerodst; 24140778Ssklower register struct eon_llinfo *el = (struct eon_llinfo *)rt->rt_llinfo; 24236382Ssklower 24340778Ssklower /* 24440778Ssklower * Common Housekeeping 24540778Ssklower */ 24640778Ssklower switch (cmd) { 24743333Ssklower case RTM_DELETE: 24843333Ssklower if (el) { 24943333Ssklower remque(&(el->el_qhdr)); 25043333Ssklower if (el->el_iproute.ro_rt) 25143333Ssklower RTFREE(el->el_iproute.ro_rt); 25243333Ssklower Free(el); 25343333Ssklower rt->rt_llinfo = 0; 25443333Ssklower } 25543333Ssklower return; 25640778Ssklower 257*48751Ssklower case RTM_ADD: 25843333Ssklower case RTM_RESOLVE: 259*48751Ssklower rt->rt_rmx.rmx_mtu = loif.if_mtu; /* unless better below */ 26043333Ssklower R_Malloc(el, struct eon_llinfo *, sizeof(*el)); 26143333Ssklower rt->rt_llinfo = (caddr_t)el; 26243333Ssklower if (el == 0) 26343333Ssklower return; 26443333Ssklower Bzero(el, sizeof(*el)); 26540778Ssklower insque(&(el->el_qhdr), &eon_llinfo.el_qhdr); 26640778Ssklower el->el_rt = rt; 26740778Ssklower break; 26840778Ssklower } 26940778Ssklower if (gate || (gate = rt->rt_gateway)) switch (gate->sa_family) { 27040778Ssklower case AF_LINK: 27142321Ssklower #define SDL(x) ((struct sockaddr_dl *)x) 27242321Ssklower if (SDL(gate)->sdl_alen = 1) 27342321Ssklower el->el_snpaoffset = *(u_char *)LLADDR(SDL(gate)); 27442321Ssklower else 27542321Ssklower ipaddrloc = LLADDR(SDL(gate)); 27640778Ssklower break; 27740778Ssklower case AF_INET: 27842321Ssklower #define SIN(x) ((struct sockaddr_in *)x) 27942321Ssklower ipaddrloc = (caddr_t) &SIN(gate)->sin_addr; 28040778Ssklower break; 28140778Ssklower default: 28240778Ssklower return; 28340778Ssklower } 28440778Ssklower el->el_flags |= RTF_UP; 28541926Ssklower eoniphdr(&el->el_ei, ipaddrloc, &el->el_iproute, EON_NORMAL_ADDR, 0); 286*48751Ssklower if (el->el_iproute.ro_rt) 287*48751Ssklower rt->rt_rmx.rmx_mtu = el->el_iproute.ro_rt - sizeof(el->el_ei); 28836382Ssklower } 28936382Ssklower 29036382Ssklower /* 29140778Ssklower * FUNCTION: eoninit 29236382Ssklower * 29340778Ssklower * PURPOSE: initialization 29436382Ssklower * 29536382Ssklower * RETURNS: nothing 29636382Ssklower */ 29736382Ssklower 29840778Ssklower eoninit(unit) 29940778Ssklower int unit; 30036382Ssklower { 30140778Ssklower printf("eon driver-init eon%d\n", unit); 30236382Ssklower } 30336382Ssklower 30436382Ssklower 30536382Ssklower /* 30636382Ssklower * FUNCTION: eonoutput 30736382Ssklower * 30836382Ssklower * PURPOSE: prepend an eon header and hand to IP 30936382Ssklower * ARGUMENTS: (ifp) is points to the ifnet structure for this unit/device 31036382Ssklower * (m) is an mbuf *, *m is a CLNL packet 31136382Ssklower * (dst) is a destination address - have to interp. as 31236382Ssklower * multicast or broadcast or real address. 31336382Ssklower * 31436382Ssklower * RETURNS: unix error code 31536382Ssklower * 31636382Ssklower * NOTES: 31736382Ssklower * 31836382Ssklower */ 31940778Ssklower eonoutput(ifp, m, dst, rt) 32037469Ssklower struct ifnet *ifp; 32140778Ssklower register struct mbuf *m; /* packet */ 32236382Ssklower struct sockaddr_iso *dst; /* destination addr */ 32340778Ssklower struct rtentry *rt; 32436382Ssklower { 32540778Ssklower register struct eon_llinfo *el; 32640778Ssklower register struct eon_iphdr *ei; 32740778Ssklower struct route *ro; 32840778Ssklower int datalen; 32940778Ssklower struct mbuf *mh; 33045896Ssklower int error = 0, class = 0, alen = 0; 33145896Ssklower caddr_t ipaddrloc; 33240778Ssklower static struct eon_iphdr eon_iphdr; 33340778Ssklower static struct route route; 33436382Ssklower 33536382Ssklower IFDEBUG(D_EON) 33636382Ssklower printf("eonoutput \n" ); 33736382Ssklower ENDDEBUG 33836382Ssklower 33939195Ssklower ifp->if_lastchange = time; 34039195Ssklower ifp->if_opackets++; 34140778Ssklower if (rt == 0 || (el = (struct eon_llinfo *)rt->rt_llinfo) == 0) { 34240778Ssklower if (dst->siso_family == AF_LINK) { 34340778Ssklower register struct sockaddr_dl *sdl = (struct sockaddr_dl *)dst; 34440778Ssklower 34545896Ssklower ipaddrloc = LLADDR(sdl); 34645896Ssklower alen = sdl->sdl_alen; 34745896Ssklower } else if (dst->siso_family == AF_ISO && dst->siso_data[0] == AFI_SNA) { 34845896Ssklower alen = dst->siso_nlen - 1; 34945896Ssklower ipaddrloc = (caddr_t) dst->siso_data + 1; 35040778Ssklower } 35145896Ssklower switch (alen) { 35245896Ssklower case 5: 35345896Ssklower class = 4[(u_char *)ipaddrloc]; 35445896Ssklower case 4: 35545896Ssklower ro = &route; 35645896Ssklower ei = &eon_iphdr; 35745896Ssklower eoniphdr(ei, ipaddrloc, ro, class, 1); 35845896Ssklower goto send; 35945896Ssklower } 36040778Ssklower einval: 36137469Ssklower error = EINVAL; 36237469Ssklower goto flush; 36337469Ssklower } 36440778Ssklower if ((el->el_flags & RTF_UP) == 0) { 36540778Ssklower eonrtrequest(RTM_CHANGE, rt, (struct sockaddr *)0); 36640778Ssklower if ((el->el_flags & RTF_UP) == 0) { 36740778Ssklower error = EHOSTUNREACH; 36840778Ssklower goto flush; 36940778Ssklower } 37040778Ssklower } 37140778Ssklower if ((m->m_flags & M_PKTHDR) == 0) { 37237469Ssklower printf("eon: got non headered packet\n"); 37337469Ssklower goto einval; 37437469Ssklower } 37540778Ssklower ei = &el->el_ei; 37640778Ssklower ro = &el->el_iproute; 37742321Ssklower if (el->el_snpaoffset) { 37842321Ssklower if (dst->siso_family == AF_ISO) { 37942321Ssklower bcopy((caddr_t) &dst->siso_data[el->el_snpaoffset], 38042321Ssklower (caddr_t) &ei->ei_ip.ip_dst, sizeof(ei->ei_ip.ip_dst)); 38142321Ssklower } else 38242321Ssklower goto einval; 38342321Ssklower } 38440778Ssklower send: 38540778Ssklower /* put an eon_hdr in the buffer, prepended by an ip header */ 38640778Ssklower datalen = m->m_pkthdr.len + EONIPLEN; 38737469Ssklower MGETHDR(mh, M_DONTWAIT, MT_HEADER); 38837469Ssklower if(mh == (struct mbuf *)0) 38940778Ssklower goto flush; 39040778Ssklower mh->m_next = m; 39140778Ssklower m = mh; 39240778Ssklower MH_ALIGN(m, sizeof(struct eon_iphdr)); 39340778Ssklower m->m_len = sizeof(struct eon_iphdr); 39439195Ssklower ifp->if_obytes += 39540778Ssklower (ei->ei_ip.ip_len = (u_short)(m->m_pkthdr.len = datalen)); 39640778Ssklower *mtod(m, struct eon_iphdr *) = *ei; 39736382Ssklower 39836382Ssklower IFDEBUG(D_EON) 39940778Ssklower printf("eonoutput dst ip addr : %x\n", ei->ei_ip.ip_dst.s_addr); 40040778Ssklower printf("eonoutput ip_output : eonip header:\n"); 40140778Ssklower dump_buf(ei, sizeof(struct eon_iphdr)); 40236382Ssklower ENDDEBUG 40336382Ssklower 40440778Ssklower error = ip_output(m, (struct mbuf *)0, ro, 0); 40540778Ssklower m = 0; 40639195Ssklower if (error) { 40739195Ssklower ifp->if_oerrors++; 40839195Ssklower ifp->if_opackets--; 40940778Ssklower ifp->if_obytes -= datalen; 41039195Ssklower } 41140778Ssklower flush: 41240778Ssklower if (m) 41340778Ssklower m_freem(m); 41436382Ssklower return error; 41536382Ssklower } 41636382Ssklower 41737469Ssklower eoninput(m, iphlen) 41836382Ssklower register struct mbuf *m; 41937469Ssklower int iphlen; 42036382Ssklower { 42136382Ssklower register struct eon_hdr *eonhdr; 42236382Ssklower register struct ip *iphdr; 42336382Ssklower struct ifnet *eonifp; 42437469Ssklower int s; 42536382Ssklower 42636382Ssklower eonifp = &eonif[0]; /* kludge - really want to give CLNP 42736382Ssklower * the ifp for eon, not for the real device 42836382Ssklower */ 42936382Ssklower 43036382Ssklower IFDEBUG(D_EON) 43137469Ssklower printf("eoninput() 0x%x m_data 0x%x m_len 0x%x dequeued\n", 43237469Ssklower m, m?m->m_data:0, m?m->m_len:0); 43336382Ssklower ENDDEBUG 43436382Ssklower 43537469Ssklower if (m == 0) 43637469Ssklower return; 43737469Ssklower if (iphlen > sizeof (struct ip)) 43837469Ssklower ip_stripoptions(m, (struct mbuf *)0); 43937469Ssklower if (m->m_len < EONIPLEN) { 44037469Ssklower if ((m = m_pullup(m, EONIPLEN)) == 0) { 44137469Ssklower IncStat(es_badhdr); 44237469Ssklower drop: 44337469Ssklower IFDEBUG(D_EON) 44437469Ssklower printf("eoninput: DROP \n" ); 44537469Ssklower ENDDEBUG 44637469Ssklower eonifp->if_ierrors ++; 44737469Ssklower m_freem(m); 44837469Ssklower return; 44937469Ssklower } 45036382Ssklower } 45139195Ssklower eonif->if_ibytes += m->m_pkthdr.len; 45239195Ssklower eonif->if_lastchange = time; 45336382Ssklower iphdr = mtod(m, struct ip *); 45436382Ssklower /* do a few checks for debugging */ 45536382Ssklower if( iphdr->ip_p != IPPROTO_EON ) { 45636382Ssklower IncStat(es_badhdr); 45736382Ssklower goto drop; 45836382Ssklower } 45937469Ssklower /* temporarily drop ip header from the mbuf */ 46037469Ssklower m->m_data += sizeof(struct ip); 46136382Ssklower eonhdr = mtod(m, struct eon_hdr *); 46237469Ssklower if( iso_check_csum( m, sizeof(struct eon_hdr) ) != EOK ) { 46337469Ssklower IncStat(es_badcsum); 46437469Ssklower goto drop; 46537469Ssklower } 46637469Ssklower m->m_data -= sizeof(struct ip); 46737469Ssklower 46836382Ssklower IFDEBUG(D_EON) 46937469Ssklower printf("eoninput csum ok class 0x%x\n", eonhdr->eonh_class ); 47036382Ssklower printf("eoninput: eon header:\n"); 47136382Ssklower dump_buf(eonhdr, sizeof(struct eon_hdr)); 47236382Ssklower ENDDEBUG 47336382Ssklower 47436382Ssklower /* checks for debugging */ 47536382Ssklower if( eonhdr->eonh_vers != EON_VERSION) { 47636382Ssklower IncStat(es_badhdr); 47736382Ssklower goto drop; 47836382Ssklower } 47937469Ssklower m->m_flags &= ~(M_BCAST|M_MCAST); 48036382Ssklower switch( eonhdr->eonh_class) { 48136382Ssklower case EON_BROADCAST: 48236382Ssklower IncStat(es_in_broad); 48337469Ssklower m->m_flags |= M_BCAST; 48436382Ssklower break; 48536382Ssklower case EON_NORMAL_ADDR: 48636382Ssklower IncStat(es_in_normal); 48736382Ssklower break; 48836382Ssklower case EON_MULTICAST_ES: 48936382Ssklower IncStat(es_in_multi_es); 49037469Ssklower m->m_flags |= M_MCAST; 49136382Ssklower break; 49236382Ssklower case EON_MULTICAST_IS: 49336382Ssklower IncStat(es_in_multi_is); 49437469Ssklower m->m_flags |= M_MCAST; 49536382Ssklower break; 49636382Ssklower } 49739195Ssklower eonifp->if_ipackets++; 49836382Ssklower 49936382Ssklower { 50036382Ssklower /* put it on the CLNP queue and set soft interrupt */ 50136382Ssklower struct ifqueue *ifq; 50236382Ssklower extern struct ifqueue clnlintrq; 50336382Ssklower 50437469Ssklower m->m_pkthdr.rcvif = eonifp; /* KLUDGE */ 50536382Ssklower IFDEBUG(D_EON) 50636382Ssklower printf("eoninput to clnl IFQ\n"); 50736382Ssklower ENDDEBUG 50836382Ssklower ifq = &clnlintrq; 50937469Ssklower s = splimp(); 51036382Ssklower if (IF_QFULL(ifq)) { 51136382Ssklower IF_DROP(ifq); 51236382Ssklower m_freem(m); 51339195Ssklower eonifp->if_iqdrops++; 51439195Ssklower eonifp->if_ipackets--; 51536382Ssklower splx(s); 51636382Ssklower return; 51736382Ssklower } 51836382Ssklower IF_ENQUEUE(ifq, m); 51936382Ssklower IFDEBUG(D_EON) 52036382Ssklower printf( 52137469Ssklower "0x%x enqueued on clnp Q: m_len 0x%x m_type 0x%x m_data 0x%x\n", 52237469Ssklower m, m->m_len, m->m_type, m->m_data); 52336382Ssklower dump_buf(mtod(m, caddr_t), m->m_len); 52436382Ssklower ENDDEBUG 52537469Ssklower schednetisr(NETISR_ISO); 52637469Ssklower splx(s); 52736382Ssklower } 52836382Ssklower } 52936382Ssklower 53036382Ssklower int 53136382Ssklower eonctlinput(cmd, sin) 53236382Ssklower int cmd; 53336382Ssklower struct sockaddr_in *sin; 53436382Ssklower { 53536382Ssklower extern u_char inetctlerrmap[]; 53636382Ssklower 53736382Ssklower IFDEBUG(D_EON) 53836382Ssklower printf("eonctlinput: cmd 0x%x addr: ", cmd); 53936382Ssklower dump_isoaddr(sin); 54036382Ssklower printf("\n"); 54136382Ssklower ENDDEBUG 54236382Ssklower 54336382Ssklower if (cmd < 0 || cmd > PRC_NCMDS) 54436382Ssklower return 0; 54536382Ssklower 54636382Ssklower IncStat(es_icmp[cmd]); 54736382Ssklower switch (cmd) { 54836382Ssklower 54937469Ssklower case PRC_QUENCH: 55036382Ssklower case PRC_QUENCH2: 55136382Ssklower /* TODO: set the dec bit */ 55236382Ssklower break; 55336382Ssklower case PRC_TIMXCEED_REASS: 55436382Ssklower case PRC_ROUTEDEAD: 55536382Ssklower case PRC_HOSTUNREACH: 55636382Ssklower case PRC_UNREACH_NET: 55736382Ssklower case PRC_IFDOWN: 55836382Ssklower case PRC_UNREACH_HOST: 55936382Ssklower case PRC_HOSTDEAD: 56036382Ssklower case PRC_TIMXCEED_INTRANS: 56136382Ssklower /* TODO: mark the link down */ 56236382Ssklower break; 56336382Ssklower 56436382Ssklower case PRC_UNREACH_PROTOCOL: 56536382Ssklower case PRC_UNREACH_PORT: 56636382Ssklower case PRC_UNREACH_SRCFAIL: 56736382Ssklower case PRC_REDIRECT_NET: 56836382Ssklower case PRC_REDIRECT_HOST: 56936382Ssklower case PRC_REDIRECT_TOSNET: 57036382Ssklower case PRC_REDIRECT_TOSHOST: 57136382Ssklower case PRC_MSGSIZE: 57236382Ssklower case PRC_PARAMPROB: 57345896Ssklower /* printf("eonctlinput: ICMP cmd 0x%x\n", cmd );*/ 57436382Ssklower break; 57536382Ssklower } 57636382Ssklower return 0; 57736382Ssklower } 57836382Ssklower 57937469Ssklower #endif 580