ethernet.rs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. use core::borrow::BorrowMut;
  2. use core::marker::PhantomData;
  3. use Error;
  4. use phy::Device;
  5. use wire::{EthernetAddress, EthernetProtocol, EthernetFrame};
  6. use wire::{ArpPacket, ArpRepr, ArpOperation};
  7. use wire::{IpAddress, IpProtocol};
  8. use wire::{Ipv4Packet, Ipv4Repr};
  9. use wire::{Icmpv4Packet, Icmpv4Repr, Icmpv4DstUnreachable};
  10. use wire::{TcpPacket, TcpRepr, TcpControl};
  11. use socket::Socket;
  12. use super::{ArpCache};
  13. /// An Ethernet network interface.
  14. ///
  15. /// The network interface logically owns a number of other data structures; to avoid
  16. /// a dependency on heap allocation, it instead owns a `BorrowMut<[T]>`, which can be
  17. /// a `&mut [T]`, or `Vec<T>` if a heap is available.
  18. #[derive(Debug)]
  19. pub struct Interface<'a, 'b: 'a,
  20. DeviceT: Device,
  21. ArpCacheT: ArpCache,
  22. ProtocolAddrsT: BorrowMut<[IpAddress]>,
  23. SocketsT: BorrowMut<[Socket<'a, 'b>]>
  24. > {
  25. device: DeviceT,
  26. arp_cache: ArpCacheT,
  27. hardware_addr: EthernetAddress,
  28. protocol_addrs: ProtocolAddrsT,
  29. sockets: SocketsT,
  30. phantom: PhantomData<Socket<'a, 'b>>
  31. }
  32. impl<'a, 'b: 'a,
  33. DeviceT: Device,
  34. ArpCacheT: ArpCache,
  35. ProtocolAddrsT: BorrowMut<[IpAddress]>,
  36. SocketsT: BorrowMut<[Socket<'a, 'b>]>
  37. > Interface<'a, 'b, DeviceT, ArpCacheT, ProtocolAddrsT, SocketsT> {
  38. /// Create a network interface using the provided network device.
  39. ///
  40. /// # Panics
  41. /// See the restrictions on [set_hardware_addr](#method.set_hardware_addr)
  42. /// and [set_protocol_addrs](#method.set_protocol_addrs) functions.
  43. pub fn new(device: DeviceT, arp_cache: ArpCacheT, hardware_addr: EthernetAddress,
  44. protocol_addrs: ProtocolAddrsT, sockets: SocketsT) ->
  45. Interface<'a, 'b, DeviceT, ArpCacheT, ProtocolAddrsT, SocketsT> {
  46. Self::check_hardware_addr(&hardware_addr);
  47. Self::check_protocol_addrs(protocol_addrs.borrow());
  48. Interface {
  49. device: device,
  50. arp_cache: arp_cache,
  51. hardware_addr: hardware_addr,
  52. protocol_addrs: protocol_addrs,
  53. sockets: sockets,
  54. phantom: PhantomData
  55. }
  56. }
  57. fn check_hardware_addr(addr: &EthernetAddress) {
  58. if addr.is_multicast() {
  59. panic!("hardware address {} is not unicast", addr)
  60. }
  61. }
  62. /// Get the hardware address of the interface.
  63. pub fn hardware_addr(&self) -> EthernetAddress {
  64. self.hardware_addr
  65. }
  66. /// Set the hardware address of the interface.
  67. ///
  68. /// # Panics
  69. /// This function panics if the address is not unicast.
  70. pub fn set_hardware_addr(&mut self, addr: EthernetAddress) {
  71. self.hardware_addr = addr;
  72. Self::check_hardware_addr(&self.hardware_addr);
  73. }
  74. fn check_protocol_addrs(addrs: &[IpAddress]) {
  75. for addr in addrs {
  76. if !addr.is_unicast() {
  77. panic!("protocol address {} is not unicast", addr)
  78. }
  79. }
  80. }
  81. /// Get the protocol addresses of the interface.
  82. pub fn protocol_addrs(&self) -> &[IpAddress] {
  83. self.protocol_addrs.borrow()
  84. }
  85. /// Update the protocol addresses of the interface.
  86. ///
  87. /// # Panics
  88. /// This function panics if any of the addresses is not unicast.
  89. pub fn update_protocol_addrs<F: FnOnce(&mut ProtocolAddrsT)>(&mut self, f: F) {
  90. f(&mut self.protocol_addrs);
  91. Self::check_protocol_addrs(self.protocol_addrs.borrow())
  92. }
  93. /// Check whether the interface has the given protocol address assigned.
  94. pub fn has_protocol_addr<T: Into<IpAddress>>(&self, addr: T) -> bool {
  95. let addr = addr.into();
  96. self.protocol_addrs.borrow().iter().any(|&probe| probe == addr)
  97. }
  98. /// Get the set of sockets owned by the interface.
  99. pub fn sockets(&mut self) -> &mut SocketsT {
  100. &mut self.sockets
  101. }
  102. /// Receive and process a packet, if available.
  103. pub fn poll(&mut self) -> Result<(), Error> {
  104. enum Response<'a> {
  105. Nop,
  106. Arp(ArpRepr),
  107. Icmpv4(Ipv4Repr, Icmpv4Repr<'a>),
  108. Tcpv4(Ipv4Repr, TcpRepr<'a>)
  109. }
  110. // First, transmit any outgoing packets.
  111. loop {
  112. if try!(self.emit()) { break }
  113. }
  114. // Now, receive any incoming packets.
  115. let rx_buffer = try!(self.device.receive());
  116. let eth_frame = try!(EthernetFrame::new(&rx_buffer));
  117. let mut response = Response::Nop;
  118. match eth_frame.ethertype() {
  119. // Snoop all ARP traffic, and respond to ARP packets directed at us.
  120. EthernetProtocol::Arp => {
  121. let arp_packet = try!(ArpPacket::new(eth_frame.payload()));
  122. match try!(ArpRepr::parse(&arp_packet)) {
  123. // Respond to ARP requests aimed at us, and fill the ARP cache
  124. // from all ARP requests, including gratuitous.
  125. ArpRepr::EthernetIpv4 {
  126. operation: ArpOperation::Request,
  127. source_hardware_addr, source_protocol_addr,
  128. target_protocol_addr, ..
  129. } => {
  130. self.arp_cache.fill(source_protocol_addr.into(), source_hardware_addr);
  131. if self.has_protocol_addr(target_protocol_addr) {
  132. response = Response::Arp(ArpRepr::EthernetIpv4 {
  133. operation: ArpOperation::Reply,
  134. source_hardware_addr: self.hardware_addr,
  135. source_protocol_addr: target_protocol_addr,
  136. target_hardware_addr: source_hardware_addr,
  137. target_protocol_addr: source_protocol_addr
  138. })
  139. }
  140. },
  141. // Fill the ARP cache from gratuitous ARP replies.
  142. ArpRepr::EthernetIpv4 {
  143. operation: ArpOperation::Reply,
  144. source_hardware_addr, source_protocol_addr, ..
  145. } => {
  146. self.arp_cache.fill(source_protocol_addr.into(), source_hardware_addr)
  147. },
  148. _ => return Err(Error::Unrecognized)
  149. }
  150. },
  151. // Handle IP packets directed at us.
  152. EthernetProtocol::Ipv4 => {
  153. let ip_packet = try!(Ipv4Packet::new(eth_frame.payload()));
  154. let ip_repr = try!(Ipv4Repr::parse(&ip_packet));
  155. // Fill the ARP cache from IP header.
  156. self.arp_cache.fill(IpAddress::Ipv4(ip_repr.src_addr), eth_frame.src_addr());
  157. match ip_repr {
  158. // Ignore IP packets not directed at us.
  159. Ipv4Repr { dst_addr, .. } if !self.has_protocol_addr(dst_addr) => (),
  160. // Respond to ICMP packets.
  161. Ipv4Repr { protocol: IpProtocol::Icmp, src_addr, dst_addr } => {
  162. let icmp_packet = try!(Icmpv4Packet::new(ip_packet.payload()));
  163. let icmp_repr = try!(Icmpv4Repr::parse(&icmp_packet));
  164. match icmp_repr {
  165. // Respond to echo requests.
  166. Icmpv4Repr::EchoRequest {
  167. ident, seq_no, data
  168. } => {
  169. let ip_reply_repr = Ipv4Repr {
  170. src_addr: dst_addr,
  171. dst_addr: src_addr,
  172. protocol: IpProtocol::Icmp
  173. };
  174. let icmp_reply_repr = Icmpv4Repr::EchoReply {
  175. ident: ident,
  176. seq_no: seq_no,
  177. data: data
  178. };
  179. response = Response::Icmpv4(ip_reply_repr, icmp_reply_repr)
  180. }
  181. // Ignore any echo replies.
  182. Icmpv4Repr::EchoReply { .. } => (),
  183. // FIXME: do something correct here?
  184. _ => return Err(Error::Unrecognized)
  185. }
  186. },
  187. // Try dispatching a packet to a socket.
  188. Ipv4Repr { src_addr, dst_addr, protocol } => {
  189. let mut handled = false;
  190. for socket in self.sockets.borrow_mut() {
  191. match socket.collect(&src_addr.into(), &dst_addr.into(),
  192. protocol, ip_packet.payload()) {
  193. Ok(()) => { handled = true; break }
  194. Err(Error::Rejected) => continue,
  195. Err(e) => return Err(e)
  196. }
  197. }
  198. if !handled && protocol == IpProtocol::Tcp {
  199. let tcp_packet = try!(TcpPacket::new(ip_packet.payload()));
  200. let ip_reply_repr = Ipv4Repr {
  201. src_addr: dst_addr,
  202. dst_addr: src_addr,
  203. protocol: IpProtocol::Tcp
  204. };
  205. let tcp_reply_repr = TcpRepr {
  206. src_port: tcp_packet.dst_port(),
  207. dst_port: tcp_packet.src_port(),
  208. control: TcpControl::Rst,
  209. seq_number: 0,
  210. ack_number: Some(tcp_packet.seq_number() + 1),
  211. window_len: 0,
  212. payload: &[]
  213. };
  214. response = Response::Tcpv4(ip_reply_repr, tcp_reply_repr);
  215. } else if !handled {
  216. let reason;
  217. if protocol == IpProtocol::Udp {
  218. reason = Icmpv4DstUnreachable::PortUnreachable
  219. } else {
  220. reason = Icmpv4DstUnreachable::ProtoUnreachable
  221. }
  222. let mut data = [0; 8];
  223. data.copy_from_slice(&ip_packet.payload()[0..8]);
  224. let ip_reply_repr = Ipv4Repr {
  225. src_addr: dst_addr,
  226. dst_addr: src_addr,
  227. protocol: IpProtocol::Icmp
  228. };
  229. let icmp_reply_repr = Icmpv4Repr::DstUnreachable {
  230. reason: reason,
  231. header: ip_repr,
  232. length: ip_packet.payload().len(),
  233. data: data
  234. };
  235. response = Response::Icmpv4(ip_reply_repr, icmp_reply_repr)
  236. }
  237. },
  238. }
  239. }
  240. // Drop all other traffic.
  241. _ => return Err(Error::Unrecognized)
  242. }
  243. macro_rules! ip_response {
  244. ($tx_buffer:ident, $frame:ident, $ip_repr:ident, $length:expr) => ({
  245. let dst_hardware_addr =
  246. match self.arp_cache.lookup($ip_repr.dst_addr.into()) {
  247. None => return Err(Error::Unaddressable),
  248. Some(hardware_addr) => hardware_addr
  249. };
  250. let payload_len = $length;
  251. let frame_len = EthernetFrame::<&[u8]>::buffer_len($ip_repr.buffer_len() +
  252. payload_len);
  253. $tx_buffer = try!(self.device.transmit(frame_len));
  254. $frame = try!(EthernetFrame::new(&mut $tx_buffer));
  255. $frame.set_src_addr(self.hardware_addr);
  256. $frame.set_dst_addr(dst_hardware_addr);
  257. $frame.set_ethertype(EthernetProtocol::Ipv4);
  258. let mut ip_packet = try!(Ipv4Packet::new($frame.payload_mut()));
  259. $ip_repr.emit(&mut ip_packet, payload_len);
  260. ip_packet
  261. })
  262. }
  263. match response {
  264. Response::Arp(repr) => {
  265. let tx_len = EthernetFrame::<&[u8]>::buffer_len(repr.buffer_len());
  266. let mut tx_buffer = try!(self.device.transmit(tx_len));
  267. let mut frame = try!(EthernetFrame::new(&mut tx_buffer));
  268. frame.set_src_addr(self.hardware_addr);
  269. frame.set_dst_addr(match repr {
  270. ArpRepr::EthernetIpv4 { target_hardware_addr, .. } => target_hardware_addr,
  271. _ => unreachable!()
  272. });
  273. frame.set_ethertype(EthernetProtocol::Arp);
  274. let mut packet = try!(ArpPacket::new(frame.payload_mut()));
  275. repr.emit(&mut packet);
  276. Ok(())
  277. },
  278. Response::Icmpv4(ip_repr, icmp_repr) => {
  279. let mut tx_buffer;
  280. let mut frame;
  281. let mut ip_packet = ip_response!(tx_buffer, frame, ip_repr,
  282. icmp_repr.buffer_len());
  283. let mut icmp_packet = try!(Icmpv4Packet::new(ip_packet.payload_mut()));
  284. icmp_repr.emit(&mut icmp_packet);
  285. Ok(())
  286. }
  287. Response::Tcpv4(ip_repr, tcp_repr) => {
  288. let mut tx_buffer;
  289. let mut frame;
  290. let mut ip_packet = ip_response!(tx_buffer, frame, ip_repr,
  291. tcp_repr.buffer_len());
  292. let mut tcp_packet = try!(TcpPacket::new(ip_packet.payload_mut()));
  293. tcp_repr.emit(&mut tcp_packet,
  294. &IpAddress::Ipv4(ip_repr.src_addr),
  295. &IpAddress::Ipv4(ip_repr.dst_addr));
  296. Ok(())
  297. }
  298. Response::Nop => {
  299. Ok(())
  300. }
  301. }
  302. }
  303. pub fn emit(&mut self) -> Result<bool, Error> {
  304. // Borrow checker is being overly careful around closures, so we have
  305. // to hack around that.
  306. let src_hardware_addr = self.hardware_addr;
  307. let src_protocol_addrs = self.protocol_addrs.borrow();
  308. let arp_cache = &mut self.arp_cache;
  309. let device = &mut self.device;
  310. let mut nothing_to_transmit = true;
  311. for socket in self.sockets.borrow_mut() {
  312. let result = socket.dispatch(&mut |src_addr, dst_addr, protocol, payload| {
  313. let src_addr =
  314. match src_addr {
  315. &IpAddress::Ipv4(_) if src_addr.is_unspecified() => {
  316. let mut assigned_addr = None;
  317. for addr in src_protocol_addrs {
  318. match addr {
  319. addr @ &IpAddress::Ipv4(_) => {
  320. assigned_addr = Some(addr);
  321. break
  322. }
  323. _ => ()
  324. }
  325. }
  326. assigned_addr.expect(
  327. "to respond to an UDP packet without a source address,\
  328. the interface must have an assigned address from \
  329. the same family")
  330. },
  331. addr => addr
  332. };
  333. let ip_repr =
  334. match (src_addr, dst_addr) {
  335. (&IpAddress::Ipv4(src_addr),
  336. &IpAddress::Ipv4(dst_addr)) => {
  337. Ipv4Repr {
  338. src_addr: src_addr,
  339. dst_addr: dst_addr,
  340. protocol: protocol
  341. }
  342. },
  343. _ => unreachable!()
  344. };
  345. let dst_hardware_addr =
  346. match arp_cache.lookup(*dst_addr) {
  347. None => return Err(Error::Unaddressable),
  348. Some(hardware_addr) => hardware_addr
  349. };
  350. let tx_len = EthernetFrame::<&[u8]>::buffer_len(ip_repr.buffer_len() +
  351. payload.buffer_len());
  352. let mut tx_buffer = try!(device.transmit(tx_len));
  353. let mut frame = try!(EthernetFrame::new(&mut tx_buffer));
  354. frame.set_src_addr(src_hardware_addr);
  355. frame.set_dst_addr(dst_hardware_addr);
  356. frame.set_ethertype(EthernetProtocol::Ipv4);
  357. let mut ip_packet = try!(Ipv4Packet::new(frame.payload_mut()));
  358. ip_repr.emit(&mut ip_packet, payload.buffer_len());
  359. payload.emit(src_addr, dst_addr, ip_packet.payload_mut());
  360. Ok(())
  361. });
  362. match result {
  363. Ok(()) => {
  364. nothing_to_transmit = false;
  365. break
  366. }
  367. Err(Error::Exhausted) => continue,
  368. Err(e) => return Err(e)
  369. }
  370. }
  371. Ok(nothing_to_transmit)
  372. }
  373. }