rarpLib.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:13k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* rarpLib.c - Reverse Address Resolution Protocol (RARP) client library */
  2. /* Copyright 1999 - 2002 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5.  * Copyright (c) 1982, 1986, 1988, 1993
  6.  *      The Regents of the University of California.  All rights reserved.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  *      This product includes software developed by the University of
  19.  *      California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  *
  36.  *      @(#)if_ether.c  8.2 (Berkeley) 9/26/94
  37.  */
  38. /*
  39. modification history
  40. --------------------
  41. 01i,17dec01,vvv  fixed doc build errors
  42. 01h,05nov01,vvv  fixed compilation warnings
  43. 01g,29mar01,spm  file creation: copied from version 01f of tor2_0.open_stack
  44.                  branch (wpwr VOB) for unified code base; fixed published
  45.                  routine name for coding conventions
  46. 01f,29jun00,spm  updated to handle NPT version of MUX interface
  47. 01e,11may00,brx  fixed error returns to set errno and return ERROR
  48. 01d,11may00,ead  added calls to virtualStackIdCheck() in the various RARP
  49.                  commands
  50. 01c,25apr00,spm  made virtual stack support optional (enabled by default)
  51. 01b,18apr00,ead  modified to be multi-instance
  52. 01a,28dec99,brx  created from RARP code found in if_ether.c
  53. */
  54. /*
  55. DESCRIPTION
  56. This library is an implementation of the Reverse Address Resolution Protocol.
  57. This protocol allows devices such as diskless workstations request an IP 
  58. address at boot-time from a dedicated server on the local network.
  59. The routine rarpGet() broadcasts a RARP request on the local ethernet and
  60. returns a response.  If a RARP server does not respond after the specified
  61. timeout interval, rarpGet() returns with an error code set in errno.
  62.  
  63. */
  64. #include "vxWorks.h"
  65. #include "stdio.h"
  66. #include "taskLib.h"
  67. #include "end.h"
  68. #include "muxLib.h"
  69. #include "ipProto.h"
  70. #include "sysLib.h"
  71. #include "logLib.h"
  72. #include "errnoLib.h"
  73. #ifdef VIRTUAL_STACK
  74. #include "netinet/vsLib.h"
  75. #endif /* VIRTUAL_STACK */
  76. /* defines */
  77. #define SAMPLE_RATE 6
  78. /* define ERROR codes */
  79. #define S_rarpLib_TIMEOUT           (M_rarpLib | 1)
  80. #define S_rarpLib_NETDOWN           (M_rarpLib | 2)
  81. #define S_rarpLib_INPROGRESS        (M_rarpLib | 3)
  82. #define S_rarpLib_NORESPONSE        (M_rarpLib | 4)
  83. /* typedefs */
  84. /* externs */
  85. /* locals */
  86. #ifndef VIRTUAL_STACK
  87. LOCAL SEM_ID revarpInProgress = NULL;
  88. #endif /* VIRTUAL_STACK */
  89. /* revarp state */
  90. #ifndef VIRTUAL_STACK
  91. typedef struct
  92.     {
  93.     BOOL ipAddrInitialized; 
  94.     struct in_addr  ipAddr;
  95.     END_OBJ *pEndId;
  96.     BOOL rarpDebug;
  97.     } RARPSTATE;
  98. LOCAL RARPSTATE rarpState;
  99. #endif /* VIRTUAL_STACK */
  100. /* forward declarations */
  101. void rarpSetDebug( int );
  102. int rarpGet ( char *, int, struct in_addr *, int);
  103. void rarpIn ( END_OBJ *, long, M_BLK_ID, LL_HDR_INFO *, IP_DRV_CTRL *);
  104. int revarpwhoami(struct in_addr *, struct ifnet *, int);
  105. void revarprequest(struct ifnet *);
  106. void in_revarpinput(struct ether_arp *);
  107. /******************************************************************************
  108. *
  109. * rarpLibInit - Initialize rarp client
  110. *
  111. * This routine links the RARP facility into the VxWorks system.
  112. * These routines are included automatically if INCLUDE_RARP is defined.
  113. *
  114. * Returns: N/A
  115. *
  116. */
  117. STATUS rarpLibInit(void)
  118.     {
  119. #ifndef VIRTUAL_STACK
  120.     if (revarpInProgress == NULL){
  121. #endif /* VIRTUAL_STACK */
  122.         revarpInProgress = semBCreate(SEM_Q_PRIORITY, SEM_FULL);
  123.         if (revarpInProgress == NULL)
  124.          return ERROR;
  125.         return OK;
  126. #ifndef VIRTUAL_STACK
  127.     }
  128.     else
  129.         return OK;
  130. #endif /* VIRTUAL_STACK */
  131. #ifdef VIRTUAL_STACK
  132.     rarpState.ipAddrInitialized = FALSE;
  133.     rarpState.ipAddr.s_addr = 0;
  134.     rarpState.pEndId = 0;
  135.     rarpState.rarpDebug = FALSE;
  136.     return OK;
  137. #endif /* VIRTUAL_STACK */
  138.     }
  139. /******************************************************************************
  140. *
  141. * rarpDebugSet - Set the debug facility in RARP
  142. *
  143. * This routine sets the RARP debug facility.  If the argument is non-zero, 
  144. * debug messages will be sent to the logging task.  If the argument is zero
  145. * RARP operates quietly.  Default is quiet operation.
  146. *
  147. * Returns: N/A
  148. *
  149. */
  150. void rarpDebugSet
  151.     (
  152.     int flag
  153.     )
  154.     {
  155. #ifdef VIRTUAL_STACK
  156.     virtualStackIdCheck();
  157. #endif /* VIRTUAL_STACK */
  158.     logMsg("Setting rarpDebug to %dn", flag, 0, 0, 0, 0, 0);
  159.     rarpState.rarpDebug = (flag != 0) ? TRUE : FALSE;
  160.     }
  161. /*******************************************************************************
  162. *
  163. * rarpGet - broadcast a RARP packet and wait for a reply
  164. *
  165. * rarpGet() maps ethernet hardware addresses to IP protocol addresses.
  166. * This routine generates an ethertype 0x8035 packet and 
  167. * broadcasts it on the device local network.  If a RARP server is on the 
  168. * network, it replies with an IP address that corresponds to the device 
  169. * hardware address. 
  170. *
  171. * .IP <IFname>
  172. * Expects a pointer to the character string which contains the name of the 
  173. * interface.
  174. * .IP <IFunit>
  175. * Expects a number which is the unit of the device named in IFname.
  176. * .IP <Addr> 
  177. * Expects a pointer to a struct in_addr. The IP address of the device will
  178. * be placed in this buffer after it is received from the RARP server.
  179. * .IP <Tmo>
  180. * Expects an integer for timeout value in seconds.
  181. *
  182. * Returns: OK, S_rarpLib_NETDOWN if IFname is not a valid device, 
  183. *          S_rarpLib_INPROGRESS if another RARP request is in progress, 
  184. *          S_rarpLib_NORESPONSE if there is no response from a server.
  185. */
  186. int rarpGet
  187.     (
  188.     char *IFname, 
  189.     int IFunit, 
  190.     struct in_addr *Addr, 
  191.     int tmo
  192.     )
  193.     {
  194.     struct ifnet *pIf;
  195.     END_OBJ * pEnd;
  196.     void *pCookie;
  197.     int errorFlag = 0;
  198.     char cName[16];
  199. #ifdef VIRTUAL_STACK
  200.     virtualStackIdCheck();
  201. #endif /* VIRTUAL_STACK */
  202.     semTake(revarpInProgress, WAIT_FOREVER);
  203.     rarpState.ipAddrInitialized = FALSE;
  204.     rarpState.ipAddr.s_addr = 0;
  205.     pEnd = endFindByName (IFname, IFunit);
  206.     sprintf(cName,"%s%d", IFname, IFunit);
  207.     pIf = (struct ifnet *)ifunit(cName);
  208.     if (pIf == NULL || pEnd == NULL) 
  209.         {
  210. if (rarpState.rarpDebug)
  211.             logMsg ("RARP: Can't find interface %s!n", (int)cName,
  212.                     0, 0, 0, 0, 0);
  213. semGive(revarpInProgress);
  214.         errnoSet(S_rarpLib_NETDOWN);
  215. return ERROR;
  216.         }
  217.     if ((pCookie = muxBind(IFname, IFunit, (FUNCPTR)rarpIn, NULL, 
  218. NULL, NULL, 0x8035, "IP 4.4 RARP", NULL )) == NULL)
  219.         {
  220.  if (rarpState.rarpDebug)
  221.               logMsg("RARP: Can't bind to MUXn",0,0,0,0,0,0);
  222.  semGive(revarpInProgress);
  223.          errnoSet(S_rarpLib_NETDOWN);
  224.  return ERROR;
  225.         }
  226.     rarpState.pEndId = pEnd;
  227.     /* broadcast  RARP request, wait for answer */
  228.     errorFlag = revarpwhoami(Addr, pIf, tmo); 
  229.     if( muxUnbind( pCookie, 0x8035, (FUNCPTR)rarpIn) != OK)
  230. if (rarpState.rarpDebug)
  231.     logMsg("RARP: Error in MUX unbindn",0,0,0,0,0,0);
  232.     semGive(revarpInProgress);
  233.     if (errorFlag != 0)
  234.         {
  235. if (rarpState.rarpDebug)
  236.     logMsg("RARP: no responsen",0,0,0,0,0,0);
  237.         errnoSet(errorFlag);
  238. return ERROR;
  239.         }
  240.     else 
  241.     return OK;
  242.     }
  243. /*******************************************************************************
  244. *
  245. * revarpwhoami - issues RARP request and waits for a reply from a server
  246. *
  247. *
  248. * RETURNS: OK if the IP has been received, S_rarpLib_NORESPONSE if no
  249. *          response has been received before tmo seconds.
  250. *
  251. *
  252. * NOMANUAL
  253. */
  254. int
  255. revarpwhoami
  256.     (
  257.     struct in_addr *pClientIn,
  258.     struct ifnet *pIfp,
  259.     int tmo
  260.     )
  261.     {
  262.     int count;
  263.     if (rarpState.ipAddrInitialized) 
  264.         return OK;
  265.     if (rarpState.rarpDebug)
  266. logMsg("RARP: sending requestn",0,0,0,0,0,0);
  267.     revarprequest(pIfp);
  268.     for(count=0; count < SAMPLE_RATE*tmo; count++)
  269.         {
  270.         if (rarpState.ipAddrInitialized == FALSE)
  271.             taskDelay (sysClkRateGet()/SAMPLE_RATE); 
  272.         else 
  273.     {
  274.             bcopy((caddr_t)&rarpState.ipAddr, (char *)pClientIn, 
  275.    sizeof(*pClientIn));
  276.             if (rarpState.rarpDebug)
  277.         logMsg("RARP: received reply: 0x%xn",
  278.         (unsigned int)rarpState.ipAddr.s_addr, 0, 0, 0, 0, 0);
  279.             return OK;
  280.             } 
  281.         }
  282.     /* no reply before time out */
  283.     if (rarpState.rarpDebug)
  284.         logMsg("RARP: did not receive reply after %d secondsn",
  285.         tmo, 0, 0, 0, 0, 0);
  286.     errnoSet(S_rarpLib_NORESPONSE);
  287.     return ERROR;
  288.     }
  289.    
  290. /*******************************************************************************
  291. *
  292. * revarprequest - form RARP ether packet and transmit
  293. *
  294. * Send a RARP request for the ip address of the specified interface.
  295. *
  296. * RETURNS: NA
  297. *
  298. * NOMANUAL
  299. */
  300. void
  301. revarprequest
  302.     (
  303.     struct ifnet *pIfp
  304.     )
  305.     {
  306. struct sockaddr sa;
  307. struct mbuf *pMbuf;
  308. struct ether_header *eh;
  309. struct ether_arp *ea;
  310. struct arpcom *ac = (struct arpcom *)pIfp;
  311. if ((pMbuf = mHdrClGet(M_DONTWAIT, MT_DATA, sizeof(*ea), TRUE)) == NULL)
  312.     return; 
  313. pMbuf->m_len = sizeof(*ea);
  314. pMbuf->m_pkthdr.len = sizeof(*ea);
  315. MH_ALIGN(pMbuf, sizeof(*ea));
  316. ea = mtod(pMbuf, struct ether_arp *);
  317. eh = (struct ether_header *)sa.sa_data;
  318. bzero((caddr_t)ea, sizeof(*ea));
  319. bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
  320.       sizeof(eh->ether_dhost));
  321. eh->ether_type = ETHERTYPE_REVARP; /* htons is done in ipOutput */
  322. ea->arp_hrd = htons(ARPHRD_ETHER);
  323. ea->arp_pro = htons(ETHERTYPE_IP);
  324. ea->arp_hln = sizeof(ea->arp_sha); /* hardware address length */
  325. ea->arp_pln = sizeof(ea->arp_spa); /* protocol address length */
  326. ea->arp_op = htons(ARPOP_REVREQUEST);
  327. bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_sha,
  328.    sizeof(ea->arp_sha));
  329. bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_tha,
  330.    sizeof(ea->arp_tha));
  331. sa.sa_family = AF_UNSPEC;
  332. sa.sa_len = sizeof(sa);
  333. pIfp->if_output(pIfp, pMbuf, &sa, (struct rtentry *)0);
  334.     }
  335. /*******************************************************************************
  336. *
  337. * rarpIn -  callback routine bound to MUX 
  338. *
  339. * This routine is called by the mux when a packet is ready to be processed
  340. *
  341. * RETURNS: N/A
  342. *
  343. */
  344. void rarpIn        
  345.     (
  346.     END_OBJ *           pCookie,        /* Returned by muxBind() call. */
  347.     long                type,           /* Protocol type.  */
  348.     M_BLK_ID            m,           /* The whole packet. */
  349.     LL_HDR_INFO *       pLinkHdrInfo,   /* pointer to linklevel header*/
  350.     IP_DRV_CTRL *       pDrvCtrl        /* ip Drv ctrl */
  351.     )
  352.     {
  353.     struct arphdr *pArphdr;
  354.     struct ether_arp *ea;
  355.     char   *pChar;
  356.     /* verify correct interface */
  357.     if (rarpState.pEndId != pCookie)
  358.         goto out;
  359.         
  360.     /* if a previous reply has already answered, we're done */
  361.     if (rarpState.ipAddrInitialized)
  362.         goto out;
  363.     if (m->m_len < sizeof(struct arphdr))
  364. goto out;
  365.     pChar = mtod(m, char *);
  366.     pArphdr = (struct arphdr *)(pChar + pLinkHdrInfo->dataOffset);
  367.     /* verify supported RARP values per RFC 903 */
  368.     ea = (struct ether_arp *)pArphdr;
  369.     if (ntohs(pArphdr->ar_hrd) != ARPHRD_ETHER)
  370. goto out;
  371.     if (ntohs(pArphdr->ar_pro) != ETHERTYPE_IP)
  372. goto out;
  373.     if (ntohs(ea->arp_op) != ARPOP_REVREPLY)
  374. goto out;
  375.     if (m->m_len < sizeof(struct arphdr) + 
  376.         2 * (pArphdr->ar_hln + pArphdr->ar_pln))
  377. goto out;
  378. /** copy address into global variable **/
  379.     bcopy((caddr_t)ea->arp_tpa, (caddr_t)&rarpState.ipAddr, 
  380.    sizeof(rarpState.ipAddr));
  381.     rarpState.ipAddrInitialized = TRUE;
  382.     out:
  383. m_freem(m);
  384.     }