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

VxWorks

开发平台:

C/C++

  1. /* hostLib.c - host table subroutine library */
  2. /* Copyright 1984 - 2001 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 02d,10may02,kbw  making man page edits
  8. 02c,15oct01,rae  merge from truestack ver 02g, base 02b (SPR #63610)
  9. 02b,15mar99,c_c  Doc: updated hostGetByName manual page (SPR #5184).
  10. 02a,14mar99,jdi  doc: removed refs to config.h and/or configAll.h (SPR 25663).
  11. 01z,20aug,97,jag added functions hostTblSearchByAddr(), hostTblSearchByName() 
  12.  to address (SPR #9175)
  13. 01x,19may97,spm  added checks for NULL pointers to user interface routines
  14. 01w,20apr97,kbw  fixed man page format problems, did a spell check
  15. 01v,07apr97,jag  added hooks for the resolver library.
  16. 01w,17nov97,dgp  doc: SPR 9410, hostGetByName() returns addr in network byte
  17. order
  18. 01v,29aug97,dgp  doc: SPR 9196 correct ERROR return for hostAdd()
  19. 01u,16feb94,caf  added check for NULL pointer in hostGetByName() (SPR #2920).
  20. 01t,02feb93,jdi  documentation cleanup for 5.1.
  21. 01s,13nov92,dnw  added include of semLibP.h
  22. 01r,27jul92,elh  Moved hostShow to netShow.c
  23. 01q,18jul92,smb  Changed errno.h to errnoLib.h.
  24. 01p,26may92,rrr  the tree shuffle
  25.   -changed includes to have absolute path from h/
  26. 01o,10dec91,gae  more cleanup of ANSI warnings.
  27. 01n,25oct91,rrr  cleanup of some ansi warnings.
  28. 01m,04oct91,rrr  passed through the ansification filter
  29.                   -changed functions to ansi style
  30.   -changed includes to have absolute path from h/
  31.   -changed VOID to void
  32.   -changed copyright notice
  33. 01l,05apr91,jdi  documentation -- removed header parens and x-ref numbers;
  34.  doc review by dnw.
  35. 01k,12feb91,jaa  documentation.
  36. 01j,02oct90,hjb  defined HOSTNAME_LEN. added sethostname() and gethostname().
  37. 01i,15jul90,dnw  changed hostNameFill() to coerce malloc() to (char*)
  38. 01h,26jun90,jcf  changed hostList semaphore to type mutex.
  39. 01g,23may89,shl  changed addr parameter in hostGetByAddr() from char* to int.
  40. 01f,21apr89,shl  added hostGetByAddr().
  41.  added hostDelete ().
  42. 01e,18mar88,gae  documentation.
  43. 01d,07jul88,jcf  fixed malloc to match new declaration.
  44. 01c,04jun88,gae  changed S_remLib_* to S_hostLib_*.
  45. 01b,30may88,dnw  changed to v4 names.
  46. 01a,28may88,dnw  extracted from remLib.
  47. */
  48. /*
  49. DESCRIPTION
  50. This library provides routines to store and access the network host database.
  51. The host table contains information regarding the known hosts on the
  52. local network.  The host table (displayed with hostShow()) contains
  53. the Internet address, the official host name, and aliases.
  54. By convention, network addresses are specified in dotted (".") decimal 
  55. notation.  The library inetLib contains Internet address manipulation 
  56. routines.  Host names and aliases may contain any printable character.
  57. Before any of the routines in this module can be used, the library must be
  58. initialized by hostTblInit().  This is done automatically if INCLUDE_HOST_TBL
  59. is defined.
  60. INCLUDE FILES: hostLib.h
  61. SEE ALSO
  62. inetLib
  63. */
  64. #include "vxWorks.h"
  65. #include "sys/types.h"
  66. #include "netinet/in.h"
  67. #include "stdlib.h"
  68. #include "semLib.h"
  69. #include "string.h"
  70. #include "inetLib.h"
  71. #include "lstLib.h"
  72. #include "hostLib.h"
  73. #include "errnoLib.h"
  74. #include "stdio.h"
  75. #include "private/semLibP.h"
  76. #include "memPartLib.h"
  77. #ifdef VIRTUAL_STACK
  78. #include "netinet/vsLib.h"
  79. #endif
  80. #ifndef VIRTUAL_STACK
  81. #define HOSTNAME_LEN 128
  82. /* globals */
  83. LIST hostList;
  84. SEM_ID hostListSem = NULL;
  85. BOOL hostInitFlag = FALSE;
  86. #endif /* VIRTUAL_STACK */
  87. /* Function pointers installed by resolvLib, when the resolver is included */
  88. /* Use DNS resolver for the name query */
  89. FUNCPTR _presolvHostLibGetByName = NULL;  
  90. /* Use DNS resolver for the pointer query */
  91. FUNCPTR _presolvHostLibGetByAddr = NULL;  
  92. /* mutual exclusion options */
  93. int mutexOptionsHostLib = SEM_Q_FIFO | SEM_DELETE_SAFE;
  94. #ifndef VIRTUAL_STACK
  95. /* locals */
  96. LOCAL char targetName [HOSTNAME_LEN]; /* name for this target machine */
  97. #endif /* VIRTUAL_STACK */
  98. /* forward static functions */
  99. static STATUS hostNameFill (HOSTNAME *pHostName, char *newHostName);
  100. /*******************************************************************************
  101. *
  102. * hostTblInit - initialize the network host table
  103. *
  104. * This routine initializes the host list data structure used by routines
  105. * throughout this module.  It should be called before any other routines in
  106. * this module.  This is done automatically if INCLUDE_HOST_TBL is defined.
  107. *
  108. * RETURNS: N/A
  109. *
  110. * SEE ALSO: usrConfig
  111. */
  112. void hostTblInit (void)
  113.     {
  114.     if (!hostInitFlag)
  115. {
  116. hostInitFlag = TRUE;
  117. lstInit (&hostList);
  118. hostListSem = semMCreate (mutexOptionsHostLib);
  119. }
  120.     }
  121. /*******************************************************************************
  122. *
  123. * hostAdd - add a host to the host table
  124. *
  125. * This routine adds a host name to the local host table.
  126. * This must be called before sockets on the remote host are opened,
  127. * or before files on the remote host are accessed via netDrv or nfsDrv.
  128. *
  129. * The host table has one entry per Internet address.
  130. * More than one name may be used for an address.
  131. * Additional host names are added as aliases.
  132. *
  133. * EXAMPLE
  134. * .CS
  135. *    -> hostAdd "wrs", "90.2"
  136. *    -> hostShow
  137. *    hostname         inet address       aliases
  138. *    --------         ------------       -------
  139. *    localhost        127.0.0.1
  140. *    yuba             90.0.0.3
  141. *    wrs              90.0.0.2
  142. *    value = 12288 = 0x3000 = _bzero + 0x18
  143. * .CE
  144. * RETURNS:
  145. * OK, or ERROR if the host table is full, the host name/inet address pair
  146. * is already entered, the Internet address is invalid, or memory is 
  147. * insufficient.
  148. *
  149. * SEE ALSO: netDrv, nfsDrv
  150. */
  151. STATUS hostAdd
  152.     (
  153.     char *hostName,     /* host name */
  154.     char *hostAddr      /* host addr in standard Internet format */
  155.     )
  156.     {
  157.     HOSTNAME *pHostNamePrev = NULL; /* pointer to previous host name entry */
  158.     FAST HOSTNAME *pHostName; /* pointer to host name entry */
  159.     FAST HOSTENTRY *pHostEntry;
  160.     struct in_addr netAddr; /* network address */
  161.     if (hostName == NULL || hostAddr == NULL)
  162.         {
  163.         errnoSet (S_hostLib_INVALID_PARAMETER);
  164.         return (ERROR);
  165.         }
  166.     if ((netAddr.s_addr = inet_addr (hostAddr)) == ERROR)
  167. return (ERROR);
  168.     if (semTake (hostListSem, WAIT_FOREVER) == ERROR)
  169. return (ERROR);
  170.     for (pHostEntry = (HOSTENTRY *)lstFirst (&hostList);
  171.  pHostEntry != NULL;
  172.  pHostEntry = (HOSTENTRY *)lstNext (&pHostEntry->node))
  173. {
  174. if (pHostEntry->netAddr.s_addr == netAddr.s_addr)
  175.     {
  176.     /* host internet address already in table, add name as an alias */
  177.     pHostNamePrev = &pHostEntry->hostName;
  178.     for (pHostName = &pHostEntry->hostName;
  179.  pHostName != NULL;
  180.  pHostName = pHostName->link)
  181. {
  182. /* make sure name is not already used for this address */
  183. if (strcmp (pHostName->name, hostName) == 0)
  184.     {
  185.     semGive (hostListSem);
  186.     errnoSet (S_hostLib_HOST_ALREADY_ENTERED);
  187.     return (ERROR);
  188.     }
  189. pHostNamePrev = pHostName;
  190. }
  191.     if (pHostNamePrev == NULL)
  192. {
  193. /* XXX corrupted list! */
  194. return (ERROR);
  195. }
  196.     /* name not used for this address, add it as an alias */
  197.     if ((pHostNamePrev->link = (HOSTNAME *)
  198.  KHEAP_ALLOC(sizeof (HOSTNAME))) == NULL)
  199. {
  200. semGive (hostListSem);
  201. return (ERROR);
  202. }
  203.     bzero ((char *)pHostNamePrev->link, sizeof(HOSTNAME));
  204.     if (hostNameFill (pHostNamePrev->link, hostName) == ERROR)
  205. {
  206. semGive (hostListSem);
  207. return (ERROR);
  208. }
  209.     semGive (hostListSem);
  210.     return (OK);
  211.     }
  212. }
  213.     /* host name and internet address not in host table, add new host */
  214.     if ((pHostEntry = (HOSTENTRY *) KHEAP_ALLOC(sizeof (HOSTENTRY))) == NULL)
  215. {
  216. semGive (hostListSem);
  217. return (ERROR);
  218. }
  219.     bzero ((char *)pHostEntry, sizeof(HOSTENTRY));
  220.     if ((hostNameFill (&pHostEntry->hostName, hostName)) == ERROR)
  221. {
  222. semGive (hostListSem);
  223. return (ERROR);
  224. }
  225.     
  226.     pHostEntry->netAddr = netAddr;
  227.     lstAdd (&hostList, &pHostEntry->node);
  228.     semGive (hostListSem);
  229.     return (OK);
  230.     }
  231. /*******************************************************************************
  232. *
  233. * hostDelete - delete a host from the host table
  234. *
  235. * This routine deletes a host name from the local host table.  If <name> is
  236. * a host name, the host entry is deleted.  If <name> is a host name alias,
  237. * the alias is deleted.
  238. *
  239. * RETURNS: OK, or ERROR if the parameters are invalid or the host is unknown.
  240. *
  241. * ERRNO: S_hostLib_INVALID_PARAMETER, S_hostLib_UNKNOWN_HOST
  242. */
  243. STATUS hostDelete
  244.     (
  245.     char *name, /* host name or alias */
  246.     char *addr  /* host addr in standard Internet format */
  247.     )
  248.     {
  249.     HOSTNAME *pHostNamePrev; /* pointer to previous host name entry */
  250.     HOSTNAME *pHostNameNext; /* pointer to next host name entry */
  251.     FAST HOSTNAME *pHostName;
  252.     FAST HOSTENTRY *pHostEntry;
  253.     struct in_addr netAddr;
  254.     if (name == NULL || addr == NULL)
  255.         {
  256.         errnoSet (S_hostLib_INVALID_PARAMETER);
  257.         return (ERROR);
  258.         }
  259.     /* convert from string to int format */
  260.     if ((netAddr.s_addr = inet_addr (addr)) == ERROR)
  261. return ERROR;
  262.     semTake (hostListSem, WAIT_FOREVER);
  263.     /* search inet address */
  264.     for (pHostEntry = (HOSTENTRY *)lstFirst (&hostList);
  265.  pHostEntry != NULL;
  266.  pHostEntry = (HOSTENTRY *)lstNext (&pHostEntry->node))
  267.         {
  268. if (pHostEntry->netAddr.s_addr != netAddr.s_addr)
  269.     continue;
  270. if (strcmp (pHostEntry->hostName.name, name) == 0) /* given name is exact match */
  271.     {
  272.     FAST HOSTNAME * pAlias = pHostEntry->hostName.link;
  273.     FAST HOSTNAME * pNext = NULL;
  274.     /* free all associated alias(es) 1st if any, then free itself */
  275.     for ( ; pAlias != NULL; pAlias = pNext)
  276. {
  277. pNext = pAlias->link;
  278. KHEAP_FREE(pAlias->name);
  279. KHEAP_FREE((char *) pAlias);
  280. }
  281.     lstDelete (&hostList, &pHostEntry->node);
  282.     semGive (hostListSem);
  283.     KHEAP_FREE(pHostEntry->hostName.name);
  284.     KHEAP_FREE((char *) pHostEntry);
  285.     return (OK);
  286.     }
  287.         else      /* given name is an alias */
  288.     {
  289.     for (pHostNamePrev = pHostName = &pHostEntry->hostName;
  290.  pHostName != NULL;
  291.  pHostNamePrev = pHostName, pHostName = pHostName->link)
  292. {
  293. pHostNameNext = pHostName->link;
  294. if (strcmp (pHostName->name, name) == 0) /* found alias */
  295.     {
  296.     pHostNamePrev->link = pHostNameNext;
  297.     semGive (hostListSem);
  298.     KHEAP_FREE(pHostName->name);
  299.     KHEAP_FREE((char *) pHostName);
  300.     return (OK);
  301.     }
  302. }
  303.     }
  304. }
  305.     errnoSet (S_hostLib_UNKNOWN_HOST);
  306.     semGive (hostListSem);
  307.     return (ERROR);
  308.     }
  309. /*******************************************************************************
  310. *
  311. * hostTblSearchByName - look up a host in the host table by its name
  312. *
  313. * This routine returns the Internet address of a host that has
  314. * been added to the host table by hostAdd().
  315. *
  316. * RETURNS
  317. * The Internet address (as an integer in network byte order), or ERROR if the 
  318. * host is unknown.
  319. *
  320. * NOMANUAL
  321. *
  322. * INTERNAL
  323. * This function is used by the resolver to search the static host table.
  324. */
  325. int hostTblSearchByName
  326.     (
  327.     char *name          /* name of host */
  328.     )
  329.     {
  330.     HOSTNAME  *pHostName;
  331.     HOSTENTRY *pHostEntry;
  332.     int retAddr = ERROR;
  333.     semTake (hostListSem, WAIT_FOREVER);
  334.     for (pHostEntry = (HOSTENTRY *)lstFirst (&hostList);
  335.  pHostEntry != NULL;
  336.  pHostEntry = (HOSTENTRY *)lstNext (&pHostEntry->node))
  337. {
  338. /* check official name */
  339. if (strcmp (pHostEntry->hostName.name, name) == 0)
  340.     {
  341.     retAddr = (int)pHostEntry->netAddr.s_addr;
  342.     break;
  343.     }
  344. /* check aliases */
  345. for (pHostName = pHostEntry->hostName.link;
  346.      pHostName != NULL;
  347.      pHostName = pHostName->link)
  348.     {
  349.     if (strcmp (pHostName->name, name) == 0)
  350. {
  351. retAddr = (int)pHostEntry->netAddr.s_addr;
  352. /* force termination of outer loop */
  353. pHostEntry = (HOSTENTRY *)lstLast (&hostList);
  354. break;
  355. }
  356.     }
  357. }
  358.     semGive (hostListSem);
  359.     return (retAddr);
  360.     }
  361. /*******************************************************************************
  362. *
  363. * hostGetByName - look up a host in the host table by its name
  364. *
  365. * This routine returns the Internet address of a host that has
  366. * been added to the host table by hostAdd().  If the DNS resolver library
  367. * resolvLib has been configured in the vxWorks image, a query for the host
  368. * IP address is sent to the DNS server, if the name was not found in the local
  369. * host table.
  370. *
  371. * RETURNS: The Internet address (as an integer), or ERROR if the host is
  372. *          unknown.
  373. *
  374. * ERRNO: S_hostLib_INVALID_PARAMETER, S_hostLib_UNKNOWN_HOST
  375. */
  376. int hostGetByName
  377.     (
  378.     char *name          /* name of host */
  379.     )
  380.     {
  381.     int retAddr;
  382.     if (name == (char *) NULL)
  383.         {
  384.         errnoSet (S_hostLib_INVALID_PARAMETER);
  385.         return (ERROR);
  386.         }
  387.     /* Search the host table using the host name as the key */
  388.     retAddr = hostTblSearchByName (name);
  389.     if ((retAddr == ERROR) && (_presolvHostLibGetByName != NULL))
  390. {
  391. /*
  392.  * If host address was not found in the local table.  Try to get the
  393.  * IP from the DNS server, if and only if the resolver library has
  394.  * been linked with the Vxworks image.
  395.  */
  396. retAddr = (*_presolvHostLibGetByName) (name);
  397. }
  398.     if (retAddr == ERROR)
  399. errnoSet (S_hostLib_UNKNOWN_HOST);
  400.     return (retAddr);
  401.     }
  402. /*******************************************************************************
  403. *
  404. * hostTblSearchByAddr - look up a host in the host table by its Internet address
  405. *
  406. * This routine finds the host name by its Internet address and copies it to
  407. * <name>.  The buffer <name> should be preallocated with (MAXHOSTNAMELEN + 1)
  408. * bytes of memory and is NULL-terminated unless insufficient space is
  409. * provided.
  410. *
  411. * WARNING
  412. * This routine does not look for aliases.  Host names are limited to
  413. * MAXHOSTNAMELEN (from hostLib.h) characters.
  414. *
  415. * RETURNS
  416. * OK, or ERROR if the host is unknown.
  417. *
  418. * NOMANUAL
  419. *
  420. * INTERNAL
  421. * This function is used by the resolver to search the static host table.
  422. */
  423. STATUS hostTblSearchByAddr
  424.     (
  425.     int addr,           /* inet address of host */
  426.     char *name          /* buffer to hold name */
  427.     )
  428.     {
  429.     HOSTENTRY *pHostEntry;
  430.     struct in_addr netAddr;
  431.     STATUS status = ERROR;
  432.     int n;
  433.     netAddr.s_addr = addr;
  434.     semTake (hostListSem, WAIT_FOREVER);
  435.     /* search for internet address */
  436.     for (pHostEntry = (HOSTENTRY *)lstFirst (&hostList);
  437.  pHostEntry != NULL;
  438.  pHostEntry = (HOSTENTRY *)lstNext (&pHostEntry->node))
  439. {
  440. if (pHostEntry->netAddr.s_addr == netAddr.s_addr)
  441.     {
  442.     n = strlen (pHostEntry->hostName.name);
  443.     strncpy (name, pHostEntry->hostName.name,
  444. min (n + 1 , MAXHOSTNAMELEN +1));
  445.     status = OK;
  446.     break;
  447.     }
  448.    }
  449.     semGive (hostListSem);
  450.     return (status);
  451.     }
  452. /*******************************************************************************
  453. *
  454. * hostGetByAddr - look up a host in the host table by its Internet address
  455. *
  456. * This routine finds the host name by its Internet address and copies it to
  457. * <name>.  The buffer <name> should be preallocated with (MAXHOSTNAMELEN + 1)
  458. * bytes of memory and is NULL-terminated unless insufficient space is
  459. * provided.  If the DNS resolver library resolvLib has been configured in the
  460. * vxWorks image, a query for the host name is sent to the DNS server, if the
  461. * name was not found in the local host table.
  462. *
  463. * WARNING
  464. * This routine does not look for aliases.  Host names are limited to
  465. * MAXHOSTNAMELEN (from hostLib.h) characters.
  466. *
  467. * RETURNS
  468. * OK, or ERROR if buffer is invalid or the host is unknown.
  469. *
  470. * SEE ALSO
  471. * hostGetByName()
  472. */
  473. STATUS hostGetByAddr
  474.     (
  475.     int addr,           /* inet address of host */
  476.     char *name          /* buffer to hold name */
  477.     )
  478.     {
  479.     STATUS status;
  480.     if (name == NULL)
  481.         {
  482.         errnoSet (S_hostLib_INVALID_PARAMETER);
  483.         return (ERROR);
  484.         }
  485.     /* Search the host table using the host address as the key */
  486.     status = hostTblSearchByAddr (addr, name);
  487.     if ((status != OK) && (_presolvHostLibGetByAddr != NULL))
  488. {
  489. /*
  490.  * If host name was not found in the local table.  Try to get the
  491.  * name from the DNS server, if and only if the resolver library has
  492.  * been linked with the Vxworks image.
  493.  */
  494. status = (*_presolvHostLibGetByAddr) (addr, name);
  495. }
  496.     if (status != OK)
  497. errnoSet (S_hostLib_UNKNOWN_HOST);
  498.     return (status);
  499.     }
  500. /*******************************************************************************
  501. *
  502. * hostNameFill - fill in host name
  503. *
  504. * RETURNS: OK or ERROR if out of memory
  505. */
  506. LOCAL STATUS hostNameFill
  507.     (
  508.     FAST HOSTNAME *pHostName,
  509.     char *newHostName
  510.     )
  511.     {
  512.     FAST char *pName = (char *) KHEAP_ALLOC((unsigned) (strlen (newHostName) + 1));
  513.     if (pName == NULL)
  514. return (ERROR);
  515.     strcpy (pName, newHostName);
  516.     pHostName->name = pName;
  517.     pHostName->link = NULL;
  518.     return (OK);
  519.     }
  520. /*******************************************************************************
  521. *
  522. * sethostname - set the symbolic name of this machine
  523. *
  524. * This routine sets the target machine's symbolic name, which can be used
  525. * for identification.
  526. *
  527. * RETURNS: OK or ERROR.
  528. */
  529. int sethostname
  530.     (
  531.     char *name,                 /* machine name */
  532.     int  nameLen                /* length of name */
  533.     )
  534.     {
  535. #ifdef VIRTUAL_STACK
  536.     if (name != NULL && nameLen < sizeof (_targetName))
  537. {
  538.         strcpy (_targetName, name);
  539. #else
  540.     if (name != NULL && nameLen < sizeof (targetName))
  541. {
  542.         strcpy (targetName, name);
  543. #endif
  544. return (0);
  545. }
  546.     return (-1);
  547.     }
  548. /******************************************************************************
  549. *
  550. * gethostname - get the symbolic name of this machine
  551. *
  552. * This routine gets the target machine's symbolic name, which can be used
  553. * for identification.
  554. *
  555. * RETURNS: OK or ERROR.
  556. */
  557. int gethostname
  558.     (
  559.     char *name,  /* machine name */
  560.     int   nameLen  /* length of name */
  561.     )
  562.     {
  563. #ifdef VIRTUAL_STACK
  564.     if (name != NULL && strlen (_targetName) < nameLen)
  565. {
  566.         strcpy (name, _targetName);
  567. #else
  568.     if (name != NULL && strlen (targetName) < nameLen)
  569. {
  570.         strcpy (name, targetName);
  571. #endif
  572. return (0);
  573. }
  574.     return (-1);
  575.     }