#include #include #include #include #include #include #include static int fd = -1; static int op; static int hash_size = 1; static int mem_limit = 16; static void usage(char *msg) { if (msg) fprintf(stderr, "ERROR: %s\n", msg); fprintf(stderr,"Usage: ipacc [-LFsm]\n"); exit(1); } static void error(int err,char *msg) { fprintf(stderr," %s %s\n",msg,strerror(err)); exit(1); } inline void dotted(__u32 addr) { unsigned char *c = (unsigned char *) &addr; printf("%d.%d.%d.%d ",c[0],c[1],c[2],c[3]); } static void printblock(struct ip_acc_get_block *blk) { int i; struct acc_entry *e; for(i=0;ibl[i]; if(e->count == 0) break; dotted(e->src); printf("%d ",e->sprt); dotted(e->dst); printf("%d ",e->dprt); printf("%d ",e->proto); printf("%d ",e->hooknum); printf("%d %llu\n",e->mark,e->count); } } static void do_list() { int i; struct ip_acc_get_info info; struct ip_acc_get_block req; int info_len=sizeof(info); int req_len=sizeof(req); if (0 > getsockopt(fd, SOL_IP, SO_IP_ACC_INFO, &info, &info_len)) error(errno," failed: "); printf("# %lu\t%lu\t%llu\t%d\n",info.time_on.tv_sec, info.time_off.tv_sec,info.lost,info.blocks); printf("## %s",ctime(&info.time_on.tv_sec)); printf("## %s",ctime(&info.time_off.tv_sec)); for(i=0;i < info.blocks; i++ ) { req.block=i; if (0 > getsockopt(fd, SOL_IP, SO_IP_ACC_BLOCK, &req, &req_len)) error(errno," failed:"); printblock(&req); } printf("\n"); } static void do_flush() { struct ip_acc_set_rq req; int reqlen = sizeof(req); req.op = op & ( IP_ACC_SET_FLUSH | IP_ACC_SET_HASH | IP_ACC_SET_LIMIT ); req.hash_size = hash_size; req.mem_limit = mem_limit; if (0 > setsockopt(fd, SOL_IP, SO_IP_ACC, &req, sizeof(req)) ) error(errno," failed:"); } int main(int argc, char **argv) { int opt; fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) error(errno,"cannot get DGRAM socket:"); op = IP_ACC_SET_NONE; while (EOF != (opt=getopt( argc, argv, "hLFs:m:"))) switch(opt) { case 'F': op |= IP_ACC_SET_FLUSH; break; case 'L': op |= IP_ACC_GET_LIST; break; case 's': op |= IP_ACC_SET_HASH; hash_size=atoi(optarg); switch(hash_size) { case 1: case 4: case 16: break; default: usage("hash size should be 1,4 or 16 blocks"); } break; case 'm': op |= IP_ACC_SET_LIMIT; mem_limit=atoi(optarg); if( mem_limit < 16 || mem_limit > 1024 ) usage("memory limit only from 16 to 1024 allowed"); break; case 'h': usage(0); default: usage("bad option"); } if (op == IP_ACC_SET_NONE) usage("no operation specified"); if (op & IP_ACC_SET_FLUSH) do_flush(); if (op & IP_ACC_GET_LIST) do_list(); return 0; }