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