// luwenpeng 2022/11/17 use crate::protocol::ethernet::{self}; use crate::protocol::ethernet::{EtherType, EthernetFrame}; use crate::protocol::ip::IPProtocol; use crate::protocol::ipv4::{self, IPv4Header}; use crate::protocol::tcp::{self}; use bytes::Bytes; use bytes::BytesMut; use std::io; use tokio_util::codec::Decoder; use tokio_util::codec::Encoder; /****************************************************************************** * Encoder/Decoder trait ******************************************************************************/ #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Default)] pub struct PktCodec(()); impl PktCodec { pub fn new() -> PktCodec { PktCodec(()) } } fn handle_l4_over_v4( ipv4_header: IPv4Header, ipv4_payload: &[u8], ) -> Result, io::Error> { match ipv4_header.protocol { IPProtocol::TCP => match tcp::parse_tcp(ipv4_payload) { Ok((tcp_payload, tcp_header)) => { println!("{:?}, Payload: {}", tcp_header, tcp_payload.len()); //return Ok(Some(ata.split_to(data.len() - tcp_payload.len()),)); return Ok(None); } _other => { println!("parse TCP header need more data"); return Ok(None); } }, IPProtocol::UDP => { // return Ok(Some(ipv4_payload.split_to(ipv4_payload.len()))); return Ok(None); } _other => { println!("ipv4 protocol {:?} unsupport", _other); // return Ok(Some(ipv4_payload.split_to(ipv4_payload.len()))); return Ok(None); } } } fn handle_l2(eth_header: EthernetFrame, eth_payload: &[u8]) -> Result, io::Error> { match eth_header.ether_type { EtherType::IPv4 => match ipv4::parse_ipv4(eth_payload) { Ok((ipv4_payload, ipv4_header)) => { println!("{:?}, Payload: {}", ipv4_header, ipv4_payload.len()); handle_l4_over_v4(ipv4_header, ipv4_payload) } _other => { println!("parse IPv4 header need more data"); return Ok(None); } }, EtherType::IPv6 => { // return Ok(Some(eth_payload.split_to(eth_payload.len()))); return Ok(None); } _other => { println!("ethernet type {:?} unsupport", _other); // return Ok(Some(eth_payload.split_to(eth_payload.len()))); return Ok(None); } } } // TODO impl Decoder for PktCodec { type Item = BytesMut; type Error = io::Error; fn decode(&mut self, data: &mut BytesMut) -> Result, io::Error> { println!("PktCodec->decode(), handle data len: {}", data.len()); if data.is_empty() { return Ok(None); } match ethernet::parse_ethernet(data) { Ok((eth_payload, eth_header)) => { println!("{:?}, Payload: {}", eth_header, eth_payload.len()); handle_l2(eth_header, eth_payload) } _ => { println!("parse ethernet header need more data"); return Ok(None); } } } } // TODO impl Encoder for PktCodec { type Error = io::Error; fn encode(&mut self, _data: Bytes, _buf: &mut BytesMut) -> Result<(), io::Error> { Ok(()) } }