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

VxWorks

开发平台:

C/C++

  1. /* mbufSockLib.c - BSD mbuf socket interface library */
  2. /* Copyright 1984-2001 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01f,15oct01,rae  merge from truestack
  8. 01e,04dec00,adb  if (errno = EWOULDBLOCK) changed to if (EWOULDBLOCK == errno)
  9. 01d,25aug97,vin  fixed SPR8908.
  10. 01d,22nov96,vin  added new cluster support, initialized header fields for
  11.  for every packet.
  12. 01c,13nov95,dzb  changed to validate mbufId.type off MBUF_VALID (SPR #4066).
  13. 01b,20nov94,kdl  Fix blank line in comment block, for mangen.
  14. 01a,08nov94,dzb  written.
  15. */
  16. /*
  17. DESCRIPTION
  18. This library contains routines that communicate over BSD sockets using
  19. the `mbuf interface' described in the mbufLib manual page.  These mbuf
  20. socket calls interoperate with BSD sockets in a similar manner to the
  21. socket routines in sockLib, but they avoid copying data unnecessarily
  22. between application buffers and network buffers.
  23. NOMANUAL
  24. */
  25. /* includes */
  26. #include "vxWorks.h"
  27. #include "sockLib.h"
  28. #include "zbufSockLib.h"
  29. #include "mbufSockLib.h"
  30. #include "sys/socket.h"
  31. /* declare mbuf socket interface function table */
  32. LOCAL ZBUF_SOCK_FUNC mbufSockFunc =
  33.     {
  34.     (FUNCPTR) _mbufLibInit, /* back-end init pointer */
  35.     (FUNCPTR) _mbufSockSend,
  36.     (FUNCPTR) _mbufSockSendto,
  37.     (FUNCPTR) _mbufSockBufSend,
  38.     (FUNCPTR) _mbufSockBufSendto,
  39.     (FUNCPTR) _mbufSockRecv,
  40.     (FUNCPTR) _mbufSockRecvfrom
  41.     };
  42. /*******************************************************************************
  43. *
  44. * _mbufSockLibInit - initialize the BSD mbuf socket interface library
  45. *
  46. * The mbufSockLib API func table "mbufSockFunc" is published to the caller
  47. * by the return value of this routine.  Typically, this func table is used by
  48. * the zbufSock facility to call mbufSock routines within this library to
  49. * perform socket operations.  Even though the zbufSock interface defines
  50. * the ZBUF_SOCK_FUNC struct, it doesn't necessarily mean that zbufs must
  51. * be present.  This library may be used even if zbufs have been scaled out
  52. * of the system.
  53. *
  54. * RETURNS:
  55. * A pointer to a func table containing the mbufSockLib API.
  56. *
  57. * NOMANUAL
  58. */
  59. void * _mbufSockLibInit (void)
  60.     {
  61.     return ((void *) &mbufSockFunc); /* no init necessary */
  62.     }
  63. /*******************************************************************************
  64. *
  65. * _mbufSockSend - send mbuf data to a socket
  66. *
  67. * This routine transmits all of the data in <mbufId> to a previously
  68. * established connection-based (stream) socket.
  69. *
  70. * The <mbufLen> parameter is only used for determining the amount of space
  71. * needed from the socket write buffer.  <mbufLen> has no affect on how many
  72. * bytes are sent; the entire mbuf chain will be transmitted.  If the length of
  73. * <mbufId> is not known, it must be determined using _mbufLength() before
  74. * calling this routine.
  75. *
  76. * This routine transfers ownership of the mbuf chain from the user application
  77. * to the VxWorks network stack.  The mbuf ID <mbufId> is deleted by this
  78. * routine, and should not be used after this routine is called, even if
  79. * an ERROR status is returned.  The exceptions to this are if this routine
  80. * failed because the mbuf socket interface library was not uninitialized or an
  81. * invalid mbuf ID was passed in, in which case <mbufId> is not deleted.
  82. * Additionally, if the call fails during a non-blocking I/O socket write
  83. * with an errno of EWOULDBLOCK, then <mbufId> is not deleted, so that it may
  84. * be re-sent by the caller at a later time.
  85. *
  86. * RETURNS
  87. * The number of bytes sent, or ERROR if the call fails.
  88. *
  89. * SEE ALSO: mbufLength
  90. *
  91. * NOMANUAL
  92. */
  93. int _mbufSockSend
  94.     (
  95.     int s, /* socket to send to */
  96.     MBUF_ID mbufId, /* mbuf chain to transmit */
  97.     int mbufLen, /* length of entire mbuf chain */
  98.     int flags /* flags to underlying protocols */
  99.     )
  100.     {
  101.     MBUF_SEG mbufSeg; /* start of chain */
  102.     int retVal = 0; /* send() return status */
  103.     if (mbufId->type != MBUF_VALID) /* invalid mbuf ID ? */
  104. {
  105. errno = S_mbufLib_ID_INVALID;
  106. return (ERROR);
  107. }
  108.     if ((mbufSeg = mbufId->mbufHead) != NULL) /* send mbuf chain */
  109. {
  110. mbufSeg->m_pkthdr.rcvif = NULL;
  111. mbufSeg->m_pkthdr.len = mbufLen;
  112.         mbufSeg->m_flags |= M_PKTHDR;
  113.         retVal = send (s, (char *) mbufSeg, mbufLen, flags | MSG_MBUF);
  114. }
  115.     /* do not delete mbuf ID on EWOULDBLOCK error so user can resend ID */
  116.     if ((retVal != ERROR) || (errno != EWOULDBLOCK))
  117.         MBUF_ID_DELETE_EMPTY(mbufId);
  118.     return (retVal);
  119.     }
  120. /*******************************************************************************
  121. *
  122. * _mbufSockSendto - send a mbuf message to a socket
  123. *
  124. * This routine sends the entire message in <mbufId> to the datagram socket
  125. * named by <to>.  The socket <s> will be received by the receiver as the
  126. * sending socket.
  127. *
  128. * The <mbufLen> parameter is only used for determining the amount of space
  129. * needed from the socket write buffer.  <mbufLen> has no affect on how many
  130. * bytes are sent; the entire mbuf chain will be transmitted.  If the length of
  131. * <mbufId> is not known, it must be determined using _mbufLength() before
  132. * calling this routine.
  133. *
  134. * This routine transfers ownership of the mbuf chain from the user application
  135. * to the VxWorks network stack.  The mbuf ID <mbufId> is deleted by this
  136. * routine, and should not be used after this routine is called, even if
  137. * an ERROR status is returned.  The exceptions to this are if this routine
  138. * failed because the mbuf socket interface library was not uninitialized or an
  139. * invalid mbuf ID was passed in, in which case <mbufId> is not deleted.
  140. * Additionally, if the call fails during a non-blocking I/O socket write
  141. * with an errno of EWOULDBLOCK, then <mbufId> is not deleted, so that it may
  142. * be re-sent by the caller at a later time.
  143. *
  144. * RETURNS
  145. * The number of bytes sent, or ERROR if the call fails.
  146. *
  147. * SEE ALSO: mbufLength
  148. *
  149. * NOMANUAL
  150. */
  151. int _mbufSockSendto
  152.     (
  153.     int s, /* socket to send to */
  154.     MBUF_ID mbufId, /* mbuf chain to transmit */
  155.     int mbufLen, /* length of entire mbuf chain */
  156.     int flags, /* flags to underlying protocols */
  157.     struct sockaddr * to, /* recipient's address */
  158.     int tolen /* length of <to> sockaddr */
  159.     )
  160.     {
  161.     MBUF_SEG mbufSeg; /* start of chain */
  162.     int retVal = 0; /* sendto() return status */
  163.     if (mbufId->type != MBUF_VALID) /* invalid mbuf ID ? */
  164. {
  165. errno = S_mbufLib_ID_INVALID;
  166. return (ERROR);
  167. }
  168.     if ((mbufSeg = mbufId->mbufHead) != NULL) /* send mbuf chain */
  169. {
  170. mbufSeg->m_pkthdr.rcvif = NULL;
  171. mbufSeg->m_pkthdr.len = mbufLen;
  172.         mbufSeg->m_flags |= M_PKTHDR;
  173.         retVal = sendto (s, (char *) mbufSeg, mbufLen, flags | MSG_MBUF,
  174. to, tolen);
  175. }
  176.     /* do not delete mbuf ID on EWOULDBLOCK error so user can resend ID */
  177.     if ((retVal != ERROR) || (errno != EWOULDBLOCK))
  178.         MBUF_ID_DELETE_EMPTY(mbufId);
  179.     return (retVal);
  180.     }
  181. /*******************************************************************************
  182. *
  183. * _mbufSockBufSend - create an mbuf from user data and send it to a socket
  184. *
  185. * This routine creates an mbuf from the user buffer <buf>, and transmits
  186. * it to a previously established connection-based (stream) socket.
  187. *
  188. * The user provided free routine <freeRtn> will be called when <buf>
  189. * is no longer being used by the TCP/IP network stack.  If <freeRtn> is NULL,
  190. * this routine will function normally, except that the user will not be
  191. * notified when <buf> is released by the network stack.  <freeRtn> will be
  192. * called from the context of the task that last references it.  This is
  193. * typically either tNetTask context, or the caller's task context.
  194. * <freeRtn> should be declared as follows:
  195. * .CS
  196. *       void freeRtn
  197. *           (
  198. *           caddr_t     buf,    /@ pointer to user buffer @/
  199. *           int         freeArg /@ user provided argument to free routine @/
  200. *           )
  201. * .CE
  202. *
  203. * RETURNS:
  204. * The number of bytes sent, or ERROR if the call fails.
  205. *
  206. * NOMANUAL
  207. */
  208. int _mbufSockBufSend
  209.     (
  210.     int s, /* socket to send to */
  211.     char * buf, /* pointer to data buffer */
  212.     int bufLen, /* number of bytes to send */
  213.     VOIDFUNCPTR freeRtn, /* free routine callback */
  214.     int freeArg, /* argument to free routine */
  215.     int flags /* flags to underlying protocols */
  216.     )
  217.     {
  218.     struct mbufId mbufIdNew; /* dummy ID to insert into */
  219.     MBUF_SEG mbufSeg; /* start of mbuf chain */
  220.     int retVal = 0; /* send() return status */
  221.     mbufIdNew.mbufHead = NULL; /* init dummy ID */
  222.     mbufIdNew.type = MBUF_VALID;
  223.     /* build an mbuf chain with the user buffer as only mbuf */
  224.     if ((mbufSeg = _mbufInsertBuf (&mbufIdNew, NULL, 0, buf,
  225. bufLen, freeRtn, freeArg)) == NULL)
  226. {
  227.         if (freeRtn != NULL) /* call free routine on error */
  228.     (*freeRtn) (buf, freeArg);
  229.         return (ERROR);
  230. }
  231.     mbufSeg->m_pkthdr.rcvif = NULL;
  232.     mbufSeg->m_pkthdr.len = bufLen; 
  233.     mbufSeg->m_flags |= M_PKTHDR;
  234.     if (((retVal = send (s, (char *) mbufSeg, bufLen, flags | MSG_MBUF)) ==
  235. ERROR) && (errno == EWOULDBLOCK))
  236.         m_freem (mbufSeg); /* free for EWOULDBLOCK case */
  237.     return (retVal);
  238.     }
  239. /*******************************************************************************
  240. *
  241. * _mbufSockBufSendto - create an mbuf from a message and send it to a socket
  242. *
  243. * This routine creates an mbuf from the user buffer <buf>, and sends
  244. * it to the datagram socket named by <to>.  The socket <s> will be
  245. * received by the receiver as the sending socket.
  246. *
  247. * The user provided free routine <freeRtn> will be called when <buf>
  248. * is no longer being used by the UDP/IP network stack.  If <freeRtn> is NULL,
  249. * this routine will function normally, except that the user will not be
  250. * notified when <buf> is released by the network stack.  <freeRtn> will be
  251. * called from the context of the task that last references it.  This is
  252. * typically either tNetTask context or the caller's task context.
  253. * <freeRtn> should be declared as follows:
  254. * .CS
  255. *       void freeRtn
  256. *           (
  257. *           caddr_t     buf,    /@ pointer to user buffer @/
  258. *           int         freeArg /@ user provided argument to free routine @/
  259. *           )
  260. * .CE
  261. *
  262. * RETURNS:
  263. * The number of bytes sent, or ERROR if the call fails.
  264. *
  265. * NOMANUAL
  266. */
  267. int _mbufSockBufSendto
  268.     (
  269.     int s, /* socket to send to */
  270.     char * buf, /* pointer to data buffer */
  271.     int bufLen, /* number of bytes to send */
  272.     VOIDFUNCPTR freeRtn, /* free routine callback */
  273.     int freeArg, /* argument to free routine */
  274.     int flags, /* flags to underlying protocols */
  275.     struct sockaddr * to, /* recipient's address */
  276.     int tolen /* length of <to> sockaddr */
  277.     )
  278.     {
  279.     struct mbufId mbufIdNew; /* dummy ID to insert into */
  280.     MBUF_SEG mbufSeg; /* start of mbuf chain */
  281.     int retVal = 0; /* sendto() return status */
  282.     mbufIdNew.mbufHead = NULL; /* init dummy ID */
  283.     mbufIdNew.type = MBUF_VALID;
  284.     /* build an mbuf chain with the user buffer as only mbuf */
  285.     if ((mbufSeg = _mbufInsertBuf (&mbufIdNew, NULL, 0, buf,
  286. bufLen, freeRtn, freeArg)) == NULL)
  287. {
  288.         if (freeRtn != NULL) /* call free routine on error */
  289.     (*freeRtn) (buf, freeArg);
  290.         return (ERROR);
  291. }
  292.     mbufSeg->m_pkthdr.rcvif = NULL;
  293.     mbufSeg->m_pkthdr.len = bufLen; 
  294.     mbufSeg->m_flags |= M_PKTHDR;
  295.     if (((retVal = sendto (s, (char *) mbufSeg, bufLen, flags | MSG_MBUF,
  296.         to, tolen)) == ERROR) && (EWOULDBLOCK == errno))
  297.         m_freem (mbufSeg); /* free for EWOULDBLOCK case */
  298.     return (retVal);
  299.     }
  300. /*******************************************************************************
  301. *
  302. * _mbufSockRecv - receive data from a socket and place into a mbuf
  303. *
  304. * This routine receives data from a connection-based (stream) socket, and
  305. * returns the data to the user in a newly created mbuf chain.
  306. *
  307. * The <pLen> parameter indicates the number of bytes requested by the caller.
  308. * If the operation is successful, the number of bytes received will be
  309. * returned through this paramter.
  310. *
  311. * RETURNS:
  312. * The mbuf ID of a newly created mbuf chain containing the received data,
  313. * or NULL if the operation failed.
  314. *
  315. * NOMANUAL
  316. */
  317. MBUF_ID _mbufSockRecv
  318.     (
  319.     int s, /* socket to receive data from */
  320.     int flags, /* flags to underlying protocols */
  321.     int * pLen /* length of mbuf requested/received */
  322.     )
  323.     {
  324.     MBUF_ID mbufId; /* mbuf returned to user */
  325.     MBUF_SEG mbufSeg = NULL; /* received mbuf chain */
  326.     int status; /* recv() return status */
  327.     MBUF_ID_CREATE(mbufId); /* create ID for recv data */
  328.     if (mbufId == NULL)
  329.         return (NULL);
  330.     if ((status = (recv (s, (char *) &mbufSeg, *pLen, flags | MSG_MBUF))) ==
  331. ERROR) /* Rx data from the socket */
  332. {
  333. MBUF_ID_DELETE_EMPTY(mbufId);
  334. return (NULL);
  335. }
  336.     mbufId->mbufHead = mbufSeg; /* hook into mbuf ID */
  337.     *pLen = status; /* stuff return length */
  338.     return (mbufId);
  339.     }
  340. /*******************************************************************************
  341. *
  342. * _mbufSockRecvfrom - receive a message from a socket and place into a mbuf
  343. *
  344. * This routine receives a message from a datagram socket, and
  345. * returns the message to the user in a newly created mbuf chain.
  346. *
  347. * The message is received regardless of whether the socket is connected.
  348. * If <from> is non-zero, the address of the sender's socket is copied to it.
  349. * The value-result parameter <pFromLen> should be initialized to the size of
  350. * the <from> buffer.  On return, <pFromLen> contains the actual size of the
  351. * address stored in <from>.
  352. *
  353. * The <pLen> parameter indicates the number of bytes requested by the caller.
  354. * If the operation is successful, the number of bytes received will be
  355. * returned through this paramter.
  356. *
  357. * RETURNS:
  358. * The mbuf ID of a newly created mbuf chain containing the received message,
  359. * or NULL if the operation failed.
  360. *
  361. * NOMANUAL
  362. */
  363. MBUF_ID _mbufSockRecvfrom
  364.     (
  365.     int s, /* socket to receive from */
  366.     int flags, /* flags to underlying protocols */
  367.     int * pLen, /* length of mbuf requested/received */
  368.     struct sockaddr * from, /* where to copy sender's addr */
  369.     int * pFromLen /* value/result length of <from> */
  370.     )
  371.     {
  372.     MBUF_ID mbufId; /* mbuf returned to user */
  373.     MBUF_SEG mbufSeg = NULL; /* received mbuf chain */
  374.     int status; /* recvfrom() return status */
  375.     MBUF_ID_CREATE(mbufId); /* create ID for recv data */
  376.     if (mbufId == NULL)
  377.         return (NULL);
  378.     if ((status = (recvfrom (s, (char *) &mbufSeg, *pLen, flags | MSG_MBUF,
  379. from, pFromLen))) == ERROR) /* Rx message from the socket */
  380. {
  381. MBUF_ID_DELETE_EMPTY(mbufId);
  382. return (NULL);
  383. }
  384.     mbufId->mbufHead = mbufSeg; /* hook into mbuf ID */
  385.     *pLen = status; /* stuff return length */
  386.     return (mbufId);
  387.     }