4854efda036b89b4a253a4d840fb6b663182e41c
[libipt_ACCOUNT] / iptaccount / iptaccount.c
1 /***************************************************************************
2  *   Copyright (C) 2004 by Intra2net AG                                    *
3  *   opensource@intra2net.com                                              *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU Lesser General Public License           *
7  *   version 2.1 as published by the Free Software Foundation;             *
8  *                                                                         *
9  ***************************************************************************/
10
11 #ifdef HAVE_CONFIG_H
12 #include <config.h>
13 #endif
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <getopt.h>
18 #include <signal.h>
19
20 #include <ipt_ACCOUNT_cl.h>
21
22 char exit_now = 0;
23 static void sig_term(int signr)
24 {
25     signal(SIGINT, SIG_IGN);
26     signal(SIGQUIT, SIG_IGN);
27     signal(SIGTERM, SIG_IGN);
28     
29     exit_now=1;
30 }
31
32 char *addr_to_dotted(unsigned int addr)
33 {
34     static char buf[17];
35     const unsigned char *bytep;
36
37     bytep = (const unsigned char *) &addr;
38     snprintf(buf, 16, "%u.%u.%u.%u", bytep[0], bytep[1], bytep[2], bytep[3]);
39     buf[16] = 0;
40     return buf;
41 }
42
43 void show_usage(void)
44 {
45     printf ("Unknown command line option. Try: [-u] [-h] [-a] [-f] [-l name]\n");
46     printf("[-u] show kernel handle usage\n");
47     printf("[-h] free all kernel handles (experts only!)\n");
48     printf("[-a] list all table names\n\n");
49     printf("[-l name] show table data\n");
50     printf("[-f] flush data after show\n");
51     printf("[-c] loop every second (abort with CTRL+C)\n");
52     printf("\n");
53 }
54
55 int main(int argc, char *argv[])
56 {
57     struct ipt_ACCOUNT_context ctx;
58     struct ipt_acc_handle_ip *entry;
59     int i;
60     char optchar, doHandleUsage=0, doHandleFree=0, doTableNames=0,
61                   doFlush=0, doContinue=0;
62                   
63     char *table_name = NULL;
64     
65     printf("\nipt_ACCOUNT userspace accounting tool v%s\n\n", VERSION);
66
67     if (argc == 1)
68     {
69         show_usage();
70         exit(0);
71     }
72         
73     while ((optchar = getopt (argc, argv, "uhacfl:")) != -1)
74     {
75         switch (optchar)
76         {
77             case 'u':
78                 doHandleUsage=1;
79                 break;
80             case 'h':
81                 doHandleFree=1;
82                 break;
83             case 'a':
84                 doTableNames=1;
85                 break;
86             case 'f':
87                 doFlush=1;
88                 break;
89             case 'c':
90                 doContinue=1;
91                 break;
92             case 'l':
93                 table_name = (char *)strdup(optarg);
94                 break;
95             case '?':
96             default:
97                 show_usage();
98                 exit (0);
99                 break;
100         }
101     }
102     
103     // install exit handler
104     if (signal(SIGTERM, sig_term) == SIG_ERR)
105     {
106         printf("can't install signal handler for SIGTERM\n");
107         exit (-1);
108     }
109     if (signal(SIGINT, sig_term) == SIG_ERR)
110     {
111         printf("can't install signal handler for SIGINT\n");
112         exit (-1);
113     }
114     if (signal(SIGQUIT, sig_term) == SIG_ERR)
115     {
116         printf("can't install signal handler for SIGQUIT\n");
117         exit (-1);
118     }
119     
120     
121     if(ipt_ACCOUNT_init(&ctx))
122     {
123         printf("Init failed: %s\n", ctx.error_str);
124         exit (-1);
125     }
126
127     // Get handle usage?
128     if (doHandleUsage)
129     {
130         int rtn = ipt_ACCOUNT_get_handle_usage(&ctx);
131         if (rtn < 0)
132         {
133             printf("get_handle_usage failed: %s\n", ctx.error_str);
134             exit (-1);
135         }
136         
137         printf("Current kernel handle usage: %d\n", ctx.handle.itemcount);
138     }
139     
140     if (doHandleFree)
141     {
142         int rtn = ipt_ACCOUNT_free_all_handles(&ctx);
143         if (rtn < 0)
144         {
145             printf("handle_free_all failed: %s\n", ctx.error_str);
146             exit (-1);
147         }
148         
149         printf("Freed all handles in kernel space\n");
150     }
151
152     if (doTableNames)
153     {
154         int rtn = ipt_ACCOUNT_get_table_names(&ctx);
155         if (rtn < 0)
156         {
157             printf("get_table_names failed: %s\n", ctx.error_str);
158             exit (-1);
159         }
160         const char *name;
161         while ((name = ipt_ACCOUNT_get_next_name(&ctx)) != 0)
162             printf("Found table: %s\n", name);
163     }
164         
165     if (table_name)
166     {
167         // Read out data
168         printf("Showing table: %s\n", table_name);
169         i = 0;
170         while (!exit_now)
171         {
172             // Get entries from table test
173             if (ipt_ACCOUNT_read_entries(&ctx, table_name, !doFlush))
174             {
175                 printf("Read failed: %s\n", ctx.error_str);
176                 ipt_ACCOUNT_deinit(&ctx);
177                 exit (-1);
178             }
179             
180             printf("Run #%d - %u %s found\n", i, ctx.handle.itemcount,
181                    ctx.handle.itemcount == 1 ? "item" : "items");
182             
183             // Output and free entries
184             while ((entry = ipt_ACCOUNT_get_next_entry(&ctx)) != NULL)
185             {
186                 printf("IP: %s SRC packets: %u bytes: %u DST packets: %u bytes: %u\n",
187                     addr_to_dotted(entry->ip), entry->src_packets, entry->src_bytes,
188                                    entry->dst_packets, entry->dst_bytes);
189             }
190             
191             if (doContinue)
192             {
193                 sleep(1);
194                 i++;
195             } else
196                 exit_now = 1;
197         }
198     }            
199         
200     printf("Finished.\n");
201     ipt_ACCOUNT_deinit(&ctx);
202     exit (0);
203 }