OSDN Git Service

libc/inet: convert to foo-y kbuild style
[uclinux-h8/uClibc.git] / libc / inet / addr.c
1 /* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>
2  * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
3  *
4  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
5  */
6
7 /*
8  * Manuel Novoa III       Dec 2000
9  *
10  * Converted to use my new (un)signed long (long) to string routines, which
11  * are smaller than the previous functions and don't require static buffers.
12  * In the process, removed the reference to strcat and cut object size of
13  * inet_ntoa in half (from 190 bytes down to 94).
14  *
15  * Manuel Novoa III       Feb 2002
16  *
17  * Changed to use _int10tostr.
18  */
19
20 #define __FORCE_GLIBC
21 #include <features.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <ctype.h>
25 #include <netinet/in.h>
26 #include <arpa/inet.h>
27 #include <bits/uClibc_uintmaxtostr.h>
28
29 #ifdef L_inet_aton
30 /*
31  * More undocumented inet_aton features.
32  * (read: uclibc doesnt support but glibc does)
33  * http://www.mkssoftware.com/docs/man3/inet_aton.3.asp
34  *
35  * *cp can take the form of:
36  * a.b.c.d    - {a,b,c,d} -> 1 byte
37  * a.b.c      - {a,b}     -> 1 byte    {c} -> 2 bytes
38  * a.b        - {a}       -> 1 byte    {b} -> 3 bytes
39  * a          -                        {a} -> 4 bytes
40  *
41  * Each part may be decimal, octal, or hexadecimal as in ISO C.
42  * 0x or 0X    -> hexadecimal
43  * leading 0   -> octal
44  * all else    -> decimal
45  */
46 int inet_aton(const char *cp, struct in_addr *addrptr)
47 {
48         in_addr_t addr;
49         int value;
50         int part;
51
52         if (cp == NULL) {
53                 return 0;
54         }
55
56         addr = 0;
57         for (part = 1; part <= 4; part++) {
58
59                 if (!isdigit(*cp))
60                         return 0;
61
62                 value = 0;
63                 while (isdigit(*cp)) {
64                         value *= 10;
65                         value += *cp++ - '0';
66                         if (value > 255)
67                                 return 0;
68                 }
69
70                 if (part < 4) {
71                         if (*cp++ != '.')
72                                 return 0;
73                 } else {
74                         char c = *cp++;
75                         if (c != '\0' && !isspace(c))
76                                 return 0;
77                 }
78
79                 addr <<= 8;
80                 addr |= value;
81         }
82
83         /*  W. Richard Stevens in his book UNIX Network Programming,
84          *  Volume 1, second edition, on page 71 says:
85          *
86          *  An undocumented feature of inet_aton is that if addrptr is
87          *  a null pointer, the function still performs it validation
88          *  of the input string, but does not store the result.
89          */
90         if (addrptr) {
91                 addrptr->s_addr = htonl(addr);
92         }
93
94         return 1;
95 }
96 libc_hidden_def(inet_aton)
97 #endif
98
99 #ifdef L_inet_addr
100
101 in_addr_t inet_addr(const char *cp)
102 {
103         struct in_addr a;
104
105         if (!inet_aton(cp, &a))
106                 return INADDR_NONE;
107         else
108                 return a.s_addr;
109 }
110 libc_hidden_def(inet_addr)
111 #endif
112
113 #ifdef L_inet_ntoa
114
115 #define INET_NTOA_MAX_LEN       16      /* max 12 digits + 3 '.'s + 1 nul */
116
117 char *inet_ntoa_r(struct in_addr in, char buf[INET_NTOA_MAX_LEN])
118 {
119         in_addr_t addr = ntohl(in.s_addr);
120         int i;
121         char *p, *q;
122
123         q = 0;
124         p = buf + INET_NTOA_MAX_LEN - 1; /* cannot use sizeof(buf) here */
125         for (i = 0; i < 4; i++ ) {
126                 p = _int10tostr(p, addr & 0xff) - 1;
127                 addr >>= 8;
128                 if (q) {
129                         *q = '.';
130                 }
131                 q = p;
132         }
133
134         return p+1;
135 }
136 libc_hidden_def(inet_ntoa_r)
137
138 char *inet_ntoa(struct in_addr in)
139 {
140         static char buf[INET_NTOA_MAX_LEN];
141         return inet_ntoa_r(in, buf);
142 }
143 libc_hidden_def(inet_ntoa)
144 #endif
145
146 #ifdef L_inet_makeaddr
147
148 /* for some reason it does not remove the jump relocation */
149
150 /*
151  * Formulate an Internet address from network + host.  Used in
152  * building addresses stored in the ifnet structure.
153  */
154 struct in_addr inet_makeaddr(in_addr_t net, in_addr_t host)
155 {
156         in_addr_t addr;
157
158         if (net < 128)
159                 addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST);
160         else if (net < 65536)
161                 addr = (net << IN_CLASSB_NSHIFT) | (host & IN_CLASSB_HOST);
162         else if (net < 16777216UL)
163                 addr = (net << IN_CLASSC_NSHIFT) | (host & IN_CLASSC_HOST);
164         else
165                 addr = net | host;
166         addr = htonl(addr);
167         return *(struct in_addr *)&addr;
168 }
169 libc_hidden_def(inet_makeaddr)
170 #endif
171
172 #ifdef L_inet_lnaof
173 /*
174  * Return the local network address portion of an
175  * internet address; handles class a/b/c network
176  * number formats.
177  */
178 in_addr_t inet_lnaof(struct in_addr in)
179 {
180         in_addr_t i = ntohl(in.s_addr);
181
182         if (IN_CLASSA(i))
183                 return (i & IN_CLASSA_HOST);
184         else if (IN_CLASSB(i))
185                 return (i & IN_CLASSB_HOST);
186         else
187                 return (i & IN_CLASSC_HOST);
188 }
189 #endif
190
191 #ifdef L_inet_netof
192
193 /*
194  * Return the network number from an internet
195  * address; handles class a/b/c network #'s.
196  */
197 in_addr_t
198 inet_netof(struct in_addr in)
199 {
200         in_addr_t i = ntohl(in.s_addr);
201
202         if (IN_CLASSA(i))
203                 return ((i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
204         else if (IN_CLASSB(i))
205                 return ((i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
206         else
207                 return ((i & IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
208 }
209 libc_hidden_def(inet_netof)
210 #endif