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

VxWorks

开发平台:

C/C++

  1. /* inetLib.c - Internet address manipulation routines */
  2. /* Copyright 1984 - 2001 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5.  * Copyright (c) 1983 Regents of the University of California.
  6.  * All rights reserved.  The Berkeley software License Agreement
  7.  * specify the terms and conditions for redistribution.
  8.  */
  9. /*
  10. modification history
  11. --------------------
  12. 02k,10may02,kbw  making man page edits
  13. 02j,05nov01,vvv  fixed compilation warnings
  14. 02i,15oct01,rae  merge from truestack ver 02p, base 02h (SPRs 9424, 21740,
  15.                  65809, 34949, 36026)
  16. 02h,13dec97,kbw  made man page edits
  17. 02g,31jul97,kbw  fixed man page problems found in beta review
  18. 02f,15apr97,kbw  fixing man page format and minor wording issues
  19. 02e,16dec96,jag  added function inet_aton, added stricter check for invalid
  20.  IP addresses to inet_addr. Cleaned up warnings.
  21. 02d,06sep96,vin  upgraded to BSD44. Added CLASSD network and host processing.
  22.  removed call to in_makeaddr_b, no longer necessary.
  23. 02d,07oct96,dgp  doc: inet_ntoa and inet_ntoa_b - update descriptions
  24. 02c,16may96,dgp  doc fixes, SPR 5991 & 5993.
  25. 02b,09jan96,gnn  Added a define for MAX_PARTS for inet_addr.  Fixed
  26.  and array bounds checking error.  (SPR 5217)
  27. 02a,31oct95,jdi  doc: changed in.h to inet.h (SPR 5306).
  28. 01z,16oct95,jdi  doc: removed extra zeroes in some inet addresses (SPR 4869).
  29. 01y,16feb94,caf  added check for NULL pointer in inet_addr() (SPR #2920).
  30. 01x,20jan93,jdi  documentation cleanup for 5.1.
  31. 01w,18jul92,smb  Changed errno.h to errnoLib.h.
  32. 01v,26may92,rrr  the tree shuffle
  33.   -changed includes to have absolute path from h/
  34. 01u,10dec91,gae  added includes for ANSI.
  35. 01t,04oct91,rrr  passed through the ansification filter
  36.                   -changed functions to ansi style
  37.   -changed includes to have absolute path from h/
  38.   -changed VOID to void
  39.   -changed copyright notice
  40. 01s,20may91,jdi  documentation tweak.
  41. 01r,30apr91,jdi  documentation tweaks.
  42. 01q,05apr91,jdi  documentation -- removed header parens and x-ref numbers;
  43.  doc review by dnw.
  44. 01p,12feb91,jaa  documentation.
  45. 01o,26jun90,hjb  moved Show routines to netShow.c.
  46. 01n,11may90,yao  added missing modification history (01m) for the last checkin.
  47. 01m,09may90,yao  typecasted malloc to (char *).
  48. 01l,11apr90,hjb  de-linted.
  49. 01k,08sep89,hjb  added tcpstatShow(), udpstatShow(), icmpstatShow(),
  50.  inetstatShow().
  51. 01j,29sep88,gae  documentation.
  52. 01i,18aug88,gae  documentation.
  53. 01h,30may88,dnw  changed to v4 names.
  54. 01g,18feb88,dnw  changed inet_netof_string() to be work with subnet masks
  55.    by changing to call in_{makeaddr_b,netof} instead of
  56.    inet_{...}.
  57.  lint.
  58. 01f,15dec87,gae  appeased lint; checked malloc's for NULL.
  59. 01e,17nov87,ecs  lint.
  60. 01d,16nov87,jlf  documentation.
  61. 01c,16nov87,llk  documentation.
  62.  changed to use more descriptive variable names.
  63. 01b,06nov87,dnw  cleanup.
  64. 01a,01nov87,llk  written.
  65.  modified routines for VxWorks style (setStatus(), etc.)
  66.  added inet_netof_string(), inet_makeaddr_b(), inet_ntoa_b().
  67.  changed inet_ntoa() and inet_makeaddr() so that they malloc
  68.    the structures that they return.
  69.  NOTE: inet_addr returns u_long as specified in SUN documenta-
  70.    tion, NOT in ISI documentation and arpa/inet.h header file.
  71. */
  72. /*
  73. DESCRIPTION
  74. This library provides routines for manipulating Internet addresses,
  75. including the UNIX BSD 4.3 'inet_' routines.  It includes routines for
  76. converting between character addresses in Internet standard dotted decimal 
  77. notation and integer addresses, routines for extracting the 
  78. network and host portions out of an Internet address, and routines 
  79. for constructing Internet addresses given the network and host address 
  80. parts.
  81. All Internet addresses are returned in network order (bytes ordered from
  82. left to right).  All network numbers and local address parts are returned
  83. as machine format integer values.
  84. INTERNET ADDRESSES
  85. Internet addresses are typically specified in dotted decimal notation or 
  86. as a 4-byte number.  Values specified using the dotted decimal notation 
  87. take one of the following forms:
  88. .CS
  89. a.b.c.d
  90. a.b.c
  91. a.b
  92. a
  93. .CE
  94. If four parts are specified, each is interpreted as a byte of data and
  95. assigned, from left to right, to the four bytes of an Internet address.
  96. Note that when an Internet address is viewed as a 32-bit integer quantity
  97. on any MC68000 family machine, the bytes referred to above appear as
  98. "a.b.c.d" and are ordered from left to right.
  99. If a three-part address is specified, the last part is interpreted as a
  100. 16-bit quantity and placed in the right-most two bytes of the network
  101. address.  This makes the three-part address format convenient for
  102. specifying Class B network addresses as "128.net.host".
  103. If a two-part address is supplied, the last part is interpreted as a
  104. 24-bit quantity and placed in the right-most three bytes of the network
  105. address.  This makes the two-part address format convenient for specifying
  106. Class A network addresses as "net.host".
  107. If only one part is given, the value is stored directly in the network
  108. address without any byte rearrangement.
  109. Although dotted decimal notation is the default, it is possible to use the 
  110. dot notation with hexadecimal or octal numbers.  The base is indicated
  111. using the same prefixes as are used in C.  That is, a leading 
  112. 0x or 0X indicates a hexadecimal number.  A leading 0 indicates an
  113. octal number.  If there is no prefix, the number is interpreted as decimal.
  114. To use this feature, include the following component:
  115. INCLUDE_NETWRS_INETLIB
  116. INCLUDE FILES:
  117. inetLib.h, inet.h
  118. SEE ALSO: UNIX BSD 4.3 manual entry for inet(3N)
  119. */
  120. #include "vxWorks.h"
  121. #include "sys/types.h"
  122. #include "ctype.h"
  123. #include "netinet/in.h"
  124. #include "memLib.h"
  125. #include "string.h"
  126. #include "inetLib.h"
  127. #include "stdlib.h"
  128. #include "errnoLib.h"
  129. #include "stdio.h"
  130. /*******************************************************************************
  131. *
  132. * inet_addr - convert a dot notation Internet address to a long integer
  133. *
  134. * This routine interprets an Internet address.  All the network library
  135. * routines call this routine to interpret entries in the data bases
  136. * which are expected to be an address.  The value returned is in network order.
  137. * Numbers will be interpreted as octal if preceded by a zero (e.g. "017.0.0.3"),
  138. * as hexadecimal if preceded by 0x (e.g. "0x17.0.0.4"), and as decimal in all
  139. * other cases.
  140. *
  141. * EXAMPLE
  142. * The following example returns 0x5a000002:
  143. * .CS
  144. *     inet_addr ("90.0.0.2");
  145. * .CE
  146. *
  147. * RETURNS: The Internet address, or ERROR.
  148. */
  149. u_long inet_addr
  150.     (
  151.     register char *inetString    /* string inet address */
  152.     )
  153.     {
  154. #define MAX_PARTS 4  /* Maximum number of parts in an IP address. */
  155.     register u_long val, base, n;
  156.     register char c;
  157.     u_long parts[MAX_PARTS], *pp = parts;
  158.     /* check for NULL pointer */
  159.     if (inetString == (char *) NULL)
  160. {
  161. (void) errnoSet (S_inetLib_ILLEGAL_INTERNET_ADDRESS);
  162. return (ERROR);
  163. }
  164. again:
  165.     /* Collect number up to ``.''.  Values are specified as for C:
  166.      * 0x=hex, 0=octal, other=decimal. */
  167.     val = 0; base = 10;
  168.     if (*inetString == '0')
  169. {
  170. base = 8, inetString++;
  171.         if (*inetString == 'x' || *inetString == 'X')
  172.     base = 16, inetString++;
  173.         }
  174.     while ((c = *inetString))
  175. {
  176. if (isdigit ((int) c))
  177.     {
  178.     val = (val * base) + (c - '0');
  179.     inetString++;
  180.     continue;
  181.     }
  182. if (base == 16 && isxdigit ((int) c))
  183.     {
  184.     val = (val << 4) + (c + 10 - (islower ((int) c) ? 'a' : 'A'));
  185. inetString++;
  186. continue;
  187.     }
  188.     break;
  189. } /* while */
  190.     if (*inetString == '.')
  191. {
  192. /*
  193.  * Internet format:
  194.  * a.b.c.d
  195.  * a.b.c (with c treated as 16-bits)
  196.  * a.b (with b treated as 24 bits)
  197.  * Check each value for greater than 0xff for each part of the IP addr.
  198.  */
  199. if ((pp >= parts + (MAX_PARTS - 1)) || val > 0xff)
  200.     {
  201.     (void) errnoSet (S_inetLib_ILLEGAL_INTERNET_ADDRESS);
  202.     return (ERROR);
  203.     }
  204. *pp++ = val, inetString++;
  205. goto again;
  206. }
  207.     /* Check for trailing characters */
  208.     if (*inetString && !isspace ((int) *inetString)) 
  209. {
  210. (void) errnoSet (S_inetLib_ILLEGAL_INTERNET_ADDRESS);
  211. return (ERROR);
  212. }
  213.     *pp++ = val;
  214.     /* Concoct the address according to the number of parts specified. */
  215.     n = pp - parts;
  216.     switch ((int) n)
  217. {
  218. case 1: /* a -- 32 bits */
  219.     val = parts[0];
  220.     break;
  221. case 2: /* a.b -- 8.24 bits */
  222.     if (val > 0xffffff)
  223.         {
  224. (void) errnoSet (S_inetLib_ILLEGAL_INTERNET_ADDRESS);
  225. return (ERROR);
  226. }
  227.     val = (parts[0] << 24) | parts[1];
  228.     break;
  229. case 3: /* a.b.c -- 8.8.16 bits */
  230.     if (val > 0xffff)
  231.         {
  232. (void) errnoSet (S_inetLib_ILLEGAL_INTERNET_ADDRESS);
  233. return (ERROR);
  234. }
  235.     val = (parts[0] << 24) | (parts[1] << 16) | parts[2];
  236.     break;
  237. case 4: /* a.b.c.d -- 8.8.8.8 bits */
  238.     if (val > 0xff)
  239.         {
  240. (void) errnoSet (S_inetLib_ILLEGAL_INTERNET_ADDRESS);
  241. return (ERROR);
  242. }
  243.     val = (parts[0] << 24) | (parts[1] << 16) |
  244.   (parts[2] << 8) | parts[3];
  245.     break;
  246. default:
  247.     (void) errnoSet (S_inetLib_ILLEGAL_INTERNET_ADDRESS);
  248.     return (ERROR);
  249. }
  250.     return (htonl (val));
  251.     }
  252. #ifndef STANDALONE_AGENT
  253. /*******************************************************************************
  254. *
  255. * inet_lnaof - get the local address (host number) from the Internet address
  256. *
  257. * This routine returns the local network address portion of an Internet address.
  258. * The routine handles class A, B, and C network number formats.
  259. *
  260. * EXAMPLE
  261. * The following example returns 2:
  262. * .CS
  263. *     inet_lnaof (0x5a000002);
  264. * .CE
  265. *
  266. * RETURNS: The local address portion of <inetAddress>.
  267. */
  268. int inet_lnaof
  269.     (
  270.     int inetAddress   /* inet addr from which to extract local portion */
  271.     )
  272.     {
  273.     register u_long i = ntohl ((u_long) inetAddress);
  274.     if (IN_CLASSA (i))
  275. return ((i) &IN_CLASSA_HOST);
  276.     else if (IN_CLASSB (i))
  277. return ((i) &IN_CLASSB_HOST);
  278.     else if (IN_CLASSC (i))
  279. return ((i) &IN_CLASSC_HOST);
  280.     else
  281. return ((i) &IN_CLASSD_HOST); 
  282.     }
  283. /*******************************************************************************
  284. *
  285. * inet_makeaddr_b - form an Internet address from network and host numbers
  286. *
  287. * This routine constructs the Internet address from the network number and
  288. * local host address.  This routine is identical to the UNIX inet_makeaddr()
  289. * routine except that you must provide a buffer for the resulting value.
  290. *
  291. * EXAMPLE
  292. * The following copies the address 0x5a000002 to the location 
  293. * pointed to by <pInetAddr>:
  294. * .CS
  295. *     inet_makeaddr_b (0x5a, 2, pInetAddr);
  296. * .CE
  297. *
  298. * RETURNS: N/A
  299. */
  300. void inet_makeaddr_b
  301.     (
  302.     int netAddr,                /* network part of the inet address */
  303.     int hostAddr,               /* host part of the inet address */
  304.     struct in_addr *pInetAddr   /* where to return the inet address */
  305.     )
  306.     {
  307.     register u_long addr;
  308.     if (netAddr < 128)
  309. addr = (netAddr << IN_CLASSA_NSHIFT) | (hostAddr & IN_CLASSA_HOST);
  310.     else if (netAddr < 65536)
  311. addr = (netAddr << IN_CLASSB_NSHIFT) | (hostAddr & IN_CLASSB_HOST);
  312.     else if (netAddr < 16777216)
  313. addr = (netAddr << IN_CLASSC_NSHIFT) | (hostAddr & IN_CLASSC_HOST);
  314.     else
  315. addr = (netAddr << IN_CLASSD_NSHIFT) | (hostAddr & IN_CLASSD_HOST);
  316.     pInetAddr->s_addr = htonl (addr);
  317.     }
  318. /*******************************************************************************
  319. *
  320. * inet_makeaddr - form an Internet address from network and host numbers
  321. *
  322. * This routine constructs the Internet address from the network number and
  323. * local host address.
  324. *
  325. * WARNING
  326. * This routine is supplied for UNIX compatibility only.  Each time this
  327. * routine is called, four bytes are allocated from memory.  Use
  328. * inet_makeaddr_b() instead.
  329. *
  330. * EXAMPLE
  331. * The following example returns the address 0x5a000002 to the structure 
  332. * `in_addr':
  333. * .CS
  334. *     inet_makeaddr (0x5a, 2);
  335. * .CE
  336. *
  337. * RETURNS: The network address in an `in_addr' structure.
  338. *
  339. * SEE ALSO: inet_makeaddr_b()
  340. */
  341. struct in_addr inet_makeaddr
  342.     (
  343.     int netAddr,    /* network part of the address */
  344.     int hostAddr    /* host part of the address */
  345.     )
  346.     {
  347.     struct in_addr *pAddr = (struct in_addr *) malloc (sizeof (struct in_addr));
  348.     if (pAddr != NULL)
  349. inet_makeaddr_b (netAddr, hostAddr, pAddr);
  350.     return (*pAddr);
  351.     }
  352. /*******************************************************************************
  353. *
  354. * inet_netof - return the network number from an Internet address
  355. *
  356. * This routine extracts the network portion of an Internet address.
  357. *
  358. * EXAMPLE
  359. * The following example returns 0x5a:
  360. * .CS
  361. *     inet_netof (0x5a000002);
  362. * .CE
  363. *
  364. * RETURNS: The network portion of <inetAddress>.
  365. */
  366. int inet_netof
  367.     (
  368.     struct in_addr inetAddress  /* inet address */
  369.     )
  370.     {
  371.     register u_long i = ntohl ((u_long) inetAddress.s_addr);
  372.     if (IN_CLASSA (i))
  373. return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
  374.     else if (IN_CLASSB (i))
  375. return (((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
  376.     else if (IN_CLASSC (i))
  377. return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
  378.     else
  379. return (((i)&IN_CLASSD_NET) >> IN_CLASSD_NSHIFT);
  380.     }
  381. /*******************************************************************************
  382. *
  383. * inet_netof_string - extract the network address in dot notation
  384. *
  385. * This routine extracts the network Internet address from a host Internet
  386. * address (specified in dotted decimal notation).  The routine handles 
  387. * class A, B, and C network addresses.  The buffer <netString> should 
  388. * be INET_ADDR_LEN bytes long.
  389. *
  390. * NOTE
  391. * This is the only routine in inetLib that handles subnet masks correctly.
  392. *
  393. * EXAMPLE
  394. * The following example copies "90.0.0.0" to <netString>:
  395. * .CS
  396. *     inet_netof_string ("90.0.0.2", netString);
  397. * .CE
  398. *
  399. * RETURNS: N/A
  400. */
  401. void inet_netof_string
  402.     (
  403.     char *inetString,   /* inet addr to extract local portion from */
  404.     char *netString     /* net inet address to return */
  405.     )
  406.     {
  407.     struct in_addr inaddrHost;
  408.     struct in_addr inaddrNet;
  409.     /* convert string to u_long */
  410.     inaddrHost.s_addr = inet_addr (inetString);
  411.     inaddrNet.s_addr = htonl ((in_netof (inaddrHost))); 
  412.     /* convert network portion to dot notation */
  413.     inet_ntoa_b (inaddrNet, netString);
  414.     }
  415. /*******************************************************************************
  416. *
  417. * inet_network - convert an Internet network number from string to address
  418. *
  419. * This routine forms a network address from an ASCII string containing
  420. * an Internet network number.
  421. *
  422. * EXAMPLE
  423. * The following example returns 0x5a:
  424. * .CS
  425. *     inet_network ("90");
  426. * .CE
  427. *
  428. * RETURNS: The Internet address for an ASCII string, or ERROR if invalid.
  429. */
  430. u_long inet_network
  431.     (
  432.     register char *inetString           /* string version of inet addr */
  433.     )
  434.     {
  435.     register u_long val, base, n;
  436.     register char c;
  437.     u_long parts[4], *pp = parts;
  438.     register int i;
  439. again:
  440.     val = 0;
  441.     base = 10;
  442.     if (*inetString == '0')
  443. base = 8, inetString++;
  444.     if (*inetString == 'x' || *inetString == 'X')
  445. base = 16, inetString++;
  446.     while ((c = *inetString))
  447. {
  448. if (isdigit ((int) c))
  449.     {
  450.     val = (val * base) + (c - '0');
  451.     inetString++;
  452.     continue;
  453.     }
  454. if (base == 16 && isxdigit ((int) c))
  455.     {
  456.     val = (val << 4) + (c + 10 - (islower ((int) c) ? 'a' : 'A'));
  457.     inetString++;
  458.     continue;
  459.     }
  460. break;
  461. }
  462.     if (*inetString == '.')
  463. {
  464. if (pp >= parts + 4)
  465.     {
  466.     (void) errnoSet (S_inetLib_ILLEGAL_NETWORK_NUMBER);
  467.     return (ERROR);
  468.     }
  469. *pp++ = val, inetString++;
  470. goto again;
  471. }
  472.     if (*inetString && !isspace ((int) *inetString))
  473. {
  474. (void) errnoSet (S_inetLib_ILLEGAL_NETWORK_NUMBER);
  475. return (ERROR);
  476. }
  477.     *pp++ = val;
  478.     n = pp - parts;
  479.     if (n > 4)
  480. {
  481. (void) errnoSet (S_inetLib_ILLEGAL_NETWORK_NUMBER);
  482. return (ERROR);
  483. }
  484.     for (val = 0, i = 0; i < n; i++)
  485. {
  486. val <<= 8;
  487. val |= parts[i] & 0xff;
  488. }
  489.     return (val);
  490.     }
  491. /*******************************************************************************
  492. *
  493. * inet_ntoa_b - convert an network address to dot notation, store it in a buffer
  494. *
  495. * This routine converts an Internet address in network format to dotted
  496. * decimal notation.
  497. *
  498. * This routine is identical to the UNIX inet_ntoa() routine
  499. * except that you must provide a buffer of size INET_ADDR_LEN.
  500. *
  501. * EXAMPLE
  502. * The following example copies the string "90.0.0.2" to <pString>:
  503. * .CS
  504. *     struct in_addr iaddr;
  505. *      ...
  506. *     iaddr.s_addr = 0x5a000002;
  507. *      ...
  508. *     inet_ntoa_b (iaddr, pString);
  509. * .CE
  510. *
  511. * RETURNS: N/A
  512. */
  513. void inet_ntoa_b
  514.     (
  515.     struct in_addr inetAddress, /* inet address */
  516.     char *pString               /* where to return ASCII string */
  517.     )
  518.     {
  519.     register char *p = (char *)&inetAddress;
  520. #define UC(b) (((int)b)&0xff)
  521.     (void) sprintf (pString, "%d.%d.%d.%d",
  522.     UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
  523.     }
  524. /*******************************************************************************
  525. *
  526. * inet_ntoa - convert a network address to dotted decimal notation
  527. *
  528. * This routine converts an Internet address in network format to dotted
  529. * decimal notation.
  530. *
  531. * WARNING
  532. * This routine is supplied for UNIX compatibility only.  Each time this
  533. * routine is called, 18 bytes are allocated from memory.  Use inet_ntoa_b()
  534. * instead.
  535. *
  536. * EXAMPLE
  537. * The following example returns a pointer to the string "90.0.0.2":
  538. * .CS
  539. *     struct in_addr iaddr;
  540. *      ...
  541. *     iaddr.s_addr = 0x5a000002;
  542. *      ...
  543. *     inet_ntoa (iaddr);
  544. * .CE
  545. *
  546. * RETURNS: A pointer to the string version of an Internet address.
  547. *
  548. * SEE ALSO: inet_ntoa_b()
  549. */
  550. char *inet_ntoa
  551.     (
  552.     struct in_addr inetAddress    /* inet address */
  553.     )
  554.     {
  555.     FAST char *buf = (char *) malloc (INET_ADDR_LEN);
  556.     if (buf != NULL)
  557. inet_ntoa_b (inetAddress, buf);
  558.     return (buf);
  559.     }
  560. /*******************************************************************************
  561. *
  562. * inet_aton - convert a network address from dot notation, store in a structure
  563. *
  564. * This routine interprets an Internet address.  All the network library
  565. * routines call this routine to interpret entries in the data bases
  566. * that are expected to be an address.  The value returned is stored in
  567. * network byte order in the structure provided.
  568. *
  569. * EXAMPLE
  570. * The following example returns 0x5a000002 in the 's_addr' member of the 
  571. * structure pointed to by <pinetAddr>:
  572. * .CS
  573. *     inet_aton ("90.0.0.2", pinetAddr);
  574. * .CE
  575. *
  576. * RETURNS: OK, or ERROR if address is invalid.
  577. */
  578. STATUS inet_aton 
  579.     (
  580.     char           * pString,     /* string containing address, dot notation */
  581.     struct in_addr * inetAddress  /* struct in which to store address */
  582.     )
  583.     {
  584.     u_long rtnAddress;
  585.     int oldError;
  586.     /*
  587.      * Since the conversion routine returns the equivalent of ERROR for
  588.      * the string "255.255.255.255", this routine detects problems by
  589.      * a change in the global error number value. Save the original
  590.      * setting in case no error occurs. 
  591.      */
  592.     oldError = errno;
  593.     errno = 0;
  594.     rtnAddress = inet_addr (pString);
  595.     if (errno != S_inetLib_ILLEGAL_INTERNET_ADDRESS)
  596. {
  597. inetAddress->s_addr = rtnAddress; /* Valid address, even 0xffffffff */
  598.         errno = oldError;
  599. return (OK);
  600.         }
  601.     return (ERROR);
  602.     }
  603. #endif /* STANDALONE_AGENT */