1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! Internet Protocol (IP) addresses.
13 //! This module contains functions useful for parsing, formatting, and
14 //! manipulating IP addresses.
16 #![allow(missing_docs)]
18 pub use self::IpAddr::*;
22 use io::{mod, IoResult, IoError};
24 use iter::{Iterator, IteratorExt};
26 use option::Option::{None, Some};
27 use result::Result::{Ok, Err};
28 use str::{FromStr, StrPrelude};
29 use slice::{CloneSlicePrelude, SlicePrelude};
34 #[deriving(PartialEq, Eq, Clone, Hash)]
36 Ipv4Addr(u8, u8, u8, u8),
37 Ipv6Addr(u16, u16, u16, u16, u16, u16, u16, u16)
40 impl Copy for IpAddr {}
42 impl fmt::Show for IpAddr {
43 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
45 Ipv4Addr(a, b, c, d) =>
46 write!(fmt, "{}.{}.{}.{}", a, b, c, d),
48 // Ipv4 Compatible address
49 Ipv6Addr(0, 0, 0, 0, 0, 0, g, h) => {
50 write!(fmt, "::{}.{}.{}.{}", (g >> 8) as u8, g as u8,
51 (h >> 8) as u8, h as u8)
54 // Ipv4-Mapped address
55 Ipv6Addr(0, 0, 0, 0, 0, 0xFFFF, g, h) => {
56 write!(fmt, "::FFFF:{}.{}.{}.{}", (g >> 8) as u8, g as u8,
57 (h >> 8) as u8, h as u8)
60 Ipv6Addr(a, b, c, d, e, f, g, h) =>
61 write!(fmt, "{:x}:{:x}:{:x}:{:x}:{:x}:{:x}:{:x}:{:x}",
62 a, b, c, d, e, f, g, h)
67 #[deriving(PartialEq, Eq, Clone, Hash)]
68 pub struct SocketAddr {
73 impl Copy for SocketAddr {}
75 impl fmt::Show for SocketAddr {
76 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
78 Ipv4Addr(..) => write!(f, "{}:{}", self.ip, self.port),
79 Ipv6Addr(..) => write!(f, "[{}]:{}", self.ip, self.port),
85 // parsing as ASCII, so can use byte array
91 fn new(s: &'a str) -> Parser<'a> {
98 fn is_eof(&self) -> bool {
99 self.pos == self.s.len()
102 // Commit only if parser returns Some
103 fn read_atomically<T>(&mut self, cb: |&mut Parser| -> Option<T>)
113 // Commit only if parser read till EOF
114 fn read_till_eof<T>(&mut self, cb: |&mut Parser| -> Option<T>)
116 self.read_atomically(|p| {
118 Some(x) => if p.is_eof() {Some(x)} else {None},
124 // Return result of first successful parser
125 fn read_or<T>(&mut self, parsers: &mut [|&mut Parser| -> Option<T>])
127 for pf in parsers.iter_mut() {
128 match self.read_atomically(|p: &mut Parser| (*pf)(p)) {
129 Some(r) => return Some(r),
136 // Apply 3 parsers sequentially
141 pa: |&mut Parser| -> Option<A>,
142 pb: |&mut Parser| -> Option<B>,
143 pc: |&mut Parser| -> Option<C>)
144 -> Option<(A, B, C)> {
145 self.read_atomically(|p| {
147 let b = if a.is_some() { pb(p) } else { None };
148 let c = if b.is_some() { pc(p) } else { None };
150 (Some(a), Some(b), Some(c)) => Some((a, b, c)),
157 fn read_char(&mut self) -> Option<char> {
161 let r = self.s[self.pos] as char;
167 // Return char and advance iff next char is equal to requested
168 fn read_given_char(&mut self, c: char) -> Option<char> {
169 self.read_atomically(|p| {
170 match p.read_char() {
171 Some(next) if next == c => Some(next),
178 fn read_digit(&mut self, radix: u8) -> Option<u8> {
179 fn parse_digit(c: char, radix: u8) -> Option<u8> {
181 // assuming radix is either 10 or 16
182 if c >= b'0' && c <= b'9' {
184 } else if radix > 10 && c >= b'a' && c < b'a' + (radix - 10) {
186 } else if radix > 10 && c >= b'A' && c < b'A' + (radix - 10) {
193 self.read_atomically(|p| {
194 p.read_char().and_then(|c| parse_digit(c, radix))
198 fn read_number_impl(&mut self, radix: u8, max_digits: u32, upto: u32) -> Option<u32> {
200 let mut digit_count = 0;
202 match self.read_digit(radix) {
204 r = r * (radix as u32) + (d as u32);
206 if digit_count > max_digits || r >= upto {
211 if digit_count == 0 {
221 // Read number, failing if max_digits of number value exceeded
222 fn read_number(&mut self, radix: u8, max_digits: u32, upto: u32) -> Option<u32> {
223 self.read_atomically(|p| p.read_number_impl(radix, max_digits, upto))
226 fn read_ipv4_addr_impl(&mut self) -> Option<IpAddr> {
227 let mut bs = [0u8, ..4];
230 if i != 0 && self.read_given_char('.').is_none() {
234 let octet = self.read_number(10, 3, 0x100).map(|n| n as u8);
236 Some(d) => bs[i] = d,
241 Some(Ipv4Addr(bs[0], bs[1], bs[2], bs[3]))
245 fn read_ipv4_addr(&mut self) -> Option<IpAddr> {
246 self.read_atomically(|p| p.read_ipv4_addr_impl())
249 fn read_ipv6_addr_impl(&mut self) -> Option<IpAddr> {
250 fn ipv6_addr_from_head_tail(head: &[u16], tail: &[u16]) -> IpAddr {
251 assert!(head.len() + tail.len() <= 8);
252 let mut gs = [0u16, ..8];
253 gs.clone_from_slice(head);
254 gs[mut 8 - tail.len() .. 8].clone_from_slice(tail);
255 Ipv6Addr(gs[0], gs[1], gs[2], gs[3], gs[4], gs[5], gs[6], gs[7])
258 fn read_groups(p: &mut Parser, groups: &mut [u16, ..8], limit: uint) -> (uint, bool) {
262 let ipv4 = p.read_atomically(|p| {
263 if i == 0 || p.read_given_char(':').is_some() {
270 Some(Ipv4Addr(a, b, c, d)) => {
271 groups[i + 0] = (a as u16 << 8) | (b as u16);
272 groups[i + 1] = (c as u16 << 8) | (d as u16);
273 return (i + 2, true);
279 let group = p.read_atomically(|p| {
280 if i == 0 || p.read_given_char(':').is_some() {
281 p.read_number(16, 4, 0x10000).map(|n| n as u16)
287 Some(g) => groups[i] = g,
288 None => return (i, false)
295 let mut head = [0u16, ..8];
296 let (head_size, head_ipv4) = read_groups(self, &mut head, 8);
299 return Some(Ipv6Addr(
300 head[0], head[1], head[2], head[3],
301 head[4], head[5], head[6], head[7]))
304 // IPv4 part is not allowed before `::`
309 // read `::` if previous code parsed less than 8 groups
310 if !self.read_given_char(':').is_some() || !self.read_given_char(':').is_some() {
314 let mut tail = [0u16, ..8];
315 let (tail_size, _) = read_groups(self, &mut tail, 8 - head_size);
316 Some(ipv6_addr_from_head_tail(head[..head_size], tail[..tail_size]))
319 fn read_ipv6_addr(&mut self) -> Option<IpAddr> {
320 self.read_atomically(|p| p.read_ipv6_addr_impl())
323 fn read_ip_addr(&mut self) -> Option<IpAddr> {
324 let ipv4_addr = |p: &mut Parser| p.read_ipv4_addr();
325 let ipv6_addr = |p: &mut Parser| p.read_ipv6_addr();
326 self.read_or(&mut [ipv4_addr, ipv6_addr])
329 fn read_socket_addr(&mut self) -> Option<SocketAddr> {
330 let ip_addr = |p: &mut Parser| {
331 let ipv4_p = |p: &mut Parser| p.read_ip_addr();
332 let ipv6_p = |p: &mut Parser| {
333 let open_br = |p: &mut Parser| p.read_given_char('[');
334 let ip_addr = |p: &mut Parser| p.read_ipv6_addr();
335 let clos_br = |p: &mut Parser| p.read_given_char(']');
336 p.read_seq_3::<char, IpAddr, char>(open_br, ip_addr, clos_br)
337 .map(|t| match t { (_, ip, _) => ip })
339 p.read_or(&mut [ipv4_p, ipv6_p])
341 let colon = |p: &mut Parser| p.read_given_char(':');
342 let port = |p: &mut Parser| p.read_number(10, 5, 0x10000).map(|n| n as u16);
345 self.read_seq_3::<IpAddr, char, u16>(ip_addr, colon, port)
346 .map(|t| match t { (ip, _, port) => SocketAddr { ip: ip, port: port } })
350 impl FromStr for IpAddr {
351 fn from_str(s: &str) -> Option<IpAddr> {
352 Parser::new(s).read_till_eof(|p| p.read_ip_addr())
356 impl FromStr for SocketAddr {
357 fn from_str(s: &str) -> Option<SocketAddr> {
358 Parser::new(s).read_till_eof(|p| p.read_socket_addr())
362 /// A trait for objects which can be converted or resolved to one or more `SocketAddr` values.
364 /// Implementing types minimally have to implement either `to_socket_addr` or `to_socket_addr_all`
365 /// method, and its trivial counterpart will be available automatically.
367 /// This trait is used for generic address resolution when constructing network objects.
368 /// By default it is implemented for the following types:
370 /// * `SocketAddr` - `to_socket_addr` is identity function.
372 /// * `(IpAddr, u16)` - `to_socket_addr` constructs `SocketAddr` trivially.
374 /// * `(&str, u16)` - the string should be either a string representation of an IP address
375 /// expected by `FromStr` implementation for `IpAddr` or a host name.
377 /// For the former, `to_socket_addr_all` returns a vector with a single element corresponding
378 /// to that IP address joined with the given port.
380 /// For the latter, it tries to resolve the host name and returns a vector of all IP addresses
381 /// for the host name, each joined with the given port.
383 /// * `&str` - the string should be either a string representation of a `SocketAddr` as
384 /// expected by its `FromStr` implementation or a string like `<host_name>:<port>` pair
385 /// where `<port>` is a `u16` value.
387 /// For the former, `to_socker_addr_all` returns a vector with a single element corresponding
388 /// to that socker address.
390 /// For the latter, it tries to resolve the host name and returns a vector of all IP addresses
391 /// for the host name, each joined with the port.
394 /// This trait allows constructing network objects like `TcpStream` or `UdpSocket` easily with
395 /// values of various types for the bind/connection address. It is needed because sometimes
396 /// one type is more appropriate than the other: for simple uses a string like `"localhost:12345"`
397 /// is much nicer than manual construction of the corresponding `SocketAddr`, but sometimes
398 /// `SocketAddr` value is *the* main source of the address, and converting it to some other type
399 /// (e.g. a string) just for it to be converted back to `SocketAddr` in constructor methods
405 /// # #![allow(unused_must_use)]
407 /// use std::io::{TcpStream, TcpListener};
408 /// use std::io::net::udp::UdpSocket;
409 /// use std::io::net::ip::{Ipv4Addr, SocketAddr};
412 /// // The following lines are equivalent modulo possible "localhost" name resolution
414 /// let tcp_s = TcpStream::connect(SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 12345 });
415 /// let tcp_s = TcpStream::connect((Ipv4Addr(127, 0, 0, 1), 12345u16));
416 /// let tcp_s = TcpStream::connect(("127.0.0.1", 12345u16));
417 /// let tcp_s = TcpStream::connect(("localhost", 12345u16));
418 /// let tcp_s = TcpStream::connect("127.0.0.1:12345");
419 /// let tcp_s = TcpStream::connect("localhost:12345");
421 /// // TcpListener::bind(), UdpSocket::bind() and UdpSocket::send_to() behave similarly
422 /// let tcp_l = TcpListener::bind("localhost:12345");
424 /// let mut udp_s = UdpSocket::bind(("127.0.0.1", 23451u16)).unwrap();
425 /// udp_s.send_to([7u8, 7u8, 7u8].as_slice(), (Ipv4Addr(127, 0, 0, 1), 23451u16));
428 pub trait ToSocketAddr {
429 /// Converts this object to single socket address value.
431 /// If more than one value is available, this method returns the first one. If no
432 /// values are available, this method returns an `IoError`.
434 /// By default this method delegates to `to_socket_addr_all` method, taking the first
435 /// item from its result.
436 fn to_socket_addr(&self) -> IoResult<SocketAddr> {
437 self.to_socket_addr_all()
438 .and_then(|v| v.into_iter().next().ok_or_else(|| IoError {
439 kind: io::InvalidInput,
440 desc: "no address available",
445 /// Converts this object to all available socket address values.
447 /// Some values like host name string naturally corrrespond to multiple IP addresses.
448 /// This method tries to return all available addresses corresponding to this object.
450 /// By default this method delegates to `to_socket_addr` method, creating a singleton
451 /// vector from its result.
453 fn to_socket_addr_all(&self) -> IoResult<Vec<SocketAddr>> {
454 self.to_socket_addr().map(|a| vec![a])
458 impl ToSocketAddr for SocketAddr {
460 fn to_socket_addr(&self) -> IoResult<SocketAddr> { Ok(*self) }
463 impl ToSocketAddr for (IpAddr, u16) {
465 fn to_socket_addr(&self) -> IoResult<SocketAddr> {
466 let (ip, port) = *self;
467 Ok(SocketAddr { ip: ip, port: port })
471 fn resolve_socket_addr(s: &str, p: u16) -> IoResult<Vec<SocketAddr>> {
472 net::get_host_addresses(s)
473 .map(|v| v.into_iter().map(|a| SocketAddr { ip: a, port: p }).collect())
476 fn parse_and_resolve_socket_addr(s: &str) -> IoResult<Vec<SocketAddr>> {
477 macro_rules! try_opt(
478 ($e:expr, $msg:expr) => (
481 None => return Err(IoError {
482 kind: io::InvalidInput,
490 // split the string by ':' and convert the second part to u16
491 let mut parts_iter = s.rsplitn(2, ':');
492 let port_str = try_opt!(parts_iter.next(), "invalid socket address");
493 let host = try_opt!(parts_iter.next(), "invalid socket address");
494 let port: u16 = try_opt!(FromStr::from_str(port_str), "invalid port value");
495 resolve_socket_addr(host, port)
498 impl<'a> ToSocketAddr for (&'a str, u16) {
499 fn to_socket_addr_all(&self) -> IoResult<Vec<SocketAddr>> {
500 let (host, port) = *self;
502 // try to parse the host as a regular IpAddr first
503 match FromStr::from_str(host) {
504 Some(addr) => return Ok(vec![SocketAddr {
511 resolve_socket_addr(host, port)
515 // accepts strings like 'localhost:12345'
516 impl<'a> ToSocketAddr for &'a str {
517 fn to_socket_addr(&self) -> IoResult<SocketAddr> {
518 // try to parse as a regular SocketAddr first
519 match FromStr::from_str(*self) {
520 Some(addr) => return Ok(addr),
524 parse_and_resolve_socket_addr(*self)
525 .and_then(|v| v.into_iter().next()
526 .ok_or_else(|| IoError {
527 kind: io::InvalidInput,
528 desc: "no address available",
534 fn to_socket_addr_all(&self) -> IoResult<Vec<SocketAddr>> {
535 // try to parse as a regular SocketAddr first
536 match FromStr::from_str(*self) {
537 Some(addr) => return Ok(vec![addr]),
541 parse_and_resolve_socket_addr(*self)
553 fn test_from_str_ipv4() {
554 assert_eq!(Some(Ipv4Addr(127, 0, 0, 1)), FromStr::from_str("127.0.0.1"));
555 assert_eq!(Some(Ipv4Addr(255, 255, 255, 255)), FromStr::from_str("255.255.255.255"));
556 assert_eq!(Some(Ipv4Addr(0, 0, 0, 0)), FromStr::from_str("0.0.0.0"));
559 let none: Option<IpAddr> = FromStr::from_str("256.0.0.1");
560 assert_eq!(None, none);
562 let none: Option<IpAddr> = FromStr::from_str("255.0.0");
563 assert_eq!(None, none);
565 let none: Option<IpAddr> = FromStr::from_str("255.0.0.1.2");
566 assert_eq!(None, none);
567 // no number between dots
568 let none: Option<IpAddr> = FromStr::from_str("255.0..1");
569 assert_eq!(None, none);
573 fn test_from_str_ipv6() {
574 assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 0)), FromStr::from_str("0:0:0:0:0:0:0:0"));
575 assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 1)), FromStr::from_str("0:0:0:0:0:0:0:1"));
577 assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 1)), FromStr::from_str("::1"));
578 assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 0)), FromStr::from_str("::"));
580 assert_eq!(Some(Ipv6Addr(0x2a02, 0x6b8, 0, 0, 0, 0, 0x11, 0x11)),
581 FromStr::from_str("2a02:6b8::11:11"));
584 let none: Option<IpAddr> = FromStr::from_str("::00000");
585 assert_eq!(None, none);
587 let none: Option<IpAddr> = FromStr::from_str("1:2:3:4:5:6:7");
588 assert_eq!(None, none);
590 let none: Option<IpAddr> = FromStr::from_str("1:2:3:4:5:6:7:8:9");
591 assert_eq!(None, none);
593 let none: Option<IpAddr> = FromStr::from_str("1:2:::6:7:8");
594 assert_eq!(None, none);
596 let none: Option<IpAddr> = FromStr::from_str("1:2::6::8");
597 assert_eq!(None, none);
601 fn test_from_str_ipv4_in_ipv6() {
602 assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0, 49152, 545)),
603 FromStr::from_str("::192.0.2.33"));
604 assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0xFFFF, 49152, 545)),
605 FromStr::from_str("::FFFF:192.0.2.33"));
606 assert_eq!(Some(Ipv6Addr(0x64, 0xff9b, 0, 0, 0, 0, 49152, 545)),
607 FromStr::from_str("64:ff9b::192.0.2.33"));
608 assert_eq!(Some(Ipv6Addr(0x2001, 0xdb8, 0x122, 0xc000, 0x2, 0x2100, 49152, 545)),
609 FromStr::from_str("2001:db8:122:c000:2:2100:192.0.2.33"));
612 let none: Option<IpAddr> = FromStr::from_str("::127.0.0.1:");
613 assert_eq!(None, none);
615 let none: Option<IpAddr> = FromStr::from_str("1.2.3.4.5:127.0.0.1");
616 assert_eq!(None, none);
618 let none: Option<IpAddr> =
619 FromStr::from_str("1.2.3.4.5:6:7:127.0.0.1");
620 assert_eq!(None, none);
624 fn test_from_str_socket_addr() {
625 assert_eq!(Some(SocketAddr { ip: Ipv4Addr(77, 88, 21, 11), port: 80 }),
626 FromStr::from_str("77.88.21.11:80"));
627 assert_eq!(Some(SocketAddr { ip: Ipv6Addr(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), port: 53 }),
628 FromStr::from_str("[2a02:6b8:0:1::1]:53"));
629 assert_eq!(Some(SocketAddr { ip: Ipv6Addr(0, 0, 0, 0, 0, 0, 0x7F00, 1), port: 22 }),
630 FromStr::from_str("[::127.0.0.1]:22"));
633 let none: Option<SocketAddr> = FromStr::from_str("127.0.0.1");
634 assert_eq!(None, none);
636 let none: Option<SocketAddr> = FromStr::from_str("127.0.0.1:");
637 assert_eq!(None, none);
638 // wrong brackets around v4
639 let none: Option<SocketAddr> = FromStr::from_str("[127.0.0.1]:22");
640 assert_eq!(None, none);
642 let none: Option<SocketAddr> = FromStr::from_str("127.0.0.1:123456");
643 assert_eq!(None, none);
647 fn ipv6_addr_to_string() {
648 let a1 = Ipv6Addr(0, 0, 0, 0, 0, 0xffff, 0xc000, 0x280);
649 assert!(a1.to_string() == "::ffff:192.0.2.128" ||
650 a1.to_string() == "::FFFF:192.0.2.128");
651 assert_eq!(Ipv6Addr(8, 9, 10, 11, 12, 13, 14, 15).to_string(),
656 fn to_socket_addr_socketaddr() {
657 let a = SocketAddr { ip: Ipv4Addr(77, 88, 21, 11), port: 12345 };
658 assert_eq!(Ok(a), a.to_socket_addr());
659 assert_eq!(Ok(vec![a]), a.to_socket_addr_all());
663 fn to_socket_addr_ipaddr_u16() {
664 let a = Ipv4Addr(77, 88, 21, 11);
666 let e = SocketAddr { ip: a, port: p };
667 assert_eq!(Ok(e), (a, p).to_socket_addr());
668 assert_eq!(Ok(vec![e]), (a, p).to_socket_addr_all());
672 fn to_socket_addr_str_u16() {
673 let a = SocketAddr { ip: Ipv4Addr(77, 88, 21, 11), port: 24352 };
674 assert_eq!(Ok(a), ("77.88.21.11", 24352u16).to_socket_addr());
675 assert_eq!(Ok(vec![a]), ("77.88.21.11", 24352u16).to_socket_addr_all());
677 let a = SocketAddr { ip: Ipv6Addr(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), port: 53 };
678 assert_eq!(Ok(a), ("2a02:6b8:0:1::1", 53).to_socket_addr());
679 assert_eq!(Ok(vec![a]), ("2a02:6b8:0:1::1", 53).to_socket_addr_all());
681 let a = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 23924 };
682 assert!(("localhost", 23924u16).to_socket_addr_all().unwrap().contains(&a));
686 fn to_socket_addr_str() {
687 let a = SocketAddr { ip: Ipv4Addr(77, 88, 21, 11), port: 24352 };
688 assert_eq!(Ok(a), "77.88.21.11:24352".to_socket_addr());
689 assert_eq!(Ok(vec![a]), "77.88.21.11:24352".to_socket_addr_all());
691 let a = SocketAddr { ip: Ipv6Addr(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), port: 53 };
692 assert_eq!(Ok(a), "[2a02:6b8:0:1::1]:53".to_socket_addr());
693 assert_eq!(Ok(vec![a]), "[2a02:6b8:0:1::1]:53".to_socket_addr_all());
695 let a = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 23924 };
696 assert!("localhost:23924".to_socket_addr_all().unwrap().contains(&a));