Fix some incorrect code (found by valgrind).
[obnox/wireshark/wip.git] / capture.c
1 /* capture.c
2  * Routines for packet capture
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #ifdef HAVE_LIBPCAP
30
31 #ifdef HAVE_UNISTD_H
32 #include <unistd.h>
33 #endif
34
35 #include <stdlib.h>
36 #include <string.h>
37 #include <ctype.h>
38
39 #ifdef HAVE_FCNTL_H
40 #include <fcntl.h>
41 #endif
42
43 #ifdef HAVE_SYS_TYPES_H
44 #include <sys/types.h>
45 #endif
46
47 #ifdef HAVE_NETINET_IN_H
48 #include <netinet/in.h>
49 #endif
50
51 #ifdef HAVE_NETDB_H
52 #include <netdb.h>
53 #endif
54
55 #ifdef HAVE_ARPA_INET_H
56 #include <arpa/inet.h>
57 #endif
58
59 #ifdef HAVE_SYS_SOCKET_H
60 #include <sys/socket.h>         /* needed to define AF_ values on UNIX */
61 #endif
62
63 #ifdef HAVE_WINSOCK2_H
64 #include <winsock2.h>           /* needed to define AF_ values on Windows */
65 #endif
66
67 #ifdef NEED_INET_V6DEFS_H
68 # include "inet_v6defs.h"
69 #endif
70
71 #include <signal.h>
72 #include <errno.h>
73
74 #include <glib.h>
75
76 #include <epan/packet.h>
77 #include <epan/dfilter/dfilter.h>
78 #include "file.h"
79 #include "capture.h"
80 #include "capture_sync.h"
81 #include "capture_info.h"
82 #include "capture_ui_utils.h"
83 #include "util.h"
84 #include "capture-pcap-util.h"
85 #include "alert_box.h"
86 #include "simple_dialog.h"
87 #include <epan/prefs.h>
88
89 #ifdef _WIN32
90 #include "capture-wpcap.h"
91 #endif
92 #include "ui_util.h"
93 #include "wsutil/file_util.h"
94 #include "log.h"
95
96 typedef struct if_stat_cache_item_s {
97     char *name;
98     struct pcap_stat ps;
99 } if_stat_cache_item_t;
100
101 struct if_stat_cache_s {
102     int stat_fd;
103     int fork_child;
104     GList *cache_list;  /* List of if_stat_chache_entry_t */
105 };
106
107 /* this callback mechanism should possibly be replaced by the g_signal_...() stuff (if I only would know how :-) */
108 typedef struct {
109     capture_callback_t cb_fct;
110     gpointer user_data;
111 } capture_callback_data_t;
112
113 static GList *capture_callbacks = NULL;
114
115 static void
116 capture_callback_invoke(int event, capture_options *capture_opts)
117 {
118     capture_callback_data_t *cb;
119     GList *cb_item = capture_callbacks;
120
121     /* there should be at least one interested */
122     g_assert(cb_item != NULL);
123
124     while(cb_item != NULL) {
125         cb = cb_item->data;
126         cb->cb_fct(event, capture_opts, cb->user_data);
127         cb_item = g_list_next(cb_item);
128     }
129 }
130
131
132 void
133 capture_callback_add(capture_callback_t func, gpointer user_data)
134 {
135     capture_callback_data_t *cb;
136
137     cb = g_malloc(sizeof(capture_callback_data_t));
138     cb->cb_fct = func;
139     cb->user_data = user_data;
140
141     capture_callbacks = g_list_append(capture_callbacks, cb);
142 }
143
144 void
145 capture_callback_remove(capture_callback_t func)
146 {
147     capture_callback_data_t *cb;
148     GList *cb_item = capture_callbacks;
149
150     while(cb_item != NULL) {
151         cb = cb_item->data;
152         if(cb->cb_fct == func) {
153             capture_callbacks = g_list_remove(capture_callbacks, cb);
154             g_free(cb);
155             return;
156         }
157         cb_item = g_list_next(cb_item);
158     }
159
160     g_assert_not_reached();
161 }
162
163 /**
164  * Start a capture.
165  *
166  * @return TRUE if the capture starts successfully, FALSE otherwise.
167  */
168 gboolean
169 capture_start(capture_options *capture_opts)
170 {
171   gboolean ret;
172
173
174   /* close the currently loaded capture file */
175   cf_close(capture_opts->cf);
176
177   g_assert(capture_opts->state == CAPTURE_STOPPED);
178   capture_opts->state = CAPTURE_PREPARING;
179
180   g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Start ...");
181
182   /* try to start the capture child process */
183   ret = sync_pipe_start(capture_opts);
184   if(!ret) {
185       if(capture_opts->save_file != NULL) {
186           g_free(capture_opts->save_file);
187           capture_opts->save_file = NULL;
188       }
189
190       g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Start failed!");
191       capture_opts->state = CAPTURE_STOPPED;
192   } else {
193       /* the capture child might not respond shortly after bringing it up */
194       /* (especially it will block, if no input coming from an input capture pipe (e.g. mkfifo) is coming in) */
195
196       /* to prevent problems, bring the main GUI into "capture mode" right after successfully */
197       /* spawn/exec the capture child, without waiting for any response from it */
198       capture_callback_invoke(capture_cb_capture_prepared, capture_opts);
199
200       if(capture_opts->show_info)
201         capture_info_open(capture_opts);
202   }
203
204   return ret;
205 }
206
207
208 void
209 capture_stop(capture_options *capture_opts)
210 {
211   g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Stop ...");
212
213   capture_callback_invoke(capture_cb_capture_stopping, capture_opts);
214
215   /* stop the capture child gracefully */
216   sync_pipe_stop(capture_opts);
217 }
218
219
220 void
221 capture_restart(capture_options *capture_opts)
222 {
223     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Restart");
224
225     capture_opts->restart = TRUE;
226     capture_stop(capture_opts);
227 }
228
229
230 void
231 capture_kill_child(capture_options *capture_opts)
232 {
233   g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "Capture Kill");
234
235   /* kill the capture child */
236   sync_pipe_kill(capture_opts->fork_child);
237 }
238
239
240
241 /* We've succeeded a (non real-time) capture, try to read it into a new capture file */
242 static gboolean
243 capture_input_read_all(capture_options *capture_opts, gboolean is_tempfile, gboolean drops_known,
244 guint32 drops)
245 {
246   int err;
247
248
249   /* Capture succeeded; attempt to open the capture file. */
250   if (cf_open(capture_opts->cf, capture_opts->save_file, is_tempfile, &err) != CF_OK) {
251     /* We're not doing a capture any more, so we don't have a save
252        file. */
253     return FALSE;
254   }
255
256   /* Set the read filter to NULL. */
257   /* XXX - this is odd here, try to put it somewhere, where it fits better */
258   cf_set_rfcode(capture_opts->cf, NULL);
259
260   /* Get the packet-drop statistics.
261
262      XXX - there are currently no packet-drop statistics stored
263      in libpcap captures, and that's what we're reading.
264
265      At some point, we will add support in Wiretap to return
266      packet-drop statistics for capture file formats that store it,
267      and will make "cf_read()" get those statistics from Wiretap.
268      We clear the statistics (marking them as "not known") in
269      "cf_open()", and "cf_read()" will only fetch them and mark
270      them as known if Wiretap supplies them, so if we get the
271      statistics now, after calling "cf_open()" but before calling
272      "cf_read()", the values we store will be used by "cf_read()".
273
274      If a future libpcap capture file format stores the statistics,
275      we'll put them into the capture file that we write, and will
276      thus not have to set them here - "cf_read()" will get them from
277      the file and use them. */
278   if (drops_known) {
279     cf_set_drops_known(capture_opts->cf, TRUE);
280
281     /* XXX - on some systems, libpcap doesn't bother filling in
282        "ps_ifdrop" - it doesn't even set it to zero - so we don't
283        bother looking at it.
284
285        Ideally, libpcap would have an interface that gave us
286        several statistics - perhaps including various interface
287        error statistics - and would tell us which of them it
288        supplies, allowing us to display only the ones it does. */
289     cf_set_drops(capture_opts->cf, drops);
290   }
291
292   /* read in the packet data */
293   switch (cf_read(capture_opts->cf)) {
294
295   case CF_READ_OK:
296   case CF_READ_ERROR:
297     /* Just because we got an error, that doesn't mean we were unable
298        to read any of the file; we handle what we could get from the
299        file. */
300     break;
301
302   case CF_READ_ABORTED:
303     /* User wants to quit program. Exit by leaving the main loop,
304        so that any quit functions we registered get called. */
305     main_window_nested_quit();
306     return FALSE;
307   }
308
309   /* if we didn't captured even a single packet, close the file again */
310   if(cf_get_packet_count(capture_opts->cf) == 0 && !capture_opts->restart) {
311     simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
312 "%sNo packets captured!%s\n"
313 "\n"
314 "As no data was captured, closing the %scapture file!\n"
315 "\n"
316 "\n"
317 "Help about capturing can be found at:\n"
318 "\n"
319 "       http://wiki.wireshark.org/CaptureSetup"
320 #ifdef _WIN32
321 "\n\n"
322 "Wireless (Wi-Fi/WLAN):\n"
323 "Try to switch off promiscuous mode in the Capture Options!"
324 #endif
325 "",
326     simple_dialog_primary_start(), simple_dialog_primary_end(),
327     (cf_is_tempfile(capture_opts->cf)) ? "temporary " : "");
328     cf_close(capture_opts->cf);
329   }
330   return TRUE;
331 }
332
333
334 /* capture child tells us we have a new (or the first) capture file */
335 gboolean
336 capture_input_new_file(capture_options *capture_opts, gchar *new_file)
337 {
338   gboolean is_tempfile;
339   int  err;
340
341
342   if(capture_opts->state == CAPTURE_PREPARING) {
343     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture started!");
344   }
345   g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "File: \"%s\"", new_file);
346
347   g_assert(capture_opts->state == CAPTURE_PREPARING || capture_opts->state == CAPTURE_RUNNING);
348
349   /* free the old filename */
350   if(capture_opts->save_file != NULL) {
351     /* we start a new capture file, close the old one (if we had one before) */
352     /* (we can only have an open capture file in real_time_mode!) */
353     if( ((capture_file *) capture_opts->cf)->state != FILE_CLOSED) {
354         capture_callback_invoke(capture_cb_capture_update_finished, capture_opts);
355         cf_finish_tail(capture_opts->cf, &err);
356         cf_close(capture_opts->cf);
357     }
358     g_free(capture_opts->save_file);
359     is_tempfile = FALSE;
360     cf_set_tempfile(capture_opts->cf, FALSE);
361   } else {
362     /* we didn't had a save_file before, must be a tempfile */
363     is_tempfile = TRUE;
364     cf_set_tempfile(capture_opts->cf, TRUE);
365   }
366
367   /* save the new filename */
368   capture_opts->save_file = g_strdup(new_file);
369
370   /* if we are in real-time mode, open the new file now */
371   if(capture_opts->real_time_mode) {
372     /* Attempt to open the capture file and set up to read from it. */
373     switch(cf_start_tail(capture_opts->cf, capture_opts->save_file, is_tempfile, &err)) {
374     case CF_OK:
375       break;
376     case CF_ERROR:
377       /* Don't unlink (delete) the save file - leave it around,
378          for debugging purposes. */
379       g_free(capture_opts->save_file);
380       capture_opts->save_file = NULL;
381       return FALSE;
382     }
383   }
384
385   if(capture_opts->show_info) {
386     if (!capture_info_new_file(new_file))
387       return FALSE;
388   }
389
390   if(capture_opts->real_time_mode) {
391     capture_callback_invoke(capture_cb_capture_update_started, capture_opts);
392   } else {
393     capture_callback_invoke(capture_cb_capture_fixed_started, capture_opts);
394   }
395   capture_opts->state = CAPTURE_RUNNING;
396
397   return TRUE;
398 }
399
400
401 /* capture child tells us we have new packets to read */
402 void
403 capture_input_new_packets(capture_options *capture_opts, int to_read)
404 {
405   int  err;
406
407
408   g_assert(capture_opts->save_file);
409
410   if(capture_opts->real_time_mode) {
411     /* Read from the capture file the number of records the child told us it added. */
412     switch (cf_continue_tail(capture_opts->cf, to_read, &err)) {
413
414     case CF_READ_OK:
415     case CF_READ_ERROR:
416       /* Just because we got an error, that doesn't mean we were unable
417          to read any of the file; we handle what we could get from the
418          file.
419
420          XXX - abort on a read error? */
421          capture_callback_invoke(capture_cb_capture_update_continue, capture_opts);
422       break;
423
424     case CF_READ_ABORTED:
425       /* Kill the child capture process; the user wants to exit, and we
426          shouldn't just leave it running. */
427       capture_kill_child(capture_opts);
428       break;
429     }
430   } else {
431     /* increase capture file packet counter by the number or incoming packets */
432     cf_set_packet_count(capture_opts->cf,
433         cf_get_packet_count(capture_opts->cf) + to_read);
434
435     capture_callback_invoke(capture_cb_capture_fixed_continue, capture_opts);
436   }
437
438   /* update the main window, so we get events (e.g. from the stop toolbar button) */
439   main_window_update();
440
441   if(capture_opts->show_info)
442     capture_info_new_packets(to_read);
443 }
444
445
446 /* Capture child told us how many dropped packets it counted.
447  */
448 void
449 capture_input_drops(capture_options *capture_opts, int dropped)
450 {
451   g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "%d packet%s dropped", dropped, plurality(dropped, "", "s"));
452
453   g_assert(capture_opts->state == CAPTURE_RUNNING);
454
455   cf_set_drops_known(capture_opts->cf, TRUE);
456   cf_set_drops(capture_opts->cf, dropped);
457 }
458
459
460 /* Capture child told us that an error has occurred while starting/running
461    the capture.
462    The buffer we're handed has *two* null-terminated strings in it - a
463    primary message and a secondary message, one right after the other.
464    The secondary message might be a null string.
465  */
466 void
467 capture_input_error_message(capture_options *capture_opts, char *error_msg, char *secondary_error_msg)
468 {
469   gchar *safe_error_msg;
470   gchar *safe_secondary_error_msg;
471
472   g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Error message from child: \"%s\", \"%s\"",
473         error_msg, secondary_error_msg);
474
475   g_assert(capture_opts->state == CAPTURE_PREPARING || capture_opts->state == CAPTURE_RUNNING);
476
477   safe_error_msg = simple_dialog_format_message(error_msg);
478   if (*secondary_error_msg != '\0') {
479     /* We have both primary and secondary messages. */
480     safe_secondary_error_msg = simple_dialog_format_message(secondary_error_msg);
481     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s%s%s\n\n%s",
482                   simple_dialog_primary_start(), safe_error_msg,
483                   simple_dialog_primary_end(), safe_secondary_error_msg);
484     g_free(safe_secondary_error_msg);
485   } else {
486     /* We have only a primary message. */
487     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s%s%s",
488                   simple_dialog_primary_start(), safe_error_msg,
489                   simple_dialog_primary_end());
490   }
491   g_free(safe_error_msg);
492
493   /* the capture child will close the sync_pipe if required, nothing to do for now */
494 }
495
496
497
498 /* Capture child told us that an error has occurred while parsing a
499    capture filter when starting/running the capture.
500  */
501 void
502 capture_input_cfilter_error_message(capture_options *capture_opts, char *error_message)
503 {
504   dfilter_t   *rfcode = NULL;
505   gchar *safe_cfilter = simple_dialog_format_message(capture_opts->cfilter);
506   gchar *safe_cfilter_error_msg = simple_dialog_format_message(error_message);
507
508   g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture filter error message from child: \"%s\"", error_message);
509
510   g_assert(capture_opts->state == CAPTURE_PREPARING || capture_opts->state == CAPTURE_RUNNING);
511
512   /* Did the user try a display filter? */
513   if (dfilter_compile(capture_opts->cfilter, &rfcode) && rfcode != NULL) {
514     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
515       "%sInvalid capture filter: \"%s\"!%s\n"
516       "\n"
517       "That string looks like a valid display filter; however, it isn't a valid\n"
518       "capture filter (%s).\n"
519       "\n"
520       "Note that display filters and capture filters don't have the same syntax,\n"
521       "so you can't use most display filter expressions as capture filters.\n"
522       "\n"
523       "See the User's Guide for a description of the capture filter syntax.",
524       simple_dialog_primary_start(), safe_cfilter,
525       simple_dialog_primary_end(), safe_cfilter_error_msg);
526       dfilter_free(rfcode);
527   } else {
528     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
529       "%sInvalid capture filter: \"%s\"!%s\n"
530       "\n"
531       "That string isn't a valid capture filter (%s).\n"
532       "See the User's Guide for a description of the capture filter syntax.",
533       simple_dialog_primary_start(), safe_cfilter,
534       simple_dialog_primary_end(), safe_cfilter_error_msg);
535   }
536   g_free(safe_cfilter_error_msg);
537   g_free(safe_cfilter);
538
539   /* the capture child will close the sync_pipe if required, nothing to do for now */
540 }
541
542
543 /* capture child closed its side of the pipe, do the required cleanup */
544 void
545 capture_input_closed(capture_options *capture_opts)
546 {
547     int  err;
548     int  packet_count_save;
549
550     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture stopped!");
551     g_assert(capture_opts->state == CAPTURE_PREPARING || capture_opts->state == CAPTURE_RUNNING);
552
553     /* if we didn't started the capture, do a fake start */
554     /* (happens if we got an error message - we won't get a filename then) */
555     if(capture_opts->state == CAPTURE_PREPARING) {
556         if(capture_opts->real_time_mode) {
557             capture_callback_invoke(capture_cb_capture_update_started, capture_opts);
558         } else {
559             capture_callback_invoke(capture_cb_capture_fixed_started, capture_opts);
560         }
561     }
562
563     if(capture_opts->real_time_mode) {
564         cf_read_status_t status;
565
566         /* Read what remains of the capture file. */
567         status = cf_finish_tail(capture_opts->cf, &err);
568
569         /* XXX: If -Q (quit-after-cap) then cf->count clr'd below so save it first */
570         packet_count_save = cf_get_packet_count(capture_opts->cf);
571         /* Tell the GUI, we are not doing a capture any more.
572                    Must be done after the cf_finish_tail(), so file lengths are displayed
573                    correct. */
574         capture_callback_invoke(capture_cb_capture_update_finished, capture_opts);
575
576         /* Finish the capture. */
577         switch (status) {
578
579         case CF_READ_OK:
580             if ((packet_count_save == 0) && !capture_opts->restart) {
581                 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
582 "%sNo packets captured!%s\n"
583 "\n"
584 "As no data was captured, closing the %scapture file!\n"
585 "\n"
586 "\n"
587 "Help about capturing can be found at:\n"
588 "\n"
589 "       http://wiki.wireshark.org/CaptureSetup"
590 #ifdef _WIN32
591 "\n\n"
592 "Wireless (Wi-Fi/WLAN):\n"
593 "Try to switch off promiscuous mode in the Capture Options!"
594 #endif
595 "",
596               simple_dialog_primary_start(), simple_dialog_primary_end(),
597               cf_is_tempfile(capture_opts->cf) ? "temporary " : "");
598               cf_close(capture_opts->cf);
599             }
600             break;
601         case CF_READ_ERROR:
602           /* Just because we got an error, that doesn't mean we were unable
603              to read any of the file; we handle what we could get from the
604              file. */
605           break;
606
607         case CF_READ_ABORTED:
608           /* Exit by leaving the main loop, so that any quit functions
609              we registered get called. */
610           main_window_quit();
611         }
612
613     } else {
614         /* first of all, we are not doing a capture any more */
615         capture_callback_invoke(capture_cb_capture_fixed_finished, capture_opts);
616
617         /* this is a normal mode capture and if no error happened, read in the capture file data */
618         if(capture_opts->save_file != NULL) {
619             capture_input_read_all(capture_opts, cf_is_tempfile(capture_opts->cf),
620                 cf_get_drops_known(capture_opts->cf), cf_get_drops(capture_opts->cf));
621         }
622     }
623
624     if(capture_opts->show_info)
625       capture_info_close();
626
627     capture_opts->state = CAPTURE_STOPPED;
628
629     /* if we couldn't open a capture file, there's nothing more for us to do */
630     if(capture_opts->save_file == NULL) {
631         cf_close(capture_opts->cf);
632         return;
633     }
634
635     /* does the user wants to restart the current capture? */
636     if(capture_opts->restart) {
637         capture_opts->restart = FALSE;
638
639         ws_unlink(capture_opts->save_file);
640
641         /* if it was a tempfile, throw away the old filename (so it will become a tempfile again) */
642         if(cf_is_tempfile(capture_opts->cf)) {
643             g_free(capture_opts->save_file);
644             capture_opts->save_file = NULL;
645         }
646
647         /* ... and start the capture again */
648         capture_start(capture_opts);
649     } else {
650         /* We're not doing a capture any more, so we don't have a save file. */
651         g_free(capture_opts->save_file);
652         capture_opts->save_file = NULL;
653     }
654 }
655
656 /**
657  * Fetch the interface list from a child process (dumpcap).
658  *
659  * @return A GList containing if_info_t structs if successful, NULL (with err and possibly err_str set) otherwise.
660  *
661  */
662
663 /* XXX - We parse simple text output to get our interface list.  Should
664  * we use "real" data serialization instead, e.g. via XML? */
665 GList *
666 capture_interface_list(int *err, char **err_str)
667 {
668     GList     *if_list = NULL;
669     int        i, j;
670     gchar     *msg;
671     gchar    **raw_list, **if_parts, **addr_parts;
672     gchar     *name;
673     if_info_t *if_info;
674     if_addr_t *if_addr;
675
676     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface List ...");
677
678     /* Try to get our interface list */
679     *err = sync_interface_list_open(&msg);
680     if (*err != 0) {
681         g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface List failed!");
682         if (err_str) {
683             *err_str = msg;
684         } else {
685             g_free(msg);
686         }
687         return NULL;
688     }
689
690     /* Split our lines */
691 #ifdef _WIN32
692     raw_list = g_strsplit(msg, "\r\n", 0);
693 #else
694     raw_list = g_strsplit(msg, "\n", 0);
695 #endif
696     g_free(msg);
697
698     for (i = 0; raw_list[i] != NULL; i++) {
699         if_parts = g_strsplit(raw_list[i], "\t", 4);
700         if (if_parts[0] == NULL || if_parts[1] == NULL || if_parts[2] == NULL ||
701                 if_parts[3] == NULL) {
702             g_strfreev(if_parts);
703             continue;
704         }
705
706         /* Number followed by the name, e.g "1. eth0" */
707         name = strchr(if_parts[0], ' ');
708         if (name) {
709             name++;
710         } else {
711             g_strfreev(if_parts);
712             continue;
713         }
714
715         if_info = g_malloc0(sizeof(if_info_t));
716         if_info->name = g_strdup(name);
717         if (strlen(if_parts[1]) > 0)
718             if_info->description = g_strdup(if_parts[1]);
719         addr_parts = g_strsplit(if_parts[2], ",", 0);
720         for (j = 0; addr_parts[j] != NULL; j++) {
721             if_addr = g_malloc0(sizeof(if_addr_t));
722             if (inet_pton(AF_INET, addr_parts[j], &if_addr->ip_addr.ip4_addr)) {
723                 if_addr->type = AT_IPv4;
724             } else if (inet_pton(AF_INET6, addr_parts[j],
725                     &if_addr->ip_addr.ip6_addr)) {
726                 if_addr->type = AT_IPv6;
727             } else {
728                 g_free(if_addr);
729                 if_addr = NULL;
730             }
731             if (if_addr) {
732                 if_info->ip_addr = g_slist_append(if_info->ip_addr, if_addr);
733             }
734         }
735         if (strcmp(if_parts[3], "loopback") == 0)
736             if_info->loopback = TRUE;
737         g_strfreev(if_parts);
738         g_strfreev(addr_parts);
739         if_list = g_list_append(if_list, if_info);
740     }
741     g_strfreev(raw_list);
742
743     /* Check to see if we built a list */
744     if (if_list == NULL) {
745         *err = NO_INTERFACES_FOUND;
746         if (err_str)
747             *err_str = g_strdup("No interfaces found");
748     }
749     return if_list;
750 }
751
752 /* XXX - We parse simple text output to get our interface list.  Should
753  * we use "real" data serialization instead, e.g. via XML? */
754 GList *
755 capture_pcap_linktype_list(const gchar *ifname, char **err_str)
756 {
757     GList     *linktype_list = NULL;
758     int        err, i;
759     gchar     *msg;
760     gchar    **raw_list, **lt_parts;
761     data_link_info_t *data_link_info;
762
763     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface List ...");
764
765     /* Try to get our interface list */
766     err = sync_linktype_list_open(ifname, &msg);
767     if (err != 0) {
768         g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface List failed!");
769         if (err_str) {
770             *err_str = msg;
771         } else {
772             g_free(msg);
773         }
774         return NULL;
775     }
776
777     /* Split our lines */
778 #ifdef _WIN32
779     raw_list = g_strsplit(msg, "\r\n", 0);
780 #else
781     raw_list = g_strsplit(msg, "\n", 0);
782 #endif
783     g_free(msg);
784
785     for (i = 0; raw_list[i] != NULL; i++) {
786         /* ...and what if the interface name has a tab in it, Mr. Clever Programmer? */
787         lt_parts = g_strsplit(raw_list[i], "\t", 3);
788         if (lt_parts[0] == NULL || lt_parts[1] == NULL || lt_parts[2] == NULL) {
789             g_strfreev(lt_parts);
790             continue;
791         }
792
793         data_link_info = g_malloc(sizeof (data_link_info_t));
794         data_link_info->dlt = (int) strtol(lt_parts[0], NULL, 10);
795         data_link_info->name = g_strdup(lt_parts[1]);
796         if (strcmp(lt_parts[2], "(not supported)") != 0)
797             data_link_info->description = g_strdup(lt_parts[2]);
798         else
799             data_link_info->description = NULL;
800
801         linktype_list = g_list_append(linktype_list, data_link_info);
802     }
803     g_strfreev(raw_list);
804
805     /* Check to see if we built a list */
806     if (linktype_list == NULL) {
807         if (err_str)
808             *err_str = NULL;
809     }
810     return linktype_list;
811 }
812
813 if_stat_cache_t *
814 capture_stat_start(GList *if_list) {
815     int stat_fd, fork_child;
816     gchar *msg;
817     if_stat_cache_t *sc = NULL;
818     GList *if_entry;
819     if_info_t *if_info;
820     if_stat_cache_item_t *sc_item;
821
822     /* Fire up dumpcap. */
823     /*
824      * XXX - on systems with BPF, the number of BPF devices limits the
825      * number of devices on which you can capture simultaneously.
826      *
827      * This means that
828      *
829      *  1) this might fail if you run out of BPF devices
830      *
831      * and
832      *
833      *  2) opening every interface could leave too few BPF devices
834      *     for *other* programs.
835      *
836      * It also means the system could end up getting a lot of traffic
837      * that it has to pass through the networking stack and capture
838      * mechanism, so opening all the devices and presenting packet
839      * counts might not always be a good idea.
840      */
841      if (sync_interface_stats_open(&stat_fd, &fork_child, &msg) == 0) {
842         sc = g_malloc(sizeof(if_stat_cache_t));
843         sc->stat_fd = stat_fd;
844         sc->fork_child = fork_child;
845         sc->cache_list = NULL;
846
847         /* Initialize the cache */
848         for (if_entry = if_list; if_entry != NULL; if_entry = g_list_next(if_entry)) {
849             if_info = if_entry->data;
850             sc_item = g_malloc0(sizeof(if_stat_cache_item_t));
851             sc_item->name = g_strdup(if_info->name);
852             sc->cache_list = g_list_append(sc->cache_list, sc_item);
853         }
854     }
855     return sc;
856 }
857
858 #define MAX_STAT_LINE_LEN 500
859
860 static void
861 capture_stat_cache_update(if_stat_cache_t *sc) {
862     gchar stat_line[MAX_STAT_LINE_LEN];
863     gchar **stat_parts;
864     GList *sc_entry;
865     if_stat_cache_item_t *sc_item;
866
867     if (!sc)
868         return;
869
870     while (sync_pipe_gets_nonblock(sc->stat_fd, stat_line, MAX_STAT_LINE_LEN) > 0) {
871         g_strstrip(stat_line);
872         stat_parts = g_strsplit(stat_line, "\t", 3);
873         if (stat_parts[0] == NULL || stat_parts[1] == NULL ||
874             stat_parts[2] == NULL) {
875             g_strfreev(stat_parts);
876             continue;
877         }
878         for (sc_entry = sc->cache_list; sc_entry != NULL; sc_entry = g_list_next(sc_entry)) {
879             sc_item = sc_entry->data;
880             if (strcmp(sc_item->name, stat_parts[0]) == 0) {
881                 sc_item->ps.ps_recv = (u_int) strtoul(stat_parts[1], NULL, 10);
882                 sc_item->ps.ps_drop = (u_int) strtoul(stat_parts[2], NULL, 10);
883             }
884         }
885         g_strfreev(stat_parts);
886     }
887 }
888
889 gboolean
890 capture_stats(if_stat_cache_t *sc, char *ifname, struct pcap_stat *ps) {
891     GList *sc_entry;
892     if_stat_cache_item_t *sc_item;
893
894     if (!sc || !ifname || !ps) {
895         return FALSE;
896     }
897
898     capture_stat_cache_update(sc);
899     for (sc_entry = sc->cache_list; sc_entry != NULL; sc_entry = g_list_next(sc_entry)) {
900         sc_item = sc_entry->data;
901         if (strcmp(sc_item->name, ifname) == 0) {
902             memcpy(ps, &sc_item->ps, sizeof(struct pcap_stat));
903             return TRUE;
904         }
905     }
906     return FALSE;
907 }
908
909 void
910 capture_stat_stop(if_stat_cache_t *sc) {
911     GList *sc_entry;
912     if_stat_cache_item_t *sc_item;
913     gchar *msg;
914
915     if (!sc)
916         return;
917
918     sync_interface_stats_close(&sc->stat_fd, &sc->fork_child, &msg);
919
920     for (sc_entry = sc->cache_list; sc_entry != NULL; sc_entry = g_list_next(sc_entry)) {
921         sc_item = sc_entry->data;
922         g_free(sc_item->name);
923         g_free(sc_item);
924     }
925     g_free(sc);
926 }
927
928 #endif /* HAVE_LIBPCAP */