📄 flow-dscan.c
字号:
if (!(drp = malloc(sizeof (struct dscan_rec)))) fterr_err(1, "malloc(dscan_rec)"); ds.stat_malloc++; ds.stat_malloc_rec++; bzero(drp, sizeof (struct dscan_rec)); drp->ip_src = rec->srcaddr; drp->depth = 1; FT_SLIST_INSERT_HEAD(&ds.hash_scan[hash], drp, chain); FT_STAILQ_INIT(&drp->dlhead); if (!(ddp = malloc(sizeof (struct dscan_dst)))) fterr_err(1, "malloc(dscan_dst)"); bzero(ddp, sizeof (struct dscan_dst)); ds.stat_malloc++; ds.stat_malloc_dst++; FT_STAILQ_INSERT_TAIL(&drp->dlhead, ddp, chain); ddp->ip_dst = rec->dstaddr; ddp->ip_time = total_flows32; if (rec->dstport < 1024) { bit1024_store((int)rec->dstport, &ddp->portmap); } } /* * ager */ if (ds.ager_timeout && (!(total_flows % 1000))) ager(&ds, total_flows32);skip2: } /* while rec */ if (debug > 0) { ftprof_end(&ftp, ftio_get_rec_total(&ftio)); ftprof_print(&ftp, argv[0], stderr); } if (do_dump) dump_state(&ds); return 0; } /* main */int dump_state(struct dscan_state *ds){ FILE *FP; int i; char fmt_buf1[64]; struct dscan_rec *drp; struct dscan_dst *ddp; if (!(FP = fopen(ds->statefile, "w"))) { fterr_warnx("fopen(%s): failed"); return -1; } /* dump data structures */ for (i = 0; i < DSCAN_HASHSIZE; ++i) { FT_SLIST_FOREACH(drp, &ds->hash_scan[i], chain) { fmt_ipv4(fmt_buf1, drp->ip_src, FMT_JUST_LEFT); fprintf(FP, "H %d %d %d %s\n", i, (int)drp->depth, (int)drp->flags, fmt_buf1); FT_STAILQ_FOREACH(ddp, &drp->dlhead, chain) { fmt_ipv4(fmt_buf1, ddp->ip_dst, FMT_JUST_LEFT); fprintf(FP, "I %u %s\n", ddp->ip_time, fmt_buf1); bit1024_print(FP, &ddp->portmap); } } } fprintf(FP, ".\n"); if (fclose(FP)) { fterr_warnx("fclose(%s): failed", ds->statefile); return -1; } return 0;} /* dump_state */int load_state(struct dscan_state *ds){ FILE *FP; int done; struct dscan_rec *drp; struct dscan_dst *ddp; char type; char buf[1024]; u_int32 ip, hash, depth, flags, h, time, nports, i, j; if (!(FP = fopen(ds->statefile, "r"))) fterr_errx(1, "fopen(%s): failed", ds->statefile); done = 0; while (!done) { if (fscanf(FP, "%c", &type) == EOF) { fterr_warnx("fscanf(): EOF"); break; } switch (type) { case '.': done = 1; break; case 'H': /* host - hash depth flags srcIP */ fscanf(FP, "%u %u %u %64s", (unsigned*)&hash, (unsigned*)&depth, (unsigned*)&flags, buf); ip = scan_ip(buf); h = DSCAN_HASHFUNC(ip); /* create the record */ if (!(drp = malloc(sizeof (struct dscan_rec)))) fterr_err(1, "malloc(dscan_rec)"); ds->stat_malloc++; ds->stat_malloc_rec++; bzero(drp, sizeof (struct dscan_rec)); drp->ip_src = ip; drp->depth = depth; FT_SLIST_INSERT_HEAD(&ds->hash_scan[hash], drp, chain); /* init destination list */ FT_STAILQ_INIT(&drp->dlhead); break; case 'I': /* include - time dstIP */ fscanf(FP, "%u %15s", &time, buf); ip = scan_ip(buf); if (!(ddp = malloc(sizeof (struct dscan_dst)))) fterr_err(1, "malloc(dscan_dst)"); bzero(ddp, sizeof (struct dscan_dst)); ds->stat_malloc++; ds->stat_malloc_dst++; FT_STAILQ_INSERT_TAIL(&drp->dlhead, ddp, chain); ddp->ip_dst = ip; ddp->ip_time = time; break; case 'P': /* portmap - nports portlist */ fscanf(FP, "%u", &nports); for (i = 0; i < nports; ++i) { fscanf(FP, "%u", &j); if (j < 1024) { bit1024_store((int)j, &ddp->portmap); } } break; case '\n': /* ignore */ break; default: fterr_warnx("Unknown record type: %c", type); return -1; break; } /* switch */ } /* while */ fclose (FP); return 0;} /* load_state */void sig_usr1_handler(int sig){ sig_usr1 = 1;} /* sig_usr1_handler */void sig_hup_handler(int sig){ sig_hup = 1;} /* sig_usr1_handler */void ager(struct dscan_state *ds, u_int32 total_flows32){ static int ager_i; int i, work; struct dscan_rec *drp, *odrp, *drp2; struct dscan_dst *ddp, *oddp, *ddp2; u_int32 i32; work = 0; for (i = ager_i; i < DSCAN_HASHSIZE; ++i) { odrp = (void*)0L; drp = ds->hash_scan[i].slh_first; while (drp) { work += 2; oddp = (void*)0L; ddp = drp->dlhead.stqh_first; while (ddp) { ++work; if (ddp->ip_time > total_flows32) i32 = 4294967295U - ddp->ip_time + total_flows32 + 1; else i32 = total_flows32 - ddp->ip_time; if (i32 > ds->ager_timeout) { if (debug > 5) fterr_info( "ager: remove max=%u i32=%u", ds->ager_timeout, i32); --drp->depth; if (oddp) { oddp->chain.stqe_next = ddp->chain.stqe_next; if (!ddp->chain.stqe_next) /* tail update */ drp->dlhead.stqh_last = &oddp->chain.stqe_next; } else { drp->dlhead.stqh_first = ddp->chain.stqe_next; if (!ddp->chain.stqe_next) /* tail update */ drp->dlhead.stqh_last = &ddp->chain.stqe_next; } ddp2 = ddp; ddp = ddp->chain.stqe_next; free (ddp2); ++ds->stat_free; ++ds->stat_free_dst; ++ds->stat_aged_ip; continue; } oddp = ddp; ddp = ddp->chain.stqe_next; } /* while ddp */ /* if they're all gone, delete the record itself */ if (!drp->depth) { if (debug > 5) fterr_info("ager: remove record"); if (odrp) odrp->chain.sle_next = drp->chain.sle_next; else ds->hash_scan[i].slh_first = drp->chain.sle_next; drp2 = drp; drp = drp->chain.sle_next; free (drp2); ++ds->stat_free; ++ds->stat_free_rec; ++ds->stat_aged_dsr; continue; } odrp = drp; drp = drp->chain.sle_next; } /* while */ /* simple work queue */ if (++work > DSCAN_AGER_WORK) { if (debug > 2) { fterr_info("ager: work=%d malloc=%u free=%u aged_ip=%u aged_dsr=%u", work, ds->stat_malloc, ds->stat_free, ds->stat_aged_ip, ds->stat_aged_dsr); fterr_info("ager: malloc_dst=%u malloc_rec=%u free_dst=%u free_rec=%u", ds->stat_malloc_dst, ds->stat_malloc_rec, ds->stat_free_dst, ds->stat_free_rec); } ager_i = i++; goto skip3; } } /* for hash */ ager_i = 0; fterr_info("ager: reset hash run");skip3:} /* ager */int load_suppress(struct dscan_state *ds, int sd){ char buf1[1024], *c1, *c2, *c3, *c4, *c; struct dscan_sup *dsp; int match; FILE *FP; u_int32 prot, srcport, dstport; u_int32 ip, hash; char *fname; fterr_info("load_suppress %d", sd); if (!(fname = (char*)malloc(strlen(ds->supfile)+5))) fterr_err(1, "malloc()"); strcpy(fname, ds->supfile); if (sd == 0) { strcat(fname, ".src"); } else if (sd == 1) { strcat(fname, ".dst"); } if (!(FP = fopen(fname, "r"))) fterr_errx(1, "fopen(%s): failed", fname); while (1) { if (!fgets(buf1, 1024, FP)) break; /* skip whitespace */ for (c = buf1; *c && ((*c == ' ') || (*c == '\t')); ++c); c1 = c; if (*c1 == '#') continue; if (*c1 == '\n') continue; for (; *c && ((*c != ' ') && (*c != '\t')); ++c); for (; *c && ((*c == ' ') || (*c == '\t')); ++c); c2 = c; for (; *c && ((*c != ' ') && (*c != '\t')); ++c); for (; *c && ((*c == ' ') || (*c == '\t')); ++c); c3 = c; for (; *c && ((*c != ' ') && (*c != '\t')); ++c); for (; *c && ((*c == ' ') || (*c == '\t')); ++c); c4 = c; if ((!*c1) || (!*c2) || (!*c3) || (!*c4)) { fterr_warnx("suppress parser: syntax error: %s", buf1); continue; } if (debug > 5) fterr_info( "suppress parser: c1=%s c2=%s c3=%s c4=%s", c1, c2, c3, c4); ip = scan_ip(c1); sscanf(c2, "%u", &prot); sscanf(c3, "%u", &srcport); sscanf(c4, "%u", &dstport); hash = DSCAN_HASHFUNC(ip); if (sd == 0) { match = 0; FT_SLIST_FOREACH(dsp, &ds->hash_sup_src[hash], chain) { if (dsp->ip == ip) { match = 1; break; } } if (match) { fterr_warnx("suppress parser: dup ip: %s", buf1); continue; } if (*c1 == '-') { fterr_warnx("suppress parser: no src ip wildcard"); continue; } if (!(dsp = malloc(sizeof (struct dscan_sup)))) fterr_err(1, "malloc(dscan_sup)"); bzero(dsp, sizeof (struct dscan_sup)); dsp->ip = ip; dsp->srcport = srcport; dsp->dstport = dstport; dsp->protocol = prot; if (*c2 != '-') dsp->flags &= DSCAN_SUP_PROTOCOL; if (*c3 != '-') dsp->flags &= DSCAN_SUP_SRCPORT; if (*c4 != '-') dsp->flags &= DSCAN_SUP_DSTPORT; FT_SLIST_INSERT_HEAD(&ds->hash_sup_src[hash], dsp, chain); } else if (sd == 1) { match = 0; FT_SLIST_FOREACH(dsp, &ds->hash_sup_dst[hash], chain) { if (dsp->ip == ip) { match = 1; break; } } if (match) { fterr_warnx("suppress parser: dup ip: %s", buf1); continue; } if (*c1 == '-') { fterr_warnx("suppress parser: no src ip wildcard"); continue; } if (!(dsp = malloc(sizeof (struct dscan_sup)))) fterr_err(1, "malloc(dscan_sup)"); bzero(dsp, sizeof (struct dscan_sup)); dsp->ip = ip; dsp->srcport = srcport; dsp->dstport = dstport; dsp->protocol = prot; if (*c2 != '-') dsp->flags &= DSCAN_SUP_PROTOCOL; if (*c3 != '-') dsp->flags &= DSCAN_SUP_SRCPORT; if (*c4 != '-') dsp->flags &= DSCAN_SUP_DSTPORT; FT_SLIST_INSERT_HEAD(&ds->hash_sup_dst[hash], dsp, chain); } } /* while 1 */ fclose(FP); free (fname); return 0;} /* load_suppress */void clear_suppress(struct dscan_state *ds, int sd){ int i; struct dscan_sup *dsp_src, *dsp_dst; if (sd == 0) { for (i = 0; i < DSCAN_HASHSIZE; ++i) { while (ds->hash_sup_src[i].slh_first != NULL) { dsp_src = ds->hash_sup_src[i].slh_first; FT_SLIST_REMOVE_HEAD(&ds->hash_sup_src[i], chain); free (dsp_src); } /* while */ } /* for */ } /* if */ if (sd == 1) { for (i = 0; i < DSCAN_HASHSIZE; ++i) { while (ds->hash_sup_dst[i].slh_first != NULL) { dsp_dst = ds->hash_sup_dst[i].slh_first; FT_SLIST_REMOVE_HEAD(&ds->hash_sup_dst[i], chain); free (dsp_dst); } /* while */ } /* for */ } /* if */} /* clear_suppress */void flow_dump(struct fts3rec_gen *rec){ struct fttime ftt; char fmt_buf1[64], fmt_buf2[64]; struct tm *tm; static int header; if (!header) { fterr_info( "Start End Sif SrcIPaddress SrcP DIf DstIPaddress DstP P Fl Pkts Octets"); header = 1; } ftt = ftltime(rec->sysUpTime, rec->unix_secs, rec->unix_nsecs, rec->First); tm = localtime((time_t*)&ftt.secs); fterr_info( "%-2.2d%-2.2d.%-2.2d:%-2.2d:%-2.2d.%-3lu ", (int)tm->tm_mon+1, (int)tm->tm_mday, (int)tm->tm_hour, (int)tm->tm_min, (int)tm->tm_sec, (u_long)ftt.msecs); ftt = ftltime(rec->sysUpTime, rec->unix_secs, rec->unix_nsecs, rec->Last); tm = localtime((time_t*)&ftt.secs); fterr_info( "%-2.2d%-2.2d.%-2.2d:%-2.2d:%-2.2d.%-3lu ", (int)tm->tm_mon+1, (int)tm->tm_mday, (int)tm->tm_hour, (int)tm->tm_min, (int)tm->tm_sec, (u_long)ftt.msecs); /* other info */ fmt_ipv4(fmt_buf1, rec->srcaddr, FMT_PAD_RIGHT); fmt_ipv4(fmt_buf2, rec->dstaddr, FMT_PAD_RIGHT); fterr_info( "%4d %-15.15s %6d %4d %-15.15s %6d %3d %2d %10lu %10lu", (int)rec->input, fmt_buf1, (int)rec->srcport, (int)rec->output, fmt_buf2, (int)rec->dstport, (int)rec->prot, (int)rec->tcp_flags & 0x7, (u_long)rec->dPkts, (u_long)rec->dOctets);} /* flow_dump */void usage(void) { fprintf(stderr, "Usage: flow-dscan [-bBhlmpwW] [-d debug_level] [-D iplist_depth]\n"); fprintf(stderr, " [-s state_file] [-i input_filter] [-L suppress_list]\n"); fprintf(stderr, " [-o output_filter] [-O excessive_octets] [-P excessive_flows]\n"); fprintf(stderr, " [-S port_scan_trigger] [-t ager_timeout]\n"); fprintf(stderr, "Signals:\n"); fprintf(stderr, " SIGHUP - reload suppress list\n"); fprintf(stderr, " SIGUSR1 - dump state\n"); fprintf(stderr, "\n%s version %s: built by %s\n", PACKAGE, VERSION, FT_PROG_BUILD);} /* usage */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -