os/ossrv/genericopenlibs/cstdlib/LPOSIX/ARPA.C
author sl
Tue, 10 Jun 2014 14:32:02 +0200 (2014-06-10)
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /* ARPA.C
     2  * 
     3  * Portions Copyright (c) 1997-1999 Nokia Corporation and/or its subsidiary(-ies).
     4  * All rights reserved.
     5  */
     6 
     7 /*
     8  * Implementation of the ARPA/INET.H functions, based on FreeBSD.
     9  */
    10 
    11 /*
    12  * Copyright (c) 1983, 1993
    13  *      The Regents of the University of California.  All rights reserved.
    14  *
    15  * Redistribution and use in source and binary forms, with or without
    16  * modification, are permitted provided that the following conditions
    17  * are met:
    18  * 1. Redistributions of source code must retain the above copyright
    19  *    notice, this list of conditions and the following disclaimer.
    20  * 2. Redistributions in binary form must reproduce the above copyright
    21  *    notice, this list of conditions and the following disclaimer in the
    22  *    documentation and/or other materials provided with the distribution.
    23  * 3. All advertising materials mentioning features or use of this software
    24  *    must display the following acknowledgement:
    25  *      This product includes software developed by the University of
    26  *      California, Berkeley and its contributors.
    27  * 4. Neither the name of the University nor the names of its contributors
    28  *    may be used to endorse or promote products derived from this software
    29  *    without specific prior written permission.
    30  *
    31  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
    32  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    33  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    34  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
    35  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    39  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    40  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    41  * SUCH DAMAGE.
    42  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
    43  * 
    44  * Permission to use, copy, modify, and distribute this software for any
    45  * purpose with or without fee is hereby granted, provided that the above
    46  * copyright notice and this permission notice appear in all copies, and that
    47  * the name of Digital Equipment Corporation not be used in advertising or
    48  * publicity pertaining to distribution of the document or software without
    49  * specific, written prior permission.
    50  * 
    51  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
    52  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
    53  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
    54  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
    55  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
    56  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
    57  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
    58  * SOFTWARE.
    59  * -
    60  * --Copyright--
    61  */
    62 
    63 #include <stdio_r.h>
    64 #include <netdb_r.h>
    65 #include <ctype.h>
    66 #include <sys/types.h>
    67 #include <libc/netinet/in.h>
    68 #include <libc/arpa/inet.h>
    69 
    70 
    71 /**
    72 Ascii internet address interpretation routine.
    73 @return The value returned is in network order.
    74 @param cp ascii representation of an Internet address
    75 */
    76 EXPORT_C unsigned long inet_addr(const char *cp)
    77 {
    78         struct in_addr val;
    79 
    80         if (inet_aton(cp, &val))
    81                 return (val.s_addr);
    82         return (INADDR_NONE);
    83 }
    84 
    85 /**
    86 Check whether "cp" is a valid ascii representation
    87 of an Internet address and convert to a binary address.
    88 This replaces inet_addr, the return value from which
    89 cannot distinguish between failure and a local broadcast address.
    90 @return 1 if the address is valid, 0 if not.
    91 @param cp ascii representation of an Internet address
    92 @param addr internet address
    93 */
    94 EXPORT_C int inet_aton(const char* cp, struct in_addr* addr)
    95 {
    96         unsigned long val;
    97         int base, n;
    98         char c;
    99         unsigned int parts[4];
   100         unsigned int *pp = parts;
   101 
   102         c = *cp;
   103         for (;;) {
   104                 /*
   105                  * Collect number up to ``.''.
   106                  * Values are specified as for C:
   107                  * 0x=hex, 0=octal, isdigit=decimal.
   108                  */
   109                 if (!isdigit(c))
   110                         return (0);
   111                 val = 0; base = 10;
   112                 if (c == '0') {
   113                         c = *++cp;
   114                         if (c == 'x' || c == 'X')
   115                                 base = 16, c = *++cp;
   116                         else
   117                                 base = 8;
   118                 }
   119                 for (;;) {
   120                         if (isascii(c) && isdigit(c)) {
   121                                 val = (val * base) + (c - '0');
   122                                 c = *++cp;
   123                         } else if (base == 16 && isascii(c) && isxdigit(c)) {
   124                                 val = (val << 4) |
   125                                         (c + 10 - (islower(c) ? 'a' : 'A'));
   126                                 c = *++cp;
   127                         } else
   128                                 break;
   129                 }
   130                 if (c == '.') {
   131                         /*
   132                          * Internet format:
   133                          *      a.b.c.d
   134                          *      a.b.c   (with c treated as 16 bits)
   135                          *      a.b     (with b treated as 24 bits)
   136                          */
   137                         if (pp >= parts + 3)
   138                                 return (0);
   139 		                if (val > 0xff) /* Check 8-bit a, b, c */
   140 		                        return (0);
   141                         *pp++ = val;
   142                         c = *++cp;
   143                 } else
   144                         break;
   145         }
   146         /*
   147          * Check for trailing characters.
   148          */
   149         if (c != '\0' && (!isascii(c) || !isspace(c)))
   150                 return (0);
   151         /*
   152          * Concoct the address according to
   153          * the number of parts specified.
   154          */
   155         n = pp - parts + 1;
   156         switch (n) {
   157 
   158         case 0:
   159                 return (0);             /* initial nondigit */
   160 
   161         case 1:                         /* a -- 32 bits */
   162                 break;
   163 
   164         case 2:                         /* a.b -- 8.24 bits */
   165                 if (val > 0xffffff)
   166                         return (0);
   167                 val |= parts[0] << 24;
   168                 break;
   169 
   170         case 3:                         /* a.b.c -- 8.8.16 bits */
   171                 if (val > 0xffff)
   172                         return (0);
   173                 val |= (parts[0] << 24) | (parts[1] << 16);
   174                 break;
   175 
   176         case 4:                         /* a.b.c.d -- 8.8.8.8 bits */
   177                 if (val > 0xff)
   178                         return (0);
   179                 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
   180                 break;
   181         }
   182         if (addr)
   183                 addr->s_addr = htonl(val);
   184         return (1);
   185 }
   186 
   187 /*
   188  * Convert network-format internet address
   189  * to base 256 d.d.d.d representation.
   190  */
   191 EXPORT_C char* _inet_ntoa_r(struct _reent* rp, struct in_addr in)
   192 {
   193         unsigned char* p = (unsigned char *)&in;
   194         _sprintf_r(rp, rp->_tmpnam, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
   195         return rp->_tmpnam;
   196 }
   197 
   198 #ifndef _REENT_ONLY
   199 
   200 EXPORT_C char* inet_ntoa(struct in_addr in)
   201 {
   202 	return _inet_ntoa_r(_REENT,in);
   203 }
   204 
   205 #endif /* _REENT_ONLY */
   206 
   207 /**
   208 Return the local network address portion of an
   209 internet address; handles class a/b/c network
   210 number formats.
   211 @return the local network address portion of an
   212 internet address
   213 @param in 
   214 */ 
   215 EXPORT_C unsigned long inet_lnaof(struct in_addr in)
   216 {
   217         register unsigned long i = ntohl(in.s_addr);
   218 
   219         if (IN_CLASSA(i))
   220                 return ((i)&IN_CLASSA_HOST);
   221         else if (IN_CLASSB(i))
   222                 return ((i)&IN_CLASSB_HOST);
   223         else
   224                 return ((i)&IN_CLASSC_HOST);
   225 }
   226 
   227 /**
   228 @return the network number from an internet
   229 address; handles class a/b/c network #'s.
   230 @param in
   231 */
   232 EXPORT_C unsigned long inet_netof(struct in_addr in)
   233 {
   234         unsigned long i = ntohl(in.s_addr);
   235 
   236         if (IN_CLASSA(i))
   237                 return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
   238         else if (IN_CLASSB(i))
   239                 return (((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
   240         else
   241                 return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
   242 }
   243 
   244 /** Formulate an Internet address from network + host.
   245 */
   246 EXPORT_C struct in_addr inet_makeaddr(unsigned long net, unsigned long host)
   247 {
   248         unsigned long addr;
   249 
   250         if (net < IN_CLASSA_MAX)
   251                 addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST);
   252         else if (net < IN_CLASSB_MAX)
   253                 addr = (net << IN_CLASSB_NSHIFT) | (host & IN_CLASSB_HOST);
   254         else if (net < IN_CLASSC_MAX)
   255                 addr = (net << IN_CLASSC_NSHIFT) | (host & IN_CLASSC_HOST);
   256         else
   257                 addr = net | host;
   258         addr = htonl(addr);
   259         return (*(struct in_addr *)&addr);
   260 }
   261