Looks good to me, thanks. Reviewed-by: Yifeng Sun <pkusunyif...@gmail.com>
On Sun, Nov 11, 2018 at 3:41 PM Ben Pfaff <b...@ovn.org> wrote: > Someone sent me one of these and OVS couldn't read it. This fixes the > problem. > > Signed-off-by: Ben Pfaff <b...@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); > + 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, ð, sizeof eth); > + } > + > *bufp = buf; > return 0; > } > -- > 2.16.1 > > _______________________________________________ > dev mailing list > d...@openvswitch.org > https://mail.openvswitch.org/mailman/listinfo/ovs-dev > _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev