ktcpdump3.c
最終更新:2010/1/12
001: /* 002: * ktcpdump3.c 003: * libpcap を使った TCP パケット解析サンプルコード 004: * ・コネクションごとに別ファイルにダンプする。 005: * ・起動後に SYN を検出したものだけ記録する。 006: * ・Ctrl-C で終了。 007: */ 008: 009: #define PROG_NAME "ktcpdump3" 010: 011: #include "mystab_pcap.h" 012: #include "apr_getopt.h" 013: #include "apr_network_io.h" 014: 015: /* デバッグフラグ D0 全パケットの表示等 */ 016: #define D0 0 017: 018: /* デバッグフラグ D1 全状態遷移の表示 */ 019: #define D1 0 020: 021: /* デバッグフラグ D2 オープンクローズの表示 */ 022: #define D2 1 023: 024: /* デバッグフラグ DD その他 */ 025: #define DD 0 026: 027: 028: /* コマンドラインオプション定義 */ 029: 030: static const apr_getopt_option_t opt_option[] = { 031: /* long-option, short-option, has-arg flag, description */ 032: { "port_number", 'p', TRUE, "[MUST] port_number" }, 033: { "interface", 'i', TRUE, "[MUST] network device to use" }, 034: { "log_dir", 'l', TRUE, "[MUST] log directory" }, 035: { "help", 'h', FALSE, "[OPTION] show help" }, /* -h or --help */ 036: 037: #if defined(WIN32) || defined(WINDOWS) || defined(MSVC) 038: 039: { "disp_interfaces", 'D', FALSE, 040: "[OPTION] displays avalable interfaces (Windows Only)" }, 041: 042: #endif 043: 044: { NULL, 0, 0, NULL }, /* SENTINEL */ 045: }; 046: 047: 048: 049: /* コネクションレコードテーブルのサイズのデフォルト値 (65536未満)*/ 050: #define CONREC_TAB_SIZE 100 051: 052: 053: /* 応答待ち TCP ペイロードを格納するバッファのサイズ */ 054: #define TCP_PAYLOAD_BUFFER_SIZE 3000 055: 056: 057: 058: /* コネクションレコードの保持のタイムアウト秒 */ 059: #define TIME_OUT_SEC 600 060: 061: /* コネクションレコードテーブル */ 062: 063: typedef struct _st_my_conrec { 064: 065: /* ステータス(0で未使用) */ 066: apr_byte_t stat; 067: 068: /* コネクションID */ 069: apr_uint32_t id; 070: 071: /* コネクション名 XXX.XXX.XXX.XXX:XXXXX-XXX.XXX.XXX.XXX:XXXXX */ 072: char name[43]; 073: 074: /* クライアントIPアドレス */ 075: char c_ipaddr[16]; 076: /* クライアントポート番号 */ 077: apr_uint16_t c_port; 078: /* サーバIPアドレス */ 079: char s_ipaddr[16]; 080: /* サーバポート番号 */ 081: apr_uint16_t s_port; 082: 083: /* 開始日時 */ 084: apr_time_t start_time; 085: 086: /* パケットの発生した最終日時 */ 087: time_t last_time; 088: 089: /* メモリプール */ 090: apr_pool_t *pool; 091: 092: /* ログファイルのファイルポインタ */ 093: apr_file_t *fp; 094: 095: /* クライアントシーケンス番号 */ 096: apr_uint32_t c_seq_no; 097: /* サーバシーケンス番号 */ 098: apr_uint32_t s_seq_no; 099: 100: /* サーバ応答待ちのクライアントデータのサイズ */ 101: apr_uint16_t c_data_size; 102: /* クライアント応答待ちのサーバデータのサイズ */ 103: apr_uint16_t s_data_size; 104: 105: /* サーバ応答待ちのクライアントデータ */ 106: apr_byte_t c_data[TCP_PAYLOAD_BUFFER_SIZE]; 107: /* クライアント応答待ちのサーバデータ */ 108: apr_byte_t s_data[TCP_PAYLOAD_BUFFER_SIZE]; 109: 110: } my_conrec; 111: 112: 113: /* コネクションテーブルのステータス */ 114: 115: #define CLOSED 1 116: #define SYN1 2 117: #define SYN2 3 118: #define ESTAB 4 119: #define C_FIN1 5 120: #define C_FIN2 6 121: #define S_FIN1 7 122: #define S_FIN2 8 123: #define UNKNOWN 99 124: 125: static apr_uint16_t count_active_conrec_data = 0; 126: static apr_uint16_t count_id = 0; 127: 128: my_conrec conrec_tab[CONREC_TAB_SIZE]; 129: 130: /* 監視対象ポート */ 131: static apr_uint16_t target_port = 0; 132: 133: /* ローカルアドレス文字列 */ 134: static const char *local_addr = NULL; 135: 136: /* ログ保存ディレクトリ */ 137: static const char *log_dir = NULL; 138: 139: /* 観測者情報 */ 140: static char *watcher_str = NULL; 141: 142: 143: #define STAT_NORMAL 0 144: #define STAT_TIME_OUT 1 145: #define STAT_ABORTED 2 146: 147: 148: void my_conrec_close ( 149: my_conrec * cr_ptr 150: , int status 151: ) { 152: 153: if (cr_ptr->fp) { 154: apr_status_t rv = APR_SUCCESS; 155: char kbuf[32]; 156: 157: apr_file_printf(cr_ptr->fp, "0\r\n"); 158: 159: rv = apr_rfc822_date(kbuf, apr_time_now()); 160: if (rv == APR_SUCCESS) { 161: apr_file_printf(cr_ptr->fp, "End-Date: %s\r\n", kbuf); 162: } 163: switch (status) { 164: case STAT_NORMAL: 165: apr_file_printf(cr_ptr->fp, "Status: 0 NORMAL\r\n"); 166: break; 167: case STAT_TIME_OUT: 168: apr_file_printf(cr_ptr->fp, "Status: 1 TIME_OUT\r\n"); 169: break; 170: case STAT_ABORTED: 171: apr_file_printf(cr_ptr->fp, "Status: 2 ABORTED\r\n"); 172: break; 173: } 174: apr_file_printf(cr_ptr->fp, "\r\n"); 175: apr_file_close(cr_ptr->fp); 176: cr_ptr->fp = NULL; 177: } 178: if (cr_ptr->pool) { 179: apr_pool_destroy(cr_ptr->pool); 180: cr_ptr->pool = NULL; 181: } 182: 183: memset(cr_ptr, 0, sizeof(my_conrec)); 184: 185: count_active_conrec_data--; 186: } 187: 188: /* 189: * 返り値: 190: * エラー時は NULL 191: */ 192: 193: my_conrec *my_conrec_get ( 194: const char *c_ipaddr 195: , apr_uint16_t c_port 196: , const char *s_ipaddr 197: , apr_uint16_t s_port 198: ) { 199: my_conrec *cr_ptr = NULL; 200: int i=0; 201: for (i=0; i<CONREC_TAB_SIZE; i++) { 202: cr_ptr = & conrec_tab[i]; 203: if (! cr_ptr->stat) { 204: continue; 205: } 206: if (time(NULL) - cr_ptr->last_time >= TIME_OUT_SEC) { 207: if(DD)puts("#Time UP!."); 208: my_conrec_close(cr_ptr, STAT_TIME_OUT); 209: continue; 210: } 211: if (!strcmp(c_ipaddr, cr_ptr->c_ipaddr) && c_port==cr_ptr->c_port && 212: !strcmp(s_ipaddr, cr_ptr->s_ipaddr) && s_port==cr_ptr->s_port) { 213: if(0)puts("Found!"); 214: return cr_ptr; 215: } 216: } 217: 218: return NULL; 219: } 220: 221: my_conrec * my_conrec_new ( 222: const char *c_ipaddr 223: , apr_uint16_t c_port 224: , const char *s_ipaddr 225: , apr_uint16_t s_port 226: ) { 227: my_conrec *cr_ptr = NULL; 228: int i=0; 229: for (i=0; i<CONREC_TAB_SIZE; i++) { 230: cr_ptr = & conrec_tab[i]; 231: if (cr_ptr->stat > 0) { 232: if (time(NULL) - cr_ptr->last_time < TIME_OUT_SEC) { 233: continue; 234: } else { 235: my_conrec_close(cr_ptr, STAT_TIME_OUT); 236: } 237: } 238: 239: cr_ptr->stat = CLOSED; 240: strcpy (cr_ptr->c_ipaddr, c_ipaddr); 241: cr_ptr->c_port = c_port; 242: strcpy (cr_ptr->s_ipaddr, s_ipaddr); 243: cr_ptr->s_port = s_port; 244: cr_ptr->start_time = apr_time_now(); 245: cr_ptr->last_time = time(NULL); 246: 247: snprintf(cr_ptr->name, 43, "%s:%d-%s:%d", c_ipaddr, c_port, s_ipaddr, 248: s_port); 249: 250: cr_ptr->id = count_id++; 251: 252: count_active_conrec_data++; 253: return cr_ptr; 254: } 255: 256: return NULL; 257: } 258: 259: void my_conrec_open ( 260: my_conrec * cr_ptr 261: ) { 262: apr_status_t rv = APR_SUCCESS; 263: rv = apr_pool_create(& cr_ptr->pool, NULL); 264: 265: if (rv != APR_SUCCESS) { 266: return; 267: } 268: 269: { 270: apr_time_exp_t tm; 271: char *out_filename = NULL; 272: char tbuf[16]; /* YYYYMMDD-hhmmss */ 273: int retsize = 0; 274: 275: apr_time_exp_lt(&tm, cr_ptr->start_time); 276: apr_strftime(tbuf, &retsize, 16, "%Y%m%d-%H%M%S", &tm); 277: 278: out_filename = apr_psprintf(cr_ptr->pool, 279: "%s/%s-%05u-%s-%u-%s-%u.txt", 280: log_dir, tbuf, cr_ptr->id, cr_ptr->c_ipaddr, cr_ptr->c_port, 281: cr_ptr->s_ipaddr, cr_ptr->s_port); 282: 283: if(DD)printf("#%s\n", out_filename); 284: 285: rv = apr_file_open(& cr_ptr->fp, out_filename, 286: APR_FOPEN_WRITE|APR_FOPEN_CREATE|APR_FOPEN_TRUNCATE|APR_FOPEN_BINARY, 287: APR_OS_DEFAULT, cr_ptr->pool); 288: 289: if (rv != APR_SUCCESS) { 290: if(DD)printf("#ERROR: %s (%u)\n", out_filename, cr_ptr->fp); 291: return; 292: } 293: 294: apr_file_printf(cr_ptr->fp, "Watcher: %s\r\n", watcher_str); 295: apr_file_printf(cr_ptr->fp, "Session-Id: %s-%05u\r\n", tbuf, cr_ptr->id); 296: apr_file_printf(cr_ptr->fp, "Client: %s:%u\r\n", cr_ptr->c_ipaddr, 297: cr_ptr->c_port); 298: apr_file_printf(cr_ptr->fp, "Server: %s:%u\r\n", cr_ptr->s_ipaddr, 299: cr_ptr->s_port); 300: { 301: char kbuf[32]; 302: rv = apr_rfc822_date(kbuf, cr_ptr->start_time); 303: if (rv == APR_SUCCESS) { 304: apr_file_printf(cr_ptr->fp, "Date: %s\r\n", kbuf); 305: } 306: apr_file_printf(cr_ptr->fp, "\r\n"); 307: } 308: } 309: } 310: 311: 312: void my_conrec_record( 313: my_conrec *cr_ptr 314: , apr_byte_t direction_flag 315: , my_tcp_pkt *d 316: ) { 317: int i=0; 318: 319: if (! cr_ptr->fp) { 320: return; 321: } 322: apr_file_printf(cr_ptr->fp, "#%c,seq_no=%u,ack_no=%u,[", 323: (direction_flag)?'C':'S', d->tcp_seq_no, d->tcp_ack_no 324: ); 325: if (d->tcp_urg_bit) { 326: apr_file_printf(cr_ptr->fp, "urg:"); 327: } 328: if (0) if (d->tcp_ack_bit) { /* ACK ビットは必ず 1 になる */ 329: apr_file_printf(cr_ptr->fp, "ack:"); 330: } 331: if (d->tcp_psh_bit) { 332: apr_file_printf(cr_ptr->fp, "psh:"); 333: } 334: if (d->tcp_rst_bit) { 335: apr_file_printf(cr_ptr->fp, "rst:"); 336: } 337: if (d->tcp_syn_bit) { 338: apr_file_printf(cr_ptr->fp, "syn:"); 339: } 340: if (d->tcp_fin_bit) { 341: apr_file_printf(cr_ptr->fp, "fin:"); 342: } 343: apr_file_printf(cr_ptr->fp, "],size=%u", d->tcp_payload_size); 344: apr_file_printf(cr_ptr->fp, "\r\n"); 345: 346: if (0) {for (i=0; i<d->tcp_payload_size; i++) { 347: apr_file_printf(cr_ptr->fp, "%02X", d->tcp_payload_pos[i]); 348: if (i && i%32 == 31) 349: apr_file_printf(cr_ptr->fp, "\r\n"); 350: } 351: apr_file_printf(cr_ptr->fp, "\r\n"); 352: } 353: } 354: 355: void my_conrec_set( 356: my_conrec *cr_ptr 357: , apr_byte_t direction_flag 358: , my_tcp_pkt *d 359: ) { 360: if (direction_flag) { 361: if (cr_ptr->c_data_size == 0 && d->tcp_seq_no > cr_ptr->c_seq_no) { 362: cr_ptr->c_seq_no = d->tcp_seq_no; 363: } 364: if (d->tcp_seq_no + d->tcp_payload_size <= cr_ptr->c_seq_no + cr_ptr->c_data_size) { 365: apr_file_printf(cr_ptr->fp, "#WARNING: my_conrec_set (1) already set!\r\n"); 366: } else if (cr_ptr->c_seq_no + cr_ptr->c_data_size == d->tcp_seq_no) { 367: if (cr_ptr->c_data_size + d->tcp_payload_size < TCP_PAYLOAD_BUFFER_SIZE) { 368: memcpy(cr_ptr->c_data + cr_ptr->c_data_size, d->tcp_payload_pos, d->tcp_payload_size); 369: cr_ptr->c_data_size += d->tcp_payload_size; 370: } else { 371: apr_file_printf(cr_ptr->fp, "#ERROR: cr_ptr->c_data overflow!\r\n"); 372: } 373: } else { 374: apr_file_printf(cr_ptr->fp, "#WARNING: my_conrec_set (2)\r\n"); 375: } 376: } else { 377: if (cr_ptr->s_data_size == 0 && d->tcp_seq_no > cr_ptr->s_seq_no) { 378: cr_ptr->s_seq_no = d->tcp_seq_no; 379: } 380: if (d->tcp_seq_no + d->tcp_payload_size <= cr_ptr->s_seq_no + cr_ptr->s_data_size) { 381: apr_file_printf(cr_ptr->fp, "#WARNING: my_conrec_set (3) already set!\r\n"); 382: } else if (cr_ptr->s_seq_no + cr_ptr->s_data_size == d->tcp_seq_no) { 383: if (cr_ptr->s_data_size + d->tcp_payload_size < TCP_PAYLOAD_BUFFER_SIZE) { 384: memcpy(cr_ptr->s_data + cr_ptr->s_data_size, d->tcp_payload_pos, d->tcp_payload_size); 385: cr_ptr->s_data_size += d->tcp_payload_size; 386: } else { 387: apr_file_printf(cr_ptr->fp, "#ERROR: cr_ptr->s_data overflow!\r\n"); 388: } 389: } else { 390: apr_file_printf(cr_ptr->fp, "#WARNING: my_conrec_set (4)\r\n"); 391: } 392: } 393: } 394: 395: void my_conrec_ack( 396: my_conrec *cr_ptr 397: , apr_byte_t direction_flag 398: , my_tcp_pkt *d 399: ) { 400: if (direction_flag) { 401: if (d->tcp_ack_no == cr_ptr->s_seq_no + cr_ptr->s_data_size) { 402: if (cr_ptr->s_data_size > 0 && cr_ptr->fp) { 403: apr_size_t len = cr_ptr->s_data_size; 404: apr_file_printf(cr_ptr->fp, "S%u\r\n", cr_ptr->s_data_size); 405: apr_file_write(cr_ptr->fp, cr_ptr->s_data, &len); 406: apr_file_printf(cr_ptr->fp, "\r\n"); 407: cr_ptr->s_seq_no = d->tcp_ack_no; 408: cr_ptr->s_data_size = 0; 409: } 410: } else { 411: apr_file_printf(cr_ptr->fp, 412: "#WARNING: my_conrec_ack (1): (s_seq_no=%u)+(s_data_size=%u)!=(ack_no=%u)\r\n", 413: cr_ptr->s_seq_no, cr_ptr->s_data_size, d->tcp_ack_no); 414: } 415: } else { 416: if (d->tcp_ack_no == cr_ptr->c_seq_no + cr_ptr->c_data_size) { 417: if (cr_ptr->c_data_size > 0 && cr_ptr->fp) { 418: apr_size_t len = cr_ptr->c_data_size; 419: apr_file_printf(cr_ptr->fp, "C%u\r\n", cr_ptr->c_data_size); 420: apr_file_write(cr_ptr->fp, cr_ptr->c_data, &len); 421: apr_file_printf(cr_ptr->fp, "\r\n"); 422: cr_ptr->c_seq_no = d->tcp_ack_no; 423: cr_ptr->c_data_size = 0; 424: } 425: } else { 426: apr_file_printf(cr_ptr->fp, 427: "#WARNING: my_conrec_ack (2): (c_seq_no=%u)+(c_data_size=%u)!=(ack_no=%u)\r\n", 428: cr_ptr->c_seq_no, cr_ptr->c_data_size, d->tcp_ack_no); 429: } 430: } 431: } 432: 433: /* パケット(ディレクションとコードビット)による状態遷移 */ 434: 435: void my_tcp_trans (apr_byte_t direction_flag, my_tcp_pkt *d) { 436: 437: my_conrec *cr_ptr = NULL; 438: 439: char *client_ip = NULL; 440: apr_uint16_t client_port = 0; 441: char *server_ip = NULL; 442: apr_uint16_t server_port = 0; 443: 444: if (direction_flag) { 445: client_ip = d->ip_src_addr; 446: client_port = d->tcp_src_port; 447: server_ip = d->ip_dst_addr; 448: server_port = d->tcp_dst_port; 449: } else { 450: client_ip = d->ip_dst_addr; 451: client_port = d->tcp_dst_port; 452: server_ip = d->ip_src_addr; 453: server_port = d->tcp_src_port; 454: } 455: 456: if (direction_flag && d->tcp_syn_bit && !d->tcp_ack_bit) { 457: cr_ptr = my_conrec_new(client_ip, client_port, server_ip, server_port); 458: if (!cr_ptr) { 459: if(D2)puts("what's up ?! (1)"); 460: if(D2)printf("active=%d\n", count_active_conrec_data); 461: return; 462: } 463: cr_ptr->stat = SYN1; 464: cr_ptr->c_seq_no = d->tcp_seq_no; 465: return; 466: } 467: 468: cr_ptr = my_conrec_get(client_ip, client_port, server_ip, server_port); 469: if (!cr_ptr) { 470: return; 471: } 472: 473: 474: if (cr_ptr->stat == SYN1) { 475: if (!direction_flag && d->tcp_syn_bit) { 476: cr_ptr->stat = SYN2; 477: cr_ptr->s_seq_no = d->tcp_seq_no; 478: } 479: return; 480: } 481: 482: if (cr_ptr->stat == SYN2) { 483: if (direction_flag) { 484: cr_ptr->stat = ESTAB; 485: cr_ptr->c_seq_no = d->tcp_seq_no; 486: cr_ptr->s_seq_no = d->tcp_ack_no; 487: my_conrec_open(cr_ptr); 488: 489: if(D2)printf("[%s],%c,", cr_ptr->name, direction_flag?'C':'S'); 490: if(D2)printf("OPENED. active=%d\n", count_active_conrec_data); 491: return; 492: } 493: } 494: 495: my_conrec_record(cr_ptr, direction_flag, d); 496: my_conrec_ack(cr_ptr, direction_flag, d); 497: if (d->tcp_payload_size != 0) { 498: if (d->tcp_rst_bit) { 499: /* 再送パケットの処理がここに入る… */ 500: } 501: my_conrec_set(cr_ptr, direction_flag, d); 502: } 503: 504: if (cr_ptr->stat == ESTAB) { 505: 506: 507: if (direction_flag && d->tcp_fin_bit) { 508: cr_ptr->stat = C_FIN1; 509: // cr_ptr->c_seq_no++; 510: // cr_ptr->s_seq_no; 511: if(0)printf("[%s],%c,", cr_ptr->name, direction_flag?'C':'S'); 512: if(0)printf("C_FIN1.\n"); 513: return; 514: } 515: 516: if (!direction_flag && d->tcp_fin_bit) { 517: cr_ptr->stat = S_FIN1; 518: cr_ptr->c_seq_no++; 519: cr_ptr->s_seq_no++; 520: if(0)printf("[%s],%c,", cr_ptr->name, direction_flag?'C':'S'); 521: if(0)printf("S_FIN1.\n"); 522: return; 523: } 524: 525: } 526: 527: if (cr_ptr->stat == C_FIN1) { 528: if (!direction_flag) { 529: if (cr_ptr->s_data_size == 0) { 530: if(D2)printf("[%s],%c,", cr_ptr->name, direction_flag?'C':'S'); 531: my_conrec_close(cr_ptr, STAT_NORMAL); 532: if(D2)printf("C_FIN1-ACK-CLOSED. active=%d\n", count_active_conrec_data); 533: } else { 534: cr_ptr->stat = C_FIN2; 535: } 536: 537: return; 538: } 539: } 540: 541: if (cr_ptr->stat == C_FIN2) { 542: if (cr_ptr->s_data_size == 0) { 543: if(D2)printf("[%s],%c,", cr_ptr->name, direction_flag?'C':'S'); 544: my_conrec_close(cr_ptr, STAT_NORMAL); 545: if(D2)printf("C_FIN1-ACK-CLOSED. active=%d\n", count_active_conrec_data); 546: } 547: } 548: 549: if (cr_ptr->stat == S_FIN1) { 550: if (direction_flag) { 551: if(D2)printf("[%s],%c,", cr_ptr->name, direction_flag?'C':'S'); 552: my_conrec_close(cr_ptr, STAT_NORMAL); 553: if(D2)printf("S_FIN1-ACK-CLOSED. active=%d\n", count_active_conrec_data); 554: return; 555: } 556: } 557: 558: } 559: 560: /* 561: * 指定されたホストネームのIPアドレスの文字列を返す関数 562: * hostname に "" を指定した場合、動作するホストのIPアドレスが返る。 563: */ 564: 565: char * get_host_addr(const char * hostname, apr_pool_t *pool) { 566: apr_status_t rv = APR_SUCCESS; 567: apr_sockaddr_t *sa = NULL; 568: char *ipaddr = NULL; 569: rv = apr_sockaddr_info_get (&sa, hostname, APR_UNSPEC, 0, 0, pool); 570: if (rv != APR_SUCCESS) { 571: return NULL; 572: } 573: 574: rv = apr_sockaddr_ip_get (&ipaddr, sa); 575: if (rv != APR_SUCCESS) { 576: return NULL; 577: } 578: 579: return ipaddr; 580: } 581: 582: void print_usage (apr_file_t *out) { 583: apr_getopt_option_t *ptr = (apr_getopt_option_t *)opt_option; 584: 585: apr_file_printf(out, "Usage: %s ", PROG_NAME); 586: while (ptr && ptr->name) { 587: if (ptr->has_arg) { 588: apr_file_printf(out, "[ -%c <arg> | --%s <arg> ] ", ptr->optch, 589: ptr->name); 590: } else { 591: apr_file_printf(out, "[ -%c | --%s ] ", ptr->optch, ptr->name); 592: } 593: ptr++; 594: } 595: apr_file_printf(out, "\n"); 596: ptr = (apr_getopt_option_t *)opt_option; 597: while (ptr && ptr->name) { 598: apr_file_printf(out, "\t-%c, --%s\t: %s\n", ptr->optch, ptr->name, 599: ptr->description); 600: ptr++; 601: } 602: 603: } 604: 605: /* 606: * コマンドライン引数の処理 607: */ 608: 609: int my_pcap_init ( 610: int ac 611: , char **av 612: , my_pcap_params *params 613: , apr_file_t *astderr 614: , apr_pool_t *pool 615: ) { 616: apr_status_t rv = APR_SUCCESS; 617: 618: apr_getopt_t *opt = NULL; 619: int opt_ch = 0; 620: const char *opt_arg = NULL; 621: 622: const char * interface_str = NULL; 623: 624: if (ac < 2) { 625: print_usage(astderr); 626: return 0; 627: } 628: 629: rv = apr_getopt_init(&opt, pool, ac, (const char * const *)av); 630: 631: if (rv != APR_SUCCESS) { 632: apr_file_printf(astderr, "ERROR: apr_getopt_init\n"); 633: return 0; 634: } 635: 636: while ((rv = apr_getopt_long(opt, opt_option, &opt_ch, &opt_arg)) 637: == APR_SUCCESS) { 638: 639: switch (opt_ch) { 640: case 'p': 641: target_port = atoi(opt_arg); 642: break; 643: 644: case 'i': 645: interface_str = opt_arg; 646: break; 647: 648: case 'l': 649: log_dir = opt_arg; 650: break; 651: 652: #if defined(WIN32) || defined(WINDOWS) || defined(MSVC) 653: 654: case 'D': 655: { 656: char errbuf[80]; 657: if (! disp_devices(astderr, errbuf, sizeof(errbuf))) { 658: apr_file_printf(astderr, "ERROR: disp_devices: %s\n", errbuf); 659: } 660: } 661: return 0; 662: break; 663: 664: #endif 665: 666: case 'h': 667: print_usage(astderr); 668: return 0; 669: } 670: 671: } 672: 673: if (rv != APR_EOF || target_port<=0 || !interface_str || !log_dir) { 674: print_usage(astderr); 675: return 0; 676: } 677: 678: params->device = interface_str; 679: params->filter = apr_psprintf(pool, "tcp port %d", target_port); 680: 681: watcher_str = get_host_addr("", pool); 682: memset(conrec_tab, 0, sizeof(conrec_tab)); 683: return 1; 684: } 685: 686: void my_pcap_main( 687: apr_pool_t *pool 688: , apr_file_t *out 689: , my_tcp_pkt *d 690: ) { 691: 692: apr_byte_t direction_flag = 0; 693: 694: if (!d || !pool || !out) { 695: return; 696: } 697: 698: if (d->tcp_dst_port == target_port) { 699: direction_flag = 1; 700: } 701: 702: my_tcp_trans(direction_flag, d); 703: } 704: 705: /* 706: * 終期化処理 707: * コネクションテーブルの強制クローズ 708: */ 709: 710: void my_pcap_finally ( 711: apr_file_t *out 712: ) { 713: 714: int i=0; 715: my_conrec *cr_ptr = NULL; 716: for (i=0; i<CONREC_TAB_SIZE; i++) { 717: cr_ptr = & conrec_tab[i]; 718: if (cr_ptr->stat) { 719: my_conrec_close(cr_ptr, STAT_ABORTED); 720: } 721: } 722: apr_file_printf(out, "done.\n"); 723: }
KAKU PROJECT (2009) |