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 #ifdef HAVE_CONFIG_H
00042 #include "config.h"
00043 #endif
00044
00045 #include <sys/types.h>
00046
00047 #include "mstring.h"
00048 #include "debug.h"
00049 #include "plugbase.h"
00050
00051 #ifdef GIDS
00052 extern int detect_depth;
00053 #endif
00054
00055 #ifdef TEST_MSTRING
00056 #define FatalPrintError perror
00057 #else
00058 void FatalPrintError(char *);
00059 #endif
00060
00061 extern u_int8_t *doe_ptr;
00062
00063 #ifdef TEST_MSTRING
00064
00065 int main()
00066 {
00067 char test[] = "\0\0\0\0\0\0\0\0\0CKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\0\0";
00068 char find[] = "CKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\0\0";
00069
00070
00071
00072 int i;
00073 int toks;
00074 int *shift;
00075 int *skip;
00076
00077
00078
00079
00080 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,"%d\n",
00081 mSearch(test, sizeof(test) - 1, find,
00082 sizeof(find) - 1, shift, skip)););
00083
00084 return 0;
00085 }
00086
00087 #endif
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 char **mSplit(char *str, char *sep, int max_strs, int *toks, char meta)
00110 {
00111 char **retstr;
00112 char *idx;
00113 char *end;
00114 char *sep_end;
00115 char *sep_idx;
00116 int len = 0;
00117 int curr_str = 0;
00118 char last_char = (char) 0xFF;
00119
00120 if(!toks) return NULL;
00121
00122 *toks = 0;
00123
00124 if (!str) return NULL;
00125
00126 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00127 "[*] Splitting string: %s\n", str);
00128 DebugMessage(DEBUG_PATTERN_MATCH, "curr_str = %d\n", curr_str););
00129
00130
00131
00132
00133
00134 sep_end = sep + strlen(sep);
00135 end = str + strlen(str);
00136
00137
00138 while(isspace((int) *(end - 1)) && ((end - 1) >= str))
00139 *(--end) = '\0';
00140
00141
00142 sep_idx = sep;
00143 idx = str;
00144
00145
00146
00147
00148
00149 if((retstr = (char **) malloc((sizeof(char **) * max_strs))) == NULL)
00150 FatalPrintError("malloc");
00151
00152
00153 max_strs--;
00154
00155 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00156 "max_strs = %d curr_str = %d\n",
00157 max_strs, curr_str););
00158
00159
00160 while(idx < end)
00161 {
00162
00163 while(sep_idx < sep_end)
00164 {
00165
00166
00167
00168
00169 if((*idx == *sep_idx) && (last_char != meta))
00170 {
00171
00172 if(len > 0)
00173 {
00174 DEBUG_WRAP(
00175 DebugMessage(DEBUG_PATTERN_MATCH,
00176 "Allocating %d bytes for token ", len + 1););
00177 if(curr_str <= max_strs)
00178 {
00179
00180 if((retstr[curr_str] = (char *)
00181 malloc((sizeof(char) * len) + 1)) == NULL)
00182 {
00183 FatalPrintError("malloc");
00184 }
00185
00186
00187 memcpy(retstr[curr_str], (idx - len), len);
00188 retstr[curr_str][len] = 0;
00189 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00190 "tok[%d]: %s\n", curr_str,
00191 retstr[curr_str]););
00192
00193
00194 len = 0;
00195 curr_str++;
00196 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00197 "curr_str = %d\n", curr_str);
00198 DebugMessage(DEBUG_PATTERN_MATCH,
00199 "max_strs = %d curr_str = %d\n",
00200 max_strs, curr_str););
00201
00202 last_char = *idx;
00203 idx++;
00204 }
00205
00206 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00207 "Checking if curr_str (%d) >= max_strs (%d)\n",
00208 curr_str, max_strs););
00209
00210
00211
00212
00213
00214 if(curr_str >= max_strs)
00215 {
00216 while(isspace((int) *idx))
00217 idx++;
00218
00219 len = end - idx;
00220 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00221 "Finishing up...\n");
00222 DebugMessage(DEBUG_PATTERN_MATCH,
00223 "Allocating %d bytes "
00224 "for last token ", len + 1););
00225 fflush(stdout);
00226
00227 if((retstr[curr_str] = (char *)
00228 malloc((sizeof(char) * len) + 1)) == NULL)
00229 FatalPrintError("malloc");
00230
00231 memcpy(retstr[curr_str], idx, len);
00232 retstr[curr_str][len] = 0;
00233
00234 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00235 "tok[%d]: %s\n", curr_str,
00236 retstr[curr_str]););
00237
00238 *toks = curr_str + 1;
00239 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00240 "max_strs = %d curr_str = %d\n",
00241 max_strs, curr_str);
00242 DebugMessage(DEBUG_PATTERN_MATCH,
00243 "mSplit got %d tokens!\n", *toks););
00244
00245 return retstr;
00246 }
00247 }
00248 else
00249
00250
00251
00252
00253 {
00254 last_char = *idx;
00255 idx++;
00256
00257 sep_idx = sep;
00258 len = 0;
00259 }
00260 }
00261 else
00262 {
00263
00264 sep_idx++;
00265 }
00266 }
00267
00268 sep_idx = sep;
00269 len++;
00270 last_char = *idx;
00271 idx++;
00272 }
00273
00274
00275
00276 if(len > 0)
00277 {
00278 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00279 "Allocating %d bytes for last token ", len + 1););
00280
00281 if((retstr[curr_str] = (char *)
00282 malloc((sizeof(char) * len) + 1)) == NULL)
00283 FatalPrintError("malloc");
00284
00285 memcpy(retstr[curr_str], (idx - len), len);
00286 retstr[curr_str][len] = 0;
00287
00288 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,"tok[%d]: %s\n", curr_str,
00289 retstr[curr_str]););
00290 *toks = curr_str + 1;
00291 }
00292
00293 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00294 "mSplit got %d tokens!\n", *toks););
00295
00296
00297 return retstr;
00298 }
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315 void mSplitFree(char ***pbuf, int num_toks)
00316 {
00317 int i;
00318 char** buf;
00319
00320 if( pbuf==NULL || *pbuf==NULL )
00321 {
00322 return;
00323 }
00324
00325 buf = *pbuf;
00326
00327 for( i=0; i<num_toks; i++ )
00328 {
00329 if( buf[i] != NULL )
00330 {
00331 free( buf[i] );
00332 buf[i] = NULL;
00333 }
00334 }
00335
00336 free(buf);
00337 *pbuf = NULL;
00338 }
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 int mContainsSubstr(char *buf, int b_len, char *pat, int p_len)
00362 {
00363 char *b_idx;
00364 char *p_idx;
00365 char *b_end;
00366 int m_cnt = 0;
00367 #ifdef DEBUG
00368 unsigned long loopcnt = 0;
00369 #endif
00370
00371
00372 b_end = (char *) (buf + b_len);
00373
00374
00375 b_idx = buf;
00376 p_idx = pat;
00377
00378 do
00379 {
00380 #ifdef DEBUG
00381 loopcnt++;
00382 #endif
00383
00384 if(*p_idx == *b_idx)
00385 {
00386
00387 if(m_cnt == (p_len - 1))
00388 {
00389 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00390 "\n%ld compares for match\n", loopcnt););
00391 return 1;
00392 }
00393 m_cnt++;
00394 b_idx++;
00395 p_idx++;
00396 }
00397 else
00398 {
00399 if(m_cnt == 0)
00400 {
00401 b_idx++;
00402 }
00403 else
00404 {
00405 b_idx = b_idx - (m_cnt - 1);
00406 }
00407
00408 p_idx = pat;
00409
00410 m_cnt = 0;
00411 }
00412
00413 } while(b_idx < b_end);
00414
00415
00416
00417 return 0;
00418 }
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437 int *make_skip(char *ptrn, int plen)
00438 {
00439 int *skip = (int *) malloc(256 * sizeof(int));
00440 int *sptr = &skip[256];
00441
00442 if (skip == NULL)
00443 FatalPrintError("malloc");
00444
00445 while(sptr-- != skip)
00446 *sptr = plen + 1;
00447
00448 while(plen != 0)
00449 skip[(unsigned char) *ptrn++] = plen--;
00450
00451 return skip;
00452 }
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470 int *make_shift(char *ptrn, int plen)
00471 {
00472 int *shift = (int *) malloc(plen * sizeof(int));
00473 int *sptr = shift + plen - 1;
00474 char *pptr = ptrn + plen - 1;
00475 char c;
00476
00477 if (shift == NULL)
00478 FatalPrintError("malloc");
00479
00480 c = ptrn[plen - 1];
00481
00482 *sptr = 1;
00483
00484 while(sptr-- != shift)
00485 {
00486 char *p1 = ptrn + plen - 2, *p2, *p3;
00487
00488 do
00489 {
00490 while(p1 >= ptrn && *p1-- != c);
00491
00492 p2 = ptrn + plen - 2;
00493 p3 = p1;
00494
00495 while(p3 >= ptrn && *p3-- == *p2-- && p2 >= pptr);
00496 }
00497 while(p3 >= ptrn && p2 >= pptr);
00498
00499 *sptr = shift + plen - sptr + p2 - p3;
00500
00501 pptr--;
00502 }
00503
00504 return shift;
00505 }
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529 int mSearch(char *buf, int blen, char *ptrn, int plen, int *skip, int *shift)
00530 {
00531 int b_idx = plen;
00532
00533 #ifdef DEBUG
00534 char *hexbuf;
00535 int cmpcnt = 0;
00536 #endif
00537
00538 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,"buf: %p blen: %d ptrn: %p "
00539 "plen: %d\n", buf, blen, ptrn, plen););
00540
00541 #ifdef DEBUG
00542 hexbuf = fasthex(buf, blen);
00543 DebugMessage(DEBUG_PATTERN_MATCH,"buf: %s\n", hexbuf);
00544 free(hexbuf);
00545 hexbuf = fasthex(ptrn, plen);
00546 DebugMessage(DEBUG_PATTERN_MATCH,"ptrn: %s\n", hexbuf);
00547 free(hexbuf);
00548 DebugMessage(DEBUG_PATTERN_MATCH,"buf: %p blen: %d ptrn: %p "
00549 "plen: %d\n", buf, blen, ptrn, plen);
00550 #endif
00551 if(plen == 0)
00552 return 1;
00553
00554 while(b_idx <= blen)
00555 {
00556 int p_idx = plen, skip_stride, shift_stride;
00557
00558 while(buf[--b_idx] == ptrn[--p_idx])
00559 {
00560 #ifdef DEBUG
00561 cmpcnt++;
00562 #endif
00563 if(b_idx < 0)
00564 return 0;
00565
00566 if(p_idx == 0)
00567 {
00568 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00569 "match: compares = %d.\n", cmpcnt););
00570
00571 doe_ptr = &(buf[b_idx]) + plen;
00572
00573 #ifdef GIDS
00574 detect_depth = b_idx;
00575 #endif
00576
00577 return 1;
00578 }
00579 }
00580
00581 skip_stride = skip[(unsigned char) buf[b_idx]];
00582 shift_stride = shift[p_idx];
00583
00584 b_idx += (skip_stride > shift_stride) ? skip_stride : shift_stride;
00585 }
00586
00587 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00588 "no match: compares = %d.\n", cmpcnt););
00589
00590 return 0;
00591 }
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615 int mSearchCI(char *buf, int blen, char *ptrn, int plen, int *skip, int *shift)
00616 {
00617 int b_idx = plen;
00618 #ifdef DEBUG
00619 int cmpcnt = 0;
00620 #endif
00621
00622 if(plen == 0)
00623 return 1;
00624
00625 while(b_idx <= blen)
00626 {
00627 int p_idx = plen, skip_stride, shift_stride;
00628
00629 while((unsigned char) ptrn[--p_idx] ==
00630 toupper((unsigned char) buf[--b_idx]))
00631 {
00632 #ifdef DEBUG
00633 cmpcnt++;
00634 #endif
00635 if(p_idx == 0)
00636 {
00637 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00638 "match: compares = %d.\n",
00639 cmpcnt););
00640 doe_ptr = &(buf[b_idx]) + plen;
00641 #ifdef GIDS
00642 detect_depth = b_idx;
00643 #endif
00644 return 1;
00645 }
00646 }
00647
00648 skip_stride = skip[toupper((unsigned char) buf[b_idx])];
00649 shift_stride = shift[p_idx];
00650
00651 b_idx += (skip_stride > shift_stride) ? skip_stride : shift_stride;
00652 }
00653
00654 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "no match: compares = %d.\n", cmpcnt););
00655
00656 return 0;
00657 }
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680 int mSearchREG(char *buf, int blen, char *ptrn, int plen, int *skip, int *shift)
00681 {
00682 int b_idx = plen;
00683 int literal = 0;
00684 int regexcomp = 0;
00685 #ifdef DEBUG
00686 int cmpcnt = 0;
00687 #endif
00688
00689 DEBUG_WRAP(
00690 DebugMessage(DEBUG_PATTERN_MATCH, "buf: %p blen: %d ptrn: %p "
00691 " plen: %d b_idx: %d\n", buf, blen, ptrn, plen, b_idx);
00692 DebugMessage(DEBUG_PATTERN_MATCH, "packet data: \"%s\"\n", buf);
00693 DebugMessage(DEBUG_PATTERN_MATCH, "matching for \"%s\"\n", ptrn);
00694 );
00695
00696 if(plen == 0)
00697 return 1;
00698
00699 while(b_idx <= blen)
00700 {
00701 int p_idx = plen, skip_stride, shift_stride;
00702
00703 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Looping... "
00704 "([%d]0x%X (%c) -> [%d]0x%X(%c))\n",
00705 b_idx, buf[b_idx-1],
00706 buf[b_idx-1],
00707 p_idx, ptrn[p_idx-1], ptrn[p_idx-1]););
00708
00709 while(buf[--b_idx] == ptrn[--p_idx]
00710 || (ptrn[p_idx] == '?' && !literal)
00711 || (ptrn[p_idx] == '*' && !literal)
00712 || (ptrn[p_idx] == '\\' && !literal))
00713 {
00714 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "comparing: b:%c -> p:%c\n",
00715 buf[b_idx], ptrn[p_idx]););
00716 #ifdef DEBUG
00717 cmpcnt++;
00718 #endif
00719
00720 if(literal)
00721 literal = 0;
00722 if(!literal && ptrn[p_idx] == '\\')
00723 literal = 1;
00724 if(ptrn[p_idx] == '*')
00725 {
00726 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,"Checking wildcard matching...\n"););
00727 while(p_idx != 0 && ptrn[--p_idx] == '*');
00728
00729 while(buf[--b_idx] != ptrn[p_idx])
00730 {
00731 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "comparing: b[%d]:%c -> p[%d]:%c\n",
00732 b_idx, buf[b_idx], p_idx, ptrn[p_idx]););
00733
00734 regexcomp++;
00735 if(b_idx == 0)
00736 {
00737 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00738 "b_idx went to 0, returning 0\n");)
00739 return 0;
00740 }
00741 }
00742
00743 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "got wildcard final char match! (b[%d]: %c -> p[%d]: %c\n", b_idx, buf[b_idx], p_idx, ptrn[p_idx]););
00744 }
00745
00746 if(p_idx == 0)
00747 {
00748 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "match: compares = %d.\n",
00749 cmpcnt););
00750 return 1;
00751 }
00752
00753 if(b_idx == 0)
00754 break;
00755 }
00756
00757 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "skip-shifting...\n"););
00758 skip_stride = skip[(unsigned char) buf[b_idx]];
00759 shift_stride = shift[p_idx];
00760
00761 b_idx += (skip_stride > shift_stride) ? skip_stride : shift_stride;
00762 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "b_idx skip-shifted to %d\n", b_idx););
00763 b_idx += regexcomp;
00764 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00765 "b_idx regex compensated %d steps, to %d\n", regexcomp, b_idx););
00766 regexcomp = 0;
00767 }
00768
00769 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "no match: compares = %d, b_idx = %d, "
00770 "blen = %d\n", cmpcnt, b_idx, blen););
00771
00772 return 0;
00773 }