ethernet.rs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. use core::fmt;
  2. use byteorder::{ByteOrder, NetworkEndian};
  3. enum_with_unknown! {
  4. /// Ethernet protocol type.
  5. pub enum ProtocolType(u16) {
  6. Ipv4 = 0x0800,
  7. Arp = 0x0806,
  8. Iv6 = 0x86DD
  9. }
  10. }
  11. /// A six-octet Ethernet II address.
  12. #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
  13. pub struct Address(pub [u8; 6]);
  14. impl Address {
  15. /// Construct an Ethernet address from a sequence of octets, in big-endian.
  16. ///
  17. /// # Panics
  18. /// The function panics if `data` is not six octets long.
  19. pub fn from_bytes(data: &[u8]) -> Address {
  20. let mut bytes = [0; 6];
  21. bytes.copy_from_slice(data);
  22. Address(bytes)
  23. }
  24. /// Return an Ethernet address as a sequence of octets, in big-endian.
  25. pub fn as_bytes(&self) -> &[u8] {
  26. &self.0
  27. }
  28. }
  29. impl fmt::Display for Address {
  30. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  31. let bytes = self.0;
  32. write!(f, "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
  33. bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5])
  34. }
  35. }
  36. /// A read/write wrapper around an Ethernet II frame.
  37. #[derive(Debug)]
  38. pub struct Frame<T: AsRef<[u8]>>(T);
  39. mod field {
  40. use ::wire::field::*;
  41. pub const SOURCE: Field = 0..6;
  42. pub const DESTINATION: Field = 6..12;
  43. pub const LENGTH: Field = 12..14;
  44. pub const PAYLOAD: FieldFrom = 14..;
  45. }
  46. impl<T: AsRef<[u8]>> Frame<T> {
  47. /// Wrap a buffer with an Ethernet frame. Returns an error if the buffer
  48. /// is too small or too large to contain one.
  49. pub fn new(storage: T) -> Result<Frame<T>, ()> {
  50. let len = storage.as_ref().len();
  51. if !(64..1518).contains(len) {
  52. Err(()) // TODO: error type?
  53. } else {
  54. Ok(Frame(storage))
  55. }
  56. }
  57. /// Consumes the frame, returning the underlying buffer.
  58. pub fn into_inner(self) -> T {
  59. self.0
  60. }
  61. /// Return the source address field.
  62. #[inline(always)]
  63. pub fn source(&self) -> Address {
  64. let bytes = self.0.as_ref();
  65. Address::from_bytes(&bytes[field::SOURCE])
  66. }
  67. /// Return the destination address field.
  68. #[inline(always)]
  69. pub fn destination(&self) -> Address {
  70. let bytes = self.0.as_ref();
  71. Address::from_bytes(&bytes[field::DESTINATION])
  72. }
  73. /// Return the length field, without checking for 802.1Q.
  74. #[inline(always)]
  75. pub fn length(&self) -> u16 {
  76. let bytes = self.0.as_ref();
  77. NetworkEndian::read_u16(&bytes[field::LENGTH])
  78. }
  79. /// Return a pointer to the payload, without checking for 802.1Q.
  80. #[inline(always)]
  81. pub fn payload(&self) -> &[u8] {
  82. let bytes = self.0.as_ref();
  83. &bytes[field::PAYLOAD]
  84. }
  85. }
  86. impl<T: AsRef<[u8]> + AsMut<[u8]>> Frame<T> {
  87. /// Set the source address field.
  88. #[inline(always)]
  89. pub fn set_source(&mut self, value: Address) {
  90. let bytes = self.0.as_mut();
  91. bytes[field::SOURCE].copy_from_slice(value.as_bytes())
  92. }
  93. /// Set the destination address field.
  94. #[inline(always)]
  95. pub fn set_destination(&mut self, value: Address) {
  96. let bytes = self.0.as_mut();
  97. bytes[field::DESTINATION].copy_from_slice(value.as_bytes())
  98. }
  99. /// Set the length field.
  100. #[inline(always)]
  101. pub fn set_length(&mut self, value: u16) {
  102. let bytes = self.0.as_mut();
  103. NetworkEndian::write_u16(&mut bytes[field::LENGTH], value)
  104. }
  105. /// Return a mutable pointer to the payload.
  106. #[inline(always)]
  107. pub fn payload_mut(&mut self) -> &mut [u8] {
  108. let bytes = self.0.as_mut();
  109. &mut bytes[field::PAYLOAD]
  110. }
  111. }
  112. #[cfg(test)]
  113. mod test {
  114. use super::*;
  115. static FRAME_BYTES: [u8; 64] =
  116. [0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
  117. 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
  118. 0x00, 0x40,
  119. 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  120. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  121. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  122. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  123. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  124. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  125. 0x00, 0xff];
  126. static PAYLOAD_BYTES: [u8; 50] =
  127. [0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  128. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  129. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  130. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  131. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  132. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  133. 0x00, 0xff];
  134. #[test]
  135. fn test_deconstruct() {
  136. let frame = Frame::new(&FRAME_BYTES[..]).unwrap();
  137. assert_eq!(frame.source(), Address([0x01, 0x02, 0x03, 0x04, 0x05, 0x06]));
  138. assert_eq!(frame.destination(), Address([0x11, 0x12, 0x13, 0x14, 0x15, 0x16]));
  139. assert_eq!(frame.length(), FRAME_BYTES.len() as u16);
  140. assert_eq!(frame.payload(), &PAYLOAD_BYTES[..]);
  141. }
  142. #[test]
  143. fn test_construct() {
  144. let mut bytes = vec![0; 64];
  145. let mut frame = Frame::new(&mut bytes).unwrap();
  146. frame.set_source(Address([0x01, 0x02, 0x03, 0x04, 0x05, 0x06]));
  147. frame.set_destination(Address([0x11, 0x12, 0x13, 0x14, 0x15, 0x16]));
  148. frame.set_length(64);
  149. frame.payload_mut().copy_from_slice(&PAYLOAD_BYTES[..]);
  150. assert_eq!(&frame.into_inner()[..], &FRAME_BYTES[..]);
  151. }
  152. }