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
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 #include <stdlib.h>
00069 #include <stdio.h>
00070 #include <math.h>
00071 #include <sys/time.h>
00072
00073 #define min(a,b) ((a) <= (b) ? (a) : (b))
00074 #define max(a,b) ((a) >= (b) ? (a) : (b))
00075
00076 int report_ACK_err = 1;
00077
00078 void Usage(char *s)
00079 {
00080 fprintf (stderr,"\nUsage: %s\n", s);
00081 fprintf (stderr," [-w file_name] (name for output file)\n");
00082 fprintf (stderr," [-r file_name] (name for input file)\n");
00083 fprintf (stderr,"If either -w or -r is omitted, stdout(stdin) is used\n");
00084 fprintf (stderr,"\n");
00085 exit(-1);
00086 }
00087
00088 FILE *dumpFP, *outFP;
00089 FILE *logFP;
00090
00091 struct timeval recvTime;
00092 struct timeval lastTime = {0,0};
00093
00094 char ts[20];
00095
00096 char sh[25];
00097
00098 char gt[3];
00099 char lt[3];
00100 char dh[25];
00101
00102 char fl[5];
00103 char p1[50];
00104 char p2[50];
00105 char p3[50];
00106
00107
00108 unsigned long begin_seq, end_seq, seq_bytes, new_ack;
00109 unsigned long current_synseq;
00110
00111 int has_seq, has_ack;
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 unsigned long current_request_end, last_request_end;
00128
00129
00130
00131
00132
00133
00134
00135
00136 unsigned long current_response_end, last_response_end;
00137
00138
00139
00140 int syn_count = 0;
00141 int req_count = 0;
00142 int rsp_count = 0;
00143 int fin_count = 0;
00144 int rst_count = 0;
00145 int trm_count = 0;
00146 int err_count = 0;
00147 int act_req_count = 0;
00148 int act_rsp_count = 0;
00149 int pending_fin_count = 0;
00150 int pending_rst_count = 0;
00151 int pending_ack_count = 0;
00152 int pending_oth_count = 0;
00153 int pending_cmb_count = 0;
00154
00155
00156
00157
00158 int have_pending_acks = 0;
00159 int have_pending_fins = 0;
00160 int have_pending_rsts = 0;
00161 int have_pending_othr = 0;
00162
00163 int have_ACK_error = 0;
00164 int have_value_error = 0;
00165 int have_FINdata_error = 0;
00166
00167 enum states {PENDING, SYN_SENT, FIN_SENT, RESET, IN_REQUEST, IN_RESPONSE};
00168
00169 enum states connection_state = PENDING;
00170 enum states last_state = PENDING;
00171
00172 enum inputs {SYN, FIN, RST, ACK_ONLY, DATA_ACK};
00173 enum inputs input_type;
00174
00175 char current_src[25] = "";
00176 char src_host[25];
00177 char src_port[10];
00178
00179 char current_dst[25] = "";
00180 char dst_host[25];
00181 char dst_port[10];
00182
00183
00184
00185
00186
00187
00188 char start_request_time[20];
00189
00190
00191
00192
00193
00194 char start_response_time[20];
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 char response_end_time[20];
00208 char request_end_time[20];
00209
00210 char FIN_sent_time[20];
00211 char RST_sent_time[20];
00212 char last_connection_time[20];
00213
00214 char input_name[256] = "";
00215 char output_name[256] = "";
00216 char log_name[256] = "";
00217
00218 char new_line[500];
00219
00220 long elapsed;
00221
00222 int new_address = 0;
00223 int rc = 0;
00224
00225 void error_line(char *s);
00226 void error_state(char *s);
00227 int parse_dump_record(void);
00228 void init_connection(void);
00229 void init_active(void);
00230 void check_tuple_reuse(void);
00231 int check_ACK_advance(unsigned long old_ack);
00232 void begin_REQ(void);
00233 void more_REQ(void);
00234 void begin_RSP(void);
00235 void more_RSP(void);
00236 void log_REQ(void);
00237 void log_RSP(void);
00238 void log_SYN(void);
00239 void log_END(char *how);
00240 void log_ACT(char *how);
00241 void log_nosyn(void);
00242 void log_connection(void);
00243 void log_log(void);
00244 long elapsed_ms(char *end, char *start);
00245 void get_host_port(char *adr, char *host, char *port);
00246 int get_sequence(char *p, unsigned long *begin, unsigned long *end,
00247 unsigned long *bytes);
00248
00249 void main (int argc, char* argv[])
00250 {
00251 int i;
00252
00253
00254 i = 1;
00255 while (i < argc) {
00256 if (strcmp (argv[i], "-r") == 0) {
00257
00258 if (++i >= argc) Usage (argv[0]);
00259 strcpy (input_name, argv[i]);
00260 }
00261 else if (strcmp (argv[i], "-w") == 0) {
00262
00263 if (++i >= argc) Usage (argv[0]);
00264 strcpy (output_name, argv[i]);
00265 }
00266 else
00267 Usage (argv[0]);
00268 i++;
00269 }
00270
00271
00272
00273
00274 if (strcmp(output_name, "") == 0)
00275
00276 outFP = stdout;
00277 else
00278 {
00279 if ((outFP = fopen (output_name, "w")) == NULL) {
00280 fprintf (stderr, "error opening %s\n", output_name);
00281 exit (-1);
00282 }
00283 }
00284
00285 if (strcmp(input_name, "") == 0)
00286
00287 dumpFP = stdin;
00288 else
00289 {
00290 if ((dumpFP = fopen (input_name, "r")) == NULL) {
00291 fprintf (stderr, "error opening %s\n", input_name);
00292 exit (-1);
00293 }
00294 }
00295
00296 strcpy(log_name, output_name);
00297 strcat(log_name, ".log");
00298 if ((logFP = fopen (log_name, "w")) == NULL) {
00299 fprintf (stderr, "error opening %s\n", log_name);
00300 exit (-1);
00301 }
00302
00303
00304
00305
00306
00307 while (!feof (dumpFP)) {
00308
00309
00310
00311
00312
00313 fgets (new_line, sizeof(new_line), dumpFP);
00314
00315
00316
00317
00318
00319
00320 sscanf (new_line, "%s %s %s %s %s %s %s %s",
00321 &ts, &sh, >, &dh, &fl, &p1, &p2, &p3);
00322
00323
00324
00325
00326
00327
00328
00329 if ((strcmp(current_src, sh) != 0) ||
00330 (strcmp(current_dst, dh) != 0))
00331 {
00332 log_connection();
00333
00334
00335
00336
00337 strcpy(current_src, sh);
00338 strcpy(current_dst, dh);
00339
00340 have_pending_acks = 0;
00341 have_pending_fins = 0;
00342 have_pending_rsts = 0;
00343 have_pending_othr = 0;
00344
00345 current_synseq = 0;
00346 connection_state = PENDING;
00347 last_state = PENDING;
00348 new_address = 1;
00349
00350
00351 }
00352
00353
00354
00355
00356
00357
00358
00359 if ((rc = parse_dump_record()) < 0)
00360 continue;
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408 switch (connection_state)
00409
00410
00411
00412
00413 {
00414 case PENDING:
00415 {
00416 switch (input_type)
00417 {
00418 case FIN:
00419 {
00420
00421
00422 have_pending_fins++;
00423 break;
00424 }
00425
00426 case SYN:
00427 {
00428
00429
00430 init_connection();
00431 break;
00432 }
00433
00434 case RST:
00435 {
00436
00437
00438 have_pending_rsts++;
00439 break;
00440 }
00441
00442
00443
00444
00445
00446
00447
00448
00449 case ACK_ONLY:
00450 {
00451
00452
00453 if (new_address == 1)
00454 {
00455 new_address = 0;
00456 have_pending_acks++;
00457 }
00458 else
00459 {
00460
00461
00462 if ((new_ack > 2) &&
00463 (new_ack < 16384))
00464 {
00465 log_ACT("REQ");
00466
00467 last_request_end = 1;
00468 current_request_end = new_ack;
00469
00470 last_response_end = 1;
00471 current_response_end = 1;
00472
00473
00474
00475
00476 strcpy(start_request_time, ts);
00477 strcpy(request_end_time, ts);
00478
00479 last_state = connection_state;
00480 connection_state = IN_REQUEST;
00481
00482 init_active();
00483 }
00484 else
00485 have_pending_acks++;
00486 }
00487 break;
00488 }
00489
00490 case DATA_ACK:
00491 {
00492
00493
00494 if ((seq_bytes > 1) &&
00495 (seq_bytes < 65535))
00496 {
00497 log_ACT("RSP");
00498
00499
00500
00501 last_request_end = 1;
00502 current_request_end = 1;
00503
00504 last_response_end = 0;
00505 current_response_end = seq_bytes;
00506
00507
00508
00509
00510
00511 strcpy(start_response_time, ts);
00512 strcpy(response_end_time, ts);
00513
00514 last_state = connection_state;
00515 connection_state = IN_RESPONSE;
00516
00517 init_active();
00518 }
00519 else
00520 have_pending_othr++;
00521 break;
00522 }
00523 default:
00524 break;
00525 }
00526 break;
00527 }
00528
00529 case SYN_SENT:
00530 {
00531
00532
00533
00534
00535
00536
00537 switch (input_type)
00538 {
00539 case FIN:
00540
00541
00542
00543 {
00544 if ((has_ack == 1) &&
00545 (new_ack > (current_request_end + 1)))
00546
00547
00548 {
00549
00550
00551
00552
00553 begin_REQ();
00554 log_REQ();
00555 }
00556
00557
00558
00559
00560
00561
00562 if ((has_seq == 1) &&
00563 (end_seq > current_response_end))
00564 {
00565 begin_RSP();
00566 log_RSP();
00567 }
00568 last_state = SYN_SENT;
00569 connection_state = FIN_SENT;
00570
00571
00572 if (strcmp(FIN_sent_time, "") == 0)
00573 strcpy(FIN_sent_time, ts);
00574 break;
00575 }
00576
00577 case SYN:
00578 {
00579
00580
00581
00582 check_tuple_reuse();
00583 break;
00584 }
00585
00586 case RST:
00587 {
00588 connection_state = RESET;
00589 last_state = SYN_SENT;
00590
00591
00592
00593 if (strcmp(RST_sent_time, "") == 0)
00594 strcpy(RST_sent_time, ts);
00595 break;
00596 }
00597
00598 case ACK_ONLY:
00599 {
00600
00601
00602
00603
00604
00605 if (new_ack > (current_request_end + 1))
00606 begin_REQ();
00607 break;
00608 }
00609
00610 case DATA_ACK:
00611 {
00612
00613
00614
00615
00616
00617 if (new_ack > (current_request_end + 1))
00618 {
00619
00620
00621 begin_REQ();
00622
00623
00624
00625
00626
00627 if (end_seq > current_response_end)
00628 {
00629
00630
00631
00632 log_REQ();
00633 begin_RSP();
00634 }
00635 }
00636 else
00637
00638
00639
00640
00641 if ((end_seq > last_response_end) &&
00642 (seq_bytes > 0))
00643 begin_RSP();
00644 break;
00645 }
00646 default:
00647 break;
00648 }
00649 break;
00650 }
00651
00652 case FIN_SENT:
00653 {
00654 switch (input_type)
00655 {
00656 case SYN:
00657 {
00658
00659
00660
00661 check_tuple_reuse();
00662 break;
00663 }
00664
00665 case FIN:
00666 break;
00667
00668 case RST:
00669 break;
00670
00671 case ACK_ONLY:
00672
00673
00674
00675
00676
00677
00678 break;
00679
00680 case DATA_ACK:
00681 {
00682
00683
00684
00685
00686
00687
00688
00689 if ((end_seq > (current_response_end + 2)) &&
00690 (have_FINdata_error == 0))
00691 {
00692 error_state("new data in FIN_SENT state");
00693 have_FINdata_error = 1;
00694 }
00695 break;
00696 }
00697 default:
00698 break;
00699 }
00700 break;
00701 }
00702
00703 case RESET:
00704 {
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716 switch (input_type)
00717 {
00718 case RST:
00719 break;
00720
00721 case SYN:
00722 {
00723
00724
00725
00726 check_tuple_reuse();
00727 break;
00728 }
00729
00730 case ACK_ONLY:
00731
00732
00733
00734
00735
00736 break;
00737
00738 case FIN:
00739 {
00740
00741
00742
00743
00744
00745 if (last_state == IN_RESPONSE)
00746 {
00747 if ((has_seq == 1) &&
00748 (end_seq > current_response_end))
00749 more_RSP();
00750 log_RSP();
00751
00752 last_state = RESET;
00753 connection_state = FIN_SENT;
00754
00755
00756
00757 if (strcmp(FIN_sent_time, "") == 0)
00758 strcpy(FIN_sent_time, ts);
00759 }
00760 break;
00761 }
00762
00763 case DATA_ACK:
00764 {
00765
00766
00767
00768
00769
00770
00771
00772 if (last_state == IN_RESPONSE)
00773 {
00774 if (new_ack > (last_request_end + 1))
00775 {
00776 log_RSP();
00777 last_state = RESET;
00778 break;
00779 }
00780
00781
00782
00783
00784 if ((end_seq > current_response_end) &&
00785 (seq_bytes > 0))
00786 more_RSP();
00787 }
00788 break;
00789 }
00790 default:
00791 break;
00792 }
00793 break;
00794 }
00795
00796 case IN_RESPONSE:
00797 {
00798
00799
00800
00801
00802
00803 switch (input_type)
00804 {
00805 case FIN:
00806 {
00807
00808
00809
00810
00811
00812
00813
00814 if (has_ack == 1)
00815 {
00816 if ((rc = check_ACK_advance(current_request_end)) < 0)
00817 break;
00818 }
00819
00820
00821
00822
00823
00824
00825 if ((has_ack == 1) &&
00826 (new_ack > (current_request_end + 1)))
00827 {
00828
00829
00830 log_RSP();
00831
00832
00833
00834
00835 begin_REQ();
00836 log_REQ();
00837
00838
00839
00840
00841
00842 if ((has_seq == 1) &&
00843 (end_seq > last_response_end))
00844 {
00845 begin_RSP();
00846 log_RSP();
00847 }
00848
00849
00850
00851
00852
00853
00854
00855 }
00856 else
00857
00858
00859
00860 {
00861 if ((has_seq == 1) &&
00862 (end_seq > current_response_end))
00863 more_RSP();
00864 log_RSP();
00865 }
00866
00867 last_state = IN_RESPONSE;
00868 connection_state = FIN_SENT;
00869
00870 if (strcmp(FIN_sent_time, "") == 0)
00871 strcpy(FIN_sent_time, ts);
00872 break;
00873 }
00874
00875 case RST:
00876
00877
00878
00879
00880
00881
00882 {
00883
00884
00885 last_state = IN_RESPONSE;
00886 connection_state = RESET;
00887
00888 if (strcmp(RST_sent_time, "") == 0)
00889 strcpy(RST_sent_time, ts);
00890 break;
00891 }
00892
00893 case SYN:
00894 {
00895
00896
00897
00898 check_tuple_reuse();
00899 break;
00900 }
00901
00902 case ACK_ONLY:
00903
00904
00905
00906
00907 {
00908
00909
00910
00911
00912
00913
00914 if (new_ack > (last_request_end + 1))
00915 {
00916
00917
00918 log_RSP();
00919
00920
00921
00922
00923
00924
00925 begin_REQ();
00926 }
00927 break;
00928 }
00929
00930 case DATA_ACK:
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941 {
00942 if ((rc = check_ACK_advance(last_request_end)) < 0)
00943 break;
00944
00945
00946
00947
00948
00949
00950 if (new_ack > (last_request_end + 1))
00951 {
00952
00953
00954 log_RSP();
00955 begin_REQ();
00956
00957
00958
00959
00960
00961 if ((end_seq > current_response_end) &&
00962 (seq_bytes > 0))
00963 {
00964 log_REQ();
00965 begin_RSP();
00966 }
00967 }
00968 else
00969
00970
00971
00972 if (end_seq > current_response_end)
00973 more_RSP();
00974 break;
00975 }
00976 default:
00977 break;
00978 }
00979 break;
00980 }
00981
00982 case IN_REQUEST:
00983 {
00984
00985
00986
00987
00988
00989 switch (input_type)
00990 {
00991 case FIN:
00992
00993
00994
00995
00996
00997
00998
00999
01000 {
01001
01002
01003
01004
01005
01006
01007 if ((has_ack == 1) &&
01008 (new_ack > (current_request_end + 1)))
01009 more_REQ();
01010 else
01011 if (has_ack == 1)
01012 {
01013 if ((rc = check_ACK_advance(current_request_end)) < 0)
01014 break;
01015 }
01016
01017 log_REQ();
01018
01019
01020
01021
01022 if ((has_seq == 1) &&
01023 (end_seq > last_response_end))
01024 {
01025 begin_RSP();
01026 log_RSP();
01027 }
01028
01029 last_state = IN_REQUEST;
01030 connection_state = FIN_SENT;
01031
01032 if (strcmp(FIN_sent_time, "") == 0)
01033 strcpy(FIN_sent_time, ts);
01034 break;
01035 }
01036
01037 case RST:
01038 {
01039
01040
01041
01042
01043 log_REQ();
01044 last_state = IN_REQUEST;
01045 connection_state = RESET;
01046
01047 if (strcmp(RST_sent_time, "") == 0)
01048 strcpy(RST_sent_time, ts);
01049 break;
01050 }
01051
01052 case SYN:
01053 {
01054
01055
01056
01057 check_tuple_reuse();
01058 break;
01059 }
01060
01061 case ACK_ONLY:
01062 {
01063
01064
01065
01066
01067
01068
01069 if (new_ack > (current_request_end + 1))
01070 more_REQ();
01071 break;
01072 }
01073
01074 case DATA_ACK:
01075 {
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086 if (new_ack > (current_request_end + 1))
01087 more_REQ();
01088 else
01089 if ((rc = check_ACK_advance(current_request_end)) < 0)
01090 break;
01091
01092
01093
01094
01095
01096 if ((end_seq > last_response_end) &&
01097 (seq_bytes > 0))
01098 {
01099
01100
01101
01102 log_REQ();
01103 begin_RSP();
01104 }
01105 break;
01106 }
01107 default:
01108 break;
01109 }
01110 break;
01111 }
01112
01113 default:
01114 break;
01115 }
01116
01117
01118 strcpy(last_connection_time, ts);
01119
01120 }
01121 log_log();
01122 close (dumpFP);
01123 close (outFP);
01124 close (logFP);
01125 }
01126
01127
01128
01129
01130
01131 void init_connection(void)
01132 {
01133 log_SYN();
01134 connection_state = SYN_SENT;
01135
01136
01137 if (has_seq == 1)
01138 current_synseq = begin_seq;
01139 else
01140 error_line ("SYN without valid sequence #");
01141
01142
01143
01144
01145
01146 last_request_end = 1;
01147 last_response_end = 1;
01148 current_response_end = 1;
01149 current_request_end = 1;
01150
01151 strcpy(FIN_sent_time, "");
01152 strcpy(RST_sent_time, "");
01153 strcpy(last_connection_time, "");
01154
01155 have_ACK_error = 0;
01156 have_value_error = 0;
01157 have_FINdata_error = 0;
01158 }
01159
01160
01161
01162
01163
01164
01165 void init_active(void)
01166 {
01167 strcpy(FIN_sent_time, "");
01168 strcpy(RST_sent_time, "");
01169 strcpy(last_connection_time, "");
01170
01171 have_ACK_error = 0;
01172 have_value_error = 0;
01173 have_FINdata_error = 0;
01174
01175 }
01176
01177
01178
01179
01180
01181 int check_ACK_advance(unsigned long old_ack)
01182 {
01183
01184 if ((new_ack < old_ack) &&
01185 report_ACK_err)
01186 {
01187 if (have_ACK_error == 0)
01188 {
01189 error_state("ACK error -- backward");
01190 have_ACK_error = 1;
01191 }
01192 return(-1);
01193 }
01194 else
01195 return (0);
01196 }
01197
01198
01199
01200 void check_tuple_reuse(void)
01201 {
01202
01203
01204 if ((has_seq == 1) &&
01205 (current_synseq != begin_seq))
01206 {
01207
01208
01209
01210
01211 if ((connection_state == SYN_SENT) ||
01212 ((connection_state == RESET) && (last_state == SYN_SENT)))
01213 {
01214 log_END("TRM");
01215 init_connection();
01216 return;
01217 }
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231 if (connection_state == FIN_SENT)
01232 elapsed = 60001;
01233 else
01234 elapsed = elapsed_ms(ts, last_connection_time);
01235
01236 if (elapsed < 60000)
01237 error_state("Non-duplicate SYN in connection");
01238 else
01239 {
01240
01241
01242
01243 switch (connection_state)
01244 {
01245 case FIN_SENT:
01246 log_END("FIN");
01247 break;
01248 case RESET:
01249 if (last_state == IN_RESPONSE)
01250 log_RSP();
01251
01252 log_END("RST");
01253 break;
01254 case IN_RESPONSE:
01255 log_RSP();
01256 log_END("TRM");
01257 break;
01258 case IN_REQUEST:
01259 log_REQ();
01260 log_END("TRM");
01261 break;
01262 default:
01263 break;
01264 }
01265 init_connection();
01266 }
01267 }
01268 }
01269
01270
01271
01272 void begin_REQ(void)
01273 {
01274 current_request_end = new_ack;
01275
01276
01277
01278
01279 strcpy(start_request_time, ts);
01280 strcpy(request_end_time, ts);
01281
01282 last_state = connection_state;
01283 connection_state = IN_REQUEST;
01284 }
01285
01286
01287
01288 void more_REQ(void)
01289 {
01290 current_request_end = new_ack;
01291 strcpy(request_end_time, ts);
01292 }
01293
01294
01295
01296 void begin_RSP(void)
01297 {
01298 current_response_end = end_seq;
01299
01300
01301
01302
01303
01304 strcpy(start_response_time, ts);
01305 strcpy(response_end_time, ts);
01306
01307 last_state = connection_state;
01308 connection_state = IN_RESPONSE;
01309 }
01310
01311
01312
01313 void more_RSP(void)
01314 {
01315 current_response_end = end_seq;
01316
01317 strcpy(response_end_time, ts);
01318 }
01319
01320
01321
01322
01323
01324
01325
01326
01327 int parse_dump_record()
01328 {
01329 begin_seq = end_seq = seq_bytes = new_ack = 0;
01330 has_ack = has_seq = 0;
01331
01332
01333
01334
01335 if ((strcmp(fl, "SFRP") == 0) ||
01336 (strcmp(fl, "SFR") == 0) ||
01337 (strcmp(fl, "SFP") == 0) ||
01338 (strcmp(fl, "SF") == 0) ||
01339 (strcmp(fl, "SRP") == 0) ||
01340 (strcmp(fl, "SR") == 0))
01341 {
01342
01343
01344
01345 if (connection_state != PENDING)
01346 error_line ("SYN in combination with F or R");
01347 return(-1);
01348 }
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359 if (strcmp(p1, "ack") == 0)
01360 {
01361 has_seq = 0;
01362 has_ack = 1;
01363 new_ack = strtoul(p2, (char **)NULL, 10);
01364 }
01365 else
01366 {
01367 if (strcmp(p1, "win") == 0)
01368 {
01369 has_ack = 0;
01370 has_seq = 0;
01371 }
01372 else
01373 {
01374
01375
01376
01377
01378
01379 if ((rc = get_sequence(p1, &begin_seq, &end_seq, &seq_bytes)) < 0)
01380 {
01381 error_line ("invalid sequence # field");
01382 return (-1);
01383 }
01384 has_seq = 1;
01385
01386
01387
01388 if (strcmp(p2, "ack") == 0)
01389 {
01390 has_ack = 1;
01391 new_ack = strtoul(p3, (char **)NULL, 10);
01392 }
01393 else
01394 has_ack = 0;
01395 }
01396 }
01397
01398
01399
01400 if ((strcmp(fl, "F") == 0) ||
01401 (strcmp(fl, "FP") == 0) ||
01402 (strcmp(fl, "FR") == 0) ||
01403 (strcmp(fl, "FRP") == 0))
01404 input_type = FIN;
01405 else
01406 {
01407 if ((strcmp(fl, "R") == 0) ||
01408 (strcmp(fl, "RP") == 0))
01409 input_type = RST;
01410 else
01411 {
01412 if ((strcmp(fl, "S") == 0) ||
01413 (strcmp(fl, "SP") == 0))
01414 input_type = SYN;
01415 else
01416 {
01417 if ((has_ack == 1) &&
01418 (has_seq == 0))
01419 input_type = ACK_ONLY;
01420 else
01421 if ((has_seq == 1) &&
01422 (has_ack == 1))
01423 input_type = DATA_ACK;
01424 else
01425 {
01426 error_line("Unexpected Data/ACK combination");
01427 return (-1);
01428 }
01429 }
01430 }
01431 }
01432
01433
01434 if ((connection_state == IN_RESPONSE) ||
01435 (connection_state == IN_REQUEST) ||
01436 (connection_state == SYN_SENT) ||
01437 ((connection_state == RESET) && (last_state == IN_RESPONSE)))
01438 {
01439
01440
01441 if (((input_type == FIN) ||
01442 (input_type == DATA_ACK)) &&
01443 (end_seq > (current_response_end + 65535)))
01444 {
01445 if (have_value_error == 0)
01446 {
01447 error_line ("suspect sequence # value");
01448 have_value_error = 1;
01449 }
01450 return (-1);
01451 }
01452
01453
01454
01455 if (((input_type == FIN) ||
01456 (input_type == ACK_ONLY) ||
01457 (input_type == DATA_ACK)) &&
01458 (new_ack > (current_request_end + 16384)))
01459 {
01460 if (have_value_error == 0)
01461 {
01462 error_line ("suspect ACK value");
01463 have_value_error = 1;
01464 }
01465 return (-1);
01466 }
01467 }
01468 return(0);
01469 }
01470
01471
01472
01473 void log_connection(void)
01474 {
01475
01476
01477
01478 if (connection_state == IN_REQUEST)
01479 log_REQ();
01480 else
01481 {
01482
01483
01484
01485 if ((connection_state == IN_RESPONSE) ||
01486 ((connection_state == RESET) && last_state == IN_RESPONSE))
01487 {
01488 if (current_response_end > (last_response_end + 1))
01489 log_RSP();
01490 }
01491 }
01492
01493
01494
01495
01496
01497 if (connection_state != PENDING)
01498 {
01499 if (connection_state == FIN_SENT)
01500 log_END("FIN");
01501 else
01502 {
01503 if (connection_state == RESET)
01504 log_END("RST");
01505 else
01506 log_END("TRM");
01507 }
01508 }
01509 else
01510 {
01511 if (((have_pending_fins > 0) +
01512 (have_pending_rsts > 0) +
01513 (have_pending_othr > 0) +
01514 (have_pending_acks > 0)) > 1)
01515 pending_cmb_count++;
01516 else
01517 {
01518 pending_fin_count += (have_pending_fins > 0);
01519 pending_rst_count += (have_pending_rsts > 0);
01520 pending_ack_count += (have_pending_acks > 0);
01521 pending_oth_count += (have_pending_othr > 0);
01522 }
01523 }
01524 }
01525
01526
01527 void log_log(void)
01528 {
01529 fprintf(logFP, "Input tcpdump file: %s \n", input_name);
01530 fprintf(logFP, "Output connection file: %s \n", output_name);
01531 fprintf(logFP, " SYNs %8d \n", syn_count);
01532 fprintf(logFP, " REQs %8d \n", req_count);
01533 fprintf(logFP, " ACT-REQs %8d \n", act_req_count);
01534 fprintf(logFP, " RSPs %8d \n", rsp_count);
01535 fprintf(logFP, " ACT-RSPs %8d \n", act_rsp_count);
01536 fprintf(logFP, " FINs %8d \n", fin_count);
01537 fprintf(logFP, " RSTs %8d \n", rst_count);
01538 fprintf(logFP, " TRMs %8d \n", trm_count);
01539 fprintf(logFP, " ERRs %8d \n", err_count);
01540 fprintf(logFP, "Partial Connections:\n");
01541 fprintf(logFP, " FIN only %8d \n", pending_fin_count);
01542 fprintf(logFP, " RST only %8d \n", pending_rst_count);
01543 fprintf(logFP, " ACK only %8d \n", pending_ack_count);
01544 fprintf(logFP, " Combos %8d \n", pending_cmb_count);
01545 fprintf(logFP, " Other %8d \n", pending_oth_count);
01546 }
01547
01548
01549
01550
01551
01552
01553
01554
01555 void log_REQ(void)
01556 {
01557
01558 get_host_port(current_src, src_host, src_port);
01559
01560
01561 get_host_port(current_dst, dst_host, dst_port);
01562
01563
01564
01565
01566
01567
01568 fprintf(outFP, "%s %-15s %5s > %-15s %4s: REQ %12d %s\n",
01569 start_request_time,
01570 dst_host, dst_port, src_host, src_port,
01571 current_request_end - last_request_end,
01572 request_end_time);
01573
01574 last_request_end = current_request_end;
01575 req_count++;
01576 }
01577
01578 void log_RSP(void)
01579 {
01580
01581 get_host_port(current_src, src_host, src_port);
01582
01583
01584 get_host_port(current_dst, dst_host, dst_port);
01585
01586
01587
01588
01589
01590
01591
01592 fprintf(outFP, "%s %-15s %5s > %-15s %4s: RSP %12d %s\n",
01593 response_end_time,
01594 dst_host, dst_port, src_host, src_port,
01595 current_response_end - last_response_end,
01596 start_response_time);
01597 #ifdef FOO
01598 fprintf(outFP, "%s %-15s %5s > %-15s %4s RSP %d %s\n", start_response_time,
01599 src_host, src_port, dst_host, dst_port,
01600 current_response_end - last_response_end,
01601 response_end_time);
01602 fprintf(outFP, "%s %s > %s RSP %d\n", start_response_time, current_src,
01603 current_dst,
01604 current_response_end - last_response_end);
01605 #endif
01606
01607 last_response_end = current_response_end;
01608 rsp_count++;
01609 }
01610
01611 void log_SYN(void)
01612 {
01613
01614 get_host_port(current_src, src_host, src_port);
01615
01616
01617 get_host_port(current_dst, dst_host, dst_port);
01618
01619 fprintf(outFP, "%s %-15s %5s > %-15s %4s: SYN\n", ts,
01620 dst_host, dst_port, src_host, src_port);
01621 syn_count++;
01622 }
01623
01624 void log_END(char *how)
01625 {
01626 char logical_end_time[20];
01627
01628
01629 get_host_port(current_src, src_host, src_port);
01630
01631
01632 get_host_port(current_dst, dst_host, dst_port);
01633
01634 if (strcmp(how, "FIN") == 0)
01635 {
01636 fin_count++;
01637 strcpy(logical_end_time, FIN_sent_time);
01638 }
01639 else
01640 {
01641 if (strcmp(how, "RST") == 0)
01642 {
01643 rst_count++;
01644 strcpy(logical_end_time, RST_sent_time);
01645 }
01646 else
01647 if (strcmp(how, "TRM") == 0)
01648 {
01649 trm_count++;
01650 strcpy(logical_end_time, last_connection_time);
01651 }
01652 }
01653
01654
01655
01656
01657
01658
01659 fprintf(outFP, "%s %-15s %5s > %-15s %4s: %s %s\n",
01660 last_connection_time,
01661 dst_host, dst_port, src_host, src_port,
01662 how, logical_end_time);
01663 }
01664
01665 void log_ACT(char *how)
01666 {
01667
01668 get_host_port(current_src, src_host, src_port);
01669
01670
01671 get_host_port(current_dst, dst_host, dst_port);
01672
01673
01674
01675
01676
01677
01678 fprintf(outFP, "%s %-15s %5s > %-15s %4s: ACT-%s\n", ts,
01679 dst_host, dst_port, src_host, src_port,
01680 how);
01681 if (strcmp(how, "REQ") == 0)
01682 act_req_count++;
01683 else
01684 if (strcmp(how, "RSP") == 0)
01685 act_rsp_count++;
01686 }
01687
01688 void error_line(char * s)
01689 {
01690
01691 get_host_port(sh, src_host, src_port);
01692
01693
01694 get_host_port(dh, dst_host, dst_port);
01695
01696 fprintf(outFP, "%s %-15s %5s > %-15s %4s: ERR: %s\n", ts,
01697 dst_host, dst_port, src_host, src_port, s);
01698 err_count++;
01699 }
01700
01701 void error_state(char * s)
01702 {
01703
01704 get_host_port(sh, src_host, src_port);
01705
01706
01707 get_host_port(dh, dst_host, dst_port);
01708
01709 fprintf(outFP, "%s %-15s %5s > %-15s %4s: ERR: %s\n", ts,
01710 dst_host, dst_port, src_host, src_port, s);
01711 err_count++;
01712 }
01713
01714 void get_host_port(char *adr, char *host, char *port)
01715 {
01716 char *fp;
01717 char *fpx;
01718 char adr_field[50];
01719
01720 strcpy(adr_field, adr);
01721
01722 fp = (char *)rindex(adr_field, '.');
01723 *fp = '\0';
01724 strcpy(host, adr_field);
01725
01726 fp++;
01727 fpx = (char *)index(fp, ':');
01728 if (fpx != NULL)
01729 *fpx = '\0';
01730 strcpy(port, fp);
01731 }
01732
01733 int get_sequence(char *p, unsigned long *begin, unsigned long *end,
01734 unsigned long *bytes)
01735 {
01736 char seq_field[50];
01737 char *cursor = seq_field;
01738 char *fp;
01739
01740 strcpy (seq_field, p);
01741
01742 fp = (char *)strsep(&cursor, ":" );
01743 if ((cursor == (char *)NULL) ||
01744 (fp == (char *)NULL))
01745 return (-1);
01746 else
01747 *begin = strtoul(fp, (char **)NULL, 10);
01748
01749 fp = (char *)strsep(&cursor, "(" );
01750 if ((cursor == (char *)NULL) ||
01751 (fp == (char *)NULL))
01752 return (-1);
01753 else
01754 *end = strtoul(fp, (char **)NULL, 10);
01755
01756 fp = (char *)strsep(&cursor, ")" );
01757 if ((cursor == (char *)NULL) ||
01758 (fp == (char *)NULL))
01759 return (-1);
01760 else
01761 *bytes = strtoul(fp, (char **)NULL, 10);
01762 return(0);
01763 }
01764
01765
01766
01767
01768
01769 static void
01770 tvsub(tdiff, t1, t0)
01771 struct timeval *tdiff, *t1, *t0;
01772 {
01773
01774 tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
01775 tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
01776 if (tdiff->tv_usec < 0)
01777 {
01778 tdiff->tv_sec--;
01779 tdiff->tv_usec += 1000000;
01780 }
01781 }
01782
01783
01784
01785
01786
01787 long elapsed_ms(char *end, char *start)
01788 {
01789 struct timeval delta, end_time, start_time;
01790 long elapsed_time;
01791
01792 char end_tmp[20];
01793 char start_tmp[20];
01794
01795 char *cursor;
01796 char *cp;
01797
01798 strcpy(end_tmp, end);
01799 cursor = end_tmp;
01800 cp = (char *)strsep(&cursor, "." );
01801 end_time.tv_sec = atoi(end_tmp);
01802 end_time.tv_usec = atoi(cursor);
01803
01804 strcpy(start_tmp, start);
01805 cursor = start_tmp;
01806 cp = (char *)strsep(&cursor, "." );
01807 start_time.tv_sec = atoi(start_tmp);
01808 start_time.tv_usec = atoi(cursor);
01809
01810 tvsub(&delta, &end_time, &start_time);
01811
01812 elapsed_time = (delta.tv_sec * 1000) + (delta.tv_usec/1000);
01813 return (elapsed_time);
01814 }
01815