1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
use prelude::Protocol;
use ffi::{IntoI32, AF_UNSPEC, AF_INET, AF_INET6, SOCK_RAW,
IPPROTO_ICMP, IPPROTO_ICMPV6};
use raw_socket::RawSocket;
use ip::{IpProtocol, IpEndpoint, Resolver, ResolverIter, ResolverQuery};
use std::io;
use std::fmt;
use std::mem;
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd)]
pub struct Icmp {
family: i32,
protocol: i32,
}
impl Protocol for Icmp {
type Endpoint = IpEndpoint<Self>;
fn family_type(&self) -> i32 {
self.family
}
fn socket_type(&self) -> i32 {
SOCK_RAW as i32
}
fn protocol_type(&self) -> i32 {
self.protocol
}
unsafe fn uninitialized(&self) -> Self::Endpoint {
mem::uninitialized()
}
}
impl IpProtocol for Icmp {
fn v4() -> Icmp {
Icmp { family: AF_INET as i32, protocol: IPPROTO_ICMP.i32() }
}
fn v6() -> Icmp {
Icmp { family: AF_INET6 as i32, protocol: IPPROTO_ICMPV6.i32() }
}
}
impl fmt::Debug for Icmp {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.is_v4() {
write!(f, "ICMPv4")
} else if self.is_v6() {
write!(f, "ICMPv6")
} else {
unreachable!("Invalid address family ({}).", self.family);
}
}
}
impl<'a> ResolverQuery<Icmp> for &'a str {
fn iter(self) -> io::Result<ResolverIter<Icmp>> {
ResolverIter::new(&Icmp { family: AF_UNSPEC, protocol: 0 }, self.as_ref(), "", 0)
}
}
impl fmt::Debug for IpEndpoint<Icmp> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Endpoint(ICMP/{})", self)
}
}
impl fmt::Debug for Resolver<Icmp, RawSocket<Icmp>> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Resolver(ICMP)")
}
}
pub type IcmpEndpoint = IpEndpoint<Icmp>;
pub type IcmpSocket = RawSocket<Icmp>;
pub type IcmpResolver = Resolver<Icmp, RawSocket<Icmp>>;
#[test]
fn test_icmp() {
assert!(Icmp::v4() == Icmp::v4());
assert!(Icmp::v6() == Icmp::v6());
assert!(Icmp::v4() != Icmp::v6());
}
#[test]
fn test_icmp_resolve() {
use core::IoContext;
use ip::*;
let ctx = &IoContext::new().unwrap();
let re = IcmpResolver::new(ctx);
for ep in re.resolve("127.0.0.1").unwrap() {
assert!(ep == IcmpEndpoint::new(IpAddrV4::loopback(), 0));
}
for ep in re.resolve("::1").unwrap() {
assert!(ep == IcmpEndpoint::new(IpAddrV6::loopback(), 0));
}
for ep in re.resolve(("localhost")).unwrap() {
assert!(ep.addr().is_loopback());
}
}
#[test]
#[ignore]
fn test_format() {
use core::IoContext;
let ctx = &IoContext::new().unwrap();
println!("{:?}", Icmp::v4());
println!("{:?}", IcmpEndpoint::new(Icmp::v4(), 12345));
println!("{:?}", IcmpSocket::new(ctx, Icmp::v4()).unwrap());
println!("{:?}", IcmpResolver::new(ctx));
}