00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #include "lwip/opt.h"
00049 #include "lwip/arch.h"
00050 #include "lwip/def.h"
00051 #include "lwip/inet.h"
00052 #include <ctype.h>
00053
00054 #define htons HTONS
00055 #define htonl HTONL
00056
00057
00058 static u16_t
00059 lwip_chksum(void *dataptr, int len)
00060 {
00061 u32_t acc;
00062
00063 DEBUGF(INET_DEBUG, ("lwip_chksum(%p, %d)\n", dataptr, len));
00064 for(acc = 0; len > 1; len -= 2) {
00065
00066 acc += *(u16_t *)dataptr;
00067 dataptr = (void *)((u16_t *)dataptr + 1);
00068 }
00069
00070
00071 if(len == 1) {
00072 acc += htons((u16_t)((*(u8_t *)dataptr) & 0xff) << 8);
00073 DEBUGF(INET_DEBUG, ("inet: chksum: odd byte %d\n", *(u8_t *)dataptr));
00074 } else {
00075 DEBUGF(INET_DEBUG, ("inet: chksum: no odd byte\n"));
00076 }
00077 acc = (acc >> 16) + (acc & 0xffffUL);
00078
00079 if((acc & 0xffff0000) != 0) {
00080 acc = (acc >> 16) + (acc & 0xffffUL);
00081 }
00082
00083 return (u16_t)acc;
00084 }
00085
00086
00087
00088
00089
00090
00091 u16_t
00092 inet_chksum_pseudo(struct pbuf *p,
00093 struct ip_addr *src, struct ip_addr *dest,
00094 u8_t proto, u16_t proto_len)
00095 {
00096 u32_t acc;
00097 struct pbuf *q;
00098 u8_t swapped;
00099
00100 acc = 0;
00101 swapped = 0;
00102
00103 for(q = p; q != NULL; q = q->next) {
00104 DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n", (void *) q, (void *)q->next));
00105 acc += lwip_chksum(q->payload, q->len);
00106
00107 while(acc >> 16) {
00108 acc = (acc & 0xffffUL) + (acc >> 16);
00109 }
00110 if(q->len % 2 != 0) {
00111 swapped = 1 - swapped;
00112 acc = ((acc & 0xff) << 8) | ((acc & 0xff00UL) >> 8);
00113 }
00114
00115 }
00116
00117 if(swapped) {
00118 acc = ((acc & 0xff) << 8) | ((acc & 0xff00UL) >> 8);
00119 }
00120 acc += (src->addr & 0xffffUL);
00121 acc += ((src->addr >> 16) & 0xffffUL);
00122 acc += (dest->addr & 0xffffUL);
00123 acc += ((dest->addr >> 16) & 0xffffUL);
00124 acc += (u32_t)htons((u16_t)proto);
00125 acc += (u32_t)htons(proto_len);
00126
00127 while(acc >> 16) {
00128 acc = (acc & 0xffffUL) + (acc >> 16);
00129 }
00130 DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%lx\n", acc));
00131 return ~(acc & 0xffffUL);
00132 }
00133
00134
00135
00136
00137
00138
00139
00140 u16_t
00141 inet_chksum(void *dataptr, u16_t len)
00142 {
00143 u32_t acc;
00144
00145 acc = lwip_chksum(dataptr, len);
00146 while(acc >> 16) {
00147 acc = (acc & 0xffff) + (acc >> 16);
00148 }
00149 return ~(acc & 0xffff);
00150 }
00151
00152 u16_t
00153 inet_chksum_pbuf(struct pbuf *p)
00154 {
00155 u32_t acc;
00156 struct pbuf *q;
00157 u8_t swapped;
00158
00159 acc = 0;
00160 swapped = 0;
00161 for(q = p; q != NULL; q = q->next) {
00162 acc += lwip_chksum(q->payload, q->len);
00163 while(acc >> 16) {
00164 acc = (acc & 0xffffUL) + (acc >> 16);
00165 }
00166 if(q->len % 2 != 0) {
00167 swapped = 1 - swapped;
00168 acc = (acc & 0x00ffUL << 8) | (acc & 0xff00UL >> 8);
00169 }
00170 }
00171
00172 if(swapped) {
00173 acc = ((acc & 0x00ffUL) << 8) | ((acc & 0xff00UL) >> 8);
00174 }
00175 return ~(acc & 0xffffUL);
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 u32_t inet_addr(const char *cp)
00222 {
00223 struct in_addr val;
00224
00225 if (inet_aton(cp, &val)) {
00226 return (val.s_addr);
00227 }
00228 return (INADDR_NONE);
00229 }
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 int inet_aton(const char *cp, struct in_addr *addr)
00241 {
00242 u32_t val;
00243 int base, n;
00244 char c;
00245
00246
00247 u32_t parts[4];
00248 u32_t* pp = parts;
00249
00250 c = *cp;
00251 for (;;) {
00252
00253
00254
00255
00256
00257 if (!isdigit(c))
00258 return (0);
00259 val = 0; base = 10;
00260 if (c == '0') {
00261 c = *++cp;
00262 if (c == 'x' || c == 'X')
00263 base = 16, c = *++cp;
00264 else
00265 base = 8;
00266 }
00267 for (;;) {
00268 if (isascii(c) && isdigit(c)) {
00269 val = (val * base) + (c - '0');
00270 c = *++cp;
00271 } else if (base == 16 && isascii(c) && isxdigit(c)) {
00272 val = (val << 4) |
00273 (c + 10 - (islower(c) ? 'a' : 'A'));
00274 c = *++cp;
00275 } else
00276 break;
00277 }
00278 if (c == '.') {
00279
00280
00281
00282
00283
00284
00285 if (pp >= parts + 3)
00286 return (0);
00287 *pp++ = val;
00288 c = *++cp;
00289 } else
00290 break;
00291 }
00292
00293
00294
00295 if (c != '\0' && (!isascii(c) || !isspace(c)))
00296 return (0);
00297
00298
00299
00300
00301 n = pp - parts + 1;
00302 switch (n) {
00303
00304 case 0:
00305 return (0);
00306
00307 case 1:
00308 break;
00309
00310 case 2:
00311 if (val > 0xffffff)
00312 return (0);
00313 val |= parts[0] << 24;
00314 break;
00315
00316 case 3:
00317 if (val > 0xffff)
00318 return (0);
00319 val |= (parts[0] << 24) | (parts[1] << 16);
00320 break;
00321
00322 case 4:
00323 if (val > 0xff)
00324 return (0);
00325 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
00326 break;
00327 }
00328 if (addr)
00329 addr->s_addr = htonl(val);
00330 return (1);
00331 }
00332
00333 static unsigned int i2a(char* dest,unsigned int x) {
00334 register unsigned int tmp=x;
00335 register unsigned int len=0;
00336 if (x>=100) { *dest++=tmp/100+'0'; tmp=tmp%100; ++len; }
00337 if (x>=10) { *dest++=tmp/10+'0'; tmp=tmp%10; ++len; }
00338 *dest++=tmp+'0';
00339 return len+1;
00340 }
00341
00342 char *inet_ntoa(struct in_addr in) {
00343 static char buf[20];
00344 unsigned int len;
00345 unsigned char *ip=(unsigned char*)∈
00346 len=i2a(buf,ip[0]); buf[len]='.'; ++len;
00347 len+=i2a(buf+ len,ip[1]); buf[len]='.'; ++len;
00348 len+=i2a(buf+ len,ip[2]); buf[len]='.'; ++len;
00349 len+=i2a(buf+ len,ip[3]); buf[len]=0;
00350 return buf;
00351 }