]> The Tcpdump Group git mirrors - libpcap/commitdiff
From Stephen Donnelly:
authorguy <guy>
Mon, 5 Nov 2007 21:45:07 +0000 (21:45 +0000)
committerguy <guy>
Mon, 5 Nov 2007 21:45:07 +0000 (21:45 +0000)
support ERF extension headers;

collect the ifdefs for different ERF types into a header
to improve readability;

add in a couple of new types.

pcap-dag.c
pcap-dag.h

index 97c174960bf3f5aa76c55b5c6d156cf7aa0fb6fa..4834f9446484356193c2cc63a302e5722ffc9b2f 100644 (file)
@@ -17,7 +17,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-       "@(#) $Header: /tcpdump/master/libpcap/pcap-dag.c,v 1.32 2007-10-30 10:16:45 guy Exp $ (LBL)";
+       "@(#) $Header: /tcpdump/master/libpcap/pcap-dag.c,v 1.33 2007-11-05 21:45:07 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -46,6 +46,8 @@ struct rtentry;               /* declarations in <net/if.h> */
 #include "dagnew.h"
 #include "dagapi.h"
 
+#include "pcap-dag.h"
+
 #define ATM_CELL_SIZE          52
 #define ATM_HDR_SIZE           4
 
@@ -83,7 +85,6 @@ static const unsigned short endian_test_word = 0x0100;
 
 #ifdef DAG_ONLY
 /* This code is required when compiling for a DAG device only. */
-#include "pcap-dag.h"
 
 /* Replace dag function names with pcap equivalent. */
 #define dag_open_live pcap_open_live
@@ -180,6 +181,38 @@ new_pcap_dag(pcap_t *p)
        return 0;
 }
 
+static unsigned int
+dag_erf_ext_header_count(uint8_t * erf, size_t len)
+{
+       uint32_t hdr_num = 0;
+       uint8_t  hdr_type;
+
+       /* basic sanity checks */
+       if ( erf == NULL )
+               return 0;
+       if ( len < 16 )
+               return 0;
+
+       /* check if we have any extension headers */
+       if ( (erf[8] & 0x80) == 0x00 )
+               return 0;
+
+       /* loop over the extension headers */
+       do {
+       
+               /* sanity check we have enough bytes */
+               if ( len <= (24 + (hdr_num * 8)) )
+                       return hdr_num;
+
+               /* get the header type */
+               hdr_type = erf[(16 + (hdr_num * 8))];
+               hdr_num++;
+
+       } while ( hdr_type & 0x80 );
+
+       return hdr_num;
+}
+
 /*
  *  Read at most max_packets from the capture stream and call the callback
  *  for each of them. Returns the number of packets handled, -1 if an
@@ -191,6 +224,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
        unsigned int processed = 0;
        int flags = p->md.dag_offset_flags;
        unsigned int nonblocking = flags & DAGF_NONBLOCK;
+       unsigned int num_ext_hdr = 0;
 
        /* Get the next bufferful of packets (if necessary). */
        while (p->md.dag_mem_top - p->md.dag_mem_bottom < dag_record_size) {
@@ -281,6 +315,8 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                }
                p->md.dag_mem_bottom += rlen;
 
+               num_ext_hdr = dag_erf_ext_header_count(dp, rlen);
+
                /* ERF encapsulation */
                /* The Extensible Record Format is not dropped for this kind of encapsulation, 
                 * and will be handled as a pseudo header by the decoding application.
@@ -298,13 +334,14 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                if (p->linktype == DLT_ERF) {
                        packet_len = ntohs(header->wlen) + dag_record_size;
                        caplen = rlen;
-                       switch (header->type) {
+                       switch ((header->type & 0x7f)) {
                        case TYPE_MC_AAL5:
                        case TYPE_MC_ATM:
                        case TYPE_MC_HDLC:
                                packet_len += 4; /* MC header */
                                break;
 
+                       case TYPE_COLOR_HASH_ETH:
                        case TYPE_DSM_COLOR_ETH:
                        case TYPE_COLOR_ETH:
                        case TYPE_ETH:
@@ -312,37 +349,38 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                                break;
                        } /* switch type */
 
+                       /* Include ERF extension headers */
+                       packet_len += (8 * num_ext_hdr);
+
                        if (caplen > packet_len) {
                                caplen = packet_len;
                        }
                } else {
                        /* Other kind of encapsulation according to the header Type */
+
+                       /* Skip over generic ERF header */
                        dp += dag_record_size;
+                       /* Skip over extension headers */
+                       dp += 8 * num_ext_hdr;
                        
-                       switch(header->type) {
+                       switch((header->type & 0x7f)) {
                        case TYPE_ATM:
-#ifdef TYPE_AAL5
                        case TYPE_AAL5:
                                if (header->type == TYPE_AAL5) {
                                        packet_len = ntohs(header->wlen);
                                        caplen = rlen - dag_record_size;
                                }
-#endif
-#ifdef TYPE_MC_ATM
                        case TYPE_MC_ATM:
                                if (header->type == TYPE_MC_ATM) {
                                        caplen = packet_len = ATM_CELL_SIZE;
                                        dp+=4;
                                }
-#endif
-#ifdef TYPE_MC_AAL5
                        case TYPE_MC_AAL5:
                                if (header->type == TYPE_MC_AAL5) {
                                        packet_len = ntohs(header->wlen);
                                        caplen = rlen - dag_record_size - 4;
                                        dp+=4;
                                }
-#endif
                                if (header->type == TYPE_ATM) {
                                        caplen = packet_len = ATM_CELL_SIZE;
                                }
@@ -367,12 +405,9 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                                }
                                break;
 
-#ifdef TYPE_DSM_COLOR_ETH
+                       case TYPE_COLOR_HASH_ETH:
                        case TYPE_DSM_COLOR_ETH:
-#endif
-#ifdef TYPE_COLOR_ETH
                        case TYPE_COLOR_ETH:
-#endif
                        case TYPE_ETH:
                                packet_len = ntohs(header->wlen);
                                packet_len -= (p->md.dag_fcs_bits >> 3);
@@ -382,12 +417,10 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                                }
                                dp += 2;
                                break;
-#ifdef TYPE_DSM_COLOR_HDLC_POS
+
+                       case TYPE_COLOR_HASH_POS:
                        case TYPE_DSM_COLOR_HDLC_POS:
-#endif
-#ifdef TYPE_COLOR_HDLC_POS
                        case TYPE_COLOR_HDLC_POS:
-#endif
                        case TYPE_HDLC_POS:
                                packet_len = ntohs(header->wlen);
                                packet_len -= (p->md.dag_fcs_bits >> 3);
@@ -396,10 +429,8 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                                        caplen = packet_len;
                                }
                                break;
-#ifdef TYPE_COLOR_MC_HDLC_POS
+
                        case TYPE_COLOR_MC_HDLC_POS:
-#endif
-#ifdef TYPE_MC_HDLC
                        case TYPE_MC_HDLC:
                                packet_len = ntohs(header->wlen);
                                packet_len -= (p->md.dag_fcs_bits >> 3);
@@ -409,11 +440,12 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                                }
                                /* jump the MC_HDLC_HEADER */
                                dp += 4;
+#ifdef DLT_MTP2_WITH_PHDR
                                if (p->linktype == DLT_MTP2_WITH_PHDR) {
                                        /* Add the MTP2 Pseudo Header */
                                        caplen += MTP2_HDR_LEN;
                                        packet_len += MTP2_HDR_LEN;
-
+                                       
                                        TempPkt[MTP2_SENT_OFFSET] = 0;
                                        TempPkt[MTP2_ANNEX_A_USED_OFFSET] = MTP2_ANNEX_A_USED_UNKNOWN;
                                        *(TempPkt+MTP2_LINK_NUMBER_OFFSET) = ((header->rec.mc_hdlc.mc_header>>16)&0x01);
@@ -421,45 +453,43 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                                        memcpy(TempPkt+MTP2_HDR_LEN, dp, caplen);
                                        dp = TempPkt;
                                }
-                               break;
 #endif
+                               break;
+
+                       case TYPE_IPV4:
+                               packet_len = ntohs(header->wlen);
+                               caplen = rlen - dag_record_size;
+                               if (caplen > packet_len) {
+                                       caplen = packet_len;
+                               }
+                               break;
+
                        default:
                                /* Unhandled ERF type.
                                 * Ignore rather than generating error
                                 */
                                continue;
                        } /* switch type */
+
+                       /* Skip over extension headers */
+                       caplen -= (8 * num_ext_hdr);
+
                } /* ERF encapsulation */
                
                if (caplen > p->snapshot)
                        caplen = p->snapshot;
 
                /* Count lost packets. */
-               switch(header->type) {
-#ifdef TYPE_COLOR_HDLC_POS
-                       /* in this type the color value overwrites the lctr */
+               switch((header->type & 0x7f)) {
+                       /* in these types the color value overwrites the lctr */
                case TYPE_COLOR_HDLC_POS:
-                       break;
-#endif
-#ifdef TYPE_COLOR_ETH
-                       /* in this type the color value overwrites the lctr */
                case TYPE_COLOR_ETH:
-                       break;
-#endif
-#ifdef TYPE_DSM_COLOR_HDLC_POS
-                       /* in this type the color value overwrites the lctr */
                case TYPE_DSM_COLOR_HDLC_POS:
-                       break;
-#endif
-#ifdef TYPE_DSM_COLOR_ETH
-                       /* in this type the color value overwrites the lctr */
                case TYPE_DSM_COLOR_ETH:
-                       break;
-#endif
-#ifdef TYPE_COLOR_MC_HDLC_POS
                case TYPE_COLOR_MC_HDLC_POS:
+               case TYPE_COLOR_HASH_ETH:
+               case TYPE_COLOR_HASH_POS:
                        break;
-#endif
 
                default:
                        if (header->lctr) {
@@ -537,7 +567,9 @@ dag_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
 pcap_t *
 dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf)
 {
+#if 0
        char conf[30]; /* dag configure string */
+#endif
        pcap_t *handle;
        char *s;
        int n;
@@ -858,7 +890,7 @@ dag_platform_finddevs(pcap_if_t **devlistp, char *errbuf)
                        }
 #ifdef HAVE_DAG_STREAMS_API
                        {
-                               int stream, rxstreams, found=0;
+                               int stream, rxstreams;
                                rxstreams = dag_rx_get_stream_count(dagfd);
                                for(stream=0;stream<16;stream+=2) {
                                        if (0 == dag_attach_stream(dagfd, stream, 0, 0)) {
@@ -1001,15 +1033,13 @@ dag_get_datalink(pcap_t *p)
 
        {
 #endif
-               switch(types[index]) {
+               switch((types[index] & 0x7f)) {
 
                case TYPE_HDLC_POS:
-#ifdef TYPE_COLOR_HDLC_POS
                case TYPE_COLOR_HDLC_POS:
-#endif
-#ifdef TYPE_DSM_COLOR_HDLC_POS
                case TYPE_DSM_COLOR_HDLC_POS:
-#endif
+               case TYPE_COLOR_HASH_POS:
+
                        if (p->dlt_list != NULL) {
                                p->dlt_list[dlt_index++] = DLT_CHDLC;
                                p->dlt_list[dlt_index++] = DLT_PPP_SERIAL;
@@ -1020,12 +1050,9 @@ dag_get_datalink(pcap_t *p)
                        break;
 
                case TYPE_ETH:
-#ifdef TYPE_COLOR_ETH
                case TYPE_COLOR_ETH:
-#endif
-#ifdef TYPE_DSM_COLOR_ETH
                case TYPE_DSM_COLOR_ETH:
-#endif
+               case TYPE_COLOR_HASH_ETH:
                        /*
                         * This is (presumably) a real Ethernet capture; give it a
                         * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
@@ -1045,15 +1072,9 @@ dag_get_datalink(pcap_t *p)
                        break;
 
                case TYPE_ATM: 
-#ifdef TYPE_AAL5
                case TYPE_AAL5:
-#endif
-#ifdef TYPE_MC_ATM
                case TYPE_MC_ATM:
-#endif
-#ifdef TYPE_MC_AAL5
                case TYPE_MC_AAL5:
-#endif
                        if (p->dlt_list != NULL) {
                                p->dlt_list[dlt_index++] = DLT_ATM_RFC1483;
                                p->dlt_list[dlt_index++] = DLT_SUNATM;
@@ -1062,10 +1083,7 @@ dag_get_datalink(pcap_t *p)
                                p->linktype = DLT_ATM_RFC1483;
                        break;
 
-#ifdef TYPE_COLOR_MC_HDLC_POS
                case TYPE_COLOR_MC_HDLC_POS:
-#endif
-#ifdef TYPE_MC_HDLC
                case TYPE_MC_HDLC:
                        if (p->dlt_list != NULL) {
                                p->dlt_list[dlt_index++] = DLT_CHDLC;
@@ -1078,7 +1096,11 @@ dag_get_datalink(pcap_t *p)
                        if(!p->linktype)
                                p->linktype = DLT_CHDLC;
                        break;
-#endif
+
+               case TYPE_IPV4:
+                       if(!p->linktype)
+                               p->linktype = DLT_RAW;
+                       break;
 
                case TYPE_LEGACY:
                        if(!p->linktype)
index aefaa5c56fafc876e10bc3a7640f3352b2e19be0..44bd0680edb7402bc2ad5db16ca73b13a593f5dd 100644 (file)
@@ -7,8 +7,88 @@
  *
  * Author: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com)
  *
- * @(#) $Header: /tcpdump/master/libpcap/pcap-dag.h,v 1.4 2005-07-07 06:55:20 guy Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/libpcap/pcap-dag.h,v 1.5 2007-11-05 21:45:07 guy Exp $ (LBL)
  */
 
 pcap_t *dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf);
 int dag_platform_finddevs(pcap_if_t **devlistp, char *errbuf);
+
+#ifndef TYPE_AAL5
+#define TYPE_AAL5               4
+#endif
+
+#ifndef TYPE_MC_HDLC
+#define TYPE_MC_HDLC            5
+#endif
+
+#ifndef TYPE_MC_RAW
+#define TYPE_MC_RAW             6
+#endif
+
+#ifndef TYPE_MC_ATM
+#define TYPE_MC_ATM             7
+#endif
+
+#ifndef TYPE_MC_RAW_CHANNEL
+#define TYPE_MC_RAW_CHANNEL     8
+#endif
+
+#ifndef TYPE_MC_AAL5
+#define TYPE_MC_AAL5            9
+#endif
+
+#ifndef TYPE_COLOR_HDLC_POS
+#define TYPE_COLOR_HDLC_POS     10
+#endif
+
+#ifndef TYPE_COLOR_ETH
+#define TYPE_COLOR_ETH          11
+#endif
+
+#ifndef TYPE_MC_AAL2
+#define TYPE_MC_AAL2            12
+#endif
+
+#ifndef TYPE_IP_COUNTER
+#define TYPE_IP_COUNTER         13
+#endif
+
+#ifndef TYPE_TCP_FLOW_COUNTER
+#define TYPE_TCP_FLOW_COUNTER   14
+#endif
+
+#ifndef TYPE_DSM_COLOR_HDLC_POS
+#define TYPE_DSM_COLOR_HDLC_POS 15
+#endif
+
+#ifndef TYPE_DSM_COLOR_ETH
+#define TYPE_DSM_COLOR_ETH      16
+#endif
+
+#ifndef TYPE_COLOR_MC_HDLC_POS
+#define TYPE_COLOR_MC_HDLC_POS  17
+#endif
+
+#ifndef TYPE_AAL2
+#define TYPE_AAL2               18
+#endif
+
+#ifndef TYPE_COLOR_HASH_POS
+#define TYPE_COLOR_HASH_POS     19
+#endif
+
+#ifndef TYPE_COLOR_HASH_ETH
+#define TYPE_COLOR_HASH_ETH     20
+#endif
+
+#ifndef TYPE_INFINIBAND
+#define TYPE_INFINIBAND         21
+#endif
+
+#ifndef TYPE_IPV4
+#define TYPE_IPV4               22
+#endif
+
+#ifndef TYPE_IPV6
+#define TYPE_IPV6               23
+#endif