sockLib.c
上传用户:baixin
上传日期:2008-03-13
资源大小:4795k
文件大小:53k
开发平台:

MultiPlatform

  1. /* sockLib.c - generic socket library */
  2. /* Copyright 1984 - 2002 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 05g,27jun02,rae  removed excessive accept() argument validation
  8. 05f,21may02,vvv  updated connectWithTimeout doc (SPR #27684)
  9. 05e,10may02,kbw  making man page edits
  10. 05d,28apr02,rae  Corrected getsockname() doc (SPR #70327)
  11. 05c,26apr02,vvv  updated setsockopt doc (SPR #21992/28868/30335)
  12. 05b,07dec01,rae  merge from synth ver 05c (spr #28181 correctly)
  13. 05a,15oct01,rae  merge from truestack ver 05b base 04q (SPR #28181 etc.)
  14. 04z,12sep01,cyr  doc: correct typo per SPR 29064
  15. 04y,16jan01,cco  Add 'See Also' reference to UNIX network Programming
  16. 04x,10jan01,dgr  correcting comment header block for shutdown() as per
  17.                  SPR#35529
  18. 04w,14nov00,rae  removed unused argument from sockLibAdd()
  19. 04v,10nov00,ham  doc: corrected setsockopt(SO_DEBUG) example (SPR #62267).
  20. 04u,24oct00,dgr  adding to setsockopt() comment header block (re: SPR #20562)
  21. 04t,18oct00,zhu  change return value for sockFdtosockFunc
  22. 04s,17oct00,zhu  calloc doesn't need zero out
  23. 04r,16oct00,zhu  zero out pSockFdMap and move file descriptor check funtion
  24.  here
  25. 04q,17aug99,pai  changed send() prototype to use const on the second param
  26.                  (SPR 21829)
  27. 04t,08nov99,pul  T2 cumulative patch 2
  28. 04s,29apr99,pul  Upgraded NPT phase3 code to tor2.0.0
  29. 04r,16mar99,spm  recovered orphaned code from tor2_0_x branch (SPR #25770)
  30. 04q,-2feb99,sgv  Added bitFlags to the sockLibAdd routine, added routine
  31.  sockfdtosockFunc
  32. 04p,02dec98,n_s  updated comments for sendmsg and recvmsg. spr 23552
  33. 04o,10nov98,spm  changed socket map for removal of closed files (SPR #21583)
  34. 04n,15mar99,c_c  Doc: Updated setsockopt () with SO_DEBUG flag (SPR #9636).
  35. 04m,14dec97,jdi  doc: cleanup.
  36. 04l,10dec97,kbw  fixed man page problems 
  37. 04k,04aug97,kbw  fixed man page problems found in beta review
  38. 04j,15apr97,kbw  fixed minor man page format problems
  39. 04i,14apr97,vin  added changes to setsockopt docs.
  40. 04l,14jul97,dgp  doc: change ^C to CTRL-C in setsockopt()
  41. 04k,10jul97,dgp  doc: fix SPRs 8470 & 8471, parameters of getsockopt()
  42. 04j,31jul95,dzb  check for lib init in sockLibAdd() and socket().
  43. 04i,25jul95,dzb  added fd-to-pSockFunc table.  added sockLibAdd().
  44. 04h,21jul95,dzb  changed to be a BSD/STREAMS switchyard.
  45.  Previous sockLib.c file moved to bsdSockLib.c.
  46. 04i,26oct95,rhp  doc: mention values for <flags> params in socket
  47.                  calls (SPR#4423)
  48. 04h,14oct95,jdi  doc: revised pathnames for Tornado.
  49. 04g,13mar95,dzb  added spl semaphore protection to socket() (SPR #4016).
  50. 04f,11feb95,jdi  doc format repairs.
  51. 04e,18jan95,jdi  doc cleanup for connectWithTimeout().
  52. 04d,14not94,rhp  added socket-option documentation to setsockopt man page,
  53.                  and added pointers from send() and sendto() (SPR#3785);
  54.                  specified no support for UNIX Domain sockets (SPR#3519,1432)
  55. 04c,18aug94,dzb  Removed the NOMANUAL from connectWithTimeout() (SPR #3550).
  56.                  Added m_freem() calls for mbuf interface (MSG_MBUF).
  57. 04b,22apr93,caf  ansification: added cast to ioctl() parameter.
  58. 04a,11aug93,jmm  Changed ioctl.h and socket.h to sys/ioctl.h and sys/socket.h
  59. 03z,01mar93,jdi  doc: addition of ioctl() functions (SPR 1922); added
  60.  explanation of accept() parameters (SPR 1382).
  61. 03y,03feb93,jdi  documentation cleanup for 5.1.
  62. 03x,19aug92,smb  changed systime.h to sys/times.h.
  63. 03w,26may92,rrr  the tree shuffle
  64. 03v,04oct91,rrr  passed through the ansification filter
  65.                   -changed functions to ansi style
  66.   -changed includes to have absolute path from h/
  67.   -changed copyright notice
  68. 03u,30apr91,jdi  documentation tweaks.
  69. 03t,05apr91,jdi  documentation -- removed header parens and x-ref numbers;
  70.  doc review by dnw.
  71. 03s,24mar91,jaa  documentation cleanup.
  72. 03r,07feb91,elh  changed recvfrom to check if from is NULL before filling it.
  73. 03q,31jan91,jaa  documentation.
  74. 03p,25oct90,dnw  changed utime.h to systime.h.
  75. 03o,04oct90,shl  made connectWithTimeOut() NOMANUAL.
  76. 03n,02oct90,hjb  eliminated a race and a bug in sockClose().
  77. 03m,25may90,dnw  removed malloc of file name "(socket)" before calling iosFdSet.
  78.  added "(socket)" as device name for iosFdSet optimization.
  79. 03l,11may90,yao  added missing modification history (03k) for the last checkin.
  80. 03k,09may90,yao  typecasted malloc to (char *).
  81. 03j,07may90,hjb  added sockFdVerify(), connectWithTimeout(), a hack to avoid
  82.  register d2 trashing bug.
  83. 03i,19apr90,hjb  deleted sendit(), recvit() and modified sendmsg() and
  84.  recvmsg() accordingly, de-linted.
  85. 03h,18mar90,hjb  optimization of send(), sendto(), sockWrite(), recv(),
  86.  recvfrom(), sockRead().
  87. 03g,16mar90,rdc  removed polling version of select.
  88. 03f,09jun89,gae  cleanup of 03e.
  89. 03e,07jun89,gae  changed SOCKADDR back to "struct sockaddr".
  90. 03d,24may89,hjb  fixed a bug in bind(); when sobind() fails, we now free
  91.  the allocated mbuf before returning error code.
  92. 03c,14apr89,gae  made select backward compatible with BSD 4.2, fixed bug,
  93.  made time of 0 not actually delay, more optimizing.
  94. 03b,13apr89,rdc  made select detect passively closed sockets.
  95.  installed marc ullman's select optimizations.
  96. 03a,15oct88,dnw  changed call to sleep() to ksleep().
  97. 02z,13sep88,llk  Fixed bug in select.  Now it polls at least once at all times.
  98. 02y,26aug88,gae  lint.
  99. 02x,18aug88,gae  documentation.
  100. 02w,15jul88,llk  changed to malloc the name of a socket fd before calling
  101.    iosFdNew.
  102. 02v,22jun88,dnw  changed apparent socket filename from "(network)" to "(socket)"
  103. 02u,30may88,dnw  changed to v4 names.
  104. 02t,28may88,dnw  removed setNetStatus to netLib.
  105. 02s,04may88,jcf  changed so_timeoSem to so_timeoSemId
  106.    +ecs  fixed bug in select introduced in 02r.
  107. 02r,30mar88,gae  made mainly iosLib independent.  Cleaned up select(),
  108.    made it use BSD4.3 fd_set's and caught small bug.
  109. 02q,27jan88,jcf  made kernel independent.
  110. 02p,05jan88,rdc  added include of sysm.h
  111. 02o,14dec87,gae  added include of vxWorks.h!!!
  112. 02n,18nov87,ecs  documentation.
  113. 02m,17nov87,rdc  fixed documentation for setsockopt.
  114. 02l,04nov87,dnw  fixed warning from missing coercion in sendto.
  115. 02k,03nov87,rdc  added shutdown, cleaned up documentation.
  116. 02j,13oct87,rdc  added select, setSelectDelay. make setNetStatus not be LOCAL.
  117. 02i,30sep87,gae  removed use of fdTable by replacing with calls to iosFdSet().
  118. 02h,02may87,dnw  removed unnecessary includes.
  119. 02g,01apr87,ecs  fixed bugs in getsockname & getpeername (found by lint!)
  120.  changed references to "struct sockaddr" to "SOCKADDR".
  121. 02f,26mar87,rdc  made sendit and recvit call splnet first thing.
  122. 02e,23mar87,jlf  documentation.
  123. 02d,30jan87,rdc  added getsockname and getpeername.
  124.  sendit and recvit weren't always calling setNetStatus.
  125. 02c,24dec86,gae  changed stsLib.h to vwModNum.h.
  126. 02b,08nov86,dnw  fixed bug in closeSock of not freeing fd.
  127. 02a,15oct86,rdc  completely rewritten for new 4.3 network code.
  128. 01i,04sep86,jlf  minor documentation.
  129.  made listen return OK always.
  130. 01h,01jul86,jlf  minor documentation
  131. 01g,18jun86,rdc  delinted.
  132. 01f,29apr86,rdc  changed memAllocates to mallocs and de-linted.
  133.  Added getsockopt and setsockopt to implement KEEP_ALIVE.
  134. 01e,09apr86,rdc  all linked list code now uses lstLib.
  135.  added sockCloseAll and sockNumActive.
  136. 01d,28jan86,jlf  documentation
  137. 01c,20nov85,rdc  fixed accept to be 4.2 like
  138. 01b,08oct85,rdc  de-linted
  139. 01a,03oct85,rdc  written
  140. */
  141. /*
  142. This library provides UNIX BSD 4.4 compatible socket calls.  Use these 
  143. calls to open, close, read, and write sockets. These sockets can join 
  144. processes on the same CPU or on different CPUs between which there is a
  145. network connection.  The calling sequences of these routines are identical 
  146. to their equivalents under UNIX BSD 4.4.
  147. However, although the socket interface is compatible with VxWorks, 
  148. the VxWorks environment does affect how you use sockets. Specifically, 
  149. the globally accessible file descriptors available in the single address 
  150. space world of VxWorks require that you take extra precautions when 
  151. closing a file descriptor.
  152. You must make sure that you do not close the file descriptor on which 
  153. a task is pending during an accept(). Although the accept() on the 
  154. closed file descriptor sometimes returns with an error, the accept() 
  155. can also fail to return at all. Thus, if you need to be able to close 
  156. a socket connections file descriptor asynchronously, you may need to 
  157. set up a semaphore-based locking mechanism that prevents the close 
  158. while an accept() is pending on the file descriptor.
  159. ADDRESS FAMILY
  160. VxWorks sockets support only the Internet Domain address family.  Use
  161. AF_INET for the <domain> argument in subroutines that require it.
  162. There is no support for the UNIX Domain address family.
  163. IOCTL FUNCTIONS
  164. Sockets respond to the following ioctl() functions.  These functions are
  165. defined in the header files ioLib.h and ioctl.h.
  166. .IP 'FIONBIO' 15 
  167. Turns on/off non-blocking I/O.
  168. .CS
  169.     on = TRUE;
  170.     status = ioctl (sFd, FIONBIO, &on);
  171. .CE
  172. .IP 'FIONREAD'
  173. Reports the number of read-ready bytes available on the socket.  On the 
  174. return of ioctl(), <bytesAvailable> has the number of bytes available to 
  175. read from the socket.
  176. .CS
  177.     status = ioctl (sFd, FIONREAD, &bytesAvailable);
  178. .CE
  179. .IP 'SIOCATMARK'
  180. Reports whether there is out-of-band data to be read from the socket.  On
  181. the return of ioctl(), <atMark> is TRUE (1) if there is out-of-band
  182. data.  Otherwise, it is FALSE (0).
  183. .CS
  184.     status = ioctl (sFd, SIOCATMARK, &atMark);
  185. .CE
  186. To use this feature, include the following component:
  187. INCLUDE_BSD_SOCKET
  188. INCLUDE FILES: types.h, mbuf.h, socket.h, socketvar.h
  189. SEE ALSO: netLib,
  190. .I "UNIX Network Programming", by W. Richard Stevens
  191. */
  192. /* includes */
  193. #include "vxWorks.h"
  194. #include "stdlib.h"
  195. #include "iosLib.h"
  196. #include "netLib.h"
  197. #include "errnoLib.h"
  198. #include "sockFunc.h"
  199. #include "sockLib.h"
  200. #include "memPartLib.h"
  201. #include "netBufLib.h"
  202. #include "string.h"
  203. #ifdef VIRTUAL_STACK
  204. #include "netinet/vsLib.h"
  205. #endif    /* VIRTUAL_STACK */
  206. /* globals */
  207. SOCK_FUNC **  pSockFdMap = NULL;
  208. /* locals */
  209. LOCAL SOCK_LIB_MAP * pSockLibMapH = NULL;
  210. LOCAL UINT sockFdMax = 0; /* for parameter verification */
  211. /*******************************************************************************
  212. *
  213. * sockLibInit - initialize a socket library back-end library.
  214. *
  215. * RETURNS: OK, or ERROR if the back-end could not be initialized.
  216. *
  217. * NOMANUAL
  218. */
  219. STATUS sockLibInit
  220.     (
  221.     int fdMax /* maximum file descriptors */
  222.     )
  223.     {
  224.     if (pSockFdMap != NULL) /* already initialized ? */
  225. return (OK);
  226.     /* allocate fd-to-pSockFunc mapping array */
  227.     if ((pSockFdMap = (SOCK_FUNC **) KHEAP_ALLOC(fdMax *
  228. sizeof (SOCK_FUNC **))) == NULL)
  229. return (ERROR);
  230.     
  231.     bzero ((char *)pSockFdMap, fdMax * sizeof(SOCK_FUNC **));
  232.     sockFdMax = fdMax;
  233.     return (OK);
  234.     }
  235. /*******************************************************************************
  236. *
  237. * sockLibAdd - add a socket library back-end
  238. *
  239. * RETURNS: OK, or ERROR if the socket back-end could not be added.
  240. *
  241. * NOMANUAL
  242. */
  243. STATUS sockLibAdd
  244.     (
  245.     FUNCPTR sockLibInitRtn, /* back-end init routine */
  246.     int domainMap, /* address family */
  247.     int domainReal /* address family */
  248.     )
  249.     {
  250.     SOCK_LIB_MAP * pSockLibMap; /* back-end mapping entry ptr */
  251.     if (pSockFdMap == NULL) /* initialized yet ? */
  252. return (ERROR);
  253.     if ((pSockLibMap = (SOCK_LIB_MAP *) KHEAP_ALLOC(sizeof(SOCK_LIB_MAP))) == NULL)
  254. return (ERROR);
  255.     /* init socket back-end */
  256.     if ((sockLibInitRtn == NULL) ||
  257. ((pSockLibMap->pSockFunc = (SOCK_FUNC *) (sockLibInitRtn) ()) == NULL))
  258. {
  259. KHEAP_FREE((char *)pSockLibMap); /* back-end error */
  260. return (ERROR);
  261. }
  262.     pSockLibMap->domainMap = domainMap;   /* stuff mapping address family */
  263.     pSockLibMap->domainReal = domainReal; /* stuff real address family */
  264.     pSockLibMap->pNext = pSockLibMapH;    /* hook into lib list */
  265.     pSockLibMapH = pSockLibMap; /* update lib list head */
  266.     return (OK);
  267.     }
  268. /*******************************************************************************
  269. *
  270. * socket - open a socket
  271. *
  272. * This routine opens a socket and returns a socket descriptor.
  273. * The socket descriptor is passed to the other socket routines to identify the
  274. * socket.  The socket descriptor is a standard I/O system file descriptor
  275. * (fd) and can be used with the close(), read(), write(), and ioctl() routines.
  276. *
  277. * Available socket types include:
  278. * .IP SOCK_STREAM 18
  279. * Specifies a connection-based (stream) socket.
  280. * .IP SOCK_DGRAM
  281. * Specifies a datagram (UDP) socket.
  282. * .IP SOCK_RAW
  283. * Specifies a raw socket.
  284. * .LP
  285. *
  286. * RETURNS: A socket descriptor, or ERROR.
  287. */
  288. int socket
  289.     (
  290.     int domain,         /* address family (for example, AF_INET) */
  291.     int type,           /* SOCK_STREAM, SOCK_DGRAM, or SOCK_RAW */
  292.     int protocol        /* socket protocol (usually 0) */
  293.     )
  294.     {
  295.     SOCK_LIB_MAP * pSockLibMap;
  296.     int newFd;
  297.     if (pSockFdMap == NULL) /* initialized yet ? */
  298. return (ERROR);
  299.     /* search for a suitable back-end library entry */
  300.     for (pSockLibMap = pSockLibMapH; (pSockLibMap != NULL) &&
  301. (pSockLibMap->domainMap != domain); pSockLibMap = pSockLibMap->pNext)
  302. ;
  303.     /* found library map entry ? */
  304.     if ((pSockLibMap == NULL) || (pSockLibMap->pSockFunc->socketRtn == NULL))
  305. {
  306. netErrnoSet (ENOTSUP);
  307. return (ERROR);
  308. }
  309.     /* call back-end to open a socket */
  310.     if ((newFd = (pSockLibMap->pSockFunc->socketRtn)
  311. (pSockLibMap->domainReal, type, protocol)) == ERROR)
  312. return (ERROR);
  313.     pSockFdMap[newFd] = pSockLibMap->pSockFunc; /* stuff fd map array */
  314.     return (newFd);
  315.     }
  316. /*******************************************************************************
  317. *
  318. * bind - bind a name to a socket
  319. *
  320. * This routine associates a network address (also referred to as its "name")
  321. * with a specified socket so that other processes can connect or send to it.
  322. * When a socket is created with socket(), it belongs to an address family
  323. * but has no assigned name.
  324. *
  325. * RETURNS:
  326. * OK, or ERROR if there is an invalid socket, the address is either
  327. * unavailable or in use, or the socket is already bound.
  328. */
  329. STATUS bind
  330.     (
  331.     int s,                      /* socket descriptor */
  332.     struct sockaddr *name,      /* name to be bound */
  333.     int namelen                 /* length of name */
  334.     )
  335.     {
  336.     SOCK_FUNC * pSockFunc = NULL;
  337.     if (iosFdValue (s) ==  ERROR || name == NULL)
  338.         return (ERROR);
  339.     pSockFunc = pSockFdMap[s];
  340.     if ((pSockFunc == NULL) || (pSockFunc->bindRtn == NULL))
  341. {
  342.         netErrnoSet (ENOTSUP);
  343. return (ERROR);
  344. }
  345.     return ((pSockFunc->bindRtn) (s, name, namelen));
  346.     }
  347. /*******************************************************************************
  348. *
  349. * listen - enable connections to a socket
  350. *
  351. * This routine enables connections to a socket.  It also specifies the
  352. * maximum number of unaccepted connections that can be pending at one time
  353. * (<backlog>).  After enabling connections with listen(), connections are
  354. * actually accepted by accept().
  355. *
  356. * RETURNS: OK, or ERROR if the socket is invalid or unable to listen.
  357. */
  358. STATUS listen
  359.     (
  360.     int s,              /* socket descriptor */
  361.     int backlog         /* number of connections to queue */
  362.     )
  363.     {
  364.     SOCK_FUNC * pSockFunc = NULL;
  365.    
  366.     if (iosFdValue (s) ==  ERROR)
  367.         return ERROR;
  368.     pSockFunc = pSockFdMap[s];
  369.     if (pSockFunc == NULL || pSockFunc->listenRtn == NULL)
  370. {
  371.         netErrnoSet (ENOTSUP);
  372. return (ERROR);
  373. }
  374.     return ((pSockFunc->listenRtn) (s, backlog));
  375.     }
  376. /*******************************************************************************
  377. *
  378. * accept - accept a connection from a socket
  379. *
  380. * This routine accepts a connection on a socket, and returns a new socket
  381. * created for the connection.  The socket must be bound to an address with
  382. * bind(), and enabled for connections by a call to listen().  The accept()
  383. * routine dequeues the first connection and creates a new socket with the
  384. * same properties as <s>.  It blocks the caller until a connection is
  385. * present, unless the socket is marked as non-blocking.
  386. *
  387. * The <addrlen> parameter should be initialized to the size of the available
  388. * buffer pointed to by <addr>.  Upon return, <addrlen> contains the size in
  389. * bytes of the peer's address stored in <addr>.
  390. *
  391. * WARNING
  392. * You must make sure that you do not close the file descriptor on which 
  393. * a task is pending during an accept(). Although the accept() on the 
  394. * closed file descriptor sometimes returns with an error, the accept() 
  395. * can also fail to return at all. Thus, if you need to be able to close 
  396. * a socket connections file descriptor asynchronously, you may need to 
  397. * set up a semaphore-based locking mechanism that prevents the close 
  398. * while an accept() is pending on the file descriptor.
  399. *
  400. * RETURNS
  401. * A socket descriptor, or ERROR if the call fails.
  402. */
  403. int accept
  404.     (
  405.     int s,                      /* socket descriptor */
  406.     struct sockaddr *addr,      /* peer address */
  407.     int *addrlen                /* peer address length */
  408.     )
  409.     {
  410.     int newFd;
  411.     
  412.     SOCK_FUNC * pSockFunc = NULL;
  413.     if (iosFdValue (s) ==  ERROR)
  414.         {
  415.         netErrnoSet (EINVAL);
  416.         return (ERROR);
  417.         }
  418.     pSockFunc = pSockFdMap[s];
  419.     if ((pSockFunc == NULL) || (pSockFunc->acceptRtn == NULL))
  420. {
  421.         netErrnoSet (ENOTSUP);
  422. return (ERROR);
  423. }
  424.     if ((newFd = (pSockFunc->acceptRtn) (s, addr, addrlen)) == ERROR)
  425. return (ERROR);
  426.     pSockFdMap[newFd] = pSockFunc; /* stuff fd map array */
  427.     return (newFd);
  428.     }
  429. /*******************************************************************************
  430. *
  431. * connect - initiate a connection to a socket
  432. *
  433. * If <s> is a socket of type SOCK_STREAM, this routine establishes a virtual
  434. * circuit between <s> and another socket specified by <name>.  If <s> is of
  435. * type SOCK_DGRAM, it permanently specifies the peer to which messages
  436. * are sent.  If <s> is of type SOCK_RAW, it specifies the raw socket upon
  437. * which data is to be sent and received.  The <name> parameter specifies the
  438. * address of the other socket.
  439. *
  440. * NOTE: If a socket with type SOCK_STREAM is marked non-blocking, this
  441. * routine will return ERROR with an error number of EINPROGRESS or EALREADY
  442. * if a connection attempt is pending. A later call will return ERROR and set
  443. * the error number to EISCONN once the connection is established. The
  444. * connection attempt must be repeated until that result occurs or until
  445. * this routine establishes a connection immediately and returns OK.
  446. *
  447. * RETURNS: OK, or ERROR if the connection attempt does not complete.
  448. */
  449. STATUS connect
  450.     (
  451.     int s,                      /* socket descriptor */
  452.     struct sockaddr *name,      /* addr of socket to connect */
  453.     int namelen                 /* length of name, in bytes */
  454.     )
  455.     {
  456.     SOCK_FUNC * pSockFunc = NULL;
  457.     if (name == NULL)
  458.         {
  459.         netErrnoSet (EINVAL);
  460.         return (ERROR);
  461.         }
  462.     
  463.     if (iosFdValue (s) ==  ERROR)
  464.         return (ERROR);
  465.     pSockFunc = pSockFdMap[s];
  466.     if ((pSockFunc == NULL) || (pSockFunc->connectRtn == NULL))
  467. {
  468.         netErrnoSet (ENOTSUP);
  469. return (ERROR);
  470. }
  471.     return ((pSockFunc->connectRtn) (s, name, namelen));
  472.     }
  473. /******************************************************************************
  474. *
  475. * connectWithTimeout - attempt socket connection within a specified duration
  476. *
  477. * Use this routine as an alternative to connect() when your application
  478. * requires a shorter time out on a connection attempt.  By design, a TCP
  479. * connection attempt times out after 75 seconds if unsuccessful.  Thus, a 
  480. * blocking TCP socket connect() call might not return for 75 seconds.  A 
  481. * connectWithTimeout() call lets you reduce this time out by scheduling an 
  482. * abort of the connection attempt if it is not successful before <timeVal>.
  483. * However, connectWithTimeout() does not actually change the TCP timeout
  484. * value.  Thus, you cannot use connectWithTimeout() to lengthen the
  485. * connection time out beyond the TCP default.
  486. *
  487. * In all respects other than the time out value, a connectWithTimeout() call 
  488. * behaves exactly like connect(). Thus, if no application is listening for 
  489. * connections at the other end, connectWithTimeout() returns immediately just 
  490. * like connect().  If you specify a NULL pointer for <timeVal>, 
  491. * connectWithTimeout() behaves exactly like a connect() call.
  492. *
  493. * RETURNS: OK, or ERROR if a new connection is not established before timeout.
  494. *
  495. * SEE ALSO: connect()
  496. */
  497. STATUS connectWithTimeout
  498.     (
  499.     int                 sock,           /* socket descriptor */
  500.     struct sockaddr     *adrs,          /* addr of the socket to connect */
  501.     int                 adrsLen,        /* length of the socket, in bytes */
  502.     struct timeval      *timeVal        /* time-out value */
  503.     )
  504.     {
  505.     SOCK_FUNC * pSockFunc = NULL;
  506.     if (adrs == NULL)
  507.         {
  508.         netErrnoSet (EINVAL);
  509.         return (ERROR);
  510.         }
  511.     
  512.     if (iosFdValue (sock) ==  ERROR)
  513.         return (ERROR);
  514.     pSockFunc = pSockFdMap[sock];
  515.     if ((pSockFunc == NULL) || (pSockFunc->connectWithTimeoutRtn == NULL))
  516. {
  517.         netErrnoSet (ENOTSUP);
  518. return (ERROR);
  519. }
  520.     return ((pSockFunc->connectWithTimeoutRtn) (sock, adrs,
  521. adrsLen, timeVal));
  522.     }
  523. /*******************************************************************************
  524. *
  525. * sendto - send a message to a socket
  526. *
  527. * This routine sends a message to the datagram socket named by <to>.  The
  528. * socket <s> is received by the receiver as the sending socket.
  529. *
  530. * The maximum length of <buf> is subject to the limits on UDP buffer
  531. * size. See the discussion of SO_SNDBUF in the setsockopt() manual
  532. * entry.
  533. *
  534. * You can OR the following values into the <flags> parameter with this
  535. * operation:
  536. *
  537. * .IP "MSG_OOB (0x1)" 26
  538. * Out-of-band data.
  539. *
  540. * .IP "MSG_DONTROUTE (0x4)"
  541. * Send without using routing tables.
  542. * .LP
  543. *
  544. * RETURNS
  545. * The number of bytes sent, or ERROR if the call fails.
  546. *
  547. * SEE ALSO
  548. * setsockopt()
  549. */
  550. int sendto
  551.     (
  552.     FAST int             s,             /* socket to send data to */
  553.     FAST caddr_t         buf,           /* pointer to data buffer */
  554.     FAST int             bufLen,        /* length of buffer */
  555.     FAST int             flags,         /* flags to underlying protocols */
  556.     FAST struct sockaddr *to,           /* recipient's address */
  557.     FAST int             tolen          /* length of <to> sockaddr */
  558.     )
  559.     {
  560.     SOCK_FUNC * pSockFunc = NULL;
  561.     if (buf == NULL || to == NULL)
  562.         {
  563.         netErrnoSet (EINVAL);
  564.         return (ERROR);
  565.         }
  566.     if (iosFdValue (s) ==  ERROR)
  567.         return (ERROR);
  568.     pSockFunc = pSockFdMap[s];
  569.     
  570.     if ((pSockFunc == NULL) || (pSockFunc->sendtoRtn == NULL))
  571. {
  572.         netErrnoSet (ENOTSUP);
  573. return (ERROR);
  574. }
  575.     return ((pSockFunc->sendtoRtn) (s, buf, bufLen, flags, to,
  576. tolen));
  577.     }
  578. /*******************************************************************************
  579. *
  580. * send - send data to a socket
  581. *
  582. * This routine transmits data to a previously established connection-based
  583. * (stream) socket.
  584. *
  585. * The maximum length of <buf> is subject to the limits
  586. * on TCP buffer size; see the discussion of SO_SNDBUF in the
  587. * setsockopt() manual entry.
  588. *
  589. * You may OR the following values into the <flags> parameter with this
  590. * operation:
  591. *
  592. * .IP "MSG_OOB (0x1)" 26
  593. * Out-of-band data.
  594. *
  595. * .IP "MSG_DONTROUTE (0x4)"
  596. * Send without using routing tables.
  597. * .LP
  598. *
  599. * RETURNS
  600. * The number of bytes sent, or ERROR if the call fails.
  601. *
  602. * SEE ALSO
  603. * setsockopt(), sendmsg()
  604. *
  605. */
  606. int send
  607.     (
  608.     FAST int            s,              /* socket to send to */
  609.     FAST const char *   buf,            /* pointer to buffer to transmit */
  610.     FAST int            bufLen,         /* length of buffer */
  611.     FAST int            flags           /* flags to underlying protocols */
  612.     )
  613.     {
  614.     SOCK_FUNC * pSockFunc = NULL;
  615.     if (buf == NULL || iosFdValue (s) ==  ERROR)
  616.         return (ERROR);
  617.     pSockFunc = pSockFdMap[s];
  618.     if ((pSockFunc == NULL) || (pSockFunc->sendRtn == NULL))
  619. {
  620.         netErrnoSet (ENOTSUP);
  621. return (ERROR);
  622. }
  623.     return ((pSockFunc->sendRtn) (s, buf, bufLen, flags));
  624.     }
  625. /*******************************************************************************
  626. *
  627. * sendmsg - send a message to a socket
  628. *
  629. * This routine sends a message to a datagram socket.  It may be used in
  630. * place of sendto() to decrease the overhead of reconstructing the
  631. * message-header structure (`msghdr') for each message.
  632. *
  633. * For BSD 4.4 sockets a copy of the <mp>->msg_iov array will be made.  This
  634. * requires a cluster from the network stack system pool of size 
  635. * <mp>->msg_iovlen * sizeof (struct iovec) or 8 bytes.
  636. *
  637. * RETURNS
  638. * The number of bytes sent, or ERROR if the call fails.
  639. *
  640. * SEE ALSO
  641. * sendto()
  642. */
  643. int sendmsg
  644.     (
  645.     int                 sd,     /* socket to send to */
  646.     struct msghdr       *mp,    /* scatter-gather message header */
  647.     int                 flags   /* flags to underlying protocols */
  648.     )
  649.     {
  650.     SOCK_FUNC * pSockFunc = NULL;
  651.     if (mp == NULL || iosFdValue (sd) ==  ERROR)
  652. {
  653.         netErrnoSet (EINVAL);
  654.         return (ERROR);
  655. }
  656.     pSockFunc = pSockFdMap[sd];
  657.     if ((pSockFunc == NULL) || (pSockFunc->sendmsgRtn == NULL))
  658. {
  659.         netErrnoSet (ENOTSUP);
  660. return (ERROR);
  661. }
  662.     return ((pSockFunc->sendmsgRtn) (sd, mp, flags));
  663.     }
  664. /*******************************************************************************
  665. *
  666. * recvfrom - receive a message from a socket
  667. *
  668. * This routine receives a message from a datagram socket regardless of
  669. * whether it is connected.  If <from> is non-zero, the address of the
  670. * sender's socket is copied to it.  The value-result parameter <pFromLen>
  671. * should be initialized to the size of the <from> buffer.  On return,
  672. * <pFromLen> contains the actual size of the address stored in <from>.
  673. *
  674. * The maximum length of <buf> is subject to the limits on UDP buffer
  675. * size; see the discussion of SO_RCVBUF in the setsockopt() manual
  676. * entry.
  677. *
  678. * You may OR the following values into the <flags> parameter with this
  679. * operation:
  680. *
  681. * .IP "MSG_OOB (0x1)" 26
  682. * Out-of-band data.
  683. *
  684. * .IP "MSG_PEEK (0x2)"
  685. * Return data without removing it from socket.
  686. * .LP
  687. *
  688. * RETURNS
  689. * The number of number of bytes received, or ERROR if the call fails.
  690. *
  691. * SEE ALSO
  692. * setsockopt()
  693. */
  694. int recvfrom
  695.     (
  696.     FAST int             s,         /* socket to receive from */
  697.     FAST char            *buf,      /* pointer to data buffer */
  698.     FAST int             bufLen,    /* length of buffer */
  699.     FAST int             flags,     /* flags to underlying protocols */
  700.     FAST struct sockaddr *from,     /* where to copy sender's addr */
  701.     FAST int             *pFromLen  /* value/result length of <from> */
  702.     )
  703.     {
  704.     SOCK_FUNC * pSockFunc = NULL;
  705.     if (buf == NULL || from == NULL || pFromLen == NULL || iosFdValue (s) ==  ERROR)
  706.         {
  707.         netErrnoSet (EINVAL);
  708.         return (ERROR);
  709.         }
  710.     pSockFunc = pSockFdMap[s];
  711.     if ((pSockFunc == NULL) || (pSockFunc->recvfromRtn == NULL))
  712. {
  713.         netErrnoSet (ENOTSUP);
  714. return (ERROR);
  715. }
  716.     return ((pSockFunc->recvfromRtn) (s, buf, bufLen, flags,
  717. from, pFromLen));
  718.     }
  719. /*******************************************************************************
  720. *
  721. * recv - receive data from a socket
  722. *
  723. * This routine receives data from a connection-based (stream) socket.
  724. *
  725. * The maximum length of <buf> is subject to the limits on TCP buffer
  726. * size; see the discussion of SO_RCVBUF in the setsockopt() manual
  727. * entry.
  728. *
  729. * You may OR the following values into the <flags> parameter with this
  730. * operation:
  731. *
  732. * .IP "MSG_OOB (0x1)" 26
  733. * Out-of-band data.
  734. *
  735. * .IP "MSG_PEEK (0x2)"
  736. * Return data without removing it from socket.
  737. * .LP
  738. *
  739. * RETURNS
  740. * The number of bytes received, or ERROR if the call fails.
  741. *
  742. * SEE ALSO
  743. * setsockopt()
  744. */
  745. int recv
  746.     (
  747.     FAST int    s,      /* socket to receive data from */
  748.     FAST char   *buf,   /* buffer to write data to */
  749.     FAST int    bufLen, /* length of buffer */
  750.     FAST int    flags   /* flags to underlying protocols */
  751.     )
  752.     {
  753.     SOCK_FUNC * pSockFunc = NULL;
  754.     if (buf == NULL || iosFdValue (s) ==  ERROR)
  755.         {
  756.         netErrnoSet (EINVAL);
  757.         return (ERROR);
  758.         }
  759.     pSockFunc = pSockFdMap[s];
  760.     if ((pSockFunc == NULL) || (pSockFunc->recvRtn == NULL))
  761. {
  762.         netErrnoSet (ENOTSUP);
  763. return (ERROR);
  764. }
  765.     return ((pSockFunc->recvRtn) (s, buf, bufLen, flags));
  766.     }
  767. /*******************************************************************************
  768. *
  769. * recvmsg - receive a message from a socket
  770. *
  771. * This routine receives a message from a datagram socket.  It may be used in
  772. * place of recvfrom() to decrease the overhead of breaking down the
  773. * message-header structure `msghdr' for each message.
  774. *
  775. * For BSD 4.4 sockets a copy of the <mp>->msg_iov array will be made.  This
  776. * requires a cluster from the network stack system pool of size 
  777. * <mp>->msg_iovlen * sizeof (struct iovec) or 8 bytes. 
  778. *
  779. * RETURNS
  780. * The number of bytes received, or ERROR if the call fails.
  781. */
  782. int recvmsg
  783.     (
  784.     int                 sd,     /* socket to receive from */
  785.     struct msghdr       *mp,    /* scatter-gather message header */
  786.     int                 flags   /* flags to underlying protocols */
  787.     )
  788.     {
  789.     SOCK_FUNC * pSockFunc = NULL;
  790.     if (mp == NULL || iosFdValue (sd) ==  ERROR)
  791.          {
  792.         netErrnoSet (EINVAL);
  793.         return (ERROR);
  794.         }
  795.     pSockFunc = pSockFdMap[sd];
  796.     if ((pSockFunc == NULL) || (pSockFunc->recvmsgRtn == NULL))
  797. {
  798.         netErrnoSet (ENOTSUP);
  799. return (ERROR);
  800. }
  801.     return ((pSockFunc->recvmsgRtn) (sd, mp, flags));
  802.     }
  803. /*******************************************************************************
  804. *
  805. * setsockopt - set socket options
  806. *
  807. * This routine sets the options associated with a socket.
  808. * To manipulate options at the "socket" level, <level> should be SOL_SOCKET.
  809. * Any other levels should use the appropriate protocol number.
  810. *
  811. * OPTIONS FOR STREAM SOCKETS
  812. * The following sections discuss the socket options available for
  813. * stream (TCP) sockets.
  814. *
  815. * .SS "SO_KEEPALIVE -- Detecting a Dead Connection"
  816. * Specify the SO_KEEPALIVE option to make the transport protocol (TCP)
  817. * initiate a timer to detect a dead connection:
  818. * .CS
  819. *     setsockopt (sock, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof (optval));
  820. * .CE
  821. * This prevents an application from  hanging on an invalid connection.
  822. * The value at <optval> for this option is an integer (type `int'),
  823. * either 1 (on) or 0 (off).
  824. *
  825. * The integrity of a connection is verified by transmitting
  826. * zero-length TCP segments triggered by a timer, to force a response
  827. * from a peer node.  If the peer does not respond after repeated
  828. * transmissions of the KEEPALIVE segments, the connection is dropped,
  829. * all protocol data structures are reclaimed, and processes sleeping
  830. * on the connection are awakened with an ETIMEDOUT error.
  831. *
  832. * The ETIMEDOUT timeout can happen in two ways.  If the connection is
  833. * not yet established, the KEEPALIVE timer expires after idling
  834. * for TCPTV_KEEP_INIT.  If the connection is established, the
  835. * KEEPALIVE timer starts up when there is no traffic for
  836. * TCPTV_KEEP_IDLE.  If no response is received from the peer after
  837. * sending the KEEPALIVE segment TCPTV_KEEPCNT times with interval
  838. * TCPTV_KEEPINTVL, TCP assumes that the connection is invalid.
  839. * The TCPTV_KEEP_INIT, TCPTV_KEEP_IDLE, TCPTV_KEEPCNT, and TCPTV_KEEPINTVL 
  840. * parameters are defined in the file target/h/netinet/tcp_timer.h.
  841. *
  842. * .SS "SO_LINGER -- Closing a Connection"
  843. * Specify the SO_LINGER option to determine whether TCP should perform a
  844. * "graceful" close:
  845. * .CS
  846. *     setsockopt (sock, SOL_SOCKET, SO_LINGER, &optval, sizeof (optval));
  847. * .CE
  848. * To achieve a "graceful" close in response to the shutdown of a connection,
  849. * TCP puts itself through an elaborate set of state transitions.  The goal is 
  850. * to assure that all the unacknowledged data in the transmission channel are 
  851. * acknowledged, and that the peer is shut down properly.
  852. *
  853. * The value at <optval> indicates the amount of time to linger if
  854. * there is unacknowledged data, using `struct linger' in
  855. * target/h/sys/socket.h.  The `linger' structure has two members:
  856. * `l_onoff' and `l_linger'.  `l_onoff' can be set to 1 to turn on the
  857. * SO_LINGER option, or set to 0 to turn off the SO_LINGER option.
  858. * `l_linger' indicates the amount of time to linger.  If `l_onoff' is
  859. * turned on and `l_linger' is set to 0, a default value TCP_LINGERTIME
  860. * (specified in netinet/tcp_timer.h) is used for incoming
  861. * connections accepted on the socket.
  862. *
  863. * When SO_LINGER is turned on and the `l_linger' field is set to 0,
  864. * TCP simply drops the connection by sending out an RST (if a
  865. * connection is already established).  This frees up the space for the TCP
  866. * protocol control block, and wakes up all tasks sleeping on the
  867. * socket.
  868. *
  869. * For the client side socket, the value of `l_linger' is not changed
  870. * if it is set to 0.  To make sure that the value of `l_linger' is 0
  871. * on a newly accepted socket connection, issue another setsockopt()
  872. * after the accept() call.
  873. *
  874. * Currently the exact value of `l_linger' time is actually ignored
  875. * (other than checking for 0); that is, TCP performs the state
  876. * transitions if `l_linger' is not 0, but does not explicitly use its
  877. * value.
  878. *
  879. * .SS "TCP_NODELAY -- Delivering Messages Immediately"
  880. * Specify the TCP_NODELAY option for real-time protocols, such as the X
  881. * Window System Protocol, that require immediate delivery of many small
  882. * messages:
  883. * .CS
  884. * setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof (optval));
  885. * .CE
  886. * The value at <optval> is an integer (type `int') set to either 1
  887. * (on) or 0 (off).
  888. *
  889. * By default, the VxWorks TCP implementation employs an algorithm that
  890. * attempts to avoid the congestion that can be produced by a large number
  891. * of small TCP segments. This typically arises with virtual terminal
  892. * applications (such as telnet or rlogin) across networks that have
  893. * low bandwidth and long delays.  The algorithm attempts to have no
  894. * more than one outstanding unacknowledged segment in the transmission
  895. * channel while queueing up the rest of the smaller segments for later
  896. * transmission.  Another segment is sent only if enough new data is
  897. * available to make up a maximum sized segment, or if the outstanding
  898. * data is acknowledged.
  899. *
  900. * This congestion-avoidance algorithm works well for virtual terminal
  901. * protocols and bulk data transfer protocols such as FTP without any
  902. * noticeable side effects.  However, real-time protocols that require
  903. * immediate delivery of many small messages, such as the X Window
  904. * System Protocol, need to defeat this facility to guarantee proper
  905. * responsiveness in their operation.
  906. *
  907. * TCP_NODELAY is a mechanism to turn off the use of this algorithm.
  908. * If this option is turned on and there is data to be sent out, TCP
  909. * bypasses the congestion-avoidance algorithm: any available data
  910. * segments are sent out if there is enough space in the send window.
  911. *
  912. * .SS "TCP_MAXSEG -- Changing TCP MSS for the connection"
  913. * Specify the TCP_MAXSEG option to decrease the maximum allowable size of an
  914. * outgoing TCP segment. This option cannot be used to increase the MSS.
  915. * .CS
  916. * setsockopt (sock, IPPROTO_TCP, TCP_MAXSEG, &optval, sizeof (optval));
  917. * .CE
  918. * The value at <optval> is an integer set to the desired MSS (eg. 1024).
  919. *
  920. * When a TCP socket is created, the MSS is initialized to the default MSS
  921. * value which is determined by the configuration parameter `TCP_MSS_DFLT' (512
  922. * by default). When a connection request is received from the other end with
  923. * an MSS option, the MSS is modified depending on the value of the received
  924. * MSS and on the results of Path MTU Discovery (which is enabled by default). 
  925. * The MSS may be set as high as the outgoing interface MTU (1460 for an 
  926. * Ethernet). Therefore, after a call to `socket' but before a connection is 
  927. * established, an application can only decrease the MSS from its default of 512. 
  928. * After a connection is established, the application can decrease the MSS from 
  929. * whatever value was selected.
  930. *
  931. * .SS "SO_DEBUG -- Debugging the  underlying protocol"
  932. * Specify the SO_DEBUG option to let the underlying protocol module record
  933. * debug information.
  934. * .CS
  935. *     setsockopt (sock, SOL_SOCKET, SO_DEBUG, &optval, sizeof (optval));
  936. * .CE
  937. * The value at <optval> for this option is an integer (type `int'),
  938. * either 1 (on) or 0 (off).
  939. *
  940. * OPTION FOR DATAGRAM SOCKETS
  941. * The following section discusses an option for datagram (UDP) sockets.
  942. *
  943. * .SS "SO_BROADCAST -- Sending to Multiple Destinations"
  944. * Specify the SO_BROADCAST option when an application needs to send
  945. * data to more than one destination:
  946. * .CS
  947. *     setsockopt (sock, SOL_SOCKET, SO_BROADCAST, &optval, sizeof (optval));
  948. * .CE
  949. * The value at <optval> is an integer (type <int>), either 1 (on) or 0
  950. * (off).
  951. *
  952. * OPTIONS FOR DATAGRAM AND RAW SOCKETS
  953. * The following section discusses options for multicasting on UDP and RAW
  954. * sockets.
  955. *
  956. * .SS "IP_ADD_MEMBERSHIP -- Join a Multicast Group"
  957. * Specify the IP_ADD_MEMBERSHIP option when a process needs to join
  958. * multicast group:
  959. * .CS
  960. *     setsockopt (sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&ipMreq,
  961. *                 sizeof (ipMreq));
  962. * .CE
  963. * The value of <ipMreq> is an 'ip_mreq' structure. 
  964. * `ipMreq.imr_multiaddr.s_addr' is the internet multicast address
  965. * `ipMreq.imr_interface.s_addr' is the internet unicast address of the 
  966. * interface through which the multicast packet needs to pass.
  967. *
  968. * .SS "IP_DROP_MEMBERSHIP -- Leave a Multicast Group"
  969. * Specify the IP_DROP_MEMBERSHIP option when a process needs to leave
  970. * a previously joined multicast group:
  971. * .CS
  972. *     setsockopt (sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *)&ipMreq,
  973. *                 sizeof (ipMreq));
  974. * .CE
  975. * The value of <ipMreq> is an 'ip_mreq' structure.  
  976. * `ipMreq.imr_multiaddr.s_addr' is the internet multicast address.
  977. * `ipMreq.imr_interface.s_addr' is the internet unicast address of the 
  978. * interface to which the multicast address was bound.
  979. *
  980. * .SS "IP_MULTICAST_IF -- Select a Default Interface for Outgoing Multicasts"
  981. * Specify the IP_MULTICAST_IF option when an application needs to specify
  982. * an outgoing network interface through which all multicast packets
  983. * are sent:
  984. * .CS
  985. *     setsockopt (sock, IPPROTO_IP, IP_MULTICAST_IF, (char *)&ifAddr,
  986. *                 sizeof (mCastAddr));
  987. * .CE
  988. * The value of <ifAddr> is an 'in_addr' structure.  
  989. * `ifAddr.s_addr' is the internet network interface address.
  990. *
  991. * .SS "IP_MULTICAST_TTL -- Select a Default TTL"
  992. * Specify the IP_MULTICAST_TTL option when an application needs to select
  993. * a default TTL (time to live) for outgoing multicast
  994. * packets:
  995. *
  996. * .CS
  997. *     setsockopt (sock, IPPROTO_IP, IP_MULTICAST_TTL, &optval, sizeof(optval));
  998. * .CE
  999. * The value at <optval> is an integer (type <int>), time to live value.
  1000. *
  1001. * .TS
  1002. * tab(|);
  1003. * lf3 lf3 lf3
  1004. * l l l.
  1005. * optval(TTL)  |  Application                   | Scope
  1006. * _
  1007. * 0            |                                | same interface
  1008. * 1            |                                | same subnet
  1009. * 31           | local event video              | 
  1010. * 32           |                                | same site
  1011. * 63           | local event audio              | 
  1012. * 64           |                                | same region
  1013. * 95           | IETF channel 2 video           | 
  1014. * 127          | IETF channel 1 video           | 
  1015. * 128          |                                | same continent
  1016. * 159          | IETF channel 2 audio           | 
  1017. * 191          | IETF channel 1 audio           | 
  1018. * 223          | IETF channel 2 low-rate audio  | 
  1019. * 255          | IETF channel 1 low-rate audio  |
  1020. *              | unrestricted in scope          |
  1021. * .TE
  1022. *
  1023. * .SS "IP_MULTICAST_LOOP -- Enable or Disable Loopback"
  1024. * Enable or disable loopback of outgoing multicasts.
  1025. * .CS
  1026. *     setsockopt (sock, IPPROTO_IP, IP_MULTICAST_LOOP, &optval, sizeof(optval));
  1027. * .CE
  1028. * The value at <optval> is an integer (type <int>), either 1(on) or 0
  1029. * (off).
  1030. *
  1031. * OPTIONS FOR DATAGRAM, STREAM AND RAW SOCKETS
  1032. * The following section discusses options for RAW, DGRAM or STREAM
  1033. * sockets.
  1034. *
  1035. * .SS "IP_OPTIONS -- set options to be included in outgoing datagrams"
  1036. * Sets the IP options sent from this socket with every packet.
  1037. * .CS
  1038. *     setsockopt (sock, IPPROTO_IP, IP_OPTIONS, optbuf, optbuflen);
  1039. * .CE
  1040. * Here <optbuf> is a buffer containing the options.
  1041. *
  1042. * .SS "IP_TOS-- set options to be included in outgoing datagrams"
  1043. * Sets the Type-Of-Service field for each packet sent from this socket.
  1044. * .CS
  1045. *     setsockopt (sock, IPPROTO_IP, IP_TOS, &optval, sizeof(optval));
  1046. * .CE
  1047. * Here <optval> is an integer (type <int>).  This integer can be set to
  1048. * IPTOS_LOWDELAY, IPTOS_THROUGHPUT, IPTOS_RELIABILITY, or IPTOS_MINCOST,
  1049. * to indicate how the packets sent on this socket should be prioritized.
  1050. *
  1051. * .SS "IP_TTL-- set the time-to-live field in outgoing datagrams"
  1052. * Sets the Time-To-Live field for each packet sent from this socket.
  1053. * .CS
  1054. *     setsockopt (sock, IPPROTO_IP, IP_TTL, &optval, sizeof(optval));
  1055. * .CE
  1056. * Here <optval> is an integer (type <int>), indicating the number of hops
  1057. * a packet can take before it is discarded.
  1058. *
  1059. * .SS "IP_RECVRETOPTS -- [un-]set queueing of reversed source route"
  1060. * Sets whether or not reversed source route queueing will be enabled for
  1061. * incoming datagrams. (Not implemented)
  1062. * .CS
  1063. *     setsockopt (sock, IPPROTO_IP, IP_RECVRETOPTS, &optval, sizeof(optval));
  1064. * .CE
  1065. * Here <optval> is a boolean (type <int>).  However, this option is
  1066. * currently not implemented, so setting it will not change the behavior
  1067. * of the system.
  1068. *
  1069. * .SS "IP_RECVDSTADDR -- [un-]set queueing of IP destination address"
  1070. * Sets whether or not the socket will receive the IP address of the
  1071. * destination of an incoming datagram in control data.
  1072. * .CS
  1073. *     setsockopt (sock, IPPROTO_IP, IP_RECVDSTADDR, &optval, sizeof(optval));
  1074. * .CE
  1075. * Here <optval> is a boolean (type <int>).
  1076. *
  1077. * OPTIONS FOR BOTH STREAM AND DATAGRAM SOCKETS
  1078. * The following sections describe options that can be used with either
  1079. * stream or datagram sockets.
  1080. *
  1081. * .SS "SO_REUSEADDR -- Reusing a Socket Address"
  1082. * Specify the SO_REUSEADDR option to bind a stream socket to a local
  1083. * port that may be still bound to another stream socket:
  1084. * .CS
  1085. *     setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof (optval));
  1086. * .CE
  1087. * The value at <optval> is an integer (type <int>), either 1 (on) or 0
  1088. * (off).
  1089. *
  1090. * When the SO_REUSEADDR option is turned on, applications may bind a stream 
  1091. * socket to a local port. This is possible even if the port is still bound 
  1092. * to another stream socket.  It is even  possible if that other socket is 
  1093. * associated with a "zombie" protocol control block context that has not yet 
  1094. * freed from previous sessions.  The uniqueness of port number combinations 
  1095. * for each connection is still preserved through sanity checks performed at 
  1096. * actual connection setup time.  If this option is not turned on and an 
  1097. * application attempts to bind to a port that is being used by a zombie 
  1098. * protocol control block, the bind() call fails.
  1099. *
  1100. * .SS "SO_REUSEPORT -- Reusing a Socket address and port"
  1101. * This option is similar to the SO_REUSEADDR option but it allows binding to
  1102. * the same local address and port combination. 
  1103. * .CS
  1104. *     setsockopt (sock, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof (optval));
  1105. * .CE
  1106. * The value at <optval> is an integer (type <int>), either 1 (on) or 0 (off).
  1107. *
  1108. * The SO_REUSEPORT option is mainly required by multicast applications where
  1109. * a number of applications need to bind to the same multicast address and port
  1110. * to receive multicast data. Unlike SO_REUSEADDR where only the later
  1111. * applications need to set this option, with SO_REUSEPORT all applications
  1112. * including the first to bind to the port are required to set this option. For
  1113. * multicast addresses SO_REUSEADDR and SO_REUSEPORT show the same behavior so
  1114. * SO_REUSEADDR can be used instead. 
  1115. *
  1116. * .SS "SO_SNDBUF -- Specifying the Size of the Send Buffer"
  1117. * Specify the SO_SNDBUF option to adjust the maximum size of the
  1118. * socket-level send buffer:
  1119. * .CS
  1120. *     setsockopt (sock, SOL_SOCKET, SO_SNDBUF, &optval, sizeof (optval));
  1121. * .CE
  1122. * The value at <optval> is an integer (type `int') that specifies the
  1123. * size of the socket-level send buffer to be allocated.
  1124. *
  1125. * When stream or datagram sockets are created, each transport protocol
  1126. * reserves a set amount of space at the socket level for use when the
  1127. * sockets are attached to a protocol.  For TCP, the default size of
  1128. * the send buffer is 8192 bytes.  For UDP, the default size of the
  1129. * send buffer is 9216 bytes.  Socket-level buffers are allocated
  1130. * dynamically from the mbuf pool.
  1131. *
  1132. * The effect of setting the maximum size of buffers (for both SO_SNDBUF and 
  1133. * SO_RCVBUF, described below) is not actually to allocate the mbufs from 
  1134. * the mbuf pool.  Instead, the effect is to set the high-water mark in the 
  1135. * protocol data structure, which is used later to limit the amount of mbuf 
  1136. * allocation.  Thus, the maximum size specified for the socket level send 
  1137. * and receive buffers can affect the performance of bulk data transfers.  
  1138. * For example, the size of the TCP receive windows is limited by the 
  1139. * remaining socket-level buffer space.  These parameters must be adjusted 
  1140. * to produce the optimal result for a given application.
  1141. *
  1142. * .SS "SO_RCVBUF -- Specifying the Size of the Receive Buffer"
  1143. * Specify the SO_RCVBUF option to adjust the maximum size of the
  1144. * socket-level receive buffer:
  1145. * .CS
  1146. *     setsockopt (sock, SOL_SOCKET, SO_RCVBUF, &optval, sizeof (optval));
  1147. * .CE
  1148. * The value at <optval> is an integer (type `int') that specifies the
  1149. * size of the socket-level receive buffer to be allocated.
  1150. *
  1151. * When stream or datagram sockets are created, each transport protocol
  1152. * reserves a set amount of space at the socket level for use when the
  1153. * sockets are attached to a protocol.  For TCP, the default size is
  1154. * 8192 bytes.  UDP reserves 41600 bytes, enough space for up to forty
  1155. * incoming datagrams (1 Kbyte each).
  1156. *
  1157. * See the SO_SNDBUF discussion above for a discussion of the impact of
  1158. * buffer size on application performance.
  1159. *
  1160. * .SS "SO_OOBINLINE -- Placing Urgent Data in the Normal Data Stream"
  1161. * Specify the SO_OOBINLINE option to place urgent data within the
  1162. * normal receive data stream:
  1163. * .CS
  1164. *     setsockopt (sock, SOL_SOCKET, SO_OOBINLINE, &optval, sizeof (optval));
  1165. * .CE
  1166. * TCP provides an expedited data service that does not conform to the
  1167. * normal constraints of sequencing and flow control of data
  1168. * streams. The expedited service delivers "out-of-band" (urgent) data
  1169. * ahead of other "normal" data to provide interrupt-like services (for
  1170. * example, when you hit a CTRL-C during telnet or rlogin session while
  1171. * data is being displayed on the screen.)
  1172. *
  1173. * TCP does not actually maintain a separate stream to support the
  1174. * urgent data.  Instead, urgent data delivery is implemented as a
  1175. * pointer (in the TCP header) which points to the sequence number of
  1176. * the octet following the urgent data. If more than one transmission
  1177. * of urgent data is received from the peer, they are all put into the
  1178. * normal stream. This is intended for applications that cannot afford
  1179. * to miss out on any urgent data but are usually too slow to respond
  1180. * to them promptly.
  1181. *
  1182. * RETURNS:
  1183. * OK, or ERROR if there is an invalid socket, an unknown option, an option
  1184. * length greater than MLEN, insufficient mbufs, or the call is unable to set
  1185. * the specified option.
  1186. */
  1187. STATUS setsockopt
  1188.     (
  1189.     int s,              /* target socket */
  1190.     int level,          /* protocol level of option */
  1191.     int optname,        /* option name */
  1192.     char *optval,       /* pointer to option value */
  1193.     int optlen          /* option length */
  1194.     )
  1195.     {
  1196.     SOCK_FUNC * pSockFunc = NULL;
  1197.     if (optval == NULL || iosFdValue (s) ==  ERROR)
  1198.         {
  1199.         netErrnoSet (EINVAL);
  1200.         return (ERROR);
  1201.         }
  1202.     pSockFunc = pSockFdMap[s];
  1203.     if ((pSockFunc == NULL) || (pSockFunc->setsockoptRtn == NULL))
  1204. {
  1205.         netErrnoSet (ENOTSUP);
  1206. return (ERROR);
  1207. }
  1208.     return ((pSockFunc->setsockoptRtn) (s, level, optname,
  1209.     optval, optlen));
  1210.     }
  1211. /*******************************************************************************
  1212. *
  1213. * getsockopt - get socket options
  1214. *
  1215. * This routine returns relevant option values associated with a socket.
  1216. * To manipulate options at the "socket" level, <level> should be SOL_SOCKET.
  1217. * Any other levels should use the appropriate protocol number.
  1218. * The <optlen> parameter should be initialized to indicate the amount of
  1219. * space referenced by <optval>.  On return, the value of the option is copied to
  1220. * <optval> and the actual size of the option is copied to <optlen>.
  1221. *
  1222. * Although <optval> is passed as a char *, the actual variable whose address 
  1223. * gets passed in should be an integer or a structure, depending on which 
  1224. * <optname> is being passed. Refer to setsockopt() to determine the correct 
  1225. * type of the actual variable (whose address should then be cast to a char *).
  1226. *
  1227. * RETURNS:
  1228. * OK, or ERROR if there is an invalid socket, an unknown option, or the call
  1229. * is unable to get the specified option.
  1230. *
  1231. * EXAMPLE
  1232. * Because SO_REUSEADDR has an integer parameter, the variable to be
  1233. * passed to getsockopt() should be declared as
  1234. * .CS
  1235. *    int reuseVal;
  1236. * .CE
  1237. * and passed in as 
  1238. * .CS
  1239. *    (char *)&reuseVal.
  1240. * .CE
  1241. * Otherwise the user might mistakenly declare `reuseVal' as a character,
  1242. * in which case getsockopt() will only return the first byte of the
  1243. * integer representing the state of this option.  Then whether the return
  1244. * value is correct or always 0 depends on the endian-ness of the machine.
  1245. *
  1246. * SEE ALSO: setsockopt()
  1247. */
  1248. STATUS getsockopt
  1249.     (
  1250.     int         s,              /* socket */
  1251.     int         level,          /* protocol level for options */
  1252.     int         optname,        /* name of option */
  1253.     char        *optval,        /* where to put option */
  1254.     int         *optlen         /* where to put option length */
  1255.     )
  1256.     {
  1257.     SOCK_FUNC * pSockFunc = NULL;
  1258.     if (optval == NULL || optlen == NULL || iosFdValue (s) ==  ERROR)
  1259.         {
  1260.         netErrnoSet (EINVAL);
  1261.         return (ERROR);
  1262.         }
  1263.     pSockFunc = pSockFdMap[s];
  1264.     if ((pSockFunc == NULL) || (pSockFunc->getsockoptRtn == NULL))
  1265. {
  1266.         netErrnoSet (ENOTSUP);
  1267. return (ERROR);
  1268. }
  1269.     return ((pSockFunc->getsockoptRtn) (s, level, optname,
  1270. optval, optlen));
  1271.     }
  1272. /*******************************************************************************
  1273. *
  1274. * getsockname - get a socket name
  1275. *
  1276. * This routine gets the current name for the specified socket <s>.
  1277. * The <namelen> parameter should be initialized to indicate the amount of
  1278. * space referenced by <name>.  On return, the name of the socket is copied to
  1279. * <name> and the actual size of the socket name is copied to <namelen>.
  1280. *
  1281. * RETURNS: OK, or ERROR if the socket is invalid.
  1282. */
  1283. STATUS getsockname
  1284.     (
  1285.     int s,                      /* socket descriptor */
  1286.     struct sockaddr *name,      /* where to return name */
  1287.     int *namelen                /* space available in name, later */
  1288.                                 /* filled in with actual name size */
  1289.     )
  1290.     {
  1291.     SOCK_FUNC * pSockFunc = NULL;
  1292.     if (name == NULL || namelen == NULL || iosFdValue (s) ==  ERROR)
  1293.         {
  1294.         netErrnoSet (EINVAL);
  1295.         return (ERROR);
  1296.         }
  1297.     pSockFunc = pSockFdMap[s];
  1298.     if ((pSockFunc == NULL) || (pSockFunc->getsocknameRtn == NULL))
  1299. {
  1300.         netErrnoSet (ENOTSUP);
  1301. return (ERROR);
  1302. }
  1303.     return ((pSockFunc->getsocknameRtn) (s, name, namelen));
  1304.     }
  1305. /*******************************************************************************
  1306. *
  1307. * getpeername - get the name of a connected peer
  1308. *
  1309. * This routine gets the name of the peer connected to socket <s>.
  1310. * The <namelen> parameter should be initialized to indicate the amount of
  1311. * space referenced by <name>.  On return, the name of the socket is copied to
  1312. * <name> and the actual size of the socket name is copied to <namelen>.
  1313. *
  1314. * RETURNS: OK, or ERROR if the socket is invalid
  1315. * or not connected.
  1316. */
  1317. STATUS getpeername
  1318.     (
  1319.     int s,                      /* socket descriptor */
  1320.     struct sockaddr *name,      /* where to put name */
  1321.     int *namelen                /* space available in name, later */
  1322.                                 /* filled in with actual name size */
  1323.     )
  1324.     {
  1325.     SOCK_FUNC * pSockFunc = NULL;
  1326.     if (name == NULL || namelen == NULL || iosFdValue (s) ==  ERROR)
  1327.         {
  1328.         netErrnoSet (EINVAL);
  1329.         return (ERROR);
  1330.         }
  1331.     pSockFunc = pSockFdMap[s];
  1332.     if ((pSockFunc == NULL) || (pSockFunc->getpeernameRtn == NULL))
  1333. {
  1334.         netErrnoSet (ENOTSUP);
  1335. return (ERROR);
  1336. }
  1337.     return ((pSockFunc->getpeernameRtn) (s, name, namelen));
  1338.     }
  1339. /******************************************************************************
  1340. *
  1341. * shutdown - shut down a network connection
  1342. *
  1343. * This routine shuts down all, or part, of a connection-based socket <s>.
  1344. * If the value of <how> is 0, receives are disallowed.  If <how> is 1,
  1345. * sends are disallowed.  If <how> is 2, both sends and receives are
  1346. * disallowed.
  1347. *
  1348. * RETURNS: ERROR if the socket is invalid or has no registered
  1349. * socket-specific routines; otherwise shutdown() returns the return value
  1350. * from the socket-specific shutdown routine (typically OK in the case of
  1351. * a successful shutdown or ERROR otherwise).
  1352. */
  1353. STATUS shutdown
  1354.     (
  1355.     int s,      /* socket to shut down */
  1356.     int how     /* 0 = receives disallowed */
  1357.                 /* 1 = sends disallowed */
  1358.                 /* 2 = sends and receives disallowed */
  1359.     )
  1360.     {
  1361.     SOCK_FUNC * pSockFunc = NULL;
  1362.     if (((UINT)how) > 2 || iosFdValue (s) ==  ERROR)
  1363.         {
  1364.         netErrnoSet (EINVAL);
  1365.         return (ERROR);
  1366.         }
  1367.     pSockFunc = pSockFdMap[s];
  1368.     if ((pSockFunc == NULL) || (pSockFunc->shutdownRtn == NULL))
  1369. {
  1370.         netErrnoSet (ENOTSUP);
  1371. return (ERROR);
  1372. }
  1373.     return ((pSockFunc->shutdownRtn) (s, how));
  1374.     }
  1375. SOCK_FUNC * sockFdtosockFunc
  1376.      (
  1377.      int s
  1378.      )
  1379.      {
  1380.      if (iosFdValue (s) ==  ERROR)
  1381.         return (NULL);
  1382.      return pSockFdMap[s];
  1383.      }