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

VxWorks

开发平台:

C/C++

  1. /* proxyLib.c - proxy Address Resolution Protocol (ARP) client library */
  2. /* Copyright 1984 - 2001 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01k,10may02,kbw  making man page edits
  7. 01j,15oct01,rae  merge from truestack ver 01k, base 01f (no ether hooks)
  8. 01i,07feb01,spm  added merge record for 30jan01 update from version 01g of
  9.                  tor2_0_x branch (base 01f) and fixed modification history
  10. 01h,30jan01,ijm  corrected parameters for etherInputHookDelete
  11. 01g,30jan01,ijm  merged SPR #28602 fixes: proxy ARP services are obsolete
  12. 01f,26aug97,spm  removed compiler warnings (SPR #7866)
  13. 01e,11aug93,jmm  Changed ioctl.h and socket.h to sys/ioctl.h and sys/socket.h
  14. 01d,22sep92,jdi  documentation cleanup.
  15. 01c,15jun92,elh  changed parameters to proxyReg & proxyUnreg,
  16.  renamed to proxyLib, general cleanup.
  17. 01b,26may92,rrr  the tree shuffle
  18.   -changed includes to have absolute path from h/
  19. 01a,20sep91,elh   written.
  20. */
  21. /*
  22. DESCRIPTION
  23. This library implements the client side of the proxy Address Resolution
  24. Protocol (ARP).  It allows a VxWorks target to register itself as a proxy
  25. client by calling proxyReg() and to unregister itself by calling
  26. proxyUnreg().
  27. Both commands take an interface name and an IP address as arguments.  
  28. The interface, <ifName>, specifies the interface through which to send the
  29. message.  <ifName> must be a backplane interface.  <proxyAddr> is the
  30. IP address associated with the interface <ifName>.
  31. To use this feature, include INCLUDE_PROXY_CLIENT.
  32. INCLUDE FILES: proxyArpLib.h
  33. SEE ALSO: proxyArpLib
  34. INTERNAL
  35. This registration process is pretty simple.  Basically the client broadcasts
  36. a PROXY_MSG message on the proxy network.  The client retries sending
  37. the message until it either times out or it receives an ACK from the server.
  38. There are currently three types of messages: PROXY_REG, to add the client
  39. as a proxy client, PROXY_UNREG to delete the client as a proxy client,
  40. and a PROXY_PROBE message, to probe the server.
  41.     proxyReg  proxyUnreg v
  42. |   |  proxyAckEndRecv/proxyAckNptRecv
  43. v   v                             |                        
  44.      proxyMsgSend                               v
  45.                                            proxyAckCheck
  46. */
  47. /* includes */
  48. #include "vxWorks.h"
  49. #include "proxyArpLib.h"
  50. #include "netinet/in.h"
  51. #include "sys/socket.h"
  52. #include "net/if_arp.h"
  53. #include "net/if.h"
  54. #include "netinet/if_ether.h"
  55. #include "errno.h"
  56. #include "arpLib.h"
  57. #include "stdio.h"
  58. #include "string.h"
  59. #include "sysLib.h"
  60. #include "inetLib.h"
  61. #include "muxLib.h"
  62. #include "taskLib.h"
  63. #include "muxLib.h"
  64. #include "muxTkLib.h"
  65. #include "ipProto.h"
  66. /* globals */
  67. int proxyXmitMax   = XMIT_MAX; /* max rexmits      */
  68. int proxyVerbose     = FALSE; /* debug messages   */
  69. /* locals */
  70. LOCAL BOOL proxyAckReceived = FALSE; /* got ack     */
  71. LOCAL PROXY_MSG  proxyMsg; /* proxy message    */
  72. /* forward declarations */
  73. STATUS proxyMsgSend (char * ifName, char * proxyAddr, int op);
  74. LOCAL BOOL proxyAckCheck (M_BLK_ID pMblk);
  75. LOCAL BOOL proxyAckEndRecv (void * pCookie, long type, M_BLK_ID pBuff,
  76.     LL_HDR_INFO * pLinkHdrInfo, void * pSpare);
  77. LOCAL BOOL proxyAckNptRecv (void * callbackId ,long type, M_BLK_ID pBuff,
  78.     void * pSpareData);
  79. /* imports */
  80. IMPORT struct ifnet * ifunit ();
  81. /*******************************************************************************
  82. *
  83. * proxyReg - register a proxy client
  84. *
  85. * This routine sends a message over the network interface <ifName> to register
  86. * <proxyAddr> as a proxy client. 
  87. *
  88. * RETURNS: OK, or ERROR if unsuccessful.
  89. */
  90. STATUS proxyReg
  91.     (
  92.     char * ifName, /* interface name */
  93.     char *   proxyAddr /* proxy address  */
  94.     )
  95.     {
  96.     if (ifName == NULL || proxyAddr == NULL)
  97. {
  98. errno = S_proxyArpLib_INVALID_PARAMETER;
  99. return (ERROR);
  100. }
  101.     if (proxyMsgSend (ifName, proxyAddr, PROXY_REG) == ERROR)
  102. return (ERROR);
  103.     arpFlush ();
  104.     return (OK);
  105.     }
  106. /*******************************************************************************
  107. *
  108. * proxyUnreg - unregister a proxy client
  109. *
  110. * This routine sends a  message over the network interface <ifName> to
  111. * unregister <proxyAddr> as a proxy client.
  112. *
  113. * RETURNS: OK, or ERROR if unsuccessful.
  114. */
  115. STATUS proxyUnreg
  116.     (
  117.     char * ifName, /* interface name */
  118.     char *  proxyAddr /* proxy address  */
  119.     )
  120.     {
  121.     if (ifName == NULL || proxyAddr == NULL)
  122. {
  123. errno = S_proxyArpLib_INVALID_PARAMETER;
  124. return (ERROR);
  125. }
  126.     if (proxyMsgSend (ifName, proxyAddr, PROXY_UNREG) == ERROR)
  127. return (ERROR);
  128.     arpFlush ();
  129.     return (OK);
  130.     }
  131. /*******************************************************************************
  132. *
  133. * proxyMsgSend - send a proxy message
  134. *
  135. * This routine creates a proxy message with operation type <op>. It then
  136. * broadcasts this message over the proxy interface identified by <proxyAddr>.
  137. *
  138. * NOMANUAL
  139. *
  140. * RETURNS: OK, or ERROR if unsuccessful.
  141. *
  142. * ERRNO
  143. *   S_proxyArpLib_INVALID_PARAMETER
  144. *   S_proxyArpLib_INVALID_INTERFACE
  145. *   S_proxyArpLib_INVALID_ADDRESS
  146. *   S_proxyArpLib_TIMEOUT
  147. *
  148. * INTERNAL
  149. * This routine is global but no manual because it is useful for debugging
  150. * purposes.
  151. */
  152. STATUS proxyMsgSend
  153.     (
  154.     char * ifName, /* interface name */
  155.     char *  proxyAddr, /* proxy interface addr */
  156.     int op  /* operation */
  157.     )
  158.     {
  159.     struct ether_header  eh;  /* ethernet header */
  160.     int ix; /* index variable */
  161.     int delay; /* xmit delay value  */
  162.     struct ifnet * pIf;
  163.     struct mbuf * pMbuf;
  164.     struct sockaddr dst;
  165.     IP_DRV_CTRL * pDrvCtrl;
  166.     void * pCookie;
  167.     FUNCPTR pBoundRtn = NULL;
  168.     int  level;
  169.     int  result;
  170.     if (op < PROXY_PROBE || op >= PROXY_ACK)
  171. {
  172. errno = S_proxyArpLib_INVALID_PARAMETER;
  173. return (ERROR); /* invalid op */
  174. }
  175.     if ((pIf = ifunit (ifName)) == NULL      ||
  176. (pIf->if_output == NULL)             ||
  177. (pIf->if_flags & IFF_BROADCAST) == 0 ||
  178. (pDrvCtrl = (IP_DRV_CTRL *)pIf->pCookie) == NULL)
  179. {
  180. errno = S_proxyArpLib_INVALID_INTERFACE;
  181. return (ERROR);                  /* interface not attached */
  182. }
  183.     /* fill in proxy message */
  184.     bzero ((caddr_t ) &proxyMsg, sizeof (proxyMsg));
  185.     proxyMsg.op = htonl (op);
  186.     if ((proxyMsg.clientAddr.s_addr = inet_addr (proxyAddr)) == ERROR)
  187. {
  188. errno = S_proxyArpLib_INVALID_ADDRESS;
  189. return (ERROR);
  190. }
  191.     bcopy ((caddr_t) ((struct arpcom *)pIf)->ac_enaddr,
  192.    (caddr_t) proxyMsg.clientHwAddr, sizeof (proxyMsg.clientHwAddr));
  193.     /* fill in ethernet header */
  194.     bzero ((caddr_t) &eh, sizeof (eh));
  195.     eh.ether_type = PROXY_TYPE; /* htons is done in ipOutput */
  196.     bcopy ((char *) etherbroadcastaddr, (char *) eh.ether_dhost,
  197.    sizeof (etherbroadcastaddr));
  198.     proxyAckReceived = FALSE;
  199.     bzero ((caddr_t)&dst, sizeof (dst));
  200.     dst.sa_len = sizeof (dst);
  201.     dst.sa_family = AF_UNSPEC;
  202.     bcopy((caddr_t)&eh, (caddr_t)&dst.sa_data, sizeof(eh));
  203.     /* bind proxyAckInput as SNARF */
  204.     if (muxTkDrvCheck (pIf->if_name))
  205. {
  206. pCookie = muxTkBind (pIf->if_name, pIf->if_unit,
  207.      (FUNCPTR)proxyAckNptRecv, NULL, NULL, NULL,
  208.      MUX_PROTO_SNARF, "PROXY ACK NPT",
  209.      pDrvCtrl, NULL, NULL);
  210. pBoundRtn = (FUNCPTR)proxyAckNptRecv;
  211. }
  212.     else
  213. {
  214. pCookie = muxBind (pIf->if_name, pIf->if_unit,
  215.    (FUNCPTR)proxyAckEndRecv, NULL, NULL, NULL,
  216.    MUX_PROTO_SNARF, "PROXY ACK END",
  217.    pDrvCtrl);
  218. pBoundRtn = (FUNCPTR)proxyAckEndRecv;
  219. }
  220.     if (proxyVerbose)
  221.      printf ("sending <%d> client %sn", op, proxyAddr);
  222.     for (ix = 0; ix < proxyXmitMax; ix++)
  223.         {
  224. printf (".");
  225.         /* form an ARP packet */
  226.         if ((pMbuf = bcopy_to_mbufs ((caddr_t)&proxyMsg, sizeof (PROXY_MSG),
  227.  0, pIf, NONE)) == NULL)
  228.             return (ERROR);
  229.         level = splnet ();
  230.         result = pIf->if_output (pIf, pMbuf, &dst, NULL);
  231.         splx (level);
  232. if (result)
  233.     break;
  234. delay = sysClkRateGet () * XMIT_DELAY; /* rexmit delay */
  235. while (delay-- > 0)
  236.     {
  237.     if (proxyAckReceived)
  238. {
  239. muxUnbind (pCookie, MUX_PROTO_SNARF, pBoundRtn);
  240. return (OK);
  241. }
  242.     taskDelay (1);
  243.     }
  244. }
  245.     if (ix == proxyXmitMax)
  246.        errno = S_proxyArpLib_TIMEOUT;
  247.     muxUnbind (pCookie, MUX_PROTO_SNARF, pBoundRtn);
  248.     return (ERROR);
  249.     }
  250. /*******************************************************************************
  251. *
  252. * proxyAckCheck - check proxy ack
  253. * This routine checks given link frame if it is an expected proxy arp ACK.
  254. * If it is the case, this routine consumed the pMblk and frees it.
  255. *
  256. * RETURNS:TRUE if received an expected arp ACK, or FALSE
  257. */
  258. LOCAL BOOL proxyAckCheck
  259.     (
  260.     M_BLK_ID pMblk /* incoming link frame */
  261.     )
  262.     {
  263.     struct ether_header *  eh;            /* ethernet header      */
  264.     PROXY_MSG *    pMsg; /* pointer to message */
  265.     char    inputBuffer [2176];  /* frame buffer  */
  266.     UINT            length; /* packet length */
  267.     /* check proxy message type in ethernet header */
  268.     eh = (struct ether_header *)pMblk->mBlkHdr.mData;
  269.     length = pMblk->mBlkHdr.mLen;
  270.     if (length <= SIZEOF_ETHERHEADER ||
  271. (ntohs (eh->ether_type)) != PROXY_TYPE)
  272.         return (FALSE);
  273.     /* get proxy arp message */
  274.      
  275.     bzero (inputBuffer, sizeof (inputBuffer));
  276.     bcopyBytes ((caddr_t)((u_char *)pMblk->mBlkHdr.mData + SIZEOF_ETHERHEADER),
  277.                 inputBuffer, length - SIZEOF_ETHERHEADER);
  278.     pMsg = (PROXY_MSG *)inputBuffer;
  279.     /*  check to make sure I sent out the original message  */
  280.     if ((ntohl (pMsg->op) == PROXY_ACK) &&
  281.         (pMsg->clientAddr.s_addr == proxyMsg.clientAddr.s_addr) &&
  282.         (bcmp ((caddr_t) pMsg->clientHwAddr, (caddr_t) proxyMsg.clientHwAddr,
  283.                sizeof (pMsg->clientHwAddr)) == 0))
  284.         {
  285.         proxyAckReceived = TRUE;
  286.         netMblkClChainFree (pMblk);
  287.         return (TRUE);
  288.         }
  289.     return (FALSE);
  290.     }
  291. /*******************************************************************************
  292. *
  293. * proxyAckEndRecv - End version of a proxy ACK receive routine
  294. *
  295. * This module is the SNARF input routine used to receive the ACK
  296. * for a previous operation sent to the proxy server via proxyMsgSend.
  297. *
  298. * RETURNS: See proxyAckCheck().
  299. */
  300. LOCAL BOOL proxyAckEndRecv
  301.     (
  302.     void *              pCookie,        /* device identifier from driver */
  303.     long                type,           /* Protocol type.  */
  304.     M_BLK_ID            pMblk,          /* The whole packet. */
  305.     LL_HDR_INFO *       pLinkHdrInfo,   /* pointer to link level header info */
  306.     void *              pSpare          /* pointer to IP_DRV_CTRL */
  307.     )
  308.     {
  309.     /* already got a reply, or unknown device */
  310.     if (proxyAckReceived || pMblk == NULL)
  311. return (FALSE);
  312.     return (proxyAckCheck (pMblk));
  313.     }
  314. /*******************************************************************************
  315. *
  316. * proxyAckNptRecv - NPT version of a proxy ACK receive routine
  317. *
  318. * This module is the SNARF input routine used to receive the ACK
  319. * for a previous operation sent to the proxy server via proxyMsgSend.
  320. *
  321. * RETURNS: See proxyAckCheck().
  322. */
  323. LOCAL BOOL proxyAckNptRecv
  324.     (
  325.     void *    ipCallbackId,  /* Sent down in muxTkBind call. */
  326.     long      type,          /* Protocol type.  */
  327.     M_BLK_ID  pMblk,         /* The whole packet. */
  328.     void *    pSpareData     /* out of band data */
  329.     )
  330.     {
  331.     if (proxyAckReceived || pMblk == NULL)
  332.         return (FALSE);
  333.     return (proxyAckCheck (pMblk));
  334.     }