데이터 패킷을 작성, 구문 분석 및 조작합니다. 이 상자는 직관적 인 높은 수준의 인터페이스를 사용하여 데이터 패킷으로 쉽게 작동하는 데 사용할 수있는 도구를 제공합니다. 기능이나 개선 사항을 요청하려면 물론 버그를보고하는 것만 큼 문제를 열어주십시오.
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에서 패킷 구조를 사용하여 이더넷> 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 단계
헤더 만 읽기 때문에 데이터가 필요하지 않은 ICMP 에코와 같은 경우이 단계는 항상 필요한 것은 아닙니다. 그러나 대부분의 경우 일부 페이로드 데이터를 추가하고 싶을 것입니다. 다시 말하지만,이를 수행하는 두 가지 방법이 있습니다. 방법 1은 익힌 페이로드 데이터를 덮어 씁니다 (새로운 패킷이라면 어쨌든 아무것도 없지만 원시 데이터에서 구문 분석 된 패킷 인 경우 일부가있을 수 있습니다). 메소드 2는 기존 페이로드 데이터에 추가됩니다. 방법 2에 .collect() 가 없음을 확인하십시오. 코드는 여전히 작동하지만 필요하지 않습니다. 소스의 함수 서명을 보면 이유를 알 수 있습니다.
// method 1
new_packet.set_payload("Hello, world!".bytes().collect());
// method 2
new_packet.extend_payload("Hello, world!".bytes());
4 단계
이제 데이터가 준비되었으므로 패킷을 구워야합니다. 이곳에서 IP 헤더의 것과 같은 체크섬 필드 및 길이 필드가 채워질 곳입니다 (OS가 과다 쓸 가능성이 있지만이를 계산하기로 결정한 이유에 대한 설명은이 문서 페이지를 참조하십시오).
let data: Vec<u8> = new_packet.into_vec();
}
항상 &Vec<u8> &[u8] 하는 함수로 전달 될 수 있다는 것을 기억하십시오. :)
패킷을 구문 분석하는 것은 패킷이 IP 헤더 또는 이더넷 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);
}
참고 : Parsing은 아직 IPv6 패킷에 구현되지 않았습니다.
새 패킷 작성 예제에서 생성 된 패킷을 방금 구문 분석 했으므로 ETH> IP> TCP 패킷이므로 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);
}