The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netiso/if_eon.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: if_eon.c,v 1.42 2003/09/30 00:01:18 christos Exp $     */
    2 
    3 /*-
    4  * Copyright (c) 1991, 1993
    5  *      The Regents of the University of California.  All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. Neither the name of the University nor the names of its contributors
   16  *    may be used to endorse or promote products derived from this software
   17  *    without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  *
   31  *      @(#)if_eon.c    8.2 (Berkeley) 1/9/95
   32  */
   33 
   34 /***********************************************************
   35                 Copyright IBM Corporation 1987
   36 
   37                       All Rights Reserved
   38 
   39 Permission to use, copy, modify, and distribute this software and its
   40 documentation for any purpose and without fee is hereby granted,
   41 provided that the above copyright notice appear in all copies and that
   42 both that copyright notice and this permission notice appear in
   43 supporting documentation, and that the name of IBM not be
   44 used in advertising or publicity pertaining to distribution of the
   45 software without specific, written prior permission.
   46 
   47 IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
   48 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
   49 IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
   50 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
   51 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
   52 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
   53 SOFTWARE.
   54 
   55 ******************************************************************/
   56 
   57 /*
   58  * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
   59  */
   60 /*
   61  *      EON rfc
   62  *  Layer between IP and CLNL
   63  *
   64  * TODO:
   65  * Put together a current rfc986 address format and get the right offset
   66  * for the nsel
   67  */
   68 
   69 #include <sys/cdefs.h>
   70 __KERNEL_RCSID(0, "$NetBSD: if_eon.c,v 1.42 2003/09/30 00:01:18 christos Exp $");
   71 
   72 #include "opt_eon.h"
   73 
   74 #ifdef EON
   75 #define NEON 1
   76 
   77 
   78 #include <sys/param.h>
   79 #include <sys/systm.h>
   80 #include <sys/mbuf.h>
   81 #include <sys/buf.h>
   82 #include <sys/protosw.h>
   83 #include <sys/socket.h>
   84 #include <sys/ioctl.h>
   85 #include <sys/errno.h>
   86 
   87 #include <machine/cpu.h>        /* XXX for setsoftnet().  This must die. */
   88 
   89 #include <net/if.h>
   90 #include <net/if_types.h>
   91 #include <net/if_dl.h>
   92 #include <net/netisr.h>
   93 #include <net/route.h>
   94 
   95 #include <net/if_ether.h>
   96 
   97 #include <netinet/in.h>
   98 #include <netinet/in_systm.h>
   99 #include <netinet/in_var.h>
  100 #include <netinet/ip.h>
  101 #include <netinet/ip_var.h>
  102 
  103 #include <netiso/iso.h>
  104 #include <netiso/iso_var.h>
  105 #include <netiso/iso_snpac.h>
  106 #include <netiso/argo_debug.h>
  107 #include <netiso/iso_errno.h>
  108 #include <netiso/eonvar.h>
  109 
  110 #include <machine/stdarg.h>
  111 
  112 #include "loop.h"
  113 
  114 extern struct ifnet loif[NLOOP];
  115 
  116 extern struct timeval time;
  117 
  118 #define EOK 0
  119 
  120 struct ifnet    eonif[1];
  121 
  122 void
  123 eonprotoinit()
  124 {
  125         (void) eonattach();
  126 }
  127 
  128 struct eon_llinfo eon_llinfo;
  129 #define PROBE_OK 0;
  130 
  131 
  132 /*
  133  * FUNCTION:            eonattach
  134  *
  135  * PURPOSE:                     autoconf attach routine
  136  *
  137  * RETURNS:                     void
  138  */
  139 
  140 void
  141 eonattach()
  142 {
  143         struct ifnet *ifp = eonif;
  144 
  145 #ifdef ARGO_DEBUG
  146         if (argo_debug[D_EON]) {
  147                 printf("eonattach()\n");
  148         }
  149 #endif
  150         sprintf(ifp->if_xname, "eon%d", 0);
  151         ifp->if_mtu = ETHERMTU;
  152         ifp->if_softc = NULL;
  153         /* since everything will go out over ether or token ring */
  154 
  155         ifp->if_ioctl = eonioctl;
  156         ifp->if_output = eonoutput;
  157         ifp->if_type = IFT_EON;
  158         ifp->if_addrlen = 5;
  159         ifp->if_hdrlen = EONIPLEN;
  160         ifp->if_flags = IFF_BROADCAST;
  161         if_attach(ifp);
  162         if_alloc_sadl(ifp);
  163         eonioctl(ifp, SIOCSIFADDR, (caddr_t) ifp->if_addrlist.tqh_first);
  164         eon_llinfo.el_qhdr.link =
  165                 eon_llinfo.el_qhdr.rlink = &(eon_llinfo.el_qhdr);
  166 
  167 #ifdef ARGO_DEBUG
  168         if (argo_debug[D_EON]) {
  169                 printf("eonattach()\n");
  170         }
  171 #endif
  172 }
  173 
  174 
  175 /*
  176  * FUNCTION:            eonioctl
  177  *
  178  * PURPOSE:                     io controls - ifconfig
  179  *                              need commands to
  180  *                                      link-UP (core addr) (flags: ES, IS)
  181  *                                      link-DOWN (core addr) (flags: ES, IS)
  182  *                              must be callable from kernel or user
  183  *
  184  * RETURNS:                     nothing
  185  */
  186 int
  187 eonioctl(ifp, cmd, data)
  188         struct ifnet *ifp;
  189         u_long          cmd;
  190         caddr_t data;
  191 {
  192         int             s = splnet();
  193         int    error = 0;
  194 
  195 #ifdef ARGO_DEBUG
  196         if (argo_debug[D_EON]) {
  197                 printf("eonioctl (cmd 0x%lx) \n", cmd);
  198         }
  199 #endif
  200 
  201         switch (cmd) {
  202                 struct ifaddr *ifa;
  203 
  204         case SIOCSIFADDR:
  205                 if ((ifa = (struct ifaddr *) data) != NULL) {
  206                         ifp->if_flags |= IFF_UP;
  207                         if (ifa->ifa_addr->sa_family != AF_LINK)
  208                                 ifa->ifa_rtrequest = eonrtrequest;
  209                 }
  210                 break;
  211         default:
  212                 error = EINVAL;
  213                 break;
  214         }
  215         splx(s);
  216         return (error);
  217 }
  218 
  219 
  220 void
  221 eoniphdr(hdr, loc, ro, class, zero)
  222         struct route   *ro;
  223         struct eon_iphdr *hdr;
  224         caddr_t         loc;
  225         int             class, zero;
  226 {
  227         struct mbuf     mhead;
  228         struct sockaddr_in *sin = satosin(&ro->ro_dst);
  229         if (zero) {
  230                 bzero((caddr_t) hdr, sizeof(*hdr));
  231                 bzero((caddr_t) ro, sizeof(*ro));
  232         }
  233         sin->sin_family = AF_INET;
  234         sin->sin_len = sizeof(*sin);
  235         bcopy(loc, (caddr_t) & sin->sin_addr, sizeof(struct in_addr));
  236         /*
  237          * If there is a cached route,
  238          * check that it is to the same destination
  239          * and is still up.  If not, free it and try again.
  240          */
  241         if (ro->ro_rt) {
  242                 struct sockaddr_in *dst = satosin(rt_key(ro->ro_rt));
  243                 if ((ro->ro_rt->rt_flags & RTF_UP) == 0 ||
  244                     sin->sin_addr.s_addr != dst->sin_addr.s_addr) {
  245                         RTFREE(ro->ro_rt);
  246                         ro->ro_rt = (struct rtentry *) 0;
  247                 }
  248         }
  249         rtalloc(ro);
  250         if (ro->ro_rt)
  251                 ro->ro_rt->rt_use++;
  252         hdr->ei_ip.ip_dst = sin->sin_addr;
  253         hdr->ei_ip.ip_p = IPPROTO_EON;
  254         hdr->ei_ip.ip_ttl = MAXTTL;
  255         hdr->ei_eh.eonh_class = class;
  256         hdr->ei_eh.eonh_vers = EON_VERSION;
  257         hdr->ei_eh.eonh_csum = 0;
  258         mhead.m_data = (caddr_t) & hdr->ei_eh;
  259         mhead.m_len = sizeof(struct eon_hdr);
  260         mhead.m_next = 0;
  261 #ifdef ARGO_DEBUG
  262         if (argo_debug[D_EON]) {
  263                 printf("eonoutput : gen csum (%p, offset %lu, datalen %ld)\n",
  264                     &mhead, (unsigned long)offsetof(struct eon_hdr, eonh_csum),
  265                     (long)sizeof(struct eon_hdr));
  266         }
  267 #endif
  268         iso_gen_csum(&mhead,
  269               offsetof(struct eon_hdr, eonh_csum), sizeof(struct eon_hdr));
  270 }
  271 /*
  272  * FUNCTION:            eonrtrequest
  273  *
  274  * PURPOSE:                     maintains list of direct eon recipients.
  275  *                                      sets up IP route for rest.
  276  *
  277  * RETURNS:                     nothing
  278  */
  279 void
  280 eonrtrequest(cmd, rt, info)
  281         int cmd;
  282         struct rtentry *rt;
  283         struct rt_addrinfo *info;
  284 {
  285         unsigned long   zerodst = 0;
  286         caddr_t         ipaddrloc = (caddr_t) & zerodst;
  287         struct eon_llinfo *el = (struct eon_llinfo *) rt->rt_llinfo;
  288         struct sockaddr *gate;
  289 
  290         /*
  291          * Common Housekeeping
  292          */
  293         switch (cmd) {
  294         case RTM_DELETE:
  295                 if (el) {
  296                         remque(&(el->el_qhdr));
  297                         if (el->el_iproute.ro_rt)
  298                                 RTFREE(el->el_iproute.ro_rt);
  299                         Free(el);
  300                         rt->rt_llinfo = 0;
  301                 }
  302                 return;
  303 
  304         case RTM_ADD:
  305         case RTM_RESOLVE:
  306                 rt->rt_rmx.rmx_mtu = loif[0].if_mtu;    /* unless better below */
  307                 R_Malloc(el, struct eon_llinfo *, sizeof(*el));
  308                 rt->rt_llinfo = (caddr_t) el;
  309                 if (el == 0)
  310                         return;
  311                 Bzero(el, sizeof(*el));
  312                 insque(&(el->el_qhdr), &eon_llinfo.el_qhdr);
  313                 el->el_rt = rt;
  314                 break;
  315         }
  316         if (info && (gate = info->rti_info[RTAX_GATEWAY]))      /*XXX*/
  317                 switch (gate->sa_family) {
  318                 case AF_LINK:
  319 #define SDL(x) ((struct sockaddr_dl *)x)
  320                         if (SDL(gate)->sdl_alen == 1)
  321                                 el->el_snpaoffset = *(u_char *) LLADDR(SDL(gate));
  322                         else
  323                                 ipaddrloc = LLADDR(SDL(gate));
  324                         break;
  325                 case AF_INET:
  326                         ipaddrloc = (caddr_t) & satosin(gate)->sin_addr;
  327                         break;
  328                 default:
  329                         return;
  330                 }
  331         el->el_flags |= RTF_UP;
  332         eoniphdr(&el->el_ei, ipaddrloc, &el->el_iproute, EON_NORMAL_ADDR, 0);
  333         if (el->el_iproute.ro_rt)
  334                 rt->rt_rmx.rmx_mtu = el->el_iproute.ro_rt->rt_rmx.rmx_mtu
  335                         - sizeof(el->el_ei);
  336 }
  337 
  338 /*
  339  * FUNCTION:            eonoutput
  340  *
  341  * PURPOSE:             prepend an eon header and hand to IP
  342  * ARGUMENTS:           (ifp) is points to the ifnet structure for this
  343  *                      unit/device (m)  is an mbuf *, *m is a CLNL packet
  344  *                      (dst) is a destination address - have to interp. as
  345  *                      multicast or broadcast or real address.
  346  *
  347  * RETURNS:             unix error code
  348  *
  349  * NOTES:
  350  *
  351  */
  352 int
  353 eonoutput(ifp, m, sdst, rt)
  354         struct ifnet   *ifp;
  355         struct mbuf *m; /* packet */
  356         struct sockaddr *sdst;          /* destination addr */
  357         struct rtentry *rt;
  358 {
  359         struct sockaddr_iso *dst = (struct sockaddr_iso *) sdst;
  360         struct eon_llinfo *el;
  361         struct eon_iphdr *ei;
  362         struct route   *ro;
  363         int             datalen;
  364         struct mbuf    *mh;
  365         int             error = 0, class = 0, alen = 0;
  366         caddr_t         ipaddrloc = NULL;
  367         static struct eon_iphdr eon_iphdr;
  368         static struct route route;
  369 
  370 #ifdef ARGO_DEBUG
  371         if (argo_debug[D_EON]) {
  372                 printf("eonoutput \n");
  373         }
  374 #endif
  375 
  376         ifp->if_opackets++;
  377         if (rt == 0 || (el = (struct eon_llinfo *) rt->rt_llinfo) == 0) {
  378                 if (dst->siso_family == AF_LINK) {
  379                         struct sockaddr_dl *sdl = (struct sockaddr_dl *) dst;
  380 
  381                         ipaddrloc = LLADDR(sdl);
  382                         alen = sdl->sdl_alen;
  383                 } else if (dst->siso_family == AF_ISO &&
  384                            dst->siso_data[0] == AFI_SNA) {
  385                         alen = dst->siso_nlen - 1;
  386                         ipaddrloc = (caddr_t) dst->siso_data + 1;
  387                 }
  388                 switch (alen) {
  389                 case 5:
  390                         class = 4[(u_char *) ipaddrloc];
  391                 case 4:
  392                         ro = &route;
  393                         ei = &eon_iphdr;
  394                         eoniphdr(ei, ipaddrloc, ro, class, 1);
  395                         goto send;
  396                 }
  397 einval:
  398                 error = EINVAL;
  399                 goto flush;
  400         }
  401         if ((el->el_flags & RTF_UP) == 0) {
  402                 eonrtrequest(RTM_CHANGE, rt, (struct rt_addrinfo *) 0);
  403                 if ((el->el_flags & RTF_UP) == 0) {
  404                         error = EHOSTUNREACH;
  405                         goto flush;
  406                 }
  407         }
  408         if ((m->m_flags & M_PKTHDR) == 0) {
  409                 printf("eon: got non headered packet\n");
  410                 goto einval;
  411         }
  412         ei = &el->el_ei;
  413         ro = &el->el_iproute;
  414         if (el->el_snpaoffset) {
  415                 if (dst->siso_family == AF_ISO) {
  416                         bcopy((caddr_t) & dst->siso_data[el->el_snpaoffset],
  417                               (caddr_t) & ei->ei_ip.ip_dst, sizeof(ei->ei_ip.ip_dst));
  418                 } else
  419                         goto einval;
  420         }
  421 send:
  422         /* put an eon_hdr in the buffer, prepended by an ip header */
  423         datalen = m->m_pkthdr.len + EONIPLEN;
  424         if (datalen > IP_MAXPACKET) {
  425                 error = EMSGSIZE;
  426                 goto flush;
  427         }
  428         MGETHDR(mh, M_DONTWAIT, MT_HEADER);
  429         if (mh == (struct mbuf *) 0) {
  430                 error = ENOBUFS;
  431                 goto flush;
  432         }
  433         mh->m_next = m;
  434         m = mh;
  435         MH_ALIGN(m, sizeof(struct eon_iphdr));
  436         m->m_len = sizeof(struct eon_iphdr);
  437         m->m_pkthdr.len = datalen;
  438         ei->ei_ip.ip_len = htons(datalen);
  439         ifp->if_obytes += datalen;
  440         *mtod(m, struct eon_iphdr *) = *ei;
  441 
  442 #ifdef ARGO_DEBUG
  443         if (argo_debug[D_EON]) {
  444                 printf("eonoutput dst ip addr : %x\n", ei->ei_ip.ip_dst.s_addr);
  445                 printf("eonoutput ip_output : eonip header:\n");
  446                 dump_buf(ei, sizeof(struct eon_iphdr));
  447         }
  448 #endif
  449 
  450         error = ip_output(m, (struct mbuf *) 0, ro, 0,
  451             (struct ip_moptions *)NULL, (struct socket *)NULL);
  452         m = 0;
  453         if (error) {
  454                 ifp->if_oerrors++;
  455                 ifp->if_opackets--;
  456                 ifp->if_obytes -= datalen;
  457         }
  458 flush:
  459         if (m)
  460                 m_freem(m);
  461         return error;
  462 }
  463 
  464 void
  465 #if __STDC__
  466 eoninput(struct mbuf *m, ...)
  467 #else
  468 eoninput(m, va_alist)
  469         struct mbuf *m;
  470         va_dcl
  471 #endif
  472 {
  473         int             iphlen;
  474         struct eon_hdr *eonhdr;
  475         struct ip *iphdr;
  476         struct ifnet   *eonifp;
  477         int             s;
  478         va_list ap;
  479 
  480         va_start(ap, m);
  481         iphlen = va_arg(ap, int);
  482         va_end(ap);
  483 
  484         eonifp = &eonif[0];     /* kludge - really want to give CLNP the ifp
  485                                  * for eon, not for the real device */
  486 
  487 #ifdef ARGO_DEBUG
  488         if (argo_debug[D_EON]) {
  489                 printf("eoninput() %p m_data %p m_len 0x%x dequeued\n",
  490                     m, (m ? m->m_data : 0), m ? m->m_len : 0);
  491         }
  492 #endif
  493 
  494         if (m == 0)
  495                 return;
  496         if (iphlen > sizeof(struct ip))
  497                 ip_stripoptions(m, (struct mbuf *) 0);
  498         if (m->m_len < EONIPLEN) {
  499                 if ((m = m_pullup(m, EONIPLEN)) == 0) {
  500                         IncStat(es_badhdr);
  501         drop:
  502 #ifdef ARGO_DEBUG
  503                         if (argo_debug[D_EON]) {
  504                                 printf("eoninput: DROP \n");
  505                         }
  506 #endif
  507                         eonifp->if_ierrors++;
  508                         m_freem(m);
  509                         return;
  510                 }
  511         }
  512         eonif->if_ibytes += m->m_pkthdr.len;
  513         iphdr = mtod(m, struct ip *);
  514         /* do a few checks for debugging */
  515         if (iphdr->ip_p != IPPROTO_EON) {
  516                 IncStat(es_badhdr);
  517                 goto drop;
  518         }
  519         /* temporarily drop ip header from the mbuf */
  520         m->m_data += sizeof(struct ip);
  521         eonhdr = mtod(m, struct eon_hdr *);
  522         if (iso_check_csum(m, sizeof(struct eon_hdr)) != EOK) {
  523                 IncStat(es_badcsum);
  524                 goto drop;
  525         }
  526         m->m_data -= sizeof(struct ip);
  527 
  528 #ifdef ARGO_DEBUG
  529         if (argo_debug[D_EON]) {
  530                 printf("eoninput csum ok class 0x%x\n", eonhdr->eonh_class);
  531                 printf("eoninput: eon header:\n");
  532                 dump_buf(eonhdr, sizeof(struct eon_hdr));
  533         }
  534 #endif
  535 
  536         /* checks for debugging */
  537         if (eonhdr->eonh_vers != EON_VERSION) {
  538                 IncStat(es_badhdr);
  539                 goto drop;
  540         }
  541         m->m_flags &= ~(M_BCAST | M_MCAST);
  542         switch (eonhdr->eonh_class) {
  543         case EON_BROADCAST:
  544                 IncStat(es_in_broad);
  545                 m->m_flags |= M_BCAST;
  546                 break;
  547         case EON_NORMAL_ADDR:
  548                 IncStat(es_in_normal);
  549                 break;
  550         case EON_MULTICAST_ES:
  551                 IncStat(es_in_multi_es);
  552                 m->m_flags |= M_MCAST;
  553                 break;
  554         case EON_MULTICAST_IS:
  555                 IncStat(es_in_multi_is);
  556                 m->m_flags |= M_MCAST;
  557                 break;
  558         }
  559         eonifp->if_ipackets++;
  560 
  561         {
  562                 /* put it on the CLNP queue and set soft interrupt */
  563                 struct ifqueue *ifq;
  564                 extern struct ifqueue clnlintrq;
  565 
  566                 m->m_pkthdr.rcvif = eonifp;     /* KLUDGE */
  567 #ifdef ARGO_DEBUG
  568                 if (argo_debug[D_EON]) {
  569                         printf("eoninput to clnl IFQ\n");
  570                 }
  571 #endif
  572                 ifq = &clnlintrq;
  573                 s = splnet();
  574                 if (IF_QFULL(ifq)) {
  575                         IF_DROP(ifq);
  576                         m_freem(m);
  577                         eonifp->if_iqdrops++;
  578                         eonifp->if_ipackets--;
  579                         splx(s);
  580                         return;
  581                 }
  582                 IF_ENQUEUE(ifq, m);
  583 #ifdef ARGO_DEBUG
  584                 if (argo_debug[D_EON]) {
  585                         printf(
  586                             "%p enqueued on clnp Q: m_len 0x%x m_type 0x%x m_data %p\n",
  587                             m, m->m_len, m->m_type, m->m_data);
  588                         dump_buf(mtod(m, caddr_t), m->m_len);
  589                 }
  590 #endif
  591                 schednetisr(NETISR_ISO);
  592                 splx(s);
  593         }
  594 }
  595 
  596 void *
  597 eonctlinput(cmd, sa, dummy)
  598         int             cmd;
  599         struct sockaddr *sa;
  600         void *dummy;
  601 {
  602         struct sockaddr_in *sin = (struct sockaddr_in *) sa;
  603 #ifdef ARGO_DEBUG
  604         if (argo_debug[D_EON]) {
  605                 printf("eonctlinput: cmd 0x%x addr: ", cmd);
  606                 dump_isoaddr((struct sockaddr_iso *) sin);
  607                 printf("\n");
  608         }
  609 #endif
  610 
  611         if ((unsigned)cmd >= PRC_NCMDS)
  612                 return NULL;
  613 
  614         IncStat(es_icmp[cmd]);
  615         switch (cmd) {
  616 
  617         case PRC_QUENCH:
  618         case PRC_QUENCH2:
  619                 /* TODO: set the dec bit */
  620                 break;
  621         case PRC_TIMXCEED_REASS:
  622         case PRC_ROUTEDEAD:
  623         case PRC_HOSTUNREACH:
  624         case PRC_UNREACH_NET:
  625         case PRC_IFDOWN:
  626         case PRC_UNREACH_HOST:
  627         case PRC_HOSTDEAD:
  628         case PRC_TIMXCEED_INTRANS:
  629                 /* TODO: mark the link down */
  630                 break;
  631 
  632         case PRC_UNREACH_PROTOCOL:
  633         case PRC_UNREACH_PORT:
  634         case PRC_UNREACH_SRCFAIL:
  635         case PRC_REDIRECT_NET:
  636         case PRC_REDIRECT_HOST:
  637         case PRC_REDIRECT_TOSNET:
  638         case PRC_REDIRECT_TOSHOST:
  639         case PRC_MSGSIZE:
  640         case PRC_PARAMPROB:
  641 #if 0
  642                 printf("eonctlinput: ICMP cmd 0x%x\n", cmd );
  643 #endif
  644                 break;
  645         }
  646         return NULL;
  647 }
  648 
  649 #endif

Cache object: cb977e09bdd441a63e13a26af8ba19c5


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.