parsers.rs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  1. #![cfg_attr(not(feature = "proto-ipv6"), allow(dead_code))]
  2. use core::str::FromStr;
  3. use core::result;
  4. use wire::{EthernetAddress, IpAddress, IpCidr};
  5. use wire::{Ipv4Address, Ipv4Cidr};
  6. #[cfg(feature = "proto-ipv6")]
  7. use wire::{Ipv6Address, Ipv6Cidr};
  8. type Result<T> = result::Result<T, ()>;
  9. struct Parser<'a> {
  10. data: &'a [u8],
  11. pos: usize
  12. }
  13. impl<'a> Parser<'a> {
  14. fn new(data: &'a str) -> Parser<'a> {
  15. Parser {
  16. data: data.as_bytes(),
  17. pos: 0
  18. }
  19. }
  20. fn lookahead_char(&self, ch: u8) -> bool {
  21. if self.pos < self.data.len() {
  22. self.data[self.pos] == ch
  23. } else {
  24. false
  25. }
  26. }
  27. fn advance(&mut self) -> Result<u8> {
  28. match self.data.get(self.pos) {
  29. Some(&chr) => {
  30. self.pos += 1;
  31. Ok(chr)
  32. }
  33. None => Err(())
  34. }
  35. }
  36. fn try<F, T>(&mut self, f: F) -> Option<T>
  37. where F: FnOnce(&mut Parser<'a>) -> Result<T> {
  38. let pos = self.pos;
  39. match f(self) {
  40. Ok(res) => Some(res),
  41. Err(()) => {
  42. self.pos = pos;
  43. None
  44. }
  45. }
  46. }
  47. fn accept_eof(&mut self) -> Result<()> {
  48. if self.data.len() == self.pos {
  49. Ok(())
  50. } else {
  51. Err(())
  52. }
  53. }
  54. fn until_eof<F, T>(&mut self, f: F) -> Result<T>
  55. where F: FnOnce(&mut Parser<'a>) -> Result<T> {
  56. let res = f(self)?;
  57. self.accept_eof()?;
  58. Ok(res)
  59. }
  60. fn accept_char(&mut self, chr: u8) -> Result<()> {
  61. if self.advance()? == chr {
  62. Ok(())
  63. } else {
  64. Err(())
  65. }
  66. }
  67. fn accept_str(&mut self, string: &[u8]) -> Result<()> {
  68. for byte in string.iter() {
  69. self.accept_char(*byte)?;
  70. }
  71. Ok(())
  72. }
  73. fn accept_digit(&mut self, hex: bool) -> Result<u8> {
  74. let digit = self.advance()?;
  75. if digit >= b'0' && digit <= b'9' {
  76. Ok(digit - b'0')
  77. } else if hex && digit >= b'a' && digit <= b'f' {
  78. Ok(digit - b'a' + 10)
  79. } else if hex && digit >= b'A' && digit <= b'F' {
  80. Ok(digit - b'A' + 10)
  81. } else {
  82. Err(())
  83. }
  84. }
  85. fn accept_number(&mut self, max_digits: usize, max_value: u32,
  86. hex: bool) -> Result<u32> {
  87. let mut value = self.accept_digit(hex)? as u32;
  88. for _ in 1..max_digits {
  89. match self.try(|p| p.accept_digit(hex)) {
  90. Some(digit) => {
  91. value *= if hex { 16 } else { 10 };
  92. value += digit as u32;
  93. }
  94. None => break
  95. }
  96. }
  97. if value < max_value {
  98. Ok(value)
  99. } else {
  100. Err(())
  101. }
  102. }
  103. fn accept_mac_joined_with(&mut self, separator: u8) -> Result<EthernetAddress> {
  104. let mut octets = [0u8; 6];
  105. for n in 0..6 {
  106. octets[n] = self.accept_number(2, 0x100, true)? as u8;
  107. if n != 5 {
  108. self.accept_char(separator)?;
  109. }
  110. }
  111. Ok(EthernetAddress(octets))
  112. }
  113. fn accept_mac(&mut self) -> Result<EthernetAddress> {
  114. if let Some(mac) = self.try(|p| p.accept_mac_joined_with(b'-')) {
  115. return Ok(mac)
  116. }
  117. if let Some(mac) = self.try(|p| p.accept_mac_joined_with(b':')) {
  118. return Ok(mac)
  119. }
  120. Err(())
  121. }
  122. #[cfg(feature = "proto-ipv6")]
  123. fn accept_ipv6_part(&mut self, (head, tail): (&mut [u16; 8], &mut [u16; 6]),
  124. (head_idx, tail_idx): (&mut usize, &mut usize),
  125. mut use_tail: bool, is_cidr: bool) -> Result<()> {
  126. let double_colon = match self.try(|p| p.accept_str(b"::")) {
  127. Some(_) if !use_tail && *head_idx < 7 => {
  128. // Found a double colon. Start filling out the
  129. // tail and set the double colon flag in case
  130. // this is the last character we can parse.
  131. use_tail = true;
  132. true
  133. },
  134. Some(_) => {
  135. // This is a bad address. Only one double colon is
  136. // allowed and an address is only 128 bits.
  137. return Err(());
  138. }
  139. None => {
  140. if *head_idx != 0 || use_tail && *tail_idx != 0 {
  141. // If this is not the first number or the position following
  142. // a double colon, we expect there to be a single colon.
  143. self.accept_char(b':')?;
  144. }
  145. false
  146. }
  147. };
  148. match self.try(|p| p.accept_number(4, 0x10000, true)) {
  149. Some(part) if !use_tail && *head_idx < 8 => {
  150. // Valid u16 to be added to the address
  151. head[*head_idx] = part as u16;
  152. *head_idx += 1;
  153. Ok(())
  154. },
  155. Some(part) if *tail_idx < 6 => {
  156. // Valid u16 to be added to the address
  157. tail[*tail_idx] = part as u16;
  158. *tail_idx += 1;
  159. Ok(())
  160. },
  161. Some(_) => {
  162. // Tail or head section is too long
  163. Err(())
  164. }
  165. None if double_colon && (is_cidr || self.pos == self.data.len()) => {
  166. // The address ends with "::". E.g. 1234:: or ::
  167. Ok(())
  168. }
  169. None => {
  170. // Invalid address
  171. Err(())
  172. }
  173. }?;
  174. if *head_idx + *tail_idx > 8 {
  175. // The head and tail indexes add up to a bad address length.
  176. Err(())
  177. } else if !self.lookahead_char(b':') {
  178. if *head_idx < 8 && !use_tail {
  179. // There was no double colon found, and the head is too short
  180. return Err(());
  181. }
  182. Ok(())
  183. } else {
  184. // Continue recursing
  185. self.accept_ipv6_part((head, tail), (head_idx, tail_idx), use_tail, is_cidr)
  186. }
  187. }
  188. #[cfg(feature = "proto-ipv6")]
  189. fn accept_ipv6(&mut self, is_cidr: bool) -> Result<Ipv6Address> {
  190. // IPv6 addresses may contain a "::" to indicate a series of
  191. // 16 bit sections that evaluate to 0. E.g.
  192. //
  193. // fe80:0000:0000:0000:0000:0000:0000:0001
  194. //
  195. // May be written as
  196. //
  197. // fe80::1
  198. //
  199. // As a result, we need to find the first section of colon
  200. // delimited u16's before a possible "::", then the
  201. // possible second section after the "::", and finally
  202. // combine the second optional section to the end of the
  203. // final address.
  204. //
  205. // See https://tools.ietf.org/html/rfc4291#section-2.2
  206. // for details.
  207. let (mut addr, mut tail) = ([0u16; 8], [0u16; 6]);
  208. let (mut head_idx, mut tail_idx) = (0, 0);
  209. self.accept_ipv6_part((&mut addr, &mut tail), (&mut head_idx, &mut tail_idx), false, is_cidr)?;
  210. // We need to copy the tail portion (the portion following the "::") to the
  211. // end of the address.
  212. addr[8 - tail_idx..].copy_from_slice(&tail[..tail_idx]);
  213. Ok(Ipv6Address::from_parts(&addr))
  214. }
  215. fn accept_ipv4(&mut self) -> Result<Ipv4Address> {
  216. let mut octets = [0u8; 4];
  217. for n in 0..4 {
  218. octets[n] = self.accept_number(3, 0x100, false)? as u8;
  219. if n != 3 {
  220. self.accept_char(b'.')?;
  221. }
  222. }
  223. Ok(Ipv4Address(octets))
  224. }
  225. fn accept_ip(&mut self) -> Result<IpAddress> {
  226. if let Some(ipv4) = self.try(|p| p.accept_ipv4()) {
  227. return Ok(IpAddress::Ipv4(ipv4))
  228. }
  229. #[cfg(feature = "proto-ipv6")]
  230. match self.try(|p| p.accept_ipv6(false)) {
  231. Some(ipv6) => return Ok(IpAddress::Ipv6(ipv6)),
  232. None => ()
  233. }
  234. Err(())
  235. }
  236. }
  237. impl FromStr for EthernetAddress {
  238. type Err = ();
  239. /// Parse a string representation of an Ethernet address.
  240. fn from_str(s: &str) -> Result<EthernetAddress> {
  241. Parser::new(s).until_eof(|p| p.accept_mac())
  242. }
  243. }
  244. impl FromStr for Ipv4Address {
  245. type Err = ();
  246. /// Parse a string representation of an IPv4 address.
  247. fn from_str(s: &str) -> Result<Ipv4Address> {
  248. Parser::new(s).until_eof(|p| p.accept_ipv4())
  249. }
  250. }
  251. #[cfg(feature = "proto-ipv6")]
  252. impl FromStr for Ipv6Address {
  253. type Err = ();
  254. /// Parse a string representation of an IPv6 address.
  255. fn from_str(s: &str) -> Result<Ipv6Address> {
  256. Parser::new(s).until_eof(|p| p.accept_ipv6(false))
  257. }
  258. }
  259. impl FromStr for IpAddress {
  260. type Err = ();
  261. /// Parse a string representation of an IP address.
  262. fn from_str(s: &str) -> Result<IpAddress> {
  263. Parser::new(s).until_eof(|p| p.accept_ip())
  264. }
  265. }
  266. impl FromStr for Ipv4Cidr {
  267. type Err = ();
  268. /// Parse a string representation of an IPv4 CIDR.
  269. fn from_str(s: &str) -> Result<Ipv4Cidr> {
  270. Parser::new(s).until_eof(|p| {
  271. let ip = p.accept_ipv4()?;
  272. p.accept_char(b'/')?;
  273. let prefix_len = p.accept_number(2, 33, false)? as u8;
  274. Ok(Ipv4Cidr::new(ip, prefix_len))
  275. })
  276. }
  277. }
  278. #[cfg(feature = "proto-ipv6")]
  279. impl FromStr for Ipv6Cidr {
  280. type Err = ();
  281. /// Parse a string representation of an IPv6 CIDR.
  282. fn from_str(s: &str) -> Result<Ipv6Cidr> {
  283. // https://tools.ietf.org/html/rfc4291#section-2.3
  284. Parser::new(s).until_eof(|p| {
  285. let ip = p.accept_ipv6(true)?;
  286. p.accept_char(b'/')?;
  287. let prefix_len = p.accept_number(3, 129, false)? as u8;
  288. Ok(Ipv6Cidr::new(ip, prefix_len))
  289. })
  290. }
  291. }
  292. impl FromStr for IpCidr {
  293. type Err = ();
  294. /// Parse a string representation of an IP CIDR.
  295. fn from_str(s: &str) -> Result<IpCidr> {
  296. if let Ok(ipv4) = Ipv4Cidr::from_str(s) {
  297. return Ok(IpCidr::Ipv4(ipv4))
  298. }
  299. #[cfg(feature = "proto-ipv6")]
  300. match Ipv6Cidr::from_str(s) {
  301. Ok(cidr) => return Ok(IpCidr::Ipv6(cidr)),
  302. Err(_) => ()
  303. }
  304. Err(())
  305. }
  306. }
  307. #[cfg(test)]
  308. mod test {
  309. use super::*;
  310. macro_rules! check_cidr_test_array {
  311. ($tests:expr, $from_str:path, $variant:path) => {
  312. for &(s, cidr) in &$tests {
  313. assert_eq!($from_str(s), cidr);
  314. assert_eq!(IpCidr::from_str(s), cidr.map($variant));
  315. if let Ok(cidr) = cidr {
  316. assert_eq!($from_str(&format!("{}", cidr)), Ok(cidr));
  317. assert_eq!(IpCidr::from_str(&format!("{}", cidr)),
  318. Ok($variant(cidr)));
  319. }
  320. }
  321. }
  322. }
  323. #[test]
  324. fn test_mac() {
  325. assert_eq!(EthernetAddress::from_str(""), Err(()));
  326. assert_eq!(EthernetAddress::from_str("02:00:00:00:00:00"),
  327. Ok(EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x00])));
  328. assert_eq!(EthernetAddress::from_str("01:23:45:67:89:ab"),
  329. Ok(EthernetAddress([0x01, 0x23, 0x45, 0x67, 0x89, 0xab])));
  330. assert_eq!(EthernetAddress::from_str("cd:ef:10:00:00:00"),
  331. Ok(EthernetAddress([0xcd, 0xef, 0x10, 0x00, 0x00, 0x00])));
  332. assert_eq!(EthernetAddress::from_str("00:00:00:ab:cd:ef"),
  333. Ok(EthernetAddress([0x00, 0x00, 0x00, 0xab, 0xcd, 0xef])));
  334. assert_eq!(EthernetAddress::from_str("00-00-00-ab-cd-ef"),
  335. Ok(EthernetAddress([0x00, 0x00, 0x00, 0xab, 0xcd, 0xef])));
  336. assert_eq!(EthernetAddress::from_str("AB-CD-EF-00-00-00"),
  337. Ok(EthernetAddress([0xab, 0xcd, 0xef, 0x00, 0x00, 0x00])));
  338. assert_eq!(EthernetAddress::from_str("100:00:00:00:00:00"), Err(()));
  339. assert_eq!(EthernetAddress::from_str("002:00:00:00:00:00"), Err(()));
  340. assert_eq!(EthernetAddress::from_str("02:00:00:00:00:000"), Err(()));
  341. assert_eq!(EthernetAddress::from_str("02:00:00:00:00:0x"), Err(()));
  342. }
  343. #[test]
  344. fn test_ipv4() {
  345. assert_eq!(Ipv4Address::from_str(""), Err(()));
  346. assert_eq!(Ipv4Address::from_str("1.2.3.4"),
  347. Ok(Ipv4Address([1, 2, 3, 4])));
  348. assert_eq!(Ipv4Address::from_str("001.2.3.4"),
  349. Ok(Ipv4Address([1, 2, 3, 4])));
  350. assert_eq!(Ipv4Address::from_str("0001.2.3.4"), Err(()));
  351. assert_eq!(Ipv4Address::from_str("999.2.3.4"), Err(()));
  352. assert_eq!(Ipv4Address::from_str("1.2.3.4.5"), Err(()));
  353. assert_eq!(Ipv4Address::from_str("1.2.3"), Err(()));
  354. assert_eq!(Ipv4Address::from_str("1.2.3."), Err(()));
  355. assert_eq!(Ipv4Address::from_str("1.2.3.4."), Err(()));
  356. }
  357. #[test]
  358. #[cfg(feature = "proto-ipv6")]
  359. fn test_ipv6() {
  360. // Obviously not valid
  361. assert_eq!(Ipv6Address::from_str(""), Err(()));
  362. assert_eq!(Ipv6Address::from_str("fe80:0:0:0:0:0:0:1"),
  363. Ok(Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 1)));
  364. assert_eq!(Ipv6Address::from_str("::1"),
  365. Ok(Ipv6Address::LOOPBACK));
  366. assert_eq!(Ipv6Address::from_str("::"),
  367. Ok(Ipv6Address::UNSPECIFIED));
  368. assert_eq!(Ipv6Address::from_str("fe80::1"),
  369. Ok(Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 1)));
  370. assert_eq!(Ipv6Address::from_str("1234:5678::"),
  371. Ok(Ipv6Address::new(0x1234, 0x5678, 0, 0, 0, 0, 0, 0)));
  372. assert_eq!(Ipv6Address::from_str("1234:5678::8765:4321"),
  373. Ok(Ipv6Address::new(0x1234, 0x5678, 0, 0, 0, 0, 0x8765, 0x4321)));
  374. // Two double colons in address
  375. assert_eq!(Ipv6Address::from_str("1234:5678::1::1"),
  376. Err(()));
  377. assert_eq!(Ipv6Address::from_str("4444:333:22:1::4"),
  378. Ok(Ipv6Address::new(0x4444, 0x0333, 0x0022, 0x0001, 0, 0, 0, 4)));
  379. assert_eq!(Ipv6Address::from_str("1:1:1:1:1:1::"),
  380. Ok(Ipv6Address::new(1, 1, 1, 1, 1, 1, 0, 0)));
  381. assert_eq!(Ipv6Address::from_str("::1:1:1:1:1:1"),
  382. Ok(Ipv6Address::new(0, 0, 1, 1, 1, 1, 1, 1)));
  383. assert_eq!(Ipv6Address::from_str("::1:1:1:1:1:1:1"),
  384. Err(()));
  385. // Double colon appears too late indicating an address that is too long
  386. assert_eq!(Ipv6Address::from_str("1:1:1:1:1:1:1::"),
  387. Err(()));
  388. // Section after double colon is too long for a valid address
  389. assert_eq!(Ipv6Address::from_str("::1:1:1:1:1:1:1"),
  390. Err(()));
  391. // Obviously too long
  392. assert_eq!(Ipv6Address::from_str("1:1:1:1:1:1:1:1:1"),
  393. Err(()));
  394. // Address is too short
  395. assert_eq!(Ipv6Address::from_str("1:1:1:1:1:1:1"),
  396. Err(()));
  397. // Long number
  398. assert_eq!(Ipv6Address::from_str("::000001"),
  399. Err(()));
  400. }
  401. #[test]
  402. fn test_ip_ipv4() {
  403. assert_eq!(IpAddress::from_str(""), Err(()));
  404. assert_eq!(IpAddress::from_str("1.2.3.4"),
  405. Ok(IpAddress::Ipv4(Ipv4Address([1, 2, 3, 4]))));
  406. assert_eq!(IpAddress::from_str("x"), Err(()));
  407. }
  408. #[test]
  409. #[cfg(feature = "proto-ipv6")]
  410. fn test_ip_ipv6() {
  411. assert_eq!(IpAddress::from_str(""), Err(()));
  412. assert_eq!(IpAddress::from_str("fe80::1"),
  413. Ok(IpAddress::Ipv6(Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 1))));
  414. assert_eq!(IpAddress::from_str("x"), Err(()));
  415. }
  416. #[test]
  417. fn test_cidr_ipv4() {
  418. let tests = [
  419. ("127.0.0.1/8",
  420. Ok(Ipv4Cidr::new(Ipv4Address([127, 0, 0, 1]), 8u8))),
  421. ("192.168.1.1/24",
  422. Ok(Ipv4Cidr::new(Ipv4Address([192, 168, 1, 1]), 24u8))),
  423. ("8.8.8.8/32",
  424. Ok(Ipv4Cidr::new(Ipv4Address([8, 8, 8, 8]), 32u8))),
  425. ("8.8.8.8/0",
  426. Ok(Ipv4Cidr::new(Ipv4Address([8, 8, 8, 8]), 0u8))),
  427. ("", Err(())),
  428. ("1", Err(())),
  429. ("127.0.0.1", Err(())),
  430. ("127.0.0.1/", Err(())),
  431. ("127.0.0.1/33", Err(())),
  432. ("127.0.0.1/111", Err(())),
  433. ("/32", Err(())),
  434. ];
  435. check_cidr_test_array!(tests, Ipv4Cidr::from_str, IpCidr::Ipv4);
  436. }
  437. #[test]
  438. #[cfg(feature = "proto-ipv6")]
  439. fn test_cidr_ipv6() {
  440. let tests = [
  441. ("fe80::1/64",
  442. Ok(Ipv6Cidr::new(Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 1), 64u8))),
  443. ("fe80::/64",
  444. Ok(Ipv6Cidr::new(Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 0), 64u8))),
  445. ("::1/128",
  446. Ok(Ipv6Cidr::new(Ipv6Address::LOOPBACK, 128u8))),
  447. ("::/128",
  448. Ok(Ipv6Cidr::new(Ipv6Address::UNSPECIFIED, 128u8))),
  449. ("fe80:0:0:0:0:0:0:1/64",
  450. Ok(Ipv6Cidr::new(Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 1), 64u8))),
  451. ("fe80:0:0:0:0:0:0:1|64",
  452. Err(())),
  453. ("fe80::|64",
  454. Err(())),
  455. ("fe80::1::/64",
  456. Err(()))
  457. ];
  458. check_cidr_test_array!(tests, Ipv6Cidr::from_str, IpCidr::Ipv6);
  459. }
  460. }