entered into RCS
[kopensolaris-gnu/glibc.git] / inet / inet_addr.c
1 /*
2  * ++Copyright++
3  * -
4  * Copyright (c)  Regents of the University of California.
5  * All rights reserved.
6  * 
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *      This product includes software developed by the University of
18  *      California, Berkeley and its contributors.
19  * 4. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  * 
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  * -
35  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
36  * 
37  * Permission to use, copy, modify, and distribute this software for any
38  * purpose with or without fee is hereby granted, provided that the above
39  * copyright notice and this permission notice appear in all copies, and that
40  * the name of Digital Equipment Corporation not be used in advertising or
41  * publicity pertaining to distribution of the document or software without
42  * specific, written prior permission.
43  * 
44  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
45  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
46  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
47  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
48  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
49  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
50  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
51  * SOFTWARE.
52  * -
53  * --Copyright--
54  */
55
56 #if defined(LIBC_SCCS) && !defined(lint)
57 static char sccsid[] = "@(#)inet_addr.c 5.11 (Berkeley) 12/9/91";
58 #endif /* LIBC_SCCS and not lint */
59
60 #include <sys/param.h>
61 #include <netinet/in.h>
62 #include <arpa/inet.h>
63 #include <ctype.h>
64 #include "../conf/portability.h"
65
66 #if !defined(BSD) || (BSD <= 199006)
67 /*
68  * Ascii internet address interpretation routine.
69  * The value returned is in network order.
70  */
71 u_int32_t
72 inet_addr(cp)
73         register const char *cp;
74 {
75         struct in_addr val;
76
77         if (inet_aton(cp, &val))
78                 return (val.s_addr);
79         return (INADDR_NONE);
80 }
81
82 /* 
83  * Check whether "cp" is a valid ascii representation
84  * of an Internet address and convert to a binary address.
85  * Returns 1 if the address is valid, 0 if not.
86  * This replaces inet_addr, the return value from which
87  * cannot distinguish between failure and a local broadcast address.
88  */
89 int
90 inet_aton(cp, addr)
91         register const char *cp;
92         struct in_addr *addr;
93 {
94         register u_int32_t val;
95         register int base, n;
96         register char c;
97         u_int parts[4];
98         register u_int *pp = parts;
99
100         for (;;) {
101                 /*
102                  * Collect number up to ``.''.
103                  * Values are specified as for C:
104                  * 0x=hex, 0=octal, other=decimal.
105                  */
106                 val = 0; base = 10;
107                 if (*cp == '0') {
108                         if (*++cp == 'x' || *cp == 'X')
109                                 base = 16, cp++;
110                         else
111                                 base = 8;
112                 }
113                 while ((c = *cp) != '\0') {
114                         if (isascii(c) && isdigit(c)) {
115                                 val = (val * base) + (c - '0');
116                                 cp++;
117                                 continue;
118                         }
119                         if (base == 16 && isascii(c) && isxdigit(c)) {
120                                 val = (val << 4) + 
121                                         (c + 10 - (islower(c) ? 'a' : 'A'));
122                                 cp++;
123                                 continue;
124                         }
125                         break;
126                 }
127                 if (*cp == '.') {
128                         /*
129                          * Internet format:
130                          *      a.b.c.d
131                          *      a.b.c   (with c treated as 16-bits)
132                          *      a.b     (with b treated as 24 bits)
133                          */
134                         if (pp >= parts + 3 || val > 0xff)
135                                 return (0);
136                         *pp++ = val, cp++;
137                 } else
138                         break;
139         }
140         /*
141          * Check for trailing characters.
142          */
143         if (*cp && (!isascii(*cp) || !isspace(*cp)))
144                 return (0);
145         /*
146          * Concoct the address according to
147          * the number of parts specified.
148          */
149         n = pp - parts + 1;
150         switch (n) {
151
152         case 1:                         /* a -- 32 bits */
153                 break;
154
155         case 2:                         /* a.b -- 8.24 bits */
156                 if (val > 0xffffff)
157                         return (0);
158                 val |= parts[0] << 24;
159                 break;
160
161         case 3:                         /* a.b.c -- 8.8.16 bits */
162                 if (val > 0xffff)
163                         return (0);
164                 val |= (parts[0] << 24) | (parts[1] << 16);
165                 break;
166
167         case 4:                         /* a.b.c.d -- 8.8.8.8 bits */
168                 if (val > 0xff)
169                         return (0);
170                 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
171                 break;
172         }
173         if (addr)
174                 addr->s_addr = htonl(val);
175         return (1);
176 }
177 #endif /*BSD*/