]>
Commit | Line | Data |
---|---|---|
6e6d4a8b JP |
1 | /** |
2 | * @file | |
3 | * Functions common to all TCP/IPv4 modules, such as the byte order functions. | |
4 | * | |
5 | */ | |
6 | ||
7 | /* | |
8 | * Copyright (c) 2001-2004 Swedish Institute of Computer Science. | |
9 | * All rights reserved. | |
10 | * | |
11 | * Redistribution and use in source and binary forms, with or without modification, | |
12 | * are permitted provided that the following conditions are met: | |
13 | * | |
14 | * 1. Redistributions of source code must retain the above copyright notice, | |
15 | * this list of conditions and the following disclaimer. | |
16 | * 2. Redistributions in binary form must reproduce the above copyright notice, | |
17 | * this list of conditions and the following disclaimer in the documentation | |
18 | * and/or other materials provided with the distribution. | |
19 | * 3. The name of the author may not be used to endorse or promote products | |
20 | * derived from this software without specific prior written permission. | |
21 | * | |
22 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
23 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
24 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT | |
25 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
26 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT | |
27 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
30 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY | |
31 | * OF SUCH DAMAGE. | |
32 | * | |
33 | * This file is part of the lwIP TCP/IP stack. | |
34 | * | |
35 | * Author: Adam Dunkels <adam@sics.se> | |
36 | * | |
37 | */ | |
38 | ||
39 | #include "lwip/opt.h" | |
40 | ||
41 | #include "lwip/inet.h" | |
42 | ||
43 | /* Here for now until needed in other places in lwIP */ | |
44 | #ifndef isprint | |
45 | #define in_range(c, lo, up) ((u8_t)c >= lo && (u8_t)c <= up) | |
46 | #define isprint(c) in_range(c, 0x20, 0x7f) | |
47 | #define isdigit(c) in_range(c, '0', '9') | |
48 | #define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F')) | |
49 | #define islower(c) in_range(c, 'a', 'z') | |
50 | #define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v') | |
51 | #endif | |
52 | ||
53 | /** | |
54 | * Ascii internet address interpretation routine. | |
55 | * The value returned is in network order. | |
56 | * | |
57 | * @param cp IP address in ascii represenation (e.g. "127.0.0.1") | |
58 | * @return ip address in network order | |
59 | */ | |
60 | u32_t | |
61 | inet_addr(const char *cp) | |
62 | { | |
63 | struct in_addr val; | |
64 | ||
65 | if (inet_aton(cp, &val)) { | |
66 | return (val.s_addr); | |
67 | } | |
68 | return (INADDR_NONE); | |
69 | } | |
70 | ||
71 | /** | |
72 | * Check whether "cp" is a valid ascii representation | |
73 | * of an Internet address and convert to a binary address. | |
74 | * Returns 1 if the address is valid, 0 if not. | |
75 | * This replaces inet_addr, the return value from which | |
76 | * cannot distinguish between failure and a local broadcast address. | |
77 | * | |
78 | * @param cp IP address in ascii represenation (e.g. "127.0.0.1") | |
79 | * @param addr pointer to which to save the ip address in network order | |
80 | * @return 1 if cp could be converted to addr, 0 on failure | |
81 | */ | |
82 | int | |
83 | inet_aton(const char *cp, struct in_addr *addr) | |
84 | { | |
85 | u32_t val; | |
86 | int base, n, c; | |
87 | u32_t parts[4]; | |
88 | u32_t *pp = parts; | |
89 | ||
90 | c = *cp; | |
91 | for (;;) { | |
92 | /* | |
93 | * Collect number up to ``.''. | |
94 | * Values are specified as for C: | |
95 | * 0x=hex, 0=octal, 1-9=decimal. | |
96 | */ | |
97 | if (!isdigit(c)) | |
98 | return (0); | |
99 | val = 0; | |
100 | base = 10; | |
101 | if (c == '0') { | |
102 | c = *++cp; | |
103 | if (c == 'x' || c == 'X') { | |
104 | base = 16; | |
105 | c = *++cp; | |
106 | } else | |
107 | base = 8; | |
108 | } | |
109 | for (;;) { | |
110 | if (isdigit(c)) { | |
111 | val = (val * base) + (int)(c - '0'); | |
112 | c = *++cp; | |
113 | } else if (base == 16 && isxdigit(c)) { | |
114 | val = (val << 4) | (int)(c + 10 - (islower(c) ? 'a' : 'A')); | |
115 | c = *++cp; | |
116 | } else | |
117 | break; | |
118 | } | |
119 | if (c == '.') { | |
120 | /* | |
121 | * Internet format: | |
122 | * a.b.c.d | |
123 | * a.b.c (with c treated as 16 bits) | |
124 | * a.b (with b treated as 24 bits) | |
125 | */ | |
126 | if (pp >= parts + 3) | |
127 | return (0); | |
128 | *pp++ = val; | |
129 | c = *++cp; | |
130 | } else | |
131 | break; | |
132 | } | |
133 | /* | |
134 | * Check for trailing characters. | |
135 | */ | |
136 | if (c != '\0' && (!isprint(c) || !isspace(c))) | |
137 | return (0); | |
138 | /* | |
139 | * Concoct the address according to | |
140 | * the number of parts specified. | |
141 | */ | |
142 | n = pp - parts + 1; | |
143 | switch (n) { | |
144 | ||
145 | case 0: | |
146 | return (0); /* initial nondigit */ | |
147 | ||
148 | case 1: /* a -- 32 bits */ | |
149 | break; | |
150 | ||
151 | case 2: /* a.b -- 8.24 bits */ | |
152 | if (val > 0xffffffUL) | |
153 | return (0); | |
154 | val |= parts[0] << 24; | |
155 | break; | |
156 | ||
157 | case 3: /* a.b.c -- 8.8.16 bits */ | |
158 | if (val > 0xffff) | |
159 | return (0); | |
160 | val |= (parts[0] << 24) | (parts[1] << 16); | |
161 | break; | |
162 | ||
163 | case 4: /* a.b.c.d -- 8.8.8.8 bits */ | |
164 | if (val > 0xff) | |
165 | return (0); | |
166 | val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); | |
167 | break; | |
168 | } | |
169 | if (addr) | |
170 | addr->s_addr = htonl(val); | |
171 | return (1); | |
172 | } | |
173 | ||
174 | /** | |
175 | * Convert numeric IP address into decimal dotted ASCII representation. | |
176 | * returns ptr to static buffer; not reentrant! | |
177 | * | |
178 | * @param addr ip address in network order to convert | |
179 | * @return pointer to a global static (!) buffer that holds the ASCII | |
180 | * represenation of addr | |
181 | */ | |
182 | char * | |
183 | inet_ntoa(struct in_addr addr) | |
184 | { | |
185 | static char str[16]; | |
186 | u32_t s_addr = addr.s_addr; | |
187 | char inv[3]; | |
188 | char *rp; | |
189 | u8_t *ap; | |
190 | u8_t rem; | |
191 | u8_t n; | |
192 | u8_t i; | |
193 | ||
194 | rp = str; | |
195 | ap = (u8_t *)&s_addr; | |
196 | for(n = 0; n < 4; n++) { | |
197 | i = 0; | |
198 | do { | |
199 | rem = *ap % (u8_t)10; | |
200 | *ap /= (u8_t)10; | |
201 | inv[i++] = '0' + rem; | |
202 | } while(*ap); | |
203 | while(i--) | |
204 | *rp++ = inv[i]; | |
205 | *rp++ = '.'; | |
206 | ap++; | |
207 | } | |
208 | *--rp = 0; | |
209 | return str; | |
210 | } | |
211 | ||
212 | /** | |
213 | * These are reference implementations of the byte swapping functions. | |
214 | * Again with the aim of being simple, correct and fully portable. | |
215 | * Byte swapping is the second thing you would want to optimize. You will | |
216 | * need to port it to your architecture and in your cc.h: | |
217 | * | |
218 | * #define LWIP_PLATFORM_BYTESWAP 1 | |
219 | * #define LWIP_PLATFORM_HTONS(x) <your_htons> | |
220 | * #define LWIP_PLATFORM_HTONL(x) <your_htonl> | |
221 | * | |
222 | * Note ntohs() and ntohl() are merely references to the htonx counterparts. | |
223 | */ | |
224 | ||
225 | #if (LWIP_PLATFORM_BYTESWAP == 0) && (BYTE_ORDER == LITTLE_ENDIAN) | |
226 | ||
227 | /** | |
228 | * Convert an u16_t from host- to network byte order. | |
229 | * | |
230 | * @param n u16_t in host byte order | |
231 | * @return n in network byte order | |
232 | */ | |
233 | u16_t | |
234 | htons(u16_t n) | |
235 | { | |
236 | return ((n & 0xff) << 8) | ((n & 0xff00) >> 8); | |
237 | } | |
238 | ||
239 | /** | |
240 | * Convert an u16_t from network- to host byte order. | |
241 | * | |
242 | * @param n u16_t in network byte order | |
243 | * @return n in host byte order | |
244 | */ | |
245 | u16_t | |
246 | ntohs(u16_t n) | |
247 | { | |
248 | return htons(n); | |
249 | } | |
250 | ||
251 | /** | |
252 | * Convert an u32_t from host- to network byte order. | |
253 | * | |
254 | * @param n u32_t in host byte order | |
255 | * @return n in network byte order | |
256 | */ | |
257 | u32_t | |
258 | htonl(u32_t n) | |
259 | { | |
260 | return ((n & 0xff) << 24) | | |
261 | ((n & 0xff00) << 8) | | |
262 | ((n & 0xff0000UL) >> 8) | | |
263 | ((n & 0xff000000UL) >> 24); | |
264 | } | |
265 | ||
266 | /** | |
267 | * Convert an u32_t from network- to host byte order. | |
268 | * | |
269 | * @param n u32_t in network byte order | |
270 | * @return n in host byte order | |
271 | */ | |
272 | u32_t | |
273 | ntohl(u32_t n) | |
274 | { | |
275 | return htonl(n); | |
276 | } | |
277 | ||
278 | #endif /* (LWIP_PLATFORM_BYTESWAP == 0) && (BYTE_ORDER == LITTLE_ENDIAN) */ |