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