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

remove all unwrap

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