Include limits.h in ipt_ACCOUNT_cl.c to work around compilation problems reported...
[libipt_ACCOUNT] / iptaccount / iptaccount.c
1 /***************************************************************************
2  *   Copyright (C) 2004-2006 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] [-c] [-s] [-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("[-s] CSV output (for spreadsheet import)\n");
53     printf("\n");
54 }
55
56 int main(int argc, char *argv[])
57 {
58     struct ipt_ACCOUNT_context ctx;
59     struct ipt_acc_handle_ip *entry;
60     int i;
61     char optchar, doHandleUsage=0, doHandleFree=0, doTableNames=0,
62                   doFlush=0, doContinue=0, doCSV=0;
63
64     char *table_name = NULL;
65     const char *name;
66
67     printf("\nipt_ACCOUNT userspace accounting tool v%s\n\n", VERSION);
68
69     if (argc == 1)
70     {
71         show_usage();
72         exit(0);
73     }
74         
75     while ((optchar = getopt (argc, argv, "uhacfsl:")) != -1)
76     {
77         switch (optchar)
78         {
79             case 'u':
80                 doHandleUsage=1;
81                 break;
82             case 'h':
83                 doHandleFree=1;
84                 break;
85             case 'a':
86                 doTableNames=1;
87                 break;
88             case 'f':
89                 doFlush=1;
90                 break;
91             case 'c':
92                 doContinue=1;
93                 break;
94             case 's':
95                 doCSV=1;
96                 break;
97             case 'l':
98                 table_name = (char *)strdup(optarg);
99                 break;
100             case '?':
101             default:
102                 show_usage();
103                 exit (0);
104                 break;
105         }
106     }
107
108     // install exit handler
109     if (signal(SIGTERM, sig_term) == SIG_ERR)
110     {
111         printf("can't install signal handler for SIGTERM\n");
112         exit (-1);
113     }
114     if (signal(SIGINT, sig_term) == SIG_ERR)
115     {
116         printf("can't install signal handler for SIGINT\n");
117         exit (-1);
118     }
119     if (signal(SIGQUIT, sig_term) == SIG_ERR)
120     {
121         printf("can't install signal handler for SIGQUIT\n");
122         exit (-1);
123     }
124
125     if(ipt_ACCOUNT_init(&ctx))
126     {
127         printf("Init failed: %s\n", ctx.error_str);
128         exit (-1);
129     }
130
131     // Get handle usage?
132     if (doHandleUsage)
133     {
134         int rtn = ipt_ACCOUNT_get_handle_usage(&ctx);
135         if (rtn < 0)
136         {
137             printf("get_handle_usage failed: %s\n", ctx.error_str);
138             exit (-1);
139         }
140
141         printf("Current kernel handle usage: %d\n", ctx.handle.itemcount);
142     }
143
144     if (doHandleFree)
145     {
146         int rtn = ipt_ACCOUNT_free_all_handles(&ctx);
147         if (rtn < 0)
148         {
149             printf("handle_free_all failed: %s\n", ctx.error_str);
150             exit (-1);
151         }
152
153         printf("Freed all handles in kernel space\n");
154     }
155
156     if (doTableNames)
157     {
158         int rtn = ipt_ACCOUNT_get_table_names(&ctx);
159         if (rtn < 0)
160         {
161             printf("get_table_names failed: %s\n", ctx.error_str);
162             exit (-1);
163         }
164         while ((name = ipt_ACCOUNT_get_next_name(&ctx)) != 0)
165             printf("Found table: %s\n", name);
166     }
167
168     if (table_name)
169     {
170         // Read out data
171         if (doCSV)
172             printf("IP;SRC packets;SRC bytes;DST packets;DST bytes\n");
173         else
174             printf("Showing table: %s\n", table_name);
175
176         i = 0;
177         while (!exit_now)
178         {
179             // Get entries from table test
180             if (ipt_ACCOUNT_read_entries(&ctx, table_name, !doFlush))
181             {
182                 printf("Read failed: %s\n", ctx.error_str);
183                 ipt_ACCOUNT_deinit(&ctx);
184                 exit (-1);
185             }
186
187             if (!doCSV)
188                 printf("Run #%d - %u %s found\n", i, ctx.handle.itemcount,
189                        ctx.handle.itemcount == 1 ? "item" : "items");
190
191             // Output and free entries
192             while ((entry = ipt_ACCOUNT_get_next_entry(&ctx)) != NULL)
193             {
194                 if (doCSV)
195                     printf("%s;%u;%u;%u;%u\n",
196                         addr_to_dotted(entry->ip), entry->src_packets, entry->src_bytes,
197                                     entry->dst_packets, entry->dst_bytes);
198                 else
199                     printf("IP: %s SRC packets: %u bytes: %u DST packets: %u bytes: %u\n",
200                         addr_to_dotted(entry->ip), entry->src_packets, entry->src_bytes,
201                                     entry->dst_packets, entry->dst_bytes);
202             }
203
204             if (doContinue)
205             {
206                 sleep(1);
207                 i++;
208             } else
209                 exit_now = 1;
210         }
211     }
212
213     printf("Finished.\n");
214     ipt_ACCOUNT_deinit(&ctx);
215     exit (0);
216 }