[ovs-dev] [PATCH] pcap-file: Add support for Linux SLL formatted PCAP files.

Simon Horman simon.horman at netronome.com
Fri Nov 16 16:44:10 UTC 2018


On Sun, Nov 11, 2018 at 03:41:08PM -0800, Ben Pfaff wrote:
> Someone sent me one of these and OVS couldn't read it.  This fixes the
> problem.
> 
> Signed-off-by: Ben Pfaff <blp at ovn.org>
> ---
>  lib/pcap-file.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 54 insertions(+)
> 
> diff --git a/lib/pcap-file.c b/lib/pcap-file.c
> index 81a094c2a01f..0f34c5e83cda 100644
> --- a/lib/pcap-file.c
> +++ b/lib/pcap-file.c
> @@ -39,9 +39,15 @@ enum ts_resolution {
>      PCAP_NSEC,
>  };
>  
> +enum network_type {
> +    PCAP_ETHERNET = 0,
> +    PCAP_LINUX_SLL = 0x71
> +};
> +
>  struct pcap_file {
>      FILE *file;
>      enum ts_resolution resolution;
> +    enum network_type network;
>  };
>  
>  struct pcap_hdr {
> @@ -130,10 +136,13 @@ ovs_pcap_read_header(struct pcap_file *p_file)
>          VLOG_WARN("failed to read pcap header: %s", ovs_retval_to_string(error));
>          return error;
>      }
> +    bool byte_swap;
>      if (ph.magic_number == 0xa1b2c3d4 || ph.magic_number == 0xd4c3b2a1) {
> +        byte_swap = ph.magic_number == 0xd4c3b2a1;
>          p_file->resolution = PCAP_USEC;
>      } else if (ph.magic_number == 0xa1b23c4d ||
>                 ph.magic_number == 0x4d3cb2a1) {
> +        byte_swap = ph.magic_number == 0x4d3cb2a1;
>          p_file->resolution = PCAP_NSEC;
>      } else {
>          VLOG_WARN("bad magic 0x%08"PRIx32" reading pcap file "
> @@ -141,6 +150,13 @@ ovs_pcap_read_header(struct pcap_file *p_file)
>                    "or 0x4d3cb2a1)", ph.magic_number);
>          return EPROTO;
>      }
> +    p_file->network = byte_swap ? uint32_byteswap(ph.network) : ph.network;
> +    if (p_file->network != PCAP_ETHERNET &&
> +        p_file->network != PCAP_LINUX_SLL) {
> +        VLOG_WARN("unknown network type %"PRIu16" reading pcap file",
> +                  p_file->network);

Hi Ben,

the line above seems to produce an error in travis-ci.

As per https://travis-ci.org/openvswitch/ovs/jobs/456022920

lib/pcap-file.c:157:19: error: format specifies type 'unsigned short' but the argument has underlying type 'unsigned int' [-Werror,-Wformat]
                  p_file->network);
~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~
./include/openvswitch/vlog.h:203:39: note: expanded from macro 'VLOG_WARN'
#define VLOG_WARN(...) VLOG(VLL_WARN, __VA_ARGS__)
                       ~~~~~~~~~~~~~~~^~~~~~~~~~~
./include/openvswitch/vlog.h:277:41: note: expanded from macro 'VLOG'
            vlog(&this_module, level__, __VA_ARGS__);   \
                                        ^~~~~~~~~~~
1 error generated.
make[2]: *** [lib/pcap-file.lo] Error 1
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2
The command "./.travis/${TRAVIS_OS_NAME}-build.sh $OPTS" exited with 2.



> +        return EPROTO;
> +    }
>      return 0;
>  }
>  
> @@ -218,6 +234,44 @@ ovs_pcap_read(struct pcap_file *p_file, struct dp_packet **bufp,
>          dp_packet_delete(buf);
>          return error;
>      }
> +
> +    if (p_file->network == PCAP_LINUX_SLL) {
> +        /* This format doesn't include the destination Ethernet address, which
> +         * is weird. */
> +
> +        struct sll_header {
> +            ovs_be16 packet_type;
> +            ovs_be16 arp_hrd;
> +            ovs_be16 lla_len;
> +            struct eth_addr dl_src;
> +            ovs_be16 reserved;
> +            ovs_be16 protocol;
> +        };
> +        const struct sll_header *sll;
> +        if (len < sizeof *sll) {
> +            VLOG_WARN("pcap packet too short for SLL header");
> +            dp_packet_delete(buf);
> +            return EPROTO;
> +        }
> +
> +        /* Pull Linux SLL header. */
> +        sll = dp_packet_pull(buf, sizeof *sll);
> +        if (sll->lla_len != htons(6)) {
> +            ovs_hex_dump(stdout, sll, sizeof *sll, 0, false);
> +            VLOG_WARN("bad SLL header");
> +            dp_packet_delete(buf);
> +            return EPROTO;
> +        }
> +
> +        /* Push Ethernet header. */
> +        struct eth_header eth = {
> +            /* eth_dst is all zeros because the format doesn't include it. */
> +            .eth_src = sll->dl_src,
> +            .eth_type = sll->protocol,
> +        };
> +        dp_packet_push(buf, &eth, sizeof eth);
> +    }
> +
>      *bufp = buf;
>      return 0;
>  }
> -- 
> 2.16.1
> 
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
> 


More information about the dev mailing list