Buat, parse, dan manipulasi paket data. Peti ini menyediakan alat yang dapat digunakan untuk dengan mudah bekerja dengan paket data menggunakan antarmuka tingkat tinggi yang intuitif. Jika Anda ingin meminta fitur atau peningkatan apa pun, harap buka saja masalah, juga untuk melaporkan bug apa pun.
Harap dicatat bahwa semua jenis anotasi dalam dokumentasi ini, seperti let data: Vec<u8> = packet.into_vec(); , hanya ditambahkan untuk kejelasan, dan tidak diperlukan dalam kode Anda.
Langkah 1
Impor bagian paket yang sesuai, dan buat struct paket baru untuk mulai mengisinya. There are two methods of creating a new packet, method 1 will set the capacity of the internal buffer to the appropriate length for the given protocols, and method 2 will just create a totally empty packet with the internal buffer capacity set to 0. Method 1 is preferred for large packets as it will be slightly more efficient as there will be no need to constantly increase the cpacity of the buffer each time data is added
extern crate packet_crafter;
use packet_crafter::{
//import sub-modules
headers,
protocol_numbers,
ethertype_numbers,
//import data types
Packet,
Protocol
};
fn main() {
// method 1 (preferred)
let mut new_packet = Packet::new(
vec![
Protocol::ETH,
Protocol::IP,
Protocol::TCP
]
);
// method 2
let mut new_packet = Packet::new_empty();
Langkah 2
Buat header dan tambahkan ke dalam paket. Di sini kita akan menggunakan struktur paket dalam Metode 1 dari Langkah 1, yang Ethernet> IP> TCP
new_packet.add_header(
headers::EthernetHeader::new(
[6,5,4,3,2,1], // source mac address
[1,2,3,4,5,6], // destination mac address
ethertype_numbers::ETHERTYPE_IPV4
)
);
new_packet.add_header(
headers::IpHeader::new(
[192, 168, 1, 128], // source IP
[192, 168, 1, 38], // destination IP
Protocol::TCP // next protocol
)
);
new_packet.add_header(
headers::TcpHeader::new(
3838, // source port
3838 // destination port
)
);
Langkah 3
Langkah ini mungkin tidak selalu diperlukan, dalam kasus -kasus seperti ECMP Echos di mana tidak perlu ada data karena hanya header yang dibaca. Namun, dalam banyak kasus, Anda mungkin ingin menambahkan beberapa data muatan. Sekali lagi, ada dua cara untuk melakukan ini, Metode 1 akan menimpa data muatan yang ada (jika ini adalah paket baru tidak akan ada, tetapi jika itu adalah paket yang telah diuraikan dari data mentah, mungkin ada beberapa), dan Metode 2 akan ditambahkan ke data muatan yang ada. Perhatikan tidak adanya .collect() dalam Metode 2. Kode masih akan bekerja dengannya, namun, tidak diperlukan. Anda akan melihat mengapa jika Anda melihat tanda tangan fungsi di sumbernya.
// method 1
new_packet.set_payload("Hello, world!".bytes().collect());
// method 2
new_packet.extend_payload("Hello, world!".bytes());
Langkah 4
Data sekarang siap, jadi kita hanya perlu memanggang paket. Di sinilah bidang checksum dan bidang panjang seperti yang ada di header IP akan diisi (lihat halaman dokumen ini untuk penjelasan mengapa saya memutuskan untuk menghitung ini meskipun OS kemungkinan akan menimpanya)
let data: Vec<u8> = new_packet.into_vec();
}
selalu ingat bahwa &Vec<u8> dapat diteruskan ke fungsi yang diharapkan &[u8] :)
Parsing paket dibuat sangat sederhana, selama paket ini dimulai dengan header IP atau header Ethernet II:
extern crate packet_crafter;
use packet_crafter::Packet;
fn main() {
let raw_data: &[u8] = your_function_to_read_a_packet_from_socket();
let parsed_packet: Result<Packet, packet_crafter::ParseError> = Packet::parse(raw_data);
}
Catatan: Parsing belum diterapkan untuk paket IPv6
Katakanlah kita baru saja menguraikan paket yang dibuat dalam contoh Paket Buat baru , jadi ini adalah paket ETH> IP> TCP, dan kami ingin memperbarui port desinasi dari bidang TCP serta IP tujuan:
// imports elided
fn main() {
let raw_data: &[u8] = your_function_to_read_a_packet_from_socket();
let mut packet = Packet::parse(raw_data).unwrap();
let mut tcp_header = packet.get_tcp_header().unwrap();
tcp_header.set_dst_port(21);
let mut ip_header = packet.get_ip_header().unwrap();
ip_header.set_dst_ip([192, 168, 1, 84]);
packet.update_header(ip_header);
// packet is now good to go, so make it and then send it:
let data = packet.into_vec();
your_function_to_send_packet_down_socket(&data);
}