1use ffi::if_nametoindex;
2use error::EAFNOSUPPORT;
3use ip::{LlAddr, IpAddrV4, IpAddrV6, IpAddr};
4
5use std::io;
6use std::result;
7use std::str::{Chars, FromStr};
8use std::ffi::CString;
9
10#[derive(Debug)]
11struct ParseError;
12
13type Result<T> = result::Result<T, ParseError>;
14
15trait Parser : Clone + Copy {
16 type Output;
17 fn parse<'a>(&self, it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)>;
18}
19
20#[derive(Clone, Copy)]
21struct Lit(char);
22impl Parser for Lit {
23 type Output = ();
24
25 fn parse<'a>(&self, mut it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)> {
26 match it.next() {
27 Some(ch) if ch == self.0 => Ok(((), it)),
28 _ => Err(ParseError),
29 }
30 }
31}
32
33#[derive(Clone, Copy)]
34struct LitOr(char, char);
35impl Parser for LitOr {
36 type Output = ();
37
38 fn parse<'a>(&self, mut it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)> {
39 match it.next() {
40 Some(ch) if ch == self.0 || ch == self.1 => Ok(((), it)),
41 _ => Err(ParseError),
42 }
43 }
44}
45
46#[derive(Clone, Copy)]
47struct Char(&'static str);
48impl Parser for Char {
49 type Output = char;
50
51 fn parse<'a>(&self, mut it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)> {
52 if let Some(ch) = it.next() {
53 let mut a = '\0';
54 let mut chars = self.0.chars();
55 while let Some(b) = chars.next() {
56 if b == '-' {
57 if let Some(b) = chars.next() {
58 if a < ch && ch <= b {
59 return Ok((ch, it))
60 }
61 } else if ch == '-' {
62 return Ok((ch, it));
63 }
64 } else if ch == b {
65 return Ok((ch, it))
66 }
67 a = b;
68 }
69 }
70 Err(ParseError)
71 }
72}
73
74#[derive(Clone, Copy)]
75struct Dec8;
76impl Parser for Dec8 {
77 type Output = u8;
78
79 fn parse<'a>(&self, mut it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)> {
80 let mut n = match it.next() {
81 Some(ch) => match ch.to_digit(10) {
82 Some(i) => i,
83 _ => return Err(ParseError),
84 },
85 _ => return Err(ParseError),
86 };
87 for _ in 0..2 {
88 let p = it.clone();
89 n = match it.next() {
90 Some(ch) => match ch.to_digit(10) {
91 Some(i) => n * 10 + i,
92 _ => return Ok((n as u8, p))
93 },
94 _ => return Ok((n as u8, p)),
95 };
96 }
97 if n <= 255 {
98 Ok((n as u8, it))
99 } else {
100 Err(ParseError)
101 }
102 }
103}
104
105#[derive(Clone, Copy)]
106struct Hex08;
107impl Parser for Hex08 {
108 type Output = u8;
109
110 fn parse<'a>(&self, mut it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)> {
111 let mut n = match it.next() {
112 Some(ch) => match ch.to_digit(16) {
113 Some(i) => i,
114 _ => return Err(ParseError),
115 },
116 _ => return Err(ParseError),
117 };
118 n = match it.next() {
119 Some(ch) => match ch.to_digit(16) {
120 Some(i) => n * 16 + i,
121 _ => return Err(ParseError),
122 },
123 _ => return Err(ParseError),
124 };
125 if n <= 255 {
126 Ok((n as u8, it))
127 } else {
128 Err(ParseError)
129 }
130 }
131}
132
133#[derive(Clone, Copy)]
134struct Hex16;
135impl Parser for Hex16 {
136 type Output = u16;
137
138 fn parse<'a>(&self, mut it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)> {
139 let mut n = match it.next() {
140 Some(ch) => match ch.to_digit(16) {
141 Some(i) => i,
142 _ => return Err(ParseError),
143 },
144 _ => return Err(ParseError),
145 };
146 for _ in 0..4 {
147 let p = it.clone();
148 n = match it.next() {
149 Some(ch) => match ch.to_digit(16) {
150 Some(i) => n * 16 + i,
151 _ => return Ok((n as u16, p)),
152 },
153 _ => return Ok((n as u16, p)),
154 };
155 }
156 if n < 65536 {
157 Ok((n as u16, it))
158 } else {
159 Err(ParseError)
160 }
161 }
162}
163
164#[derive(Clone, Copy)]
165struct Cat<P1, P2>(P1, P2);
166impl<P1: Parser, P2: Parser> Parser for Cat<P1, P2> {
167 type Output = (P1::Output, P2::Output);
168
169 fn parse<'a>(&self, it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)> {
170 if let Ok((a, it)) = self.0.parse(it) {
171 if let Ok((b, it)) = self.1.parse(it) {
172 return Ok(((a, b), it));
173 }
174 }
175 Err(ParseError)
176 }
177}
178
179#[derive(Clone, Copy)]
180struct Sep4By<P: Parser, By: Parser>(P, By);
181impl<P: Parser, By: Parser> Parser for Sep4By<P, By> {
182 type Output = [P::Output; 4];
183
184 fn parse<'a>(&self, it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)> {
185 let (a, it) = try!(self.0.parse(it));
186 let (_, it) = try!(self.1.parse(it));
187 let (b, it) = try!(self.0.parse(it));
188 let (_, it) = try!(self.1.parse(it));
189 let (c, it) = try!(self.0.parse(it));
190 let (_, it) = try!(self.1.parse(it));
191 let (d, it) = try!(self.0.parse(it));
192 Ok(([a,b,c,d], it))
193 }
194}
195
196#[derive(Clone, Copy)]
197struct Sep6By<P, By>(P, By);
198impl<P: Parser, By: Parser> Parser for Sep6By<P, By> {
199 type Output = [P::Output; 6];
200
201 fn parse<'a>(&self, it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)> {
202 let (a, it) = try!(self.0.parse(it));
203 let (_, it) = try!(self.1.parse(it));
204 let (b, it) = try!(self.0.parse(it));
205 let (_, it) = try!(self.1.parse(it));
206 let (c, it) = try!(self.0.parse(it));
207 let (_, it) = try!(self.1.parse(it));
208 let (d, it) = try!(self.0.parse(it));
209 let (_, it) = try!(self.1.parse(it));
210 let (e, it) = try!(self.0.parse(it));
211 let (_, it) = try!(self.1.parse(it));
212 let (f, it) = try!(self.0.parse(it));
213 Ok(([a,b,c,d,e,f], it))
214 }
215}
216
217#[derive(Clone, Copy)]
218struct SepBy<P, By>(P, By, usize);
219impl<P: Parser, By: Parser> Parser for SepBy<P, By> {
220 type Output = Vec<P::Output>;
221
222 fn parse<'a>(&self, mut it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)> {
223 let mut vec = Vec::new();
224
225 if let Ok((a, ne)) = self.0.parse(it.clone()) {
226 it = ne;
227 vec.push(a);
228
229 while vec.len() < self.2 {
230 if let Ok(((_, a), ne)) = Cat(self.1, self.0).parse(it.clone()) {
231 it = ne;
232 vec.push(a);
233 } else {
234 break;
235 }
236 }
237 }
238 Ok((vec, it))
239 }
240}
241
242#[derive(Clone, Copy)]
243struct Between<A, P, B>(A, P, B);
244impl<A: Parser, P: Parser, B: Parser> Parser for Between<A, P, B> {
245 type Output = P::Output;
246
247 fn parse<'a>(&self, it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)> {
248 let (_, it) = try!(self.0.parse(it));
249 let (a, it) = try!(self.1.parse(it));
250 let (_, it) = try!(self.2.parse(it));
251 Ok((a, it))
252 }
253}
254
255#[derive(Clone, Copy)]
256struct Eos<P>(P);
257impl<P: Parser> Parser for Eos<P> {
258 type Output = P::Output;
259
260 fn parse<'a>(&self, it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)> {
261 let (a, mut it) = try!(self.0.parse(it));
262 if let Some(_) = it.next() {
263 return Err(ParseError);
264 }
265 Ok((a, it))
266 }
267}
268
269fn hex16_to_dec8(mut hex: u16) -> Option<u8> {
270 let d = hex % 16;
271 if d >= 10 { return None; }
272 hex /= 16;
273 let c = hex % 16;
274 if c >= 10 { return None; }
275 hex /= 16;
276 let b = hex % 16;
277 if b >= 10 { return None; }
278 hex /= 16;
279 let a = hex % 16;
280 if a >= 10 { return None; }
281 Some((((a * 10 + b) * 10 + c) * 10 + d) as u8)
282}
283
284#[derive(Clone, Copy)]
285struct IpV6;
286impl Parser for IpV6 {
287 type Output = [u16; 8];
288
289 fn parse<'a>(&self, mut it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)> {
290 fn parse_ipv4<'a>(mut ar: [u16; 8], it: Chars<'a>) -> Result<([u16; 8], Chars<'a>)> {
291 if ar[0] == 0 && ar[1] == 0 && ar[2] == 0 && ar[3] == 0 && ar[4] == 0
292 && (ar[5] == 0 && ar[6] == 0 ||
293 ar[5] == 65535 && ar[6] == 0 ||
294 ar[5] == 0 && ar[6] == 65535)
295 {
296 if let Some(a) = hex16_to_dec8(ar[7]) {
297 if let Ok(((_, b), ne)) = Cat(Lit('.'), Dec8).parse(it.clone()) {
298 if let Ok(((_, c), ne)) = Cat(Lit('.'), Dec8).parse(ne) {
299 if let Ok(((_, d), ne)) = Cat(Lit('.'), Dec8).parse(ne) {
300 if ar[6] == 0xFFFF {
301 ar[5] = 0xFFFF;
302 }
303 ar[6] = (a as u16 * 256) | b as u16;
304 ar[7] = (c as u16 * 256) | d as u16;
305 return Ok((ar, ne));
306 }
307 }
308 }
309 }
310 }
311 Ok((ar, it))
312 }
313
314 fn parse_rev<'a>(mut ar: [u16; 8], i: usize, it: Chars<'a>) -> Result<([u16; 8], Chars<'a>)> {
315 if let Ok((seps, it)) = SepBy(Hex16, Lit(':'), 7-i).parse(it.clone()) {
316 for (i, hex) in seps.iter().rev().enumerate() {
317 ar[7-i] = *hex;
318 }
319 return parse_ipv4(ar, it);
320 }
321
322 Err(ParseError)
323 }
324
325 let mut ar = [0; 8];
326 for i in 0..7 {
327 if let Ok((_, it)) = Cat(Lit(':'), Lit(':')).parse(it.clone()) {
328 return parse_rev(ar, i, it);
329 } else if let Ok(((hex, _), ne)) = Cat(Hex16, Lit(':')).parse(it.clone()) {
330 ar[i] = hex;
331 it = ne;
332 if let Ok((_, it)) = Lit(':').parse(it.clone()) {
333 return parse_rev(ar, i, it);
334 }
335 } else {
336 return parse_rev(ar, i, it);
337 }
338 }
339
340 if let Ok((hex, it)) = Hex16.parse(it.clone()) {
341 ar[7] = hex;
342 Ok((ar, it))
343 } else if let Ok((_, it)) = Lit(':').parse(it) {
344 Ok((ar, it))
345 } else {
346 Err(ParseError)
347 }
348 }
349}
350
351#[derive(Clone, Copy)]
352struct ScopeId;
353impl Parser for ScopeId {
354 type Output = u32;
355
356 fn parse<'a>(&self, it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)> {
357 if let Ok((_, it)) = Lit('%').parse(it.clone()) {
358 if let Ok((ch, mut it)) = Char("a-zA-Z").parse(it.clone()) {
359 let mut vec: Vec<u8> = Vec::new();
360 vec.push(ch as u8);
361 while let Ok((ch, ne)) = Char("0-9a-zA-Z.:_-").parse(it.clone()) {
362 vec.push(ch as u8);
363 it = ne;
364 }
365 let name = unsafe { CString::from_vec_unchecked(vec) };
366 if let Ok(id) = if_nametoindex(&name) {
367 return Ok((id, it));
368 }
369 }
370 if let Ok((dec, it)) = Dec8.parse(it.clone()) {
371 return Ok((dec as u32, it));
372 }
373 }
374 Ok((0, it))
375 }
376}
377
378impl FromStr for LlAddr {
379 type Err = io::Error;
380
381 fn from_str(s: &str) -> io::Result<LlAddr> {
382 if let Ok((addr, _)) = Eos(Sep6By(Hex08, LitOr('-', ':'))).parse(s.chars()) {
383 Ok(LlAddr::new(addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]))
384 } else {
385 Err(EAFNOSUPPORT.into())
386 }
387 }
388}
389
390impl FromStr for IpAddrV4 {
391 type Err = io::Error;
392
393 fn from_str(s: &str) -> io::Result<IpAddrV4> {
394 if let Ok((addr, _)) = Eos(Sep4By(Dec8, Lit('.'))).parse(s.chars()) {
395 Ok(IpAddrV4::new(addr[0], addr[1], addr[2], addr[3]))
396 } else {
397 Err(EAFNOSUPPORT.into())
398 }
399 }
400}
401
402impl FromStr for IpAddrV6 {
403 type Err = io::Error;
404
405 fn from_str(s: &str) -> io::Result<IpAddrV6> {
406 if let Ok(((addr, id), _)) = Eos(Cat(IpV6, ScopeId)).parse(s.chars()) {
407 Ok(IpAddrV6::with_scope_id(addr[0], addr[1], addr[2], addr[3],
408 addr[4], addr[5], addr[6], addr[7], id))
409 } else {
410 Err(EAFNOSUPPORT.into())
411 }
412 }
413}
414
415impl FromStr for IpAddr {
416 type Err = io::Error;
417
418 fn from_str(s: &str) -> io::Result<IpAddr> {
419 match IpAddrV4::from_str(s) {
420 Ok(v4) => Ok(IpAddr::V4(v4)),
421 Err(_) => match IpAddrV6::from_str(s) {
422 Ok(v6) => Ok(IpAddr::V6(v6)),
423 Err(err) => Err(err),
424 }
425 }
426 }
427}
428
429#[test]
430fn test_lit() {
431 assert_eq!(Lit('.').parse(".0".chars()).unwrap().0, ());
432 assert_eq!(Lit(':').parse(":1".chars()).unwrap().0, ());
433}
434
435#[test]
436fn test_lit_or() {
437 assert_eq!(LitOr(':', '-').parse("-1".chars()).unwrap().0, ());
438 assert_eq!(LitOr(':', '-').parse(":2".chars()).unwrap().0, ());
439}
440
441#[test]
442fn test_char() {
443 assert_eq!(Char("abc").parse("a".chars()).unwrap().0, 'a');
444 assert_eq!(Char("abc").parse("b".chars()).unwrap().0, 'b');
445 assert_eq!(Char("a-z").parse("z".chars()).unwrap().0, 'z');
446 assert_eq!(Char("a-f0-9").parse("4".chars()).unwrap().0, '4');
447 assert_eq!(Char("0-0A-Za-z-").parse("-".chars()).unwrap().0, '-');
448 assert!(Char("abc").parse("d".chars()).is_err());
449}
450
451#[test]
452fn test_dec8() {
453 let p = Dec8;
454 assert_eq!(p.parse("0".chars()).unwrap().0, 0);
455 assert_eq!(p.parse("010".chars()).unwrap().0, 10);
456 assert_eq!(p.parse("123".chars()).unwrap().0, 123);
457 assert_eq!(p.parse("255".chars()).unwrap().0, 255);
458 assert!(p.parse("256".chars()).is_err());
459}
460
461#[test]
462fn test_hex08() {
463 let p = Hex08;
464 assert_eq!(p.parse("00".chars()).unwrap().0, 0);
465 assert_eq!(p.parse("10".chars()).unwrap().0, 16);
466 assert_eq!(p.parse("fF".chars()).unwrap().0, 255);
467 assert!(p.parse("0".chars()).is_err());
468 assert!(p.parse("f".chars()).is_err());
469 assert!(p.parse("-1".chars()).is_err());
470 assert!(p.parse("GF".chars()).is_err());
471}
472
473#[test]
474fn test_hex16() {
475 let p = Hex16;
476 assert_eq!(p.parse("0".chars()).unwrap().0, 0);
477 assert_eq!(p.parse("f".chars()).unwrap().0, 15);
478 assert_eq!(p.parse("10".chars()).unwrap().0, 16);
479 assert_eq!(p.parse("fF".chars()).unwrap().0, 255);
480 assert_eq!(p.parse("FfFf".chars()).unwrap().0, 65535);
481 assert!(p.parse("-1".chars()).is_err());
482 assert!(p.parse("GF".chars()).is_err());
483}
484
485#[test]
486fn test_cat() {
487 let p = Cat(Hex16, Lit(':'));
488 assert_eq!((p.parse("0:".chars()).unwrap().0).0, 0);
489 assert!((p.parse("0-".chars()).is_err()));
490 assert_eq!((p.parse("10:".chars()).unwrap().0).0, 16);
491 assert_eq!((p.parse("ff:".chars()).unwrap().0).0, 255);
492 assert_eq!((p.parse("ffff:".chars()).unwrap().0).0, 65535);
493 assert!((p.parse("fffff:".chars()).is_err()));
494}
495
496#[test]
497fn test_lladdr() {
498 assert_eq!(LlAddr::from_str("00:00:00:00:00:00").unwrap(), LlAddr::new(0,0,0,0,0,0));
499 assert_eq!(LlAddr::from_str("FF:ff:FF:fF:Ff:ff").unwrap(), LlAddr::new(255,255,255,255,255,255));
500}
501
502#[test]
503fn test_ipv6() {
504 let p = IpV6;
505 assert_eq!(p.parse("1:2:3:4:5:6:7:8".chars()).unwrap().0, [1,2,3,4,5,6,7,8]);
506 assert_eq!(p.parse("::".chars()).unwrap().0, [0;8]);
507 assert_eq!(p.parse("::1".chars()).unwrap().0, [0,0,0,0,0,0,0,1]);
508 assert_eq!(p.parse("::ffff:1".chars()).unwrap().0, [0,0,0,0,0,0,0xFFFF,1]);
509 assert_eq!(p.parse("::2:3:4:5:6:7:8".chars()).unwrap().0, [0,2,3,4,5,6,7,8]);
510 assert_eq!(p.parse("1::".chars()).unwrap().0, [1,0,0,0,0,0,0,0]);
511 assert_eq!(p.parse("1::8".chars()).unwrap().0, [1,0,0,0,0,0,0,8]);
512 assert_eq!(p.parse("1:2::8".chars()).unwrap().0, [1,2,0,0,0,0,0,8]);
513 assert_eq!(p.parse("1::7:8".chars()).unwrap().0, [1,0,0,0,0,0,7,8]);
514 assert_eq!(p.parse("1:2:3:4:5:6:7::".chars()).unwrap().0, [1,2,3,4,5,6,7,0]);
515 assert_eq!(p.parse("0:0:0:0:0:0:255.255.255.255".chars()).unwrap().0, [0,0,0,0,0,0,0xFFFF,0xFFFF]);
516 assert_eq!(p.parse("::0.255.255.0".chars()).unwrap().0, [0,0,0,0,0,0,0xFF,0xFF00]);
517 assert_eq!(p.parse("0:0:0:0:0:FFFF:255.255.255.255".chars()).unwrap().0, [0,0,0,0,0,0xFFFF,0xFFFF,0xFFFF]);
518 assert_eq!(p.parse("::FFFF:0.255.255.0".chars()).unwrap().0, [0,0,0,0,0,0xFFFF,0xFF,0xFF00]);
519 assert_eq!(p.parse("1:2:3:4:5:6:7:8:9".chars()).unwrap().0, [1,2,3,4,5,6,7,8]);
520 assert_eq!(p.parse("::2:3:4:5:6:7:8:9".chars()).unwrap().0, [0,2,3,4,5,6,7,8]);
521 assert_eq!(p.parse("::2:3:4:5:6:7:8:9".chars()).unwrap().0, [0,2,3,4,5,6,7,8]);
522 assert_eq!(p.parse("0:0:0:0:0:0:255.0.0.255.255".chars()).unwrap().0, [0,0,0,0,0,0,0xFF00,0xFF]);
523 assert_eq!(p.parse("::255.0.0.255.255".chars()).unwrap().0, [0,0,0,0,0,0,0xFF00,0xFF]);
524 assert_eq!(p.parse("0:0:0:0:0:ffff:255.0.0.255.255".chars()).unwrap().0, [0,0,0,0,0,0xFFFF,0xFF00,0xFF]);
525 assert_eq!(p.parse("::ffff:255.0.0.255.255".chars()).unwrap().0, [0,0,0,0,0,0xFFFF,0xFF00,0xFF]);
526}
527
528#[test]
529fn test_ipaddr_v4() {
530 assert_eq!(IpAddrV4::from_str("0.0.0.0").unwrap(), IpAddrV4::new(0,0,0,0));
531 assert_eq!(IpAddrV4::from_str("1.2.3.4").unwrap(), IpAddrV4::new(1,2,3,4));
532}
533
534#[test]
535fn test_ipaddr_v6() {
536 assert_eq!(IpAddrV6::from_str("1:2:3:4:5:6:7:8").unwrap(), IpAddrV6::new(1,2,3,4,5,6,7,8));
537 assert!(IpAddrV6::from_str("1:2:3:4:5:6:7:8:9").is_err());
538 assert_eq!(IpAddrV6::from_str("::").unwrap(), IpAddrV6::any());
539 assert_eq!(IpAddrV6::from_str("::192.168.0.1").unwrap(), IpAddrV6::v4_compatible(&IpAddrV4::new(192,168,0,1)).unwrap());
540 assert!(IpAddrV6::from_str("::192.168.0.1.1").is_err());
541 assert_eq!(IpAddrV6::from_str("::ffff:0.0.0.0").unwrap(), IpAddrV6::v4_mapped(&IpAddrV4::any()));
542 assert!(IpAddrV6::from_str("::1:192.168.0.1").is_err());
543 assert_eq!(IpAddrV6::from_str("1:2:3:4:5:6:7:8%10").unwrap(), IpAddrV6::with_scope_id(1,2,3,4,5,6,7,8, 10));
544
545 if cfg!(target_os = "linux") {
546 assert!(IpAddrV6::from_str("1:2:3:4:5:6:7:8%lo").unwrap().get_scope_id() != 0);
547 } else if cfg!(windows) {
548 } else {
550 assert!(IpAddrV6::from_str("1:2:3:4:5:6:7:8%lo0").unwrap().get_scope_id() != 0);
551 }
552}
553
554#[test]
555fn test_ipaddr() {
556 assert_eq!(IpAddr::from_str("0.0.0.0").unwrap(), IpAddr::V4(IpAddrV4::new(0,0,0,0)));
557 assert_eq!(IpAddr::from_str("1.2.3.4").unwrap(), IpAddr::V4(IpAddrV4::new(1,2,3,4)));
558 assert_eq!(IpAddr::from_str("1:2:3:4:5:6:7:8").unwrap(), IpAddr::V6(IpAddrV6::new(1,2,3,4,5,6,7,8)));
559 assert_eq!(IpAddr::from_str("::").unwrap(), IpAddr::V6(IpAddrV6::any()));
560 assert_eq!(IpAddr::from_str("::192.168.0.1").unwrap(), IpAddr::V6(IpAddrV6::v4_compatible(&IpAddrV4::new(192,168,0,1)).unwrap()));
561}