/* ctstat.c: A program for ip_conntrack monitoring * * Copyright 2001 by Robert Olsson * Uppsala University, Sweden * rtstat.c modified into ctstat.c by Martin Josefsson * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Additional credits: * Martin Josefsson 010828 bug fix * 030420 cleanup * 030818 more stats * 031018 fix columnordering * 040215 fix columnspacing * */ #include #include #include #define VERSION "0.37-ct 040215" extern char *optarg; extern int optind, opterr, optopt; FILE *fp; unsigned ct_size, searched[2], found[2], new[2], invalid[2], ignore[2], delete[2], delete_list[2], insert[2], insert_failed[2], drop[2], early_drop[2], icmp_error[2], expect_new[2], expect_create[2], expect_delete[2]; /* Read (and summarize for SMP) the different stats vars. */ void scan_line(int i) { unsigned temp[15]; i %= 2; searched[i] = 0; found[i] = 0; new[i] = 0; invalid[i] = 0; ignore[i] = 0; delete[i] = 0; delete_list[i] = 0; insert[i] = 0; insert_failed[i] = 0; drop[i] = 0; early_drop[i] = 0; icmp_error[i] = 0; expect_new[i] = 0; expect_create[i] = 0; expect_delete[i] = 0; while(!feof(fp)) { fscanf(fp, "%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n", &ct_size, &temp[0], /* searched */ &temp[1], /* found */ &temp[2], /* new */ &temp[3], /* invalid */ &temp[4], /* ignore */ &temp[5], /* delete */ &temp[6], /* delete_list */ &temp[7], /* insert */ &temp[8], /* insert_failed */ &temp[9], /* drop */ &temp[10], /* early_drop */ &temp[11], /* icmp_error */ &temp[12], /* expect_new */ &temp[13], /* expect_create */ &temp[14] /* expect_delete */ ); searched[i] += temp[0]; found[i] += temp[1]; new[i] += temp[2]; invalid[i] += temp[3]; ignore[i] += temp[4]; delete[i] += temp[5]; delete_list[i] += temp[6]; insert[i] += temp[7]; insert_failed[i] += temp[8]; drop[i] += temp[9]; early_drop[i] += temp[10]; icmp_error[i] += temp[11]; expect_new[i] += temp[12]; expect_create[i] += temp[13]; expect_delete[i] += temp[14]; } } void print_hdr_line(void) { printf(" size search found new ins del del_l ign inv insf drop edrop ie en ec ed\n"); } int usage(int exit_code) { fprintf(stderr, "ctstat Version %s\n", VERSION); fprintf(stderr, " -help\n"); fprintf(stderr, " -i interval\n"); fprintf(stderr, " -s subject [0-2]\n"); fprintf(stderr, "\n"); print_hdr_line(); fprintf(stderr, "\n"); fprintf(stderr, "size == ip_conntrack size\n"); fprintf(stderr, "search == searched non-matching conntrack entries per sec\n"); fprintf(stderr, "found == found conntrack entries per sec\n"); fprintf(stderr, "new == newly allocated entries per sec\n"); fprintf(stderr, "ins == inserts into hashtable per sec\n"); fprintf(stderr, "del == destroys per sec\n"); fprintf(stderr, "del_l == deletions from hashtable per sec\n"); fprintf(stderr, "ign == ignored packets per sec\n"); fprintf(stderr, "inv == invalid packets per sec\n"); fprintf(stderr, "insf == failed inserts into hashtable per sec\n"); fprintf(stderr, "drop == dropped packets per sec\n"); fprintf(stderr, "edrop == early_dropped packets per sec\n"); fprintf(stderr, "ie == icmp errors per sec\n"); fprintf(stderr, "en == expectations used per sec\n"); fprintf(stderr, "ec == expectations created per sec\n"); fprintf(stderr, "ed == expectations deleted per sec\n"); exit(exit_code); } void print(int i, int interval) { int val_new = i % 2; int val_old = !val_new; printf("%6u %7u %7u %5u %5u %5u %7u %5u %5u %6u %7u %6u %4u %5u %5u %5u\n", ct_size, (searched[val_new] - searched[val_old])/interval, (found[val_new] - found[val_old])/interval, (new[val_new] - new[val_old])/interval, (insert[val_new] - insert[val_old])/interval, (delete[val_new] - delete[val_old])/interval, (delete_list[val_new] - delete_list[val_old])/interval, (ignore[val_new] - ignore[val_old])/interval, (invalid[val_new] - invalid[val_old])/interval, (insert_failed[val_new] - insert_failed[val_old])/interval, (drop[val_new] - drop[val_old])/interval, (early_drop[val_new] - early_drop[val_old])/interval, (icmp_error[val_new] - icmp_error[val_old])/interval, (expect_new[val_new] - expect_new[val_old])/interval, (expect_create[val_new] - expect_create[val_old])/interval, (expect_delete[val_new] - expect_delete[val_old])/interval); } int main(int argc, char **argv) { int c, i, interval = 2, hdr = 2; while ((c=getopt(argc, argv,"h?s:i:")) != EOF) { switch (c) { case '?': case 'h': usage(0); break; case 'i': sscanf(optarg, "%u", &interval); break; case 's': sscanf(optarg, "%u", &hdr); break; default: usage(1); } } if (interval < 1) interval = 1; fp = fopen("/proc/net/ip_conntrack_stat", "r"); if (!fp) { perror("fopen"); exit(-1); } if (hdr > 0) print_hdr_line(); for(i = 0;;i++) { if(hdr > 1 && i != 0 && (i % 20) == 0) print_hdr_line(); scan_line(i); rewind(fp); if (i != 0) print(i, interval); sleep(interval); } return 1; } /* * Compile: gcc -g -O2 -Wall -o ctstat ctstat.c */