feat: add ip
This commit is contained in:
5
__network/ip/Cargo.lock
generated
Normal file
5
__network/ip/Cargo.lock
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "ip"
|
||||
version = "0.1.0"
|
||||
9
__network/ip/Cargo.toml
Normal file
9
__network/ip/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "ip"
|
||||
version = "0.1.0"
|
||||
authors = ["Hatter Jiang <jht5945@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
84
__network/ip/src/lib.rs
Normal file
84
__network/ip/src/lib.rs
Normal file
@@ -0,0 +1,84 @@
|
||||
|
||||
enum IpType {
|
||||
ICMP = 0x01,
|
||||
TCP = 0x06,
|
||||
UDP = 0x11,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct IpPackage {
|
||||
version: u8, // 4bits
|
||||
hlen: u8, // 4bits,
|
||||
type_of_service: u8, // 8bits
|
||||
total_length: u16, // 16bits
|
||||
identification: u16, // 16bits
|
||||
flags: u8, // 4bits
|
||||
fragment_offset: u16, // 12 bits
|
||||
ttl: u8, // 8bits
|
||||
protocol: u8, // 8bits
|
||||
header_checksum: u16, // 16bits
|
||||
source_ip_address: [u8; 4], // 32bits
|
||||
destination_ip_address: [u8; 4], // 32bits
|
||||
ip_options: [u8; 3], // 24bits
|
||||
data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl IpPackage {
|
||||
fn parse(bytes: &[u8]) -> Result<Self, String> {
|
||||
if bytes.len() < 24 {
|
||||
return Err("Length < 24".to_owned());
|
||||
}
|
||||
let mut bytes_iter = bytes.iter();
|
||||
let ver_hlen = bytes_iter.next().unwrap();
|
||||
let version = (ver_hlen >> 4) & 0x0f as u8;
|
||||
let hlen = ver_hlen & 0x0f as u8;
|
||||
let type_of_service = *bytes_iter.next().unwrap();
|
||||
let total_length_bytes = [*bytes_iter.next().unwrap(), *bytes_iter.next().unwrap()];
|
||||
let total_length = u16::from_be_bytes(total_length_bytes);
|
||||
let identification_bytes = [*bytes_iter.next().unwrap(), *bytes_iter.next().unwrap()];
|
||||
let identification = u16::from_be_bytes(identification_bytes);
|
||||
let tmp = *bytes_iter.next().unwrap();
|
||||
let flags = (tmp >> 4) & 0x0f as u8;
|
||||
let fragment_offset_bytes = [tmp & 0x0f, *bytes_iter.next().unwrap()];
|
||||
let fragment_offset = u16::from_be_bytes(fragment_offset_bytes);
|
||||
let ttl = *bytes_iter.next().unwrap();
|
||||
let protocol = *bytes_iter.next().unwrap();
|
||||
let header_checksum_bytes = [*bytes_iter.next().unwrap(), *bytes_iter.next().unwrap()];
|
||||
let header_checksum = u16::from_be_bytes(header_checksum_bytes);
|
||||
let source_ip_address = [
|
||||
*bytes_iter.next().unwrap(), *bytes_iter.next().unwrap(),
|
||||
*bytes_iter.next().unwrap(), *bytes_iter.next().unwrap()
|
||||
];
|
||||
let destination_ip_address = [
|
||||
*bytes_iter.next().unwrap(), *bytes_iter.next().unwrap(),
|
||||
*bytes_iter.next().unwrap(), *bytes_iter.next().unwrap()
|
||||
];
|
||||
let ip_options = [
|
||||
*bytes_iter.next().unwrap(), *bytes_iter.next().unwrap(), *bytes_iter.next().unwrap()
|
||||
];
|
||||
bytes_iter.next(); // padding
|
||||
let data = bytes[24..].to_vec();
|
||||
|
||||
Ok(Self{
|
||||
version, hlen, type_of_service, total_length,
|
||||
identification, flags, fragment_offset, ttl, protocol,
|
||||
header_checksum, source_ip_address, destination_ip_address, ip_options, data,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ip_package_parse() {
|
||||
let icmp_ip_package = vec![
|
||||
0x45, 0x00, 0x00, 0x54, 0x36, 0x55, 0x40, 0x00, 0x40, 0x01, 0x30, 0x6D, 0xC0, 0xA8,
|
||||
0x03, 0x2F, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x6C, 0x47, 0x08, 0xBF, 0x00, 0x01,
|
||||
0xE8, 0x4D, 0xA3, 0x5F, 0x00, 0x00, 0x00, 0x00, 0x33, 0x78, 0x05, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B,
|
||||
0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
|
||||
0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37
|
||||
];
|
||||
|
||||
let package = IpPackage::parse(&icmp_ip_package).unwrap();
|
||||
println!("{:#?}", package);
|
||||
assert_eq!(0x04, package.version);
|
||||
}
|
||||
Reference in New Issue
Block a user