if_loop.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:9k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* if_loop.c - software loopback network interface driver */
  2. /* Copyright 1984 - 2002 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /* $NetBSD: if_loop.c,v 1.13 1994/10/30 21:48:50 cgd Exp $ */
  5. /*
  6.  * Copyright (c) 1982, 1986, 1993
  7.  * The Regents of the University of California.  All rights reserved.
  8.  *
  9.  * Redistribution and use in source and binary forms, with or without
  10.  * modification, are permitted provided that the following conditions
  11.  * are met:
  12.  * 1. Redistributions of source code must retain the above copyright
  13.  *    notice, this list of conditions and the following disclaimer.
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in the
  16.  *    documentation and/or other materials provided with the distribution.
  17.  * 3. All advertising materials mentioning features or use of this software
  18.  *    must display the following acknowledgement:
  19.  * This product includes software developed by the University of
  20.  * California, Berkeley and its contributors.
  21.  * 4. Neither the name of the University nor the names of its contributors
  22.  *    may be used to endorse or promote products derived from this software
  23.  *    without specific prior written permission.
  24.  *
  25.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  26.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  29.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  30.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  31.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  34.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  35.  * SUCH DAMAGE.
  36.  *
  37.  * @(#)if_loop.c 8.1 (Berkeley) 6/10/93
  38.  */
  39. /*
  40. modification history
  41. --------------------
  42. 02d,07may02,wap  Need to use netJobAdd() again (at least for now) to avoid
  43.                  infinite recursion problem (SPR #76568)
  44. 02c,15apr02,wap  remove netJobAdd() in keeping with new behavior in if_subr.c
  45. 02b,12oct01,rae  merge from truestack ver. 02e, base 02a (SPR #69112)
  46. 02a,19mar96,vin  upgraded to BSD4.4, integrated with 01o of if_loop.c.
  47. 01o,11aug93,jmm  Changed ioctl.h and socket.h to sys/ioctl.h and sys/socket.h
  48. 01n,22feb93,jdi  documentation cleanup.
  49. 01m,09sep92,gae  documentation tweaks.
  50. 01l,26may92,rrr  the tree shuffle
  51.   -changed includes to have absolute path from h/
  52. 01k,04oct91,rrr  passed through the ansification filter
  53.                   -changed functions to ansi style
  54.   -changed includes to have absolute path from h/
  55.   -changed copyright notice
  56. 01j,02oct90,hjb  we now always turn IFF_NOTRAILERS on for loopback device
  57.    and turn IFF_RUNNING on when needed.
  58. 02i,19sep90,dab  made loattach() return STATUS.
  59. 02h,11jul90,hjb  removed references to ipintrPending(), netTaskSemId and
  60.  added a call to schednetisr().
  61. 02g,19apr90,hjb  deletd param.h, de-linted
  62. 02f,18mar90,hjb  reduction of redundant code, performance enhancement
  63. 02f,16apr89,gae  updated to new 4.3BSD.
  64. 02e,30may88,dnw  changed to v4 names.
  65. 02d,05jan88,rdc  added include of systm.h
  66. 02c,02may87,dnw  clean up.
  67. 02b,03apr87,ecs  added copyright.
  68. 02a,02feb87,jlf  Removed CLEAN ifdefs.
  69. */
  70. /*
  71. DESCRIPTION
  72. This module implements the software loopback network interface driver.
  73. The only user-callable routine is loattach(), which publishes the `lo'
  74. interface and initializes the driver and device.
  75. This interface is used for protocol testing and timing.
  76. By default, the loopback interface is accessible at Internet
  77. address 127.0.0.1.
  78. To use this feature, include the following component:
  79. INCLUDE_LOOPBACK 
  80. BOARD LAYOUT
  81. This device is "software only."  A jumpering diagram is not applicable.
  82. SEE ALSO: ifLib
  83. */
  84. #include "vxWorks.h"
  85. #include "tickLib.h"
  86. #include "netLib.h"
  87. #include "logLib.h"
  88. #include "net/mbuf.h"
  89. #include "sys/socket.h"
  90. #include "errno.h"
  91. #include "sys/ioctl.h"
  92. #include "net/if.h"
  93. #include "net/route.h"
  94. #include "net/systm.h"
  95. #include "net/if_types.h"
  96. #ifdef INET
  97. #include "netinet/in.h"
  98. #include "netinet/in_systm.h"
  99. #include "netinet/in_var.h"
  100. #include "netinet/ip_var.h"    /* for ipintr() prototype */
  101. #include "netinet/ip.h"
  102. #endif
  103. #ifdef NS
  104. #include "../netns/ns.h"
  105. #include "../netns/ns_if.h"
  106. #endif
  107. #ifdef VIRTUAL_STACK
  108. #include "netinet/vsLib.h"
  109. #endif
  110. #ifndef VIRTUAL_STACK
  111. #define NLOOP 1      /* currently only one */
  112. #endif /* VIRTUAL_STACK */
  113. #define LOMTU (1024*32) /* maximum packet size */
  114. #ifndef VIRTUAL_STACK
  115. struct ifnet loif [NLOOP];
  116. #endif /* VIRTUAL_STACK */
  117. /* forward declarations */
  118. int looutput ();
  119. static int loioctl (struct ifnet *ifp, int cmd, caddr_t data);
  120. static void lortrequest (int cmd, struct rtentry * rt, struct sockaddr * sa);
  121. /*******************************************************************************
  122. *
  123. * loattach - publish the `lo' network interface and initialize the driver and pseudo-device
  124. *
  125. * This routine attaches an `lo' Ethernet interface to the network, if the
  126. * interface exists.  It makes the interface available by filling in
  127. * the network interface record.  The system initializes the interface
  128. * when it is ready to accept packets.
  129. *
  130. * RETURNS: OK.
  131. */
  132. STATUS loattach (void)
  133.     {
  134.     FAST struct ifnet * ifp;
  135.     FAST int ix;
  136.     for (ix = 0; ix < NLOOP; ix++) 
  137. {
  138. ifp = &loif[ix];
  139. bzero ((char *)ifp, sizeof (struct ifnet));
  140. ifp->if_unit = ix;
  141. ifp->if_name = "lo";
  142. ifp->if_mtu = LOMTU;
  143. ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST;
  144. ifp->if_ioctl = loioctl;
  145. ifp->if_output = looutput;
  146. ifp->if_type = IFT_LOOP;
  147. ifp->if_hdrlen = 0;
  148. ifp->if_addrlen = 0;
  149.         ifp->pCookie = NULL;
  150. #ifdef VIRTUAL_STACK
  151.         ifp->vsNum = myStackNum; /* Assign the VS Num to the IFNET for */
  152.                                  /* processing by tNetTask on reception */
  153.                                  /* of packets. */
  154. #endif
  155. if_attach(ifp);
  156. }
  157.     return (OK);
  158.     }
  159. /*******************************************************************************
  160. *
  161. * looutput - output packet on loopback interface
  162. *
  163. * NOMANUAL
  164. */
  165. int looutput
  166.     (
  167.     struct ifnet * ifp,
  168.     FAST struct mbuf * m,
  169.     struct sockaddr * dst,
  170.     FAST struct rtentry *rt
  171.     )
  172.     {
  173.     int  s;
  174.     if ((m->m_flags & M_PKTHDR) == 0)
  175. panic("looutput no HDR");
  176.     ifp->if_lastchange = tickGet();
  177. #if NBPFILTER > 0
  178.     if (ifp->if_bpf) 
  179. {
  180. /*
  181.  * We need to prepend the address family as
  182.  * a four byte field.  Cons up a dummy header
  183.  * to pacify bpf.  This is safe because bpf
  184.  * will only read from the mbuf (i.e., it won't
  185.  * try to free it or keep a pointer to it).
  186.  */
  187. struct mbuf m0;
  188. u_int af = dst->sa_family;
  189. m0.m_next = m;
  190. m0.m_len = 4;
  191. m0.m_data = (char *)&af;
  192. bpf_mtap(ifp->if_bpf, &m0);
  193. }
  194. #endif
  195.     m->m_pkthdr.rcvif = ifp;
  196.     if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) 
  197. {
  198. m_freem(m);
  199. return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
  200. rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
  201. }
  202.     ifp->if_opackets++;
  203.     ifp->if_obytes += m->m_pkthdr.len;
  204.     switch (dst->sa_family) 
  205. {
  206. #ifdef INET
  207. case AF_INET:
  208.     netJobAdd ((FUNCPTR)ipintr, (int)m, 0, 0, 0, 0);
  209.     break;
  210. #endif
  211. default:
  212.     logMsg("lo%d: can't handle af%dn", (int)ifp->if_unit,
  213.    (int)dst->sa_family,0,0,0,0);
  214.     m_freem(m);
  215.     return (EAFNOSUPPORT);
  216. }
  217.     s = splimp();
  218.     ifp->if_ipackets++;
  219.     ifp->if_ibytes += m->m_pkthdr.len;
  220.     splx(s);
  221.     return (0);
  222.     }
  223. /*******************************************************************************
  224. *
  225. * lortrequest - handle route request for loop back
  226. *
  227. * NOMANUAL
  228. */
  229. void lortrequest
  230.     (
  231.     int  cmd,
  232.     struct rtentry * rt,
  233.     struct sockaddr * sa
  234.     )
  235.     {
  236.     if (rt)
  237. rt->rt_rmx.rmx_mtu = LOMTU;
  238.     }
  239. /*******************************************************************************
  240. *
  241. * loioctl - handle loop ioctl request
  242. */
  243. LOCAL int loioctl
  244.     (
  245.     FAST struct ifnet * ifp,
  246.     int  cmd,
  247.     caddr_t  data
  248.     )
  249.     {
  250.     FAST struct ifaddr *ifa;
  251.     FAST struct ifreq * ifr;
  252.     FAST int  error = 0;
  253.     switch (cmd)
  254. {
  255. case SIOCSIFADDR:
  256.     ifp->if_flags |= (IFF_UP | IFF_RUNNING);
  257.     ifa = (struct ifaddr *)data;
  258.     if (ifa != 0 && ifa->ifa_addr->sa_family == AF_ISO)
  259. ifa->ifa_rtrequest = lortrequest;
  260.     /* Everything else is done at a higher level. */
  261.     break;
  262. case SIOCADDMULTI:
  263. case SIOCDELMULTI:
  264.     ifr = (struct ifreq *)data;
  265.     if (ifr == 0)
  266. {
  267. error = EAFNOSUPPORT; /* XXX */
  268. break;
  269. }
  270.     switch (ifr->ifr_addr.sa_family)
  271. {
  272. #ifdef INET
  273. case AF_INET:
  274.     break;
  275. #endif
  276. default:
  277.     error = EAFNOSUPPORT;
  278.     break;
  279. }
  280.     break;
  281. default:
  282.     error = EINVAL;
  283. }
  284.     return (error);
  285.     }