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) |