packet2pcap.rs 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. use getopts::Options;
  2. use smoltcp::phy::{PcapLinkType, PcapSink};
  3. use smoltcp::time::Instant;
  4. use std::cell::RefCell;
  5. use std::env;
  6. use std::fs::File;
  7. use std::io::{self, Read, Write};
  8. use std::path::Path;
  9. use std::process::exit;
  10. fn convert(
  11. packet_filename: &Path,
  12. pcap_filename: &Path,
  13. link_type: PcapLinkType,
  14. ) -> io::Result<()> {
  15. let mut packet_file = File::open(packet_filename)?;
  16. let mut packet = Vec::new();
  17. packet_file.read_to_end(&mut packet)?;
  18. let pcap = RefCell::new(Vec::new());
  19. PcapSink::global_header(&pcap, link_type);
  20. PcapSink::packet(&pcap, Instant::from_millis(0), &packet[..]);
  21. let mut pcap_file = File::create(pcap_filename)?;
  22. pcap_file.write_all(&pcap.borrow()[..])?;
  23. Ok(())
  24. }
  25. fn print_usage(program: &str, opts: Options) {
  26. let brief = format!("Usage: {} [options] INPUT OUTPUT", program);
  27. print!("{}", opts.usage(&brief));
  28. }
  29. fn main() {
  30. let args: Vec<String> = env::args().collect();
  31. let program = args[0].clone();
  32. let mut opts = Options::new();
  33. opts.optflag("h", "help", "print this help menu");
  34. opts.optopt(
  35. "t",
  36. "link-type",
  37. "set link type (one of: ethernet ip)",
  38. "TYPE",
  39. );
  40. let matches = match opts.parse(&args[1..]) {
  41. Ok(m) => m,
  42. Err(e) => {
  43. eprintln!("{}", e);
  44. return;
  45. }
  46. };
  47. let link_type = match matches.opt_str("t").as_ref().map(|s| &s[..]) {
  48. Some("ethernet") => Some(PcapLinkType::Ethernet),
  49. Some("ip") => Some(PcapLinkType::Ip),
  50. _ => None,
  51. };
  52. if matches.opt_present("h") || matches.free.len() != 2 || link_type.is_none() {
  53. print_usage(&program, opts);
  54. return;
  55. }
  56. match convert(
  57. Path::new(&matches.free[0]),
  58. Path::new(&matches.free[1]),
  59. link_type.unwrap(),
  60. ) {
  61. Ok(()) => (),
  62. Err(e) => {
  63. eprintln!("Cannot convert packet to pcap: {}", e);
  64. exit(1);
  65. }
  66. }
  67. }