Don't include \r in linktype on win32, it looks weird in the combo box.
[metze/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 /**
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         ws_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 #ifdef _WIN32
638     raw_list = g_strsplit(msg, "\r\n", 0);
639 #else
640     raw_list = g_strsplit(msg, "\n", 0);
641 #endif
642     g_free(msg);
643
644     for (i = 0; raw_list[i] != NULL; i++) {
645         if_parts = g_strsplit(raw_list[i], "\t", 4);
646         if (if_parts[0] == NULL || if_parts[1] == NULL || if_parts[2] == NULL ||
647                 if_parts[3] == NULL) {
648             g_strfreev(if_parts);
649             continue;
650         }
651
652         /* Number followed by the name, e.g "1. eth0" */
653         name = strchr(if_parts[0], ' ');
654         if (name) {
655             name++;
656         } else {
657             g_strfreev(if_parts);
658             continue;
659         }
660
661         if_info = g_malloc0(sizeof(if_info_t));
662         if_info->name = g_strdup(name);
663         if (strlen(if_parts[1]) > 0)
664             if_info->description = g_strdup(if_parts[1]);
665         addr_parts = g_strsplit(if_parts[2], ",", 0);
666         for (j = 0; addr_parts[j] != NULL; j++) {
667             if_addr = g_malloc0(sizeof(if_addr_t));
668             if (inet_pton(AF_INET, addr_parts[j], &if_addr->ip_addr.ip4_addr)) {
669                 if_addr->type = AT_IPv4;
670             } else if (inet_pton(AF_INET6, addr_parts[j],
671                     &if_addr->ip_addr.ip6_addr)) {
672                 if_addr->type = AT_IPv6;
673             } else {
674                 g_free(if_addr);
675                 if_addr = NULL;
676             }
677             if (if_addr) {
678                 if_info->ip_addr = g_slist_append(if_info->ip_addr, if_addr);
679             }
680         }
681         if (strcmp(if_parts[3], "loopback") == 0)
682             if_info->loopback = TRUE;
683         g_strfreev(if_parts);
684         g_strfreev(addr_parts);
685         if_list = g_list_append(if_list, if_info);
686     }
687     g_strfreev(raw_list);
688
689     /* Check to see if we built a list */
690     if (if_list == NULL) {
691         if (err_str && *err_str)
692             *err_str = g_strdup("No interfaces found");
693         *err = NO_INTERFACES_FOUND;
694     }
695     return if_list;
696 }
697
698 /* XXX - We parse simple text output to get our interface list.  Should
699  * we use "real" data serialization instead, e.g. via XML? */
700 GList *
701 capture_pcap_linktype_list(const gchar *ifname, char **err_str)
702 {
703     GList     *linktype_list = NULL;
704     int        err, i;
705     gchar     *msg;
706     gchar    **raw_list, **lt_parts;
707     data_link_info_t *data_link_info;
708
709     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface List ...");
710
711     /* Try to get our interface list */
712     err = sync_linktype_list_open(ifname, &msg);
713     if (err != 0) {
714         g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface List failed!");
715         if (err_str) {
716             *err_str = msg;
717         } else {
718             g_free(msg);
719         }
720         return NULL;
721     }
722
723     /* Split our lines */
724 #ifdef _WIN32
725     raw_list = g_strsplit(msg, "\r\n", 0);
726 #else
727     raw_list = g_strsplit(msg, "\n", 0);
728 #endif
729     g_free(msg);
730
731     for (i = 0; raw_list[i] != NULL; i++) {
732         /* ...and what if the interface name has a tab in it, Mr. Clever Programmer? */
733         lt_parts = g_strsplit(raw_list[i], "\t", 3);
734         if (lt_parts[0] == NULL || lt_parts[1] == NULL || lt_parts[2] == NULL) {
735             g_strfreev(lt_parts);
736             continue;
737         }
738
739         data_link_info = g_malloc(sizeof (data_link_info_t));
740         data_link_info->dlt = (int) strtol(lt_parts[0], NULL, 10);
741         data_link_info->name = g_strdup(lt_parts[1]);
742         if (strcmp(lt_parts[2], "(not supported)") != 0)
743             data_link_info->description = g_strdup(lt_parts[2]);
744         else
745             data_link_info->description = NULL;
746
747         linktype_list = g_list_append(linktype_list, data_link_info);
748     }
749     g_strfreev(raw_list);
750
751     /* Check to see if we built a list */
752     if (linktype_list == NULL) {
753         if (err_str)
754             *err_str = NULL;
755     }
756     return linktype_list;
757 }
758
759 if_stat_cache_t *
760 capture_stat_start(GList *if_list) {
761     int stat_fd, fork_child;
762     gchar *msg;
763     if_stat_cache_t *sc = NULL;
764     GList *if_entry;
765     if_info_t *if_info;
766     if_stat_cache_item_t *sc_item;
767
768     /* Fire up dumpcap. */
769     /*
770      * XXX - on systems with BPF, the number of BPF devices limits the
771      * number of devices on which you can capture simultaneously.
772      *
773      * This means that
774      *
775      *  1) this might fail if you run out of BPF devices
776      *
777      * and
778      *
779      *  2) opening every interface could leave too few BPF devices
780      *     for *other* programs.
781      *
782      * It also means the system could end up getting a lot of traffic
783      * that it has to pass through the networking stack and capture
784      * mechanism, so opening all the devices and presenting packet
785      * counts might not always be a good idea.
786      */
787      if (sync_interface_stats_open(&stat_fd, &fork_child, &msg) == 0) {
788         sc = g_malloc(sizeof(if_stat_cache_t));
789         sc->stat_fd = stat_fd;
790         sc->fork_child = fork_child;
791         sc->cache_list = NULL;
792
793         /* Initialize the cache */
794         for (if_entry = if_list; if_entry != NULL; if_entry = g_list_next(if_entry)) {
795             if_info = if_entry->data;
796             sc_item = g_malloc0(sizeof(if_stat_cache_item_t));
797             sc_item->name = g_strdup(if_info->name);
798             sc->cache_list = g_list_append(sc->cache_list, sc_item);
799         }
800     }
801     return sc;
802 }
803
804 #define MAX_STAT_LINE_LEN 500
805
806 static void
807 capture_stat_cache_update(if_stat_cache_t *sc) {
808     gchar stat_line[MAX_STAT_LINE_LEN];
809     gchar **stat_parts;
810     GList *sc_entry;
811     if_stat_cache_item_t *sc_item;
812
813     if (!sc)
814         return;
815
816     while (sync_pipe_gets_nonblock(sc->stat_fd, stat_line, MAX_STAT_LINE_LEN) > 0) {
817         g_strstrip(stat_line);
818         stat_parts = g_strsplit(stat_line, "\t", 3);
819         if (stat_parts[0] == NULL || stat_parts[1] == NULL ||
820             stat_parts[2] == NULL) {
821             g_strfreev(stat_parts);
822             continue;
823         }
824         for (sc_entry = sc->cache_list; sc_entry != NULL; sc_entry = g_list_next(sc_entry)) {
825             sc_item = sc_entry->data;
826             if (strcmp(sc_item->name, stat_parts[0]) == 0) {
827                 sc_item->ps.ps_recv = (u_int) strtoul(stat_parts[1], NULL, 10);
828                 sc_item->ps.ps_drop = (u_int) strtoul(stat_parts[2], NULL, 10);
829             }
830         }
831         g_strfreev(stat_parts);
832     }
833 }
834
835 gboolean
836 capture_stats(if_stat_cache_t *sc, char *ifname, struct pcap_stat *ps) {
837     GList *sc_entry;
838     if_stat_cache_item_t *sc_item;
839
840     if (!sc || !ifname || !ps) {
841         return FALSE;
842     }
843
844     capture_stat_cache_update(sc);
845     for (sc_entry = sc->cache_list; sc_entry != NULL; sc_entry = g_list_next(sc_entry)) {
846         sc_item = sc_entry->data;
847         if (strcmp(sc_item->name, ifname) == 0) {
848             memcpy(ps, &sc_item->ps, sizeof(struct pcap_stat));
849             return TRUE;
850         }
851     }
852     return FALSE;
853 }
854
855 void
856 capture_stat_stop(if_stat_cache_t *sc) {
857     GList *sc_entry;
858     if_stat_cache_item_t *sc_item;
859     gchar *msg;
860
861     if (!sc)
862         return;
863
864     sync_interface_stats_close(&sc->stat_fd, &sc->fork_child, &msg);
865
866     for (sc_entry = sc->cache_list; sc_entry != NULL; sc_entry = g_list_next(sc_entry)) {
867         sc_item = sc_entry->data;
868         g_free(sc_item->name);
869         g_free(sc_item);
870     }
871     g_free(sc);
872 }
873
874 #endif /* HAVE_LIBPCAP */