Создать, разрабатывать и манипулировать пакетами данных. Этот ящик предоставляет инструменты, которые можно использовать для легко работы с пакетами данных, используя интуитивно понятный интерфейс высокого уровня. Если вы хотите запросить какие -либо функции или улучшения, просто откройте проблему, а также, чтобы сообщить о любых ошибках, конечно.
Обратите внимание, что любые аннотации типа в этой документации, такие как let data: Vec<u8> = packet.into_vec(); , добавляются только для ясности и не требуются в вашем коде.
Шаг 1
Импортируйте соответствующие части пакета и создайте новую структуру пакета, чтобы начать его заполнять. Существует два метода создания нового пакета, метод 1 установит емкость внутреннего буфера на соответствующую длину для заданных протоколов, а метод 2 просто создаст совершенно пустой пакет с внутренним буфером, установленным в 0. Метод 1 предпочтительнее для больших пакетов, так как он будет немного более эффективным, так как не будет необходимости постоянно увеличивать способность буферизации каждые время времени.
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();
Шаг 2
Создайте заголовки и добавьте их в пакет. Здесь мы собираемся пойти со структурой пакетов в методе 1 шага 1, который 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
)
);
Шаг 3
Этот шаг не всегда может понадобиться, в таких случаях, как Echos ICMP, где не нужно быть данными, потому что читаются только заголовки. Однако во многих случаях вы, вероятно, захотите добавить некоторые данные о полезной нагрузке. Опять же, есть два способа сделать это, метод 1 будет перезаписать существующие данные о полезной нагрузке (если это новый пакет, то в любом случае не будет ни одного, но если это пакет, который был проанализирован из необработанных данных, может быть некоторые), а метод 2 добавит к существующим данным полезной нагрузки. Обратите внимание на отсутствие .collect() в методе 2. Код все равно будет работать с ним, однако это не требуется. Вы поймете, почему, если вы посмотрите на подпись функции в источнике.
// method 1
new_packet.set_payload("Hello, world!".bytes().collect());
// method 2
new_packet.extend_payload("Hello, world!".bytes());
Шаг 4
Данные теперь готовы, поэтому нам просто нужно испечь пакет. Именно здесь будут заполнены полей контрольной суммы и полей длины, таких как то, что в заголовке IP (см. На этой странице DOC, чтобы объяснить, почему я решил рассчитать их, даже если ОС, вероятно, будет перезаписать их)
let data: Vec<u8> = new_packet.into_vec();
}
Всегда помните, что &Vec<u8> можно передать в функции ожидания &[u8] :)
Расположение пакета сделано очень простым, если пакет находится в начале либо с заголовка IP, либо заголовка 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);
}
ПРИМЕЧАНИЕ: анализ еще не был реализован для пакетов IPv6
Допустим, мы только что проанализировали пакет, созданный в примере «Создать новый пакет» , так что это пакет ETH> IP> TCP, и мы хотим обновить порт Desinity поля TCP, а также IP -адрес
// 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);
}