arp.rs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. use core::fmt;
  2. use byteorder::{ByteOrder, NetworkEndian};
  3. pub use super::EthernetProtocolType as ProtocolType;
  4. enum_with_unknown! {
  5. /// ARP network protocol type.
  6. pub enum HardwareType(u16) {
  7. Ethernet = 1
  8. }
  9. }
  10. enum_with_unknown! {
  11. /// ARP operation type.
  12. pub enum Operation(u16) {
  13. Request = 1,
  14. Reply = 2
  15. }
  16. }
  17. /// A read/write wrapper around an Address Resolution Protocol packet.
  18. #[derive(Debug)]
  19. pub struct Packet<T: AsRef<[u8]>>(T);
  20. mod field {
  21. #![allow(non_snake_case)]
  22. use ::wire::field::*;
  23. pub const HTYPE: Field = 0..2;
  24. pub const PTYPE: Field = 2..4;
  25. pub const HLEN: usize = 4;
  26. pub const PLEN: usize = 5;
  27. pub const OPER: Field = 6..8;
  28. #[inline(always)]
  29. pub fn SHA(hardware_len: u8, _protocol_len: u8) -> Field {
  30. let start = OPER.end;
  31. start..(start + hardware_len as usize)
  32. }
  33. #[inline(always)]
  34. pub fn SPA(hardware_len: u8, protocol_len: u8) -> Field {
  35. let start = SHA(hardware_len, protocol_len).end;
  36. start..(start + protocol_len as usize)
  37. }
  38. #[inline(always)]
  39. pub fn THA(hardware_len: u8, protocol_len: u8) -> Field {
  40. let start = SPA(hardware_len, protocol_len).end;
  41. start..(start + hardware_len as usize)
  42. }
  43. #[inline(always)]
  44. pub fn TPA(hardware_len: u8, protocol_len: u8) -> Field {
  45. let start = THA(hardware_len, protocol_len).end;
  46. start..(start + protocol_len as usize)
  47. }
  48. }
  49. impl<T: AsRef<[u8]>> Packet<T> {
  50. /// Wrap a buffer with an ARP packet. Returns an error if the buffer
  51. /// is too small to contain one.
  52. pub fn new(storage: T) -> Result<Packet<T>, ()> {
  53. let len = storage.as_ref().len();
  54. if len < field::OPER.end {
  55. Err(())
  56. } else {
  57. let packet = Packet(storage);
  58. if len < field::TPA(packet.hardware_len(), packet.protocol_len()).end {
  59. Err(())
  60. } else {
  61. Ok(packet)
  62. }
  63. }
  64. }
  65. /// Consumes the packet, returning the underlying buffer.
  66. pub fn into_inner(self) -> T {
  67. self.0
  68. }
  69. /// Return the hardware type field.
  70. pub fn hardware_type(&self) -> HardwareType {
  71. let bytes = self.0.as_ref();
  72. let raw = NetworkEndian::read_u16(&bytes[field::HTYPE]);
  73. HardwareType::from(raw)
  74. }
  75. /// Return the protocol type field.
  76. pub fn protocol_type(&self) -> ProtocolType {
  77. let bytes = self.0.as_ref();
  78. let raw = NetworkEndian::read_u16(&bytes[field::PTYPE]);
  79. ProtocolType::from(raw)
  80. }
  81. /// Return the hardware length field.
  82. pub fn hardware_len(&self) -> u8 {
  83. let bytes = self.0.as_ref();
  84. bytes[field::HLEN]
  85. }
  86. /// Return the protocol length field.
  87. pub fn protocol_len(&self) -> u8 {
  88. let bytes = self.0.as_ref();
  89. bytes[field::PLEN]
  90. }
  91. /// Return the operation field.
  92. pub fn operation(&self) -> Operation {
  93. let bytes = self.0.as_ref();
  94. let raw = NetworkEndian::read_u16(&bytes[field::OPER]);
  95. Operation::from(raw)
  96. }
  97. /// Return the source hardware address field.
  98. pub fn source_hardware_addr(&self) -> &[u8] {
  99. let bytes = self.0.as_ref();
  100. &bytes[field::SHA(self.hardware_len(), self.protocol_len())]
  101. }
  102. /// Return the source protocol address field.
  103. pub fn source_protocol_addr(&self) -> &[u8] {
  104. let bytes = self.0.as_ref();
  105. &bytes[field::SPA(self.hardware_len(), self.protocol_len())]
  106. }
  107. /// Return the target hardware address field.
  108. pub fn target_hardware_addr(&self) -> &[u8] {
  109. let bytes = self.0.as_ref();
  110. &bytes[field::THA(self.hardware_len(), self.protocol_len())]
  111. }
  112. /// Return the target protocol address field.
  113. pub fn target_protocol_addr(&self) -> &[u8] {
  114. let bytes = self.0.as_ref();
  115. &bytes[field::TPA(self.hardware_len(), self.protocol_len())]
  116. }
  117. }
  118. impl<T: AsRef<[u8]> + AsMut<[u8]>> Packet<T> {
  119. /// Set the hardware type field.
  120. pub fn set_hardware_type(&mut self, value: HardwareType) {
  121. let bytes = self.0.as_mut();
  122. NetworkEndian::write_u16(&mut bytes[field::HTYPE], value.into())
  123. }
  124. /// Set the protocol type field.
  125. pub fn set_protocol_type(&mut self, value: ProtocolType) {
  126. let bytes = self.0.as_mut();
  127. NetworkEndian::write_u16(&mut bytes[field::PTYPE], value.into())
  128. }
  129. /// Set the hardware length field.
  130. pub fn set_hardware_len(&mut self, value: u8) {
  131. let bytes = self.0.as_mut();
  132. bytes[field::HLEN] = value
  133. }
  134. /// Set the protocol length field.
  135. pub fn set_protocol_len(&mut self, value: u8) {
  136. let bytes = self.0.as_mut();
  137. bytes[field::PLEN] = value
  138. }
  139. /// Set the operation field.
  140. pub fn set_operation(&mut self, value: Operation) {
  141. let bytes = self.0.as_mut();
  142. NetworkEndian::write_u16(&mut bytes[field::OPER], value.into())
  143. }
  144. /// Set the source hardware address field.
  145. ///
  146. /// # Panics
  147. /// The function panics if `value` is not `self.hardware_len()` long.
  148. pub fn set_source_hardware_addr(&mut self, value: &[u8]) {
  149. let (hardware_len, protocol_len) = (self.hardware_len(), self.protocol_len());
  150. let bytes = self.0.as_mut();
  151. bytes[field::SHA(hardware_len, protocol_len)].copy_from_slice(value)
  152. }
  153. /// Set the source protocol address field.
  154. ///
  155. /// # Panics
  156. /// The function panics if `value` is not `self.protocol_len()` long.
  157. pub fn set_source_protocol_addr(&mut self, value: &[u8]) {
  158. let (hardware_len, protocol_len) = (self.hardware_len(), self.protocol_len());
  159. let bytes = self.0.as_mut();
  160. bytes[field::SPA(hardware_len, protocol_len)].copy_from_slice(value)
  161. }
  162. /// Set the target hardware address field.
  163. ///
  164. /// # Panics
  165. /// The function panics if `value` is not `self.hardware_len()` long.
  166. pub fn set_target_hardware_addr(&mut self, value: &[u8]) {
  167. let (hardware_len, protocol_len) = (self.hardware_len(), self.protocol_len());
  168. let bytes = self.0.as_mut();
  169. bytes[field::THA(hardware_len, protocol_len)].copy_from_slice(value)
  170. }
  171. /// Set the target protocol address field.
  172. ///
  173. /// # Panics
  174. /// The function panics if `value` is not `self.protocol_len()` long.
  175. pub fn set_target_protocol_addr(&mut self, value: &[u8]) {
  176. let (hardware_len, protocol_len) = (self.hardware_len(), self.protocol_len());
  177. let bytes = self.0.as_mut();
  178. bytes[field::TPA(hardware_len, protocol_len)].copy_from_slice(value)
  179. }
  180. }
  181. use super::{EthernetAddress, Ipv4Address};
  182. /// A high-level representation of an Address Resolution Protocol packet.
  183. #[derive(Debug, PartialEq, Eq, Clone, Copy)]
  184. pub enum Repr {
  185. /// An Ethernet and IPv4 Address Resolution Protocol packet.
  186. EthernetIpv4 {
  187. operation: Operation,
  188. source_hardware_addr: EthernetAddress,
  189. source_protocol_addr: Ipv4Address,
  190. target_hardware_addr: EthernetAddress,
  191. target_protocol_addr: Ipv4Address
  192. },
  193. #[doc(hidden)]
  194. __Nonexhaustive
  195. }
  196. impl Repr {
  197. /// Parse an Address Resolution Packet and return a high-level representation,
  198. /// or return `Err(())` if the packet is not recognized.
  199. pub fn parse<T: AsRef<[u8]>>(packet: &Packet<T>) -> Result<Repr, ()> {
  200. match (packet.hardware_type(), packet.protocol_type(),
  201. packet.hardware_len(), packet.protocol_len()) {
  202. (HardwareType::Ethernet, ProtocolType::Ipv4, 6, 4) => {
  203. Ok(Repr::EthernetIpv4 {
  204. operation: packet.operation(),
  205. source_hardware_addr:
  206. EthernetAddress::from_bytes(packet.source_hardware_addr()),
  207. source_protocol_addr:
  208. Ipv4Address::from_bytes(packet.source_protocol_addr()),
  209. target_hardware_addr:
  210. EthernetAddress::from_bytes(packet.target_hardware_addr()),
  211. target_protocol_addr:
  212. Ipv4Address::from_bytes(packet.target_protocol_addr())
  213. })
  214. },
  215. _ => Err(())
  216. }
  217. }
  218. /// Emit a high-level representation into an Address Resolution Packet.
  219. pub fn emit<T: AsRef<[u8]> + AsMut<[u8]>>(&self, packet: &mut Packet<T>) {
  220. match self {
  221. &Repr::EthernetIpv4 {
  222. operation,
  223. source_hardware_addr, source_protocol_addr,
  224. target_hardware_addr, target_protocol_addr
  225. } => {
  226. packet.set_hardware_type(HardwareType::Ethernet);
  227. packet.set_protocol_type(ProtocolType::Ipv4);
  228. packet.set_hardware_len(6);
  229. packet.set_protocol_len(4);
  230. packet.set_operation(operation);
  231. packet.set_source_hardware_addr(source_hardware_addr.as_bytes());
  232. packet.set_source_protocol_addr(source_protocol_addr.as_bytes());
  233. packet.set_target_hardware_addr(target_hardware_addr.as_bytes());
  234. packet.set_target_protocol_addr(target_protocol_addr.as_bytes());
  235. },
  236. &Repr::__Nonexhaustive => unreachable!()
  237. }
  238. }
  239. }
  240. impl<T: AsRef<[u8]>> fmt::Display for Packet<T> {
  241. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  242. match Repr::parse(self) {
  243. Ok(repr) => write!(f, "{}", repr),
  244. _ => {
  245. try!(write!(f, "ARP htype={:?} ptype={:?} hlen={:?} plen={:?} op={:?}",
  246. self.hardware_type(), self.protocol_type(),
  247. self.hardware_len(), self.protocol_len(),
  248. self.operation()));
  249. try!(write!(f, " sha={:?} spa={:?} tha={:?} tpa={:?}",
  250. self.source_hardware_addr(), self.source_protocol_addr(),
  251. self.target_hardware_addr(), self.target_protocol_addr()));
  252. Ok(())
  253. }
  254. }
  255. }
  256. }
  257. impl fmt::Display for Repr {
  258. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  259. match self {
  260. &Repr::EthernetIpv4 {
  261. operation,
  262. source_hardware_addr, source_protocol_addr,
  263. target_hardware_addr, target_protocol_addr
  264. } => {
  265. write!(f, "ARP type=Ethernet+IPv4 src={}/{} tgt={}/{} op={:?}",
  266. source_hardware_addr, source_protocol_addr,
  267. target_hardware_addr, target_protocol_addr,
  268. operation)
  269. },
  270. &Repr::__Nonexhaustive => unreachable!()
  271. }
  272. }
  273. }
  274. use super::pretty_print::{PrettyPrint, PrettyIndent};
  275. impl<T: AsRef<[u8]>> PrettyPrint<T> for Packet<T> {
  276. fn pretty_print(buffer: T, f: &mut fmt::Formatter,
  277. indent: &mut PrettyIndent) -> fmt::Result {
  278. match Packet::new(buffer) {
  279. Err(()) => write!(f, "{}(truncated)\n", indent),
  280. Ok(frame) => write!(f, "{}{}\n", indent, frame)
  281. }
  282. }
  283. }
  284. #[cfg(test)]
  285. mod test {
  286. use super::*;
  287. static PACKET_BYTES: [u8; 28] =
  288. [0x00, 0x01,
  289. 0x08, 0x00,
  290. 0x06,
  291. 0x04,
  292. 0x00, 0x01,
  293. 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
  294. 0x21, 0x22, 0x23, 0x24,
  295. 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
  296. 0x41, 0x42, 0x43, 0x44];
  297. #[test]
  298. fn test_deconstruct() {
  299. let packet = Packet::new(&PACKET_BYTES[..]).unwrap();
  300. assert_eq!(packet.hardware_type(), HardwareType::Ethernet);
  301. assert_eq!(packet.protocol_type(), ProtocolType::Ipv4);
  302. assert_eq!(packet.hardware_len(), 6);
  303. assert_eq!(packet.protocol_len(), 4);
  304. assert_eq!(packet.operation(), Operation::Request);
  305. assert_eq!(packet.source_hardware_addr(), &[0x11, 0x12, 0x13, 0x14, 0x15, 0x16]);
  306. assert_eq!(packet.source_protocol_addr(), &[0x21, 0x22, 0x23, 0x24]);
  307. assert_eq!(packet.target_hardware_addr(), &[0x31, 0x32, 0x33, 0x34, 0x35, 0x36]);
  308. assert_eq!(packet.target_protocol_addr(), &[0x41, 0x42, 0x43, 0x44]);
  309. }
  310. #[test]
  311. fn test_construct() {
  312. let mut bytes = vec![0; 28];
  313. let mut packet = Packet::new(&mut bytes).unwrap();
  314. packet.set_hardware_type(HardwareType::Ethernet);
  315. packet.set_protocol_type(ProtocolType::Ipv4);
  316. packet.set_hardware_len(6);
  317. packet.set_protocol_len(4);
  318. packet.set_operation(Operation::Request);
  319. packet.set_source_hardware_addr(&[0x11, 0x12, 0x13, 0x14, 0x15, 0x16]);
  320. packet.set_source_protocol_addr(&[0x21, 0x22, 0x23, 0x24]);
  321. packet.set_target_hardware_addr(&[0x31, 0x32, 0x33, 0x34, 0x35, 0x36]);
  322. packet.set_target_protocol_addr(&[0x41, 0x42, 0x43, 0x44]);
  323. assert_eq!(&packet.into_inner()[..], &PACKET_BYTES[..]);
  324. }
  325. fn packet_repr() -> Repr {
  326. Repr::EthernetIpv4 {
  327. operation: Operation::Request,
  328. source_hardware_addr:
  329. EthernetAddress::from_bytes(&[0x11, 0x12, 0x13, 0x14, 0x15, 0x16]),
  330. source_protocol_addr:
  331. Ipv4Address::from_bytes(&[0x21, 0x22, 0x23, 0x24]),
  332. target_hardware_addr:
  333. EthernetAddress::from_bytes(&[0x31, 0x32, 0x33, 0x34, 0x35, 0x36]),
  334. target_protocol_addr:
  335. Ipv4Address::from_bytes(&[0x41, 0x42, 0x43, 0x44])
  336. }
  337. }
  338. #[test]
  339. fn test_parse() {
  340. let packet = Packet::new(&PACKET_BYTES[..]).unwrap();
  341. let repr = Repr::parse(&packet).unwrap();
  342. assert_eq!(repr, packet_repr());
  343. }
  344. #[test]
  345. fn test_emit() {
  346. let mut bytes = vec![0; 28];
  347. let mut packet = Packet::new(&mut bytes).unwrap();
  348. packet_repr().emit(&mut packet);
  349. assert_eq!(&packet.into_inner()[..], &PACKET_BYTES[..]);
  350. }
  351. }