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
00056 #include <string.h>
00057 #include <ctype.h>
00058
00059 #include "ipsec/ipsec.h"
00060 #include "ipsec/util.h"
00061 #include "ipsec/debug.h"
00062
00069 void ipsec_print_ip(ipsec_ip_header *header)
00070 {
00071 char log_message[IPSEC_LOG_MESSAGE_SIZE+1] ;
00072 char port[4+1] ;
00073 char src[15+1] ;
00074 char dest[15+1] ;
00075 __u16 len ;
00076
00077 strcpy(src, ipsec_inet_ntoa(header->src)) ;
00078 strcpy(dest, ipsec_inet_ntoa(header->dest)) ;
00079
00080 len = ipsec_ntohs(header->len) ;
00081
00082 switch(header->protocol)
00083 {
00084 case IPSEC_PROTO_TCP:
00085 strcpy(port, " TCP") ;
00086 break ;
00087 case IPSEC_PROTO_UDP:
00088 strcpy(port, " UDP") ;
00089 break ;
00090 case IPSEC_PROTO_AH:
00091 strcpy(port, " AH") ;
00092 break ;
00093 case IPSEC_PROTO_ESP:
00094 strcpy(port, " ESP") ;
00095 break ;
00096 case IPSEC_PROTO_ICMP:
00097 strcpy(port, "ICMP") ;
00098 break ;
00099 default:
00100 strcpy(port, "????") ;
00101 }
00102
00103 sprintf(log_message, "src: %15s dest: %15s protocol: %3s size: %d", src, dest, port, len) ;
00104 printf(" %s\n", log_message) ;
00105
00106 return ;
00107 }
00108
00109
00117 __u32 ipsec_inet_addr(const char *cp)
00118 {
00119 struct ipsec_in_addr val;
00120
00121 if (ipsec_inet_aton(cp, &val)) {
00122 return (val.s_addr);
00123 }
00124 return (IPSEC_IP_ADDR_NONE);
00125 }
00126
00136 int ipsec_inet_aton(const char *cp, struct ipsec_in_addr *addr)
00137 {
00138 __u32 val;
00139 int base, n;
00140 char c;
00141 static __u32 huge parts[4];
00142 static __u32 huge *pp ;
00143
00144 pp = parts;
00145
00146 c = *cp;
00147
00148 for (;;) {
00149
00150
00151
00152
00153
00154 if (!isdigit(c))
00155 return (0);
00156 val = 0; base = 10;
00157 if (c == '0') {
00158 c = *++cp;
00159 if (c == 'x' || c == 'X')
00160 base = 16, c = *++cp;
00161 else
00162 base = 8;
00163 }
00164 for (;;) {
00165
00166 if (isdigit(c)) {
00167 val = (val * base) + (c - '0');
00168 c = *++cp;
00169
00170 } else if (base == 16 && isxdigit(c)) {
00171 val = (val << 4) |
00172 (c + 10 - (islower(c) ? 'a' : 'A'));
00173 c = *++cp;
00174 } else
00175 break;
00176 }
00177 if (c == '.') {
00178
00179
00180
00181
00182
00183
00184
00185 if (pp >= parts + 3)
00186 return (0);
00187 *pp++ = val;
00188 c = *++cp;
00189 } else
00190 break;
00191 }
00192
00193
00194
00195 if (c != '\0' && (!isalpha(c) || !isspace(c)))
00196 return (0);
00197
00198
00199
00200
00201 n = (int) (pp - parts + 1);
00202 switch (n) {
00203
00204 case 0:
00205 return (0);
00206
00207 case 1:
00208 break;
00209
00210 case 2:
00211 if (val > 0xffffff)
00212 return (0);
00213 val |= parts[0] << 24;
00214 break;
00215
00216 case 3:
00217 if (val > 0xffff)
00218 return (0);
00219 val |= (parts[0] << 24) | (parts[1] << 16);
00220 break;
00221
00222 case 4:
00223 if (val > 0xff)
00224 return (0);
00225 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
00226 break;
00227 }
00228 if (addr)
00229 addr->s_addr = ipsec_htonl(val);
00230 return (1);
00231 }
00232
00240 __u8 *ipsec_inet_ntoa(__u32 addr)
00241 {
00242 static __u8 str[16];
00243 __u8 inv[3];
00244 __u8 *rp;
00245 __u8 *ap;
00246 __u8 rem;
00247 __u8 n;
00248 __u8 i;
00249
00250 rp = str;
00251 ap = (__u8 *)&addr;
00252 for(n = 0; n < 4; n++) {
00253 i = 0;
00254 do {
00255 rem = (__u8)(*ap % (__u8)10);
00256 *ap /= (__u8)10;
00257 inv[i++] = '0' + rem;
00258 } while(*ap);
00259 while(i--)
00260 *rp++ = inv[i];
00261 *rp++ = '.';
00262 ap++;
00263 }
00264 *--rp = 0;
00265 return str;
00266 }
00267
00274 __u16 ipsec_htons(__u16 n)
00275 {
00276 return ((n & 0xff) << 8) | ((n & 0xff00) >> 8);
00277 }
00278
00285 __u16 ipsec_ntohs(__u16 n)
00286 {
00287 return ipsec_htons(n);
00288 }
00289
00296 __u32 ipsec_htonl(__u32 n)
00297 {
00298 return ((n & 0xff) << 24) |
00299 ((n & 0xff00) << 8) |
00300 ((n & 0xff0000) >> 8) |
00301 ((n & 0xff000000) >> 24);
00302 }
00303
00310 __u32 ipsec_ntohl(__u32 n)
00311 {
00312 return ipsec_htonl(n);
00313 }
00314
00322 static __u16 chksum(void *dataptr, int len)
00323 {
00324 __u32 acc;
00325
00326 for(acc = 0; len > 1; len -= 2) {
00327
00328 acc += *(__u16 *)dataptr;
00329 dataptr = (void *)((__u16 *)dataptr + 1);
00330 }
00331
00332
00333 if (len == 1) {
00334 acc += ipsec_htons((__u16)((*(__u8 *)dataptr) & 0xff) << 8);
00335 } else {
00336
00337 }
00338 acc = (acc >> 16) + (acc & 0xffffUL);
00339
00340 if ((acc & 0xffff0000) != 0) {
00341 acc = (acc >> 16) + (acc & 0xffffUL);
00342 }
00343
00344 return (__u16)acc;
00345 }
00346
00354 __u16 ipsec_ip_chksum(void *dataptr, __u16 len)
00355 {
00356 __u32 acc;
00357
00358 acc = chksum(dataptr, len);
00359 while (acc >> 16) {
00360 acc = (acc & 0xffff) + (acc >> 16);
00361 }
00362 return ~(acc & 0xffff);
00363 }
00364
00365
00366 #ifdef IPSEC_TRACE
00367 int __ipsec_trace_indication = 0;
00368 int __ipsec_trace_indication__pos = 0;
00369 #endif
00370
00381 void ipsec_dump_buffer(char *prefix, unsigned char *data, int offs, int length)
00382 {
00383 unsigned char *ptr;
00384 unsigned char *tmp_ptr;
00385 int i;
00386
00387 printf("%sDumping %d bytes from address 0x%08Lx using an offset of %d bytes\n", prefix, length, data, offs);
00388 if(length == 0) {
00389 printf("%s => nothing to dump\n", prefix);
00390 return;
00391 }
00392
00393 for(ptr = (data + offs); ptr < (data + offs + length); ptr++) {
00394 if(((ptr - (data + offs)) % 16) == 0) printf("%s%08Lx:", prefix, ptr);
00395 printf(" %02X", *ptr);
00396 if(((ptr - (data + offs)) % 16) == 15) {
00397 printf(" :");
00398 for(tmp_ptr = (ptr - 15); tmp_ptr < ptr; tmp_ptr++) {
00399 if(*tmp_ptr < 32) printf("."); else printf("%c", *tmp_ptr);
00400 }
00401 printf("\n");
00402 }
00403 }
00404
00405 if((length % 16) > 0) {
00406 for(i = 0; i < (16 - (length % 16)); i++) {
00407 printf(" ");
00408 }
00409
00410 printf(" :");
00411 for(tmp_ptr = ((data + offs + length) - (length % 16)); tmp_ptr < (data + offs + length); tmp_ptr++) {
00412 if(*tmp_ptr < 32) printf("."); else printf("%c", *tmp_ptr);
00413 }
00414 }
00415
00416 printf("\n");
00417 }
00418
00419
00431 ipsec_audit ipsec_check_replay_window(__u32 seq, __u32 lastSeq, __u32 bitField)
00432 {
00433 __u32 diff;
00434
00435 if(seq == 0) return IPSEC_AUDIT_SEQ_MISMATCH;
00436
00437 if(seq > lastSeq)
00438 {
00439 diff = seq - lastSeq;
00440 }
00441 else {
00442 diff = lastSeq - seq;
00443 }
00444
00445
00446 if(diff >= IPSEC_SEQ_MAX_WINDOW) return IPSEC_AUDIT_SEQ_MISMATCH;
00447
00448
00449 if(bitField & ((__u32)1 << diff)) return IPSEC_AUDIT_SEQ_MISMATCH;
00450
00451 return IPSEC_AUDIT_SUCCESS;
00452 }
00453
00454
00468 ipsec_audit ipsec_update_replay_window(__u32 seq, __u32 *lastSeq, __u32 *bitField)
00469 {
00470 __u32 diff;
00471
00472 if (seq == 0) return IPSEC_AUDIT_SEQ_MISMATCH;
00473 if (seq > *lastSeq) {
00474 diff = seq - *lastSeq;
00475 if (diff < IPSEC_SEQ_MAX_WINDOW) {
00476 *bitField <<= diff;
00477 *bitField |= IPSEC_AUDIT_SUCCESS;
00478 } else *bitField = IPSEC_AUDIT_SUCCESS;
00479 *lastSeq = seq;
00480 return IPSEC_AUDIT_SUCCESS;
00481 }
00482 diff = *lastSeq - seq;
00483 if (diff >= IPSEC_SEQ_MAX_WINDOW) return IPSEC_AUDIT_SEQ_MISMATCH;
00484 if (*bitField & ((__u32)1 << diff)) return IPSEC_AUDIT_SEQ_MISMATCH;
00485 *bitField |= ((__u32)1 << diff);
00486 return IPSEC_AUDIT_SUCCESS;
00487 }
00488
00489