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