1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
// Copyright (c) 2014, 2015 Robert Clipsham <robert@octarineparrot.com> // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. //! # libpnet //! //! `libpnet` provides a cross-platform API for low level networking using Rust. //! //! There are four key components: //! //! * The packet module, allowing safe construction and manipulation of packets //! * The pnet_packet crate, providing infrastructure for the packet module //! * The transport module, which allows implementation of transport protocols //! * The datalink module, which allows sending and receiving data link //! packets directly //! //! ## Terminology //! //! The documentation uses the following terms interchangably: //! //! * Layer 2, datalink layer //! * Layer 3, network layer //! * Layer 4, transport layer //! //! Unless otherwise stated, all interactions with libpnet are in host-byte //! order - any platform specific variations are handled internally. //! //! ## Examples //! //! More examples, including a packet logger, and a version of the echo server //! written at the transport layer, can be found in the examples/ directory. //! //! ### Ethernet echo server //! //! This (fairly useless) code implements an Ethernet echo server. Whenever a //! packet is received on an interface, it echo's the packet back; reversing the //! source and destination addresses. //! //! ```rust,no_run //! extern crate pnet; //! //! use pnet::datalink::{self, NetworkInterface}; //! use pnet::datalink::Channel::Ethernet; //! use pnet::packet::{Packet, MutablePacket}; //! //! use std::env; //! //! // Invoke as echo <interface name> //! fn main() { //! let interface_name = env::args().nth(1).unwrap(); //! let interface_names_match = //! |iface: &NetworkInterface| iface.name == interface_name; //! //! // Find the network interface with the provided name //! let interfaces = datalink::interfaces(); //! let interface = interfaces.into_iter() //! .filter(interface_names_match) //! .next() //! .unwrap(); //! //! // Create a new channel, dealing with layer 2 packets //! let (mut tx, mut rx) = match datalink::channel(&interface, Default::default()) { //! Ok(Ethernet(tx, rx)) => (tx, rx), //! Ok(_) => panic!("Unhandled channel type"), //! Err(e) => panic!("An error occurred when creating the datalink channel: {}", e) //! }; //! //! let mut iter = rx.iter(); //! loop { //! match iter.next() { //! Ok(packet) => { //! // Constructs a single packet, the same length as the the one received, //! // using the provided closure. This allows the packet to be constructed //! // directly in the write buffer, without copying. If copying is not a //! // problem, you could also use send_to. //! // //! // The packet is sent once the closure has finished executing. //! tx.build_and_send(1, packet.packet().len(), //! &mut |mut new_packet| { //! // Create a clone of the original packet //! new_packet.clone_from(&packet); //! //! // Switch the source and destination //! new_packet.set_source(packet.get_destination()); //! new_packet.set_destination(packet.get_source()); //! }); //! }, //! Err(e) => { //! // If an error occurs, we can handle it here //! panic!("An error occurred while reading: {}", e); //! } //! } //! } //! } //! ``` #![crate_name = "pnet"] #![crate_type = "rlib"] #![crate_type = "dylib"] #![deny(missing_docs)] #![cfg_attr(feature = "nightly", feature(custom_attribute, plugin))] #![cfg_attr(feature = "nightly", plugin(pnet_macros_plugin))] #![cfg_attr(feature = "clippy", feature(plugin))] #![cfg_attr(feature = "benchmark", feature(test))] #![cfg_attr(feature="clippy", plugin(clippy))] // We can't implement Iterator since we use streaming iterators #![cfg_attr(feature="clippy", allow(should_implement_trait))] #![cfg_attr(any(feature = "appveyor", feature = "travis"), deny(warnings))] #[cfg(feature = "benchmark")] extern crate test; #[cfg(windows)] extern crate winapi; extern crate libc; extern crate ipnetwork; extern crate pnet_macros_support; pub mod datalink; pub mod packet; pub mod transport; pub mod util; mod bindings; mod internal; mod sockets; // NOTE should probably have a cfg(pnet_test_network) here, but cargo doesn't // allow custom --cfg flags #[cfg(test)] mod pnettest; // Required to make sure that imports from pnet_macros work mod pnet { pub use packet; }