Commit 45c2db0f authored by Nawasan Wisitsingkhon's avatar Nawasan Wisitsingkhon

remove all unwrap

parent dac40824
......@@ -45,8 +45,8 @@ impl EthernetFrame {
tp if tp == EtherType::IP as u16 => {
let ip = IP::parse(&mut bytes);
match ip {
Some(ip) => Network::IP(ip),
None => Network::Unparsable(typ, bytes.fill_buf()?.to_vec()),
Ok(ip) => Network::IP(ip),
Err(_) => Network::Unparsable(typ, bytes.fill_buf()?.to_vec()),
}
}
tp if tp == (EtherType::ARP as u16) => {
......
use std::io::{BufRead, Cursor};
use byteorder::{BigEndian, ReadBytesExt};
use std::io::{BufRead, Cursor, Error, ErrorKind};
#[derive(Clone)]
pub struct ICMP {
......@@ -14,15 +13,15 @@ impl ICMP {
pub fn size_of() -> usize {
4
}
pub fn parse(bytes: &mut Cursor<Vec<u8>>) -> Option<ICMP> {
pub fn parse(bytes: &mut Cursor<Vec<u8>>) -> Result<ICMP, Error> {
if bytes.get_ref().len() < 4 {
return None;
return Err(Error::new(ErrorKind::Other, "icmp len wrong"));
}
let typ = bytes.read_u8().unwrap();
let code = bytes.read_u8().unwrap();
let checksum = bytes.read_u16::<BigEndian>().unwrap();
let payload = bytes.fill_buf().unwrap().to_vec();
Some(ICMP {
let typ = bytes.read_u8()?;
let code = bytes.read_u8()?;
let checksum = bytes.read_u16::<BigEndian>()?;
let payload = bytes.fill_buf()?.to_vec();
Ok(ICMP {
typ,
code,
checksum,
......
use super::{tcp::TCP, udp::UDP, ICMP};
use byteorder::{BigEndian, ReadBytesExt};
use std::io::{BufRead, Cursor, Read};
use std::io::{BufRead, Cursor, Error, ErrorKind, Read};
#[derive(Clone)]
pub struct Flags {
......@@ -33,60 +33,58 @@ pub struct IP {
}
impl IP {
pub fn parse(bytes: &mut Cursor<Vec<u8>>) -> Option<IP> {
pub fn parse(bytes: &mut Cursor<Vec<u8>>) -> Result<IP, Error> {
if bytes.get_ref().len() < 20 {
return None;
return Err(Error::new(ErrorKind::Other, "IP error len"));
}
let version_ihl = bytes.read_u8().unwrap();
let version_ihl = bytes.read_u8()?;
let version = version_ihl >> 4;
if version != 4 {
return None;
return Err(Error::new(ErrorKind::Other, "IPv4 wrong version"));
}
let ihl = version_ihl & 0x0f;
let tos = bytes.read_u8().unwrap();
let length = bytes.read_u16::<BigEndian>().unwrap();
let ident = bytes.read_u16::<BigEndian>().unwrap();
let fragment = bytes.read_u16::<BigEndian>().unwrap();
let tos = bytes.read_u8()?;
let length = bytes.read_u16::<BigEndian>()?;
let ident = bytes.read_u16::<BigEndian>()?;
let fragment = bytes.read_u16::<BigEndian>()?;
let flags = Flags {
dont_flagment: (fragment & 0x8000) > 0,
more_fragments: (fragment & 0x4000) > 0,
};
let ttl = bytes.read_u8().unwrap();
let protocol = bytes.read_u8().unwrap();
let checksum = bytes.read_u16::<BigEndian>().unwrap();
let src = bytes.read_u32::<BigEndian>().unwrap();
let dst = bytes.read_u32::<BigEndian>().unwrap();
let ttl = bytes.read_u8()?;
let protocol = bytes.read_u8()?;
let checksum = bytes.read_u16::<BigEndian>()?;
let src = bytes.read_u32::<BigEndian>()?;
let dst = bytes.read_u32::<BigEndian>()?;
let option_len = (ihl * 4) as usize - 20;
let mut options = vec![0u8; option_len];
bytes.read_exact(&mut options).unwrap();
bytes.read_exact(&mut options)?;
let ptcol = match protocol {
ptc if ptc == (IpProtocol::ICMP as u8) => {
let icmp = ICMP::parse(bytes);
match icmp {
Some(v) => EtherData::ICMP(v),
None => EtherData::Unparse(protocol, bytes.fill_buf().unwrap().to_vec()),
Ok(v) => EtherData::ICMP(v),
Err(_) => EtherData::Unparse(protocol, bytes.fill_buf()?.to_vec()),
}
}
ptc if ptc == (IpProtocol::TCP as u8) => {
let tcp = TCP::parser(bytes);
if tcp.is_some() {
EtherData::TCP(tcp.unwrap())
} else {
EtherData::Unparse(protocol, bytes.fill_buf().unwrap().to_vec())
match tcp {
Ok(tcp) => EtherData::TCP(tcp),
Err(_) => EtherData::Unparse(protocol, bytes.fill_buf()?.to_vec()),
}
}
ptc if ptc == (IpProtocol::UDP as u8) => {
let udp = UDP::parser(bytes);
if udp.is_some() {
EtherData::UDP(udp.unwrap())
} else {
EtherData::Unparse(protocol, bytes.fill_buf().unwrap().to_vec())
match udp {
Ok(udp) => EtherData::UDP(udp),
Err(_) => EtherData::Unparse(protocol, bytes.fill_buf()?.to_vec()),
}
}
_ => EtherData::Unparse(protocol, bytes.fill_buf().unwrap().to_vec()),
_ => EtherData::Unparse(protocol, bytes.fill_buf()?.to_vec()),
};
Some(IP {
Ok(IP {
version,
ihl,
length,
......@@ -111,4 +109,4 @@ pub enum EtherData {
TCP(TCP),
UDP(UDP),
Unparse(u8, Vec<u8>),
}
\ No newline at end of file
}
use crate::etherparser::tools::bits::bit_bool;
use byteorder::{BigEndian, ReadBytesExt};
use std::io::{BufRead, Cursor};
use std::io::{BufRead, Cursor, Error, ErrorKind};
#[derive(Clone)]
pub struct TCP {
......@@ -20,22 +20,22 @@ impl TCP {
pub fn size_of() -> usize {
20
}
pub fn parser(bytes: &mut Cursor<Vec<u8>>) -> Option<TCP> {
pub fn parser(bytes: &mut Cursor<Vec<u8>>) -> Result<TCP, Error> {
if bytes.get_ref().len() < TCP::size_of() {
return None;
return Err(Error::new(ErrorKind::Other, "Tcp wrong size"));
}
let src_port = bytes.read_u16::<BigEndian>().unwrap();
let dst_port = bytes.read_u16::<BigEndian>().unwrap();
let seq = bytes.read_u32::<BigEndian>().unwrap();
let ack = bytes.read_u32::<BigEndian>().unwrap();
let dataoff_reserv_flags = bytes.read_u16::<BigEndian>().unwrap();
let src_port = bytes.read_u16::<BigEndian>()?;
let dst_port = bytes.read_u16::<BigEndian>()?;
let seq = bytes.read_u32::<BigEndian>()?;
let ack = bytes.read_u32::<BigEndian>()?;
let dataoff_reserv_flags = bytes.read_u16::<BigEndian>()?;
let flags = TcpFlags::parser(dataoff_reserv_flags);
let offset = (dataoff_reserv_flags >> 12) as u8 & 0x0f;
let window = bytes.read_u16::<BigEndian>().unwrap();
let checksum = bytes.read_u16::<BigEndian>().unwrap();
let urgent = bytes.read_u16::<BigEndian>().unwrap();
let payload = bytes.fill_buf().unwrap().to_vec();
Some(TCP {
let window = bytes.read_u16::<BigEndian>()?;
let checksum = bytes.read_u16::<BigEndian>()?;
let urgent = bytes.read_u16::<BigEndian>()?;
let payload = bytes.fill_buf()?.to_vec();
Ok(TCP {
src_port,
dst_port,
seq,
......
use std::io::{BufRead, Cursor};
use std::io::{BufRead, Cursor, Error, ErrorKind};
use byteorder::{BigEndian, ReadBytesExt};
......@@ -14,15 +14,15 @@ impl UDP {
pub fn sizeof() -> usize {
8
}
pub fn parser(bytes: &mut Cursor<Vec<u8>>) -> Option<UDP> {
pub fn parser(bytes: &mut Cursor<Vec<u8>>) -> Result<UDP, Error> {
if bytes.get_ref().len() < UDP::sizeof() {
return None;
return Err(Error::new(ErrorKind::Other, "UDP error size"));
}
let src_port = bytes.read_u16::<BigEndian>().unwrap();
let des_port = bytes.read_u16::<BigEndian>().unwrap();
let checksum = bytes.read_u16::<BigEndian>().unwrap();
let payload = bytes.fill_buf().unwrap().to_vec();
Some(UDP {
let src_port = bytes.read_u16::<BigEndian>()?;
let des_port = bytes.read_u16::<BigEndian>()?;
let checksum = bytes.read_u16::<BigEndian>()?;
let payload = bytes.fill_buf()?.to_vec();
Ok(UDP {
src_port,
des_port,
checksum,
......
......@@ -17,34 +17,39 @@ pub trait ControllerFrame10 {
fn new() -> Self;
fn listener(address: &str) {
tcp_listener_handler(address);
let _ = tcp_listener_handler(address);
}
fn handle_header(&mut self, buf: &mut Vec<u8>) -> (u8, usize, u32) {
fn handle_header(&mut self, buf: &mut Vec<u8>) -> Option<(u8, usize, u32)> {
let ofp_header = self.ofp().header_parse(&buf);
(
ofp_header.message(),
ofp_header.pkt_size(),
ofp_header.xid(),
)
match ofp_header {
Ok(header) => Some((header.message(), header.pkt_size(), header.xid())),
Err(_) => None,
}
}
fn request_handler(&mut self, buf: &mut Vec<u8>, stream: &mut TcpStream) {
let ofp = self.ofp();
let (message, pkt_size, xid) = self.handle_header(buf);
let (message, pkt_size, xid) = match self.handle_header(buf) {
Some(header) => header,
None => return,
};
let mut payload = vec![0u8; pkt_size];
let _ = stream.read(&mut payload);
let message = ofp.msg_parse(message as u8);
match message {
Msg::Hello => self.hello_handler(xid, stream),
Msg::Error => self.error_handler(ErrorEvent::parse(&payload)),
Msg::Error => match ErrorEvent::parse(&payload) {
Ok(error) => self.error_handler(error),
Err(_) => (),
},
Msg::EchoRequest => {
self.echo_request_handler(xid, EchoRequestEvent::new(payload), stream)
}
Msg::PacketIn => {
self.packet_in_handler(xid, PacketInEvent::parse(&payload), stream);
}
Msg::PacketOut => (),
Msg::PacketIn => match PacketInEvent::parse(&payload) {
Ok(pkt_in) => self.packet_in_handler(xid, pkt_in, stream),
Err(_) => (),
},
_ => (),
}
}
......
use std::{
io::{BufRead, Cursor},
io::{BufRead, Cursor, Error},
mem::size_of,
};
......@@ -134,84 +134,90 @@ impl Action {
if bytes.get_ref().is_empty() {
vec![]
} else {
let action = Action::parse(bytes);
let mut v = vec![action];
v.append(&mut Action::parse_sequence(bytes));
v
if let Ok(action) = Action::parse(bytes) {
let mut v = vec![action];
v.append(&mut Action::parse_sequence(bytes));
v
} else {
vec![]
}
}
}
pub fn parse(bytes: &mut Cursor<Vec<u8>>) -> Action {
let action_code = bytes.read_u16::<BigEndian>().unwrap();
let _ = bytes.read_u16::<BigEndian>().unwrap();
pub fn parse(bytes: &mut Cursor<Vec<u8>>) -> Result<Action, Error> {
let action_code = bytes.read_u16::<BigEndian>()?;
let _ = bytes.read_u16::<BigEndian>()?;
match action_code {
t if t == (ActionType::Output as u16) => {
let port_code = bytes.read_u16::<BigEndian>().unwrap();
let len = bytes.read_u16::<BigEndian>().unwrap();
Action::Oputput(PseudoPort::new(port_code, Some(len as u64)))
let port_code = bytes.read_u16::<BigEndian>()?;
let len = bytes.read_u16::<BigEndian>()?;
Ok(Action::Oputput(PseudoPort::new(
port_code,
Some(len as u64),
)))
}
t if t == (ActionType::SetVlanId as u16) => {
let vid = bytes.read_u16::<BigEndian>().unwrap();
let vid = bytes.read_u16::<BigEndian>()?;
bytes.consume(2);
if vid == 0xffff {
Action::SetDlVlan(None)
Ok(Action::SetDlVlan(None))
} else {
Action::SetDlVlan(Some(vid))
Ok(Action::SetDlVlan(Some(vid)))
}
}
t if t == (ActionType::SetVlanPCP as u16) => {
let pcp = bytes.read_u8().unwrap();
let pcp = bytes.read_u8()?;
bytes.consume(3);
Action::SetDlVlanPcp(pcp)
Ok(Action::SetDlVlanPcp(pcp))
}
t if t == (ActionType::StripVlan as u16) => {
bytes.consume(4);
Action::SetDlVlan(None)
Ok(Action::SetDlVlan(None))
}
t if t == (ActionType::SetSrcMac as u16) => {
let mut addr = [0u8; 6];
for i in 0..6 {
addr[i] = bytes.read_u8().unwrap();
addr[i] = bytes.read_u8()?;
}
bytes.consume(6);
Action::SetDlSrc(mac_to_bytes(addr))
Ok(Action::SetDlSrc(mac_to_bytes(addr)))
}
t if t == (ActionType::SetDstMac as u16) => {
let mut addr = [0u8; 6];
for i in 0..6 {
addr[i] = bytes.read_u8().unwrap();
addr[i] = bytes.read_u8()?;
}
bytes.consume(6);
Action::SetDlDest(mac_to_bytes(addr))
Ok(Action::SetDlDest(mac_to_bytes(addr)))
}
t if t == (ActionType::SetIPv4Src as u16) => {
Action::SetIpSrc(bytes.read_u32::<BigEndian>().unwrap())
Ok(Action::SetIpSrc(bytes.read_u32::<BigEndian>()?))
}
t if t == (ActionType::SetIPv4Des as u16) => {
Action::SetIpDes(bytes.read_u32::<BigEndian>().unwrap())
Ok(Action::SetIpDes(bytes.read_u32::<BigEndian>()?))
}
t if t == (ActionType::SetTos as u16) => {
let tos = bytes.read_u8().unwrap();
let tos = bytes.read_u8()?;
bytes.consume(3);
Action::SetTos(tos)
Ok(Action::SetTos(tos))
}
t if t == (ActionType::SetTpSrc as u16) => {
let pt = bytes.read_u16::<BigEndian>().unwrap();
let pt = bytes.read_u16::<BigEndian>()?;
bytes.consume(2);
Action::SetTpSrc(pt)
Ok(Action::SetTpSrc(pt))
}
t if t == (ActionType::SetTpDst as u16) => {
let pt = bytes.read_u16::<BigEndian>().unwrap();
let pt = bytes.read_u16::<BigEndian>()?;
bytes.consume(2);
Action::SetTpDest(pt)
Ok(Action::SetTpDest(pt))
}
t if t == (ActionType::Enqueue as u16) => {
let pt = bytes.read_u16::<BigEndian>().unwrap();
let pt = bytes.read_u16::<BigEndian>()?;
bytes.consume(6);
let qid = bytes.read_u32::<BigEndian>().unwrap();
Action::Enqueue(PseudoPort::new(pt, Some(0)), qid)
let qid = bytes.read_u32::<BigEndian>()?;
Ok(Action::Enqueue(PseudoPort::new(pt, Some(0)), qid))
}
_ => Action::Unparsable,
_ => Ok(Action::Unparsable),
}
}
}
......@@ -240,4 +246,4 @@ impl SizeCheck for Vec<Action> {
not_ctrl.append(&mut is_ctrl);
not_ctrl
}
}
\ No newline at end of file
}
use std::{
io::{BufRead, Cursor},
io::{BufRead, Cursor, Error},
mem::size_of,
};
......@@ -19,13 +19,13 @@ impl ErrorEvent {
payload,
}
}
pub fn parse(buf: &Vec<u8>) -> ErrorEvent {
pub fn parse(buf: &Vec<u8>) -> Result<ErrorEvent, Error> {
let mut bytes = Cursor::new(buf);
let error_type = bytes.read_u16::<BigEndian>().unwrap();
let error_code = bytes.read_u16::<BigEndian>().unwrap();
let error_type = bytes.read_u16::<BigEndian>()?;
let error_code = bytes.read_u16::<BigEndian>()?;
let code = ErrorType::new(error_type, error_code);
let payload = bytes.fill_buf().unwrap().to_vec();
ErrorEvent::new(code, payload)
let payload = bytes.fill_buf()?.to_vec();
Ok(ErrorEvent::new(code, payload))
}
}
......
use std::io::Cursor;
use std::io::{Cursor, Error};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
......@@ -63,19 +63,19 @@ impl FlowModEvent {
}
}
pub fn parse(buf: &[u8]) -> FlowModEvent {
pub fn parse(buf: &[u8]) -> Result<FlowModEvent, Error> {
let mut bytes = Cursor::new(buf.to_vec());
let match_fields = MatchFields::parse(&mut bytes);
let cookie = bytes.read_u64::<BigEndian>().unwrap();
let command = FlowModCommand::parse(bytes.read_u16::<BigEndian>().unwrap());
let idle_timeout = Timeout::parse(bytes.read_u16::<BigEndian>().unwrap());
let hard_timeout = Timeout::parse(bytes.read_u16::<BigEndian>().unwrap());
let priority = bytes.read_u16::<BigEndian>().unwrap();
let buffer_id = bytes.read_i32::<BigEndian>().unwrap();
let out_port = PseudoPort::parse(bytes.read_u16::<BigEndian>().unwrap());
let flags = bytes.read_u16::<BigEndian>().unwrap();
let match_fields = MatchFields::parse(&mut bytes)?;
let cookie = bytes.read_u64::<BigEndian>()?;
let command = FlowModCommand::parse(bytes.read_u16::<BigEndian>()?);
let idle_timeout = Timeout::parse(bytes.read_u16::<BigEndian>()?);
let hard_timeout = Timeout::parse(bytes.read_u16::<BigEndian>()?);
let priority = bytes.read_u16::<BigEndian>()?;
let buffer_id = bytes.read_i32::<BigEndian>()?;
let out_port = PseudoPort::parse(bytes.read_u16::<BigEndian>()?);
let flags = bytes.read_u16::<BigEndian>()?;
let actions = Action::parse_sequence(&mut bytes);
FlowModEvent {
Ok(FlowModEvent {
command,
match_fields,
cookie,
......@@ -91,7 +91,7 @@ impl FlowModEvent {
}
},
out_port,
}
})
}
}
......@@ -117,8 +117,10 @@ impl MessageMarshal for FlowModEvent {
Some(buf_id) => buf_id as i32,
});
match self.out_port.as_ref() {
None => bytes.write_u16::<BigEndian>(OfpPort::None as u16).unwrap(),
Some(p) => p.marshal(bytes),
None => {
let _ = bytes.write_u16::<BigEndian>(OfpPort::None as u16);
}
}
self.flags.marshal(bytes);
for act in self.actions.move_controller_last() {
......
use std::io::{BufRead, Cursor};
use std::io::{BufRead, Cursor, Error};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
......@@ -162,11 +162,23 @@ impl MatchFields {
None => 0xffff,
};
let _ = bytes.write_u16::<BigEndian>(vlan);
let _ = bytes.write_u8(self.vlan_pcp.unwrap_or(0));
let _ = bytes.write_u8(match self.vlan_pcp {
Some(v) => v,
None => 0,
});
let _ = bytes.write_u8(0);
let _ = bytes.write_u16::<BigEndian>(self.ethernet_type.unwrap_or(0));
let _ = bytes.write_u8(self.tos.unwrap_or(0));
let _ = bytes.write_u8(self.protocol.unwrap_or(0));
let _ = bytes.write_u16::<BigEndian>(match self.ethernet_type {
Some(v) => v,
None => 0,
});
let _ = bytes.write_u8(match self.tos {
Some(v) => v,
None => 0,
});
let _ = bytes.write_u8(match self.protocol {
Some(v) => v,
None => 0,
});
let _ = bytes.write_u16::<BigEndian>(0);
let _ = bytes.write_u32::<BigEndian>(match &self.ip_src {
......@@ -177,23 +189,29 @@ impl MatchFields {
Some(ip) => ip.ip,
None => 0,
});
let _ = bytes.write_u16::<BigEndian>(self.transport_src.unwrap_or(0));
let _ = bytes.write_u16::<BigEndian>(self.transport_dest.unwrap_or(0));
let _ = bytes.write_u16::<BigEndian>(match self.transport_src {
Some(v) => v,
None => 0,
});
let _ = bytes.write_u16::<BigEndian>(match self.transport_dest {
Some(v) => v,
None => 0,
});
}
pub fn parse(bytes: &mut Cursor<Vec<u8>>) -> MatchFields {
let wildcards = Wildcards::parse(bytes.read_u32::<BigEndian>().unwrap());
pub fn parse(bytes: &mut Cursor<Vec<u8>>) -> Result<MatchFields, Error> {
let wildcards = Wildcards::parse(bytes.read_u32::<BigEndian>()?);
let in_port = if wildcards.in_port {
None
} else {
Some(bytes.read_u16::<BigEndian>().unwrap())
Some(bytes.read_u16::<BigEndian>()?)
};
let mac_src = if wildcards.mac_src {
None
} else {
let mut arr: [u8; 6] = [0; 6];
for i in 0..6 {
arr[i] = bytes.read_u8().unwrap();
arr[i] = bytes.read_u8()?;
}
Some(mac_to_bytes(arr))
};
......@@ -202,52 +220,52 @@ impl MatchFields {
} else {
let mut arr: [u8; 6] = [0; 6];
for i in 0..6 {
arr[i] = bytes.read_u8().unwrap();
arr[i] = bytes.read_u8()?;
}
Some(mac_to_bytes(arr))
};
let vlan_vid = if wildcards.vlan_vid {
None
} else {
let vid = bytes.read_u16::<BigEndian>().unwrap();
let vid = bytes.read_u16::<BigEndian>()?;
if vid == 0xfff {
None
} else {
Some(bytes.read_u16::<BigEndian>().unwrap())
Some(bytes.read_u16::<BigEndian>()?)
}
};
let vlan_pcp = if wildcards.vlan_pcp {
None
} else {
Some(bytes.read_u8().unwrap())
Some(bytes.read_u8()?)
};
bytes.consume(1);
let ethernet_type = if wildcards.ethernet_type {
None
} else {
Some(bytes.read_u16::<BigEndian>().unwrap())
Some(bytes.read_u16::<BigEndian>()?)
};
let tos = if wildcards.tos {
None
} else {
Some(bytes.read_u8().unwrap())
Some(bytes.read_u8()?)
};
let protocol = if wildcards.protocol {
None
} else {
Some(bytes.read_u8().unwrap())
Some(bytes.read_u8()?)
};
bytes.consume(2);
let ip_src = if wildcards.ip_src >= 32 {
None
} else if wildcards.ip_src == 0 {
Some(Mask {
ip: bytes.read_u32::<BigEndian>().unwrap(),
ip: bytes.read_u32::<BigEndian>()?,
mask: None,
})
} else {
Some(Mask {
ip: bytes.read_u32::<BigEndian>().unwrap(),
ip: bytes.read_u32::<BigEndian>()?,
mask: Some(wildcards.ip_src),
})
};
......@@ -255,26 +273,26 @@ impl MatchFields {
None
} else if wildcards.ip_dest == 0 {
Some(Mask {
ip: bytes.read_u32::<BigEndian>().unwrap(),
ip: bytes.read_u32::<BigEndian>()?,
mask: None,
})
} else {
Some(Mask {
ip: bytes.read_u32::<BigEndian>().unwrap(),
ip: bytes.read_u32::<BigEndian>()?,
mask: Some(wildcards.ip_dest),
})
};
let transport_src = if wildcards.transport_src {
None
} else {
Some(bytes.read_u16::<BigEndian>().unwrap())
Some(bytes.read_u16::<BigEndian>()?)
};
let transport_dest = if wildcards.transport_dest {
None
} else {
Some(bytes.read_u16::<BigEndian>().unwrap())
Some(bytes.read_u16::<BigEndian>()?)
};
MatchFields {
Ok(MatchFields {
in_port,
mac_src,
mac_dest,
......@@ -287,6 +305,6 @@ impl MatchFields {
tos,
transport_src,
transport_dest,
}
})
}
}
......@@ -38,28 +38,28 @@ impl PacketInEvent {
Payload::Buffered(_, p) | Payload::NoBuffered(p) => EthernetFrame::parse(&p),
}
}
pub fn parse(payload: &Vec<u8>) -> PacketInEvent {
pub fn parse(payload: &Vec<u8>) -> Result<PacketInEvent, Error> {
let mut bytes = Cursor::new(payload.to_vec());
let buf_id = match bytes.read_i32::<BigEndian>().unwrap() {
let buf_id = match bytes.read_i32::<BigEndian>()? {
-1 => None,
n => Some(n as u32),
};
let total_len = bytes.read_u16::<BigEndian>().unwrap();
let in_port = bytes.read_u16::<BigEndian>().unwrap();
let reason = PacketInReason::new(bytes.read_u8().unwrap());
let table_id = bytes.read_u8().unwrap();
let packet = bytes.fill_buf().unwrap().to_vec();
let total_len = bytes.read_u16::<BigEndian>()?;
let in_port = bytes.read_u16::<BigEndian>()?;
let reason = PacketInReason::new(bytes.read_u8()?);
let table_id = bytes.read_u8()?;
let packet = bytes.fill_buf()?.to_vec();
let payload = match buf_id {
Some(n) => Payload::Buffered(n as u32, packet),
None => Payload::NoBuffered(packet),
};
PacketInEvent {
Ok(PacketInEvent {
buf_id,
total_len,
in_port,
reason,
table_id,
payload,
}
})
}
}
use std::{
io::{BufRead, Cursor, Read},
io::{BufRead, Cursor, Error, Read},
mem::size_of,
};
......@@ -57,7 +57,7 @@ impl PacketOutEvent {
actions,
}
}
pub fn parse(buf: &Vec<u8>) -> Self {
pub fn parse(buf: &Vec<u8>) -> Result<Self, Error> {
let mut bytes = Cursor::new(buf);
let buf_id = match bytes
.read_i32::<BigEndian>()
......@@ -66,18 +66,16 @@ impl PacketOutEvent {
-1 => None,
n => Some(n),
};
let in_port = bytes.read_u16::<BigEndian>().unwrap();
let action_len = bytes.read_u16::<BigEndian>().unwrap();
let in_port = bytes.read_u16::<BigEndian>()?;
let action_len = bytes.read_u16::<BigEndian>()?;
let mut actions_buf = vec![0; action_len as usize];
let _ = bytes.read_exact(&mut actions_buf);
let mut action_bytes = Cursor::new(actions_buf);
let actions = Action::parse_sequence(&mut action_bytes);
Self {
Ok(Self {
payload: match buf_id {
None => Payload::NoBuffered(bytes.fill_buf().unwrap().to_vec()),
Some(n) => {
Payload::Buffered(n as u32, bytes.fill_buf().unwrap().to_ascii_lowercase())
}
None => Payload::NoBuffered(bytes.fill_buf()?.to_vec()),
Some(n) => Payload::Buffered(n as u32, bytes.fill_buf()?.to_ascii_lowercase()),
},
in_port: {
if in_port == OfpPort::None as u16 {
......@@ -87,6 +85,6 @@ impl PacketOutEvent {
}
},
actions,
}
})
}
}
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::{io::Cursor, mem::size_of};
use std::{
io::{Cursor, Error},
mem::size_of,
};
use crate::openflow::ofp10::OpenflowHeader;
......@@ -38,23 +41,23 @@ impl OpenflowHeader for OfpHeader {
return self.length as usize - size_of::<Self>();
}
fn parse(buf: &Vec<u8>) -> Self {
fn parse(buf: &Vec<u8>) -> Result<Self, Error> {
let mut buf_cursor = Cursor::new(buf);
let version = buf_cursor.read_u8().unwrap();
let message = buf_cursor.read_u8().unwrap();
let length = buf_cursor.read_u16::<BigEndian>().unwrap();
let xid = buf_cursor.read_u32::<BigEndian>().unwrap();
Self {
let version = buf_cursor.read_u8()?;
let message = buf_cursor.read_u8()?;
let length = buf_cursor.read_u16::<BigEndian>()?;
let xid = buf_cursor.read_u32::<BigEndian>()?;
Ok(Self {
version,
message,
length,
xid,
}
})
}
fn marshal(&self, bytes: &mut Vec<u8>) {
bytes.write_u8(self.version).unwrap();
bytes.write_u8(self.message).unwrap();
bytes.write_u16::<BigEndian>(self.length).unwrap();
bytes.write_u32::<BigEndian>(self.xid).unwrap();
let _ = bytes.write_u8(self.version);
let _ = bytes.write_u8(self.message);
let _ = bytes.write_u16::<BigEndian>(self.length);
let _ = bytes.write_u32::<BigEndian>(self.xid);
}
}
......@@ -13,7 +13,7 @@ impl Openflow10 {
}
impl OfpMsgEvent for Openflow10 {
fn header_parse(&self, bytes: &Vec<u8>) -> OfpHeader {
fn header_parse(&self, bytes: &Vec<u8>) -> Result<OfpHeader, std::io::Error> {
OfpHeader::parse(bytes)
}
fn header_size(&self) -> usize {
......
......@@ -40,9 +40,10 @@ impl PseudoPort {
p if p == (OfpPort::Normal as u16) => PseudoPort::Normal,
p if p == (OfpPort::Flood as u16) => PseudoPort::Flood,
p if p == (OfpPort::All as u16) => PseudoPort::AllPorts,
p if len.is_some() && p == (OfpPort::Controller as u16) => {
PseudoPort::Controller(len.unwrap())
}
p if p == (OfpPort::Controller as u16) => match len {
Some(len) => PseudoPort::Controller(len),
None => PseudoPort::Unsupport,
},
p if p == (OfpPort::Local as u16) => PseudoPort::InPort,
_ => {
if port <= (OfpPort::Max as u16) {
......
......@@ -5,8 +5,8 @@ use crate::openflow::ofp10::HelloEvent;
use super::{ControllerFrame10, OfpMsgEvent};
pub fn tcp_listener_handler(address: &str) {
let listener = TcpListener::bind(address).unwrap();
pub fn tcp_listener_handler(address: &str) -> Result<(), std::io::Error> {
let listener = TcpListener::bind(address)?;
for stream in listener.incoming() {
match stream {
Ok(mut stream) => {
......@@ -18,7 +18,6 @@ pub fn tcp_listener_handler(address: &str) {
let mut ctrl = Controller::new();
ctrl.send_msg(HelloEvent::new(), 0, &mut stream);
let ofp_size = ctrl.ofp().header_size();
// let ofp = controller.lock().unwrap().get_ofp();
let mut buffer = vec![0u8; ofp_size];
loop {
match stream.read(&mut buffer) {
......@@ -39,4 +38,5 @@ pub fn tcp_listener_handler(address: &str) {
Err(_) => panic!("Connection failed!"),
}
}
Ok(())
}
use std::io::Error;
use crate::openflow::ofp10::{
events::{Action, FeaturesReqEvent, HelloEvent, PacketOutEvent, Payload},
ofp_header::OfpHeader,
......@@ -20,7 +22,7 @@ pub trait MessageMarshal {
*/
pub trait OfpMsgEvent {
fn header(&self, message: u8, length: u16, xid: u32) -> OfpHeader;
fn header_parse(&self, bytes: &Vec<u8>) -> OfpHeader;
fn header_parse(&self, bytes: &Vec<u8>) -> Result<OfpHeader, Error>;
fn version(&self) -> usize;
fn ofp_version() -> usize;
fn header_size(&self) -> usize;
......
use std::io::Error;
pub trait OpenflowHeader {
fn version(&self) -> usize;
fn message(&self) -> u8;
......@@ -7,6 +9,8 @@ pub trait OpenflowHeader {
fn new(message: u8, length: usize, xid: usize) -> Self;
fn header_size(&self) -> usize;
fn parse(buf: &Vec<u8>) -> Self;
fn parse(buf: &Vec<u8>) -> Result<Self, Error>
where
Self: Sized;
fn marshal(&self, bytes: &mut Vec<u8>);
}
......@@ -11,7 +11,10 @@ mod tests {
let controller = Controller::new();
let ofp = controller.ofp();
let header = ofp.header_parse(&ofp_header_bytes);
let header = match ofp.header_parse(&ofp_header_bytes) {
Ok(v) => v,
Err(_) => panic!("cannot parse ofp header"),
};
assert_eq!(header.version(), 1);
assert_eq!(header.message(), 0);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment