Fix libsniffdet's pkg-config (add libnet cflags)
[sniffdet.git] / doc / libsniffdet-usage-example.c
1 /*
2  *  libsniffdet usage example
3  *  Copyright (c) 2002-2003
4  *      Ademar de Souza Reis Jr. <myself@ademar.org>
5  *
6  *  This program is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU General Public License
8  *  as published by the Free Software Foundation; version 2 dated
9  *  June, 1991.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14  *  See file COPYING for details.
15  *
16  * $Id: libsniffdet-usage-example.c,v 1.1 2003/07/04 04:21:11 ademar Exp $
17  */
18
19 /* compile with:
20  * gcc libsniffdet-usage-example.c -o example `libnet-config \
21  *     --defines --libs` -lsniffdet -lpcap -lpthread -g
22  */
23
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <signal.h>
27 #include <libsniffdet.h>
28
29 static int cancel_test_flag;
30
31
32 static int tests_msg_callback(struct test_status *status, 
33                 const int msg_type, char *msg);
34 void sighandler(void);
35 int print_test_result(char *target, struct test_info *info);
36
37 int main(int argc, char **argv)
38 {
39         char *iface;
40         char *target;
41         struct test_info t_info;
42         struct sndet_device *device;
43         char errbuf[LIBSNIFFDET_ERR_BUF_LEN];
44         int status;
45
46         /* blah... use a better scan_args(), this is just an example! :) */
47         if (argc != 3) {
48                 fprintf(stderr, "Usage: %s <interface> <host>\n", argv[0]);
49                 exit(1);
50         }
51         iface = argv[1]; /* something like eth0 */
52         target = argv[2]; /* something like "localhost.localdomain" or "192.168.1.1" */
53
54         if ((device = sndet_init_device(iface, 1, errbuf)) == NULL) {
55                 fprintf(stderr, "Error initializing interface %s\n", iface);
56                 exit(1);
57         }
58
59         if (!sndet_resolve(target)) {
60                 fprintf(stderr, "Cannot resolve target hostname \"%s\"\n", target);
61                 exit(1);
62         }
63
64         /* Could be any signal... SIGINT is just an example! */
65         signal(SIGINT, (void *) sighandler);
66
67         /* now we start calling the tests...
68          *
69          * Notice that we call them in sequence using the same t_info structure,
70          * the same print_* function and the same error treatment. Of course
71          * this can be improved, but it's just an example :)
72          */
73
74         /* ICMP TEST */
75         /* most of the arguments have default values, so use '0' or 'NULL' */
76         status = sndet_icmptest(target,
77                         device,
78                         20,  // timeout (secs) -- mandatory (0 means 'until interrupted')
79                         0,  // tries -- optional
80                         0, // interval (msecs) -- optional
81                         tests_msg_callback,
82                         &t_info,
83                         NULL); // fake mac address -- optional
84
85         if (status == 0)
86                 print_test_result(target, &t_info);
87         else
88                 fprintf(stderr, "Error running ICMP test\n");
89
90         cancel_test_flag = 0;
91
92         /* ARP TEST */
93         /* most of the arguments have default values, so use '0' or 'NULL' */
94         status = sndet_arptest(target,
95                         device,
96                         20,  // timeout (secs) -- mandatory (0 means 'until interrupted')
97                         0,  // tries
98                         0, // interval (msecs)
99                         tests_msg_callback,
100                         &t_info,
101                         NULL); // fake mac address
102
103         if (status == 0)
104                 print_test_result(target, &t_info);
105         else
106                 fprintf(stderr, "Error running ARP test\n");
107
108         cancel_test_flag = 0;
109
110         /* DNS TEST */
111         status = sndet_dnstest(target,
112                         device,
113                         20,  // timeout (secs) -- mandatory (0 means 'until interrupted')
114                         0,  // tries
115                         0, // interval (msecs)
116                         tests_msg_callback,
117                         &t_info,
118                         // optional data (packet data)
119                         NULL, // fake ip
120                         NULL, // fake mac
121                         0, // destination port
122                         0, // source port
123                         NULL, // payload
124                         0); // payload len
125
126         if (status == 0)
127                 print_test_result(target, &t_info);
128         else
129                 fprintf(stderr, "Error running DNS test\n");
130
131         cancel_test_flag = 0;
132
133         /* LATENCY Test */
134         status = sndet_latencytest_pktflood(target,
135                         device,
136                         300,  // timeout (secs) -- mandatory (0 means 'until interrupted')
137                         0, // interval between measures (msec)
138                         tests_msg_callback,
139                         &t_info,
140                         NULL); // bogus_pkt
141
142         if (status == 0)
143                 print_test_result(target, &t_info);
144         else
145                 fprintf(stderr, "Error running Latency test\n");
146
147         if (sndet_finish_device(device, errbuf))
148                 fprintf(stderr, "Error: %s", errbuf);
149
150         exit(0);
151 }
152
153 static int tests_msg_callback(struct test_status *status, 
154                 const int msg_type, char *msg)
155 {
156         switch (msg_type) {
157                 case RUNNING:
158                         break;
159                 case NOTIFICATION:
160                         if (msg != NULL)
161                                 printf("Notification: %s\n", msg);
162                         break;
163                 case ERROR:
164                         if (msg != NULL)
165                                 fprintf(stderr, "Error: %s\n", msg);
166                         break;
167                 case WARNING:
168                         if (msg != NULL)
169                                 fprintf(stderr, "Warning: %s\n", msg);
170                         break;
171                 case DETECTION:
172                         break;
173                 case ENDING:
174                         break;
175         }
176
177         /* could be a progressbar */
178         printf("Percentage: %d%%\n", status->percent);
179         printf("Bytes Sent: %d\n", status->bytes_sent);
180         printf("Bytes Recvd: %d\n", status->bytes_recvd);
181
182         if (cancel_test_flag) {
183                 printf("Canceling test\n");
184                 return 1;
185         }
186         else
187                 return 0;
188 }
189
190 /* Signal handler to
191  * set the flag "cancel_test_flag" to 1
192  */
193 void sighandler(void)
194 {
195         cancel_test_flag = 1;
196 }
197
198 /* 
199  * TEXT INTERFACE 
200  * 
201  * Based on the stdout plugin from sniffdet 0.8
202  *
203  */
204
205 static int print_icmptest_results(struct test_info *info);
206 static int print_arptest_results(struct test_info *info);
207 static int print_dnstest_results(struct test_info *info);
208 static int print_latencytest_results(struct test_info *info);
209 static char *timeString(time_t t);
210
211 // pointers to print result functions
212 static int (*print_test_result_table[MAX_TESTS + 1]) (
213                 struct test_info *info) = {
214                         print_icmptest_results,
215                         print_arptest_results,
216                         print_dnstest_results,
217                         print_latencytest_results,
218                         NULL };
219
220 int print_test_result(char *target, struct test_info *info)
221 {
222         int result;
223
224         printf("\n");
225         printf("------------------------------------------------------------\n");
226         printf("Test: %s\n", info->test_name);
227         printf("      %s\n", info->test_short_desc);
228         printf("------------------------------------------------------------\n");
229         printf("Validation: %s\n", info->valid ? "OK" : "INVALID");
230         printf("Started on: %s\n", timeString(info->time_start));
231         printf("Finished on: %s\n", timeString(info->time_fini)); 
232         printf("Bytes Sent: %d\n", info->b_sent);
233         printf("Bytes Received: %d\n", info->b_recvd);
234         printf("Packets Sent: %d\n", info->pkts_sent);
235         printf("Packets Received: %d\n", info->pkts_recvd);
236         printf("------------------------------------------------------------\n");
237         result = print_test_result_table[info->code](info);
238         printf("------------------------------------------------------------\n");
239         printf("\n");
240
241         return result;
242 }
243
244
245 static int print_icmptest_results(struct test_info *info)
246 {
247         printf("RESULT: %s\n",
248                         info->test.icmp.positive ? "POSITIVE" : "NEGATIVE");
249         return info->test.icmp.positive;
250 }
251
252 static int print_arptest_results(struct test_info *info)
253 {
254         printf("RESULT: %s\n",
255                         info->test.arp.positive ? "POSITIVE" : "NEGATIVE");
256         return info->test.icmp.positive;
257 }
258
259 static int print_dnstest_results(struct test_info *info)
260 {
261         printf("RESULT: %s\n",
262                         info->test.dns.positive ? "POSITIVE" : "NEGATIVE");
263         return info->test.icmp.positive;
264 }
265
266 static int print_latencytest_results(struct test_info *info)
267 {
268         printf("RESULT:\n");
269         printf("Normal time: %u.%u\n",
270                         info->test.latency.normal_time / 10,
271                         info->test.latency.normal_time % 10);
272         printf("Flood round-trip min/avg/max: %u.%u/%u.%u/%u.%u ms\n",
273                                 info->test.latency.min_time / 10,
274                                 info->test.latency.min_time % 10,
275                                 info->test.latency.mean_time / 10,
276                                 info->test.latency.mean_time % 10,
277                                 info->test.latency.max_time / 10,
278                                 info->test.latency.max_time % 10
279                                 );
280
281         // this function is non-deterministic
282         return 0;
283 }
284
285
286 /* 
287  * timeString()
288  * converts a time to a particular representation:
289  * "The preferred date and time representation for the current locale"
290  */
291 static char *timeString(time_t t)
292 {
293         static char buffer[64];
294         static char timestr[64]; 
295     struct tm *local;
296
297     local = localtime(&t);
298     strftime(buffer, 64, "%c", local);
299
300         strncpy(timestr, buffer, 64);
301
302     return timestr;
303 }

(C) 2002-2009 Ademar de Souza Reis Jr.
http://www.ademar.org/
http://blog.ademar.org/