When doing a capture, decode enough of the incoming packets to correctly
[obnox/wireshark/wip.git] / capture.c
index 4bb1c1863433109edf54fe2946de84288b54785a..1624e451598cf40eb40ed062ad573eef46ef1171 100644 (file)
--- a/capture.c
+++ b/capture.c
@@ -1,7 +1,7 @@
 /* capture.c
  * Routines for packet capture windows
  *
- * $Id: capture.c,v 1.10 1998/11/15 05:40:19 guy Exp $
+ * $Id: capture.c,v 1.18 1999/02/09 00:35:35 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
 #include <gtk/gtk.h>
 #include <pcap.h>
 
+#include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <time.h>
 #include <sys/socket.h>
 #include <sys/ioctl.h>
 #include <net/if.h>
@@ -126,7 +128,7 @@ get_interface_list() {
         ! strchr(ifr->ifr_name, ':')) {
       il = g_list_append(il, g_strdup(ifr->ifr_name));
     }
-#ifdef HAVE_SOCKADDR_SA_LEN
+#ifdef HAVE_SA_LEN
     ifr = (struct ifreq *) ((char *) ifr + ifr->ifr_addr.sa_len + IFNAMSIZ);
 #else
     ifr = (struct ifreq *) ((char *) ifr + sizeof(struct ifreq));
@@ -285,14 +287,14 @@ capture_prep_cb(GtkWidget *w, gpointer d) {
   gtk_box_pack_start (GTK_BOX (bbox), cancel_bt, TRUE, TRUE, 0);
   gtk_widget_show(cancel_bt);
 
-  /* Attach pointers to needed widges to the capture prefs window/object */
+  /* Attach pointers to needed widgets to the capture prefs window/object */
   gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_IFACE_KEY, if_cb);
   gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_FILT_KEY,  filter_te);
   gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_FILE_KEY,  file_te);
   gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_COUNT_KEY, count_cb);
   gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_OPEN_KEY,  capfile_ck);
   gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_SNAP_KEY,  snap_sb);
-  
+
   gtk_widget_show(cap_open_w);
 }
 
@@ -341,6 +343,9 @@ capture_prep_ok_cb(GtkWidget *w, gpointer data) {
   GtkWidget *if_cb, *filter_te, *file_te, *count_cb, *open_ck, *snap_sb;
   gint     open;
 
+#ifdef GTK_HAVE_FEATURES_1_1_0
+  data = w;
+#endif
   if_cb     = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(data), E_CAP_IFACE_KEY);
   filter_te = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(data), E_CAP_FILT_KEY);
   file_te   = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(data), E_CAP_FILE_KEY);
@@ -372,6 +377,9 @@ capture_prep_ok_cb(GtkWidget *w, gpointer data) {
 void
 capture_prep_close_cb(GtkWidget *w, gpointer win) {
 
+#ifdef GTK_HAVE_FEATURES_1_1_0
+  win = w;
+#endif
   gtk_grab_remove(GTK_WIDGET(win));
   gtk_widget_destroy(GTK_WIDGET(win));
 }
@@ -386,14 +394,15 @@ capture(gint open) {
   bpf_u_int32 netnum, netmask;
   time_t      upd_time, cur_time;
   
-  ld.go    = TRUE;
-  ld.count = 0;
-  ld.max   = cf.count;
-  ld.tcp   = 0;
-  ld.udp   = 0;
-  ld.ospf  = 0;
-  ld.other = 0;
-  ld.pdh   = NULL;
+  ld.go           = TRUE;
+  ld.counts.total = 0;
+  ld.max          = cf.count;
+  ld.linktype     = DLT_NULL;
+  ld.counts.tcp   = 0;
+  ld.counts.udp   = 0;
+  ld.counts.ospf  = 0;
+  ld.counts.other = 0;
+  ld.pdh          = NULL;
 
   close_cap_file(&cf, info_bar, file_ctx);
 
@@ -412,6 +421,7 @@ capture(gint open) {
         return;
       }
     }
+    ld.linktype = pcap_datalink(pch);
 
     if (cf.cfilter) {
       if (pcap_lookupnet (cf.iface, &netnum, &netmask, err_str) < 0) {
@@ -480,20 +490,23 @@ capture(gint open) {
 
         upd_time = cur_time;
 
-        sprintf(label_str, "Count: %d", ld.count);
+        sprintf(label_str, "Count: %d", ld.counts.total);
         gtk_label_set(GTK_LABEL(count_lb), label_str);
 
-        sprintf(label_str, "TCP: %d (%.1f%%)", ld.tcp, pct(ld.tcp, ld.count));
+        sprintf(label_str, "TCP: %d (%.1f%%)", ld.counts.tcp,
+          pct(ld.counts.tcp, ld.counts.total));
         gtk_label_set(GTK_LABEL(tcp_lb), label_str);
 
-        sprintf(label_str, "UDP: %d (%.1f%%)", ld.udp, pct(ld.udp, ld.count));
+        sprintf(label_str, "UDP: %d (%.1f%%)", ld.counts.udp,
+         pct(ld.counts.udp, ld.counts.total));
         gtk_label_set(GTK_LABEL(udp_lb), label_str);
 
-        sprintf(label_str, "OSPF: %d (%.1f%%)", ld.ospf, pct(ld.ospf, ld.count));
+        sprintf(label_str, "OSPF: %d (%.1f%%)", ld.counts.ospf,
+         pct(ld.counts.ospf, ld.counts.total));
         gtk_label_set(GTK_LABEL(ospf_lb), label_str);
 
-        sprintf(label_str, "Other: %d (%.1f%%)", ld.other,
-          pct(ld.other, ld.count));
+        sprintf(label_str, "Other: %d (%.1f%%)", ld.counts.other,
+          pct(ld.counts.other, ld.counts.total));
         gtk_label_set(GTK_LABEL(other_lb), label_str);
       }
     }
@@ -536,48 +549,33 @@ void
 capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
   const u_char *pd) {
   
-  guint16 etype;
-  guint8  iptype = 0;
-  gint    offset = 14;
-  
   loop_data *ld = (loop_data *) user;
   
-  if ((++ld->count >= ld->max) && (ld->max > 0)) 
+  if ((++ld->counts.total >= ld->max) && (ld->max > 0)) 
   {
      ld->go = FALSE;
   }
   /* Currently, pcap_dumper_t is a FILE *.  Let's hope that doesn't change. */
   if (ld->pdh) pcap_dump((u_char *) ld->pdh, phdr, pd);
   
-  etype = etype = (pd[12] << 8) | pd[13];
-  if (etype <= IEEE_802_3_MAX_LEN) {
-    etype = (pd[20] << 8) | pd[21];
-    offset = 22;
-  }
-  
-  switch(etype){ 
-    case ETHERTYPE_IP:
-      iptype = pd[offset + 9];
-      switch (iptype) {
-        case IP_PROTO_TCP:
-          ld->tcp++;
-          break;
-        case IP_PROTO_UDP:
-          ld->udp++;
-          break;
-        case IP_PROTO_OSPF:
-          ld->ospf++;
-          break;
-        default:
-          ld->other++;
-        }
-        break;
-      case ETHERTYPE_IPX:
-      case ETHERTYPE_IPv6:
-      case ETHERTYPE_ATALK:
-      case ETHERTYPE_VINES:
-      case ETHERTYPE_ARP:
-      default:
-        ld->other++;
+  switch (ld->linktype) {
+    case DLT_EN10MB :
+      capture_eth(pd, phdr->caplen, &ld->counts);
+      break;
+    case DLT_FDDI :
+      capture_fddi(pd, phdr->caplen, &ld->counts);
+      break;
+    case DLT_IEEE802 :
+      capture_tr(pd, phdr->caplen, &ld->counts);
+      break;
+    case DLT_NULL :
+      capture_null(pd, phdr->caplen, &ld->counts);
+      break;
+    case DLT_PPP :
+      capture_ppp(pd, phdr->caplen, &ld->counts);
+      break;
+    case DLT_RAW :
+      capture_raw(pd, phdr->caplen, &ld->counts);
+      break;
   }
 }