1use std::fmt;
3use std::net::AddrParseError;
4use std::net::IpAddr;
5use std::net::Ipv4Addr;
6use std::net::Ipv6Addr;
7use std::num::ParseIntError;
8use std::result;
9use std::str::FromStr;
10use std::u32;
11use thiserror::Error;
12
13const INIT_NEXT_VALUE: u8 = 0;
14const IPV4_PREFIX_MAX_LEN: u8 = 32;
15const IPV6_PREFIX_MAX_LEN: u8 = 128;
16
17pub type Result<T, E = SubnetworkError> = result::Result<T, E>;
18
19#[derive(Error, Debug)]
20pub enum SubnetworkError {
21 #[error("invalid input: {msg}")]
22 InvalidInput { msg: String },
23 #[error("ip addr parse error")]
24 AddrParseError(#[from] AddrParseError),
25 #[error("num parse error")]
26 ParseIntError(#[from] ParseIntError),
27}
28
29#[derive(Debug, Clone, Copy)]
30pub struct CrossIpv4Pool {
31 start: u32,
32 end: u32,
33 next: u32,
34}
35
36impl Iterator for CrossIpv4Pool {
37 type Item = Ipv4Addr;
38 fn next(&mut self) -> Option<Self::Item> {
39 if self.next <= self.end {
40 let ret = self.next;
41 self.next += 1;
42 Some(ret.into())
43 } else {
44 None
45 }
46 }
47}
48
49impl fmt::Display for CrossIpv4Pool {
50 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
51 let start: Ipv4Addr = self.start.into();
52 let end: Ipv4Addr = self.end.into();
53 let now: Ipv4Addr = self.next.into();
54 write!(f, "{}-{}, next {}", start, end, now)
55 }
56}
57
58impl CrossIpv4Pool {
59 pub fn new<T: Into<Ipv4AddrExt>>(
75 start: T,
76 end: Ipv4Addr,
77 ) -> Result<CrossIpv4Pool, SubnetworkError> {
78 let start_ip_ext: Ipv4AddrExt = start.into();
79 let end_ip_ext: Ipv4AddrExt = end.into();
80 let start_u32: u32 = start_ip_ext.addr;
81 let end_u32: u32 = end_ip_ext.addr;
82
83 if start_u32 <= end_u32 {
84 let cip = CrossIpv4Pool {
85 start: start_u32,
86 end: end_u32,
87 next: start_u32,
88 };
89 Ok(cip)
90 } else {
91 let error_range = format!("{}-{}", start_u32, end_u32);
92 Err(SubnetworkError::InvalidInput { msg: error_range })
93 }
94 }
95 pub fn to_vec(&self) -> Vec<Ipv4Addr> {
97 self.into_iter().collect()
98 }
99 pub fn contain(&self, addr: Ipv4Addr) -> bool {
101 let addr: u32 = addr.into();
102 if addr <= self.end && addr >= self.start {
103 true
104 } else {
105 false
106 }
107 }
108 pub fn len(&self) -> usize {
110 let length = self.end - self.start;
111 length as usize
112 }
113}
114
115#[derive(Debug, Clone, Copy)]
116pub struct Ipv4Pool {
117 prefix: u32,
118 mask: u32,
119 next: u32,
120 stop: u32,
121 addr: u32,
122}
123
124impl Iterator for Ipv4Pool {
125 type Item = Ipv4Addr;
126 fn next(&mut self) -> Option<Self::Item> {
127 if self.next < self.stop {
128 let ret = self.prefix + self.next;
129 self.next += 1;
130 Some(ret.into())
131 } else {
132 None
133 }
134 }
135}
136
137impl fmt::Display for Ipv4Pool {
138 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
139 let prefix_addr: Ipv4Addr = self.prefix.into();
140 let mut prefix = 0;
141 let mut mask = self.mask;
142 while mask != 0 {
143 mask <<= 1;
144 prefix += 1;
145 }
146 write!(f, "{}/{}", prefix_addr, prefix)
147 }
148}
149
150impl FromStr for Ipv4Pool {
151 type Err = SubnetworkError;
152 fn from_str(addr: &str) -> Result<Self, Self::Err> {
153 if addr.contains("/") {
154 let addr_vec: Vec<&str> = addr.split("/").collect();
155 if addr_vec.len() == 2 {
156 let ip_addr = Ipv4Addr::from_str(addr_vec[0])?;
157 let prefix = u8::from_str(addr_vec[1])?;
158 if prefix <= IPV4_PREFIX_MAX_LEN {
159 let addr: u32 = ip_addr.into();
160 let mask: u32 = u32::MAX << (IPV4_PREFIX_MAX_LEN - prefix);
161 let next = INIT_NEXT_VALUE as u32;
162 let stop = 1 << (IPV4_PREFIX_MAX_LEN - prefix);
163 let prefix = addr & mask;
164 return Ok(Ipv4Pool {
165 prefix,
166 mask,
167 next,
168 stop,
169 addr,
170 });
171 }
172 }
173 }
174 Err(SubnetworkError::InvalidInput {
176 msg: addr.to_string(),
177 })
178 }
179}
180
181impl Ipv4Pool {
182 pub fn new<T: Into<Ipv4AddrExt>>(addr: T, prefix: u8) -> Result<Ipv4Pool, SubnetworkError> {
198 let addr_ext: Ipv4AddrExt = addr.into();
199 if prefix > IPV4_PREFIX_MAX_LEN {
200 let error_addr = format!("{}/{}", addr_ext, prefix);
201 Err(SubnetworkError::InvalidInput {
202 msg: error_addr.to_string(),
203 })
204 } else {
205 let addr: u32 = addr_ext.addr;
206 let mask: u32 = u32::MAX << (IPV4_PREFIX_MAX_LEN - prefix);
207 let next = INIT_NEXT_VALUE as u32;
208 let stop = 1 << (IPV4_PREFIX_MAX_LEN - prefix);
209 let prefix = addr & mask;
210 return Ok(Ipv4Pool {
211 prefix,
212 mask,
213 next,
214 stop,
215 addr,
216 });
217 }
218 }
219 pub fn to_vec(&self) -> Vec<Ipv4Addr> {
221 self.into_iter().collect()
222 }
223 pub fn contain(&self, addr: Ipv4Addr) -> bool {
238 let addr: u32 = addr.into();
239 if addr & self.mask == self.prefix {
240 true
241 } else {
242 false
243 }
244 }
245 pub fn network(&self) -> Ipv4Addr {
248 self.prefix.into()
249 }
250 pub fn broadcast(&self) -> Ipv4Addr {
253 let biggest = !self.mask;
254 let ret = self.prefix + biggest;
255 ret.into()
256 }
257 pub fn len(&self) -> usize {
259 let biggest = !self.mask + 1;
260 biggest as usize
261 }
262 pub fn addr(&self) -> Ipv4Addr {
264 self.addr.into()
265 }
266}
267
268#[derive(Debug, Clone, Copy)]
269pub struct CrossIpv6Pool {
270 start: u128,
271 end: u128,
272 next: u128,
273}
274
275impl Iterator for CrossIpv6Pool {
276 type Item = Ipv6Addr;
277 fn next(&mut self) -> Option<Self::Item> {
278 if self.next <= self.end {
279 let ret = self.next;
280 self.next += 1;
281 Some(ret.into())
282 } else {
283 None
284 }
285 }
286}
287
288impl fmt::Display for CrossIpv6Pool {
289 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
290 let start: Ipv6Addr = self.start.into();
291 let end: Ipv6Addr = self.end.into();
292 write!(f, "{}-{}", start, end)
293 }
294}
295
296impl CrossIpv6Pool {
297 pub fn new(start: Ipv6Addr, end: Ipv6Addr) -> Result<CrossIpv6Pool, SubnetworkError> {
314 let start_ipv6: Ipv6AddrExt = start.into();
315 let end_ipv6: Ipv6AddrExt = end.into();
316 if start_ipv6.addr <= end_ipv6.addr {
317 let cip = CrossIpv6Pool {
318 start: start_ipv6.addr,
319 end: end_ipv6.addr,
320 next: start_ipv6.addr,
321 };
322 Ok(cip)
323 } else {
324 let msg = format!("{}-{}", start, end);
325 Err(SubnetworkError::InvalidInput { msg })
326 }
327 }
328 pub fn to_vec(&self) -> Vec<Ipv6Addr> {
330 self.into_iter().collect()
331 }
332 pub fn contain(&self, addr: Ipv6Addr) -> bool {
334 let addr: u128 = addr.into();
335 if addr <= self.end && addr >= self.start {
336 true
337 } else {
338 false
339 }
340 }
341 pub fn len(&self) -> usize {
343 let length = self.end - self.start;
344 length as usize
345 }
346}
347
348#[derive(Debug, Clone, Copy)]
349pub struct Ipv6Pool {
350 prefix: u128,
351 mask: u128,
352 next: u128,
353 stop: u128,
354 addr: u128,
355}
356
357impl Iterator for Ipv6Pool {
358 type Item = Ipv6Addr;
359 fn next(&mut self) -> Option<Self::Item> {
360 if self.next < self.stop {
361 let ret = self.prefix + self.next;
362 self.next += 1;
363 Some(ret.into())
364 } else {
365 None
366 }
367 }
368}
369
370impl fmt::Display for Ipv6Pool {
371 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
372 let prefix_addr: Ipv6Addr = self.prefix.into();
373 let mut prefix = 0;
374 let mut mask = self.mask;
375 while mask != 0 {
376 mask <<= 1;
377 prefix += 1;
378 }
379 write!(f, "{}/{}", prefix_addr, prefix)
380 }
381}
382
383impl FromStr for Ipv6Pool {
384 type Err = SubnetworkError;
385 fn from_str(addr: &str) -> Result<Self, Self::Err> {
386 if addr.contains("/") {
387 let addr_vec: Vec<&str> = addr.split("/").collect();
388 if addr_vec.len() == 2 {
389 let ip_addr = Ipv6Addr::from_str(addr_vec[0])?;
390 let prefix = u8::from_str(addr_vec[1])?;
391 if prefix <= IPV6_PREFIX_MAX_LEN {
392 let addr: u128 = ip_addr.into();
393 let mask: u128 = u128::MAX << (IPV6_PREFIX_MAX_LEN - prefix);
394 let next = INIT_NEXT_VALUE as u128;
395 let stop = 1 << (IPV6_PREFIX_MAX_LEN - prefix);
396 let prefix = addr & mask;
397 return Ok(Ipv6Pool {
398 prefix,
399 mask,
400 next,
401 stop,
402 addr,
403 });
404 }
405 }
406 }
407 Err(SubnetworkError::InvalidInput {
409 msg: addr.to_string(),
410 })
411 }
412}
413
414impl Ipv6Pool {
415 pub fn new(addr: Ipv6Addr, prefix: u8) -> Result<Ipv6Pool, SubnetworkError> {
432 if prefix > IPV6_PREFIX_MAX_LEN {
433 let error_addr = format!("{}/{}", addr, prefix);
434 Err(SubnetworkError::InvalidInput {
435 msg: error_addr.to_string(),
436 })
437 } else {
438 let addr: u128 = addr.into();
439 let mask: u128 = u128::MAX << (IPV6_PREFIX_MAX_LEN - prefix);
440 let next = INIT_NEXT_VALUE as u128;
441 let stop = 1 << (IPV6_PREFIX_MAX_LEN - prefix);
442 let prefix = addr & mask;
443 Ok(Ipv6Pool {
444 prefix,
445 mask,
446 next,
447 stop,
448 addr,
449 })
450 }
451 }
452 pub fn to_vec(&self) -> Vec<Ipv6Addr> {
454 self.into_iter().collect()
455 }
456 pub fn contain(&self, addr: Ipv6Addr) -> bool {
471 let addr: u128 = addr.into();
472 if addr & self.mask == self.prefix {
473 true
474 } else {
475 false
476 }
477 }
478 pub fn network(&self) -> Ipv6Addr {
481 self.prefix.into()
482 }
483 pub fn len(&self) -> usize {
485 let biggest = !self.mask + 1;
486 biggest as usize
487 }
488 pub fn addr(&self) -> Ipv6Addr {
490 self.addr.into()
491 }
492}
493
494#[derive(Debug, Clone, Copy)]
495pub enum IpPool {
496 V4(Ipv4Pool),
497 V6(Ipv6Pool),
498}
499
500impl fmt::Display for IpPool {
501 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
502 let output = match self {
503 Self::V4(x) => format!("{}", x),
504 Self::V6(x) => format!("{}", x),
505 };
506 write!(f, "{}", output)
507 }
508}
509
510impl Iterator for IpPool {
511 type Item = IpAddr;
512 fn next(&mut self) -> Option<Self::Item> {
513 match self {
514 IpPool::V4(iter) => iter.next().map(IpAddr::V4),
515 IpPool::V6(iter) => iter.next().map(IpAddr::V6),
516 }
517 }
518}
519
520#[derive(Debug, Clone, Copy)]
523pub struct Ipv4AddrExt {
524 addr: u32,
525}
526
527impl fmt::Display for Ipv4AddrExt {
528 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
529 let addr: Ipv4Addr = self.addr.into();
530 write!(f, "{}", addr)
531 }
532}
533
534impl From<Ipv4Addr> for Ipv4AddrExt {
535 fn from(addr: Ipv4Addr) -> Self {
536 let addr: u32 = addr.into();
537 Ipv4AddrExt { addr }
538 }
539}
540
541impl From<Ipv4AddrExt> for Ipv4Addr {
542 fn from(addr: Ipv4AddrExt) -> Self {
543 let new_addr: u32 = addr.addr;
544 new_addr.into()
545 }
546}
547
548impl FromStr for Ipv4AddrExt {
549 type Err = SubnetworkError;
550 fn from_str(addr: &str) -> Result<Self, Self::Err> {
551 let new_addr = Ipv4Addr::from_str(addr)?;
552 let addr: u32 = new_addr.into();
553 Ok(Ipv4AddrExt { addr })
554 }
555}
556
557impl Ipv4AddrExt {
558 pub fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4AddrExt {
560 let a_fix = (a as u32) << 24;
561 let b_fix = (b as u32) << 16;
562 let c_fix = (c as u32) << 8;
563 let d_fix = d as u32;
564 let addr = a_fix + b_fix + c_fix + d_fix;
565 Ipv4AddrExt { addr }
566 }
567 pub fn largest_identical_prefix<T: Into<Ipv4AddrExt>>(&self, target: T) -> u8 {
583 let a = self.addr;
584 let b = target.into().addr;
585 let init_mask = 2u32.pow(31);
586 let mut mask = init_mask;
587
588 for c in 0..IPV4_PREFIX_MAX_LEN {
589 if a & mask != b & mask {
590 return c;
591 }
592 mask = (mask >> 1) + init_mask;
593 }
594 0
595 }
596}
597
598#[derive(Debug, Clone, Copy)]
599pub struct Ipv6AddrExt {
600 addr: u128,
601}
602
603impl fmt::Display for Ipv6AddrExt {
604 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
605 let addr: Ipv6Addr = self.addr.into();
606 write!(f, "{}", addr)
607 }
608}
609
610impl From<Ipv6Addr> for Ipv6AddrExt {
611 fn from(addr: Ipv6Addr) -> Self {
612 let addr: u128 = addr.into();
613 Ipv6AddrExt { addr }
614 }
615}
616
617impl From<Ipv6AddrExt> for Ipv6Addr {
618 fn from(addr: Ipv6AddrExt) -> Self {
619 let new_addr: u128 = addr.addr;
620 new_addr.into()
621 }
622}
623
624impl FromStr for Ipv6AddrExt {
625 type Err = SubnetworkError;
626 fn from_str(addr: &str) -> Result<Self, Self::Err> {
627 let new_addr = Ipv6Addr::from_str(addr)?;
628 let addr: u128 = new_addr.into();
629 Ok(Ipv6AddrExt { addr })
630 }
631}
632
633impl Ipv6AddrExt {
634 pub fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Ipv6AddrExt {
636 let a_fix = (a as u128) << 112;
637 let b_fix = (b as u128) << 96;
638 let c_fix = (c as u128) << 80;
639 let d_fix = (d as u128) << 64;
640 let e_fix = (e as u128) << 48;
641 let f_fix = (f as u128) << 32;
642 let g_fix = (g as u128) << 16;
643 let h_fix = h as u128;
644 let addr = a_fix + b_fix + c_fix + d_fix + e_fix + f_fix + g_fix + h_fix;
645 Ipv6AddrExt { addr }
646 }
647 pub fn node_multicast(&self) -> Ipv6Addr {
649 let node = Ipv6Addr::new(
650 0xff01, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0xff00, 0x0000,
651 );
652 let mask = Ipv6Addr::new(
653 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00ff, 0xffff,
654 );
655 let node_u128: u128 = node.into();
656 let mask_u128: u128 = mask.into();
657 (node_u128 + (mask_u128 & self.addr)).into()
658 }
659 pub fn link_multicast(&self) -> Ipv6Addr {
661 let link = Ipv6Addr::new(
662 0xff02, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0xff00, 0x0000,
663 );
664 let mask = Ipv6Addr::new(
665 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00ff, 0xffff,
666 );
667 let link_u128: u128 = link.into();
668 let mask_u128: u128 = mask.into();
669 (link_u128 + (mask_u128 & self.addr)).into()
670 }
671 pub fn site_multicast(&self) -> Ipv6Addr {
673 let site = Ipv6Addr::new(
674 0xff05, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0xff00, 0x0000,
675 );
676 let mask = Ipv6Addr::new(
677 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00ff, 0xffff,
678 );
679 let site_u128: u128 = site.into();
680 let mask_u128: u128 = mask.into();
681 (site_u128 + (mask_u128 & self.addr)).into()
682 }
683 pub fn largest_identical_prefix<T: Into<Ipv6AddrExt>>(&self, target: T) -> u8 {
684 let a = self.addr;
685 let b = target.into().addr;
686 let init_mask = 2u128.pow(127);
687 let mut mask = init_mask;
688
689 for c in 0..IPV6_PREFIX_MAX_LEN {
690 if a & mask != b & mask {
691 return c;
692 }
693 mask = (mask >> 1) + init_mask;
694 }
695 0
696 }
697}
698
699#[derive(Debug, Clone, Copy)]
700pub struct NetmaskExt {
701 prefix: u8,
702}
703
704impl NetmaskExt {
705 pub fn new(prefix: u8) -> NetmaskExt {
717 NetmaskExt { prefix }
718 }
719 pub fn from_addr(addr: IpAddr) -> NetmaskExt {
735 let prefix = match addr {
737 IpAddr::V4(ipv4) => {
738 let mask = u32::from_be_bytes(ipv4.octets());
739 let prefix = mask.count_ones() as u8;
740 prefix
741 }
742 IpAddr::V6(ipv6) => {
743 let mask = u128::from_be_bytes(ipv6.octets());
744 let prefix = mask.count_ones() as u8;
745 prefix
746 }
747 };
748 NetmaskExt { prefix }
749 }
750 pub fn get_prefix(&self) -> u8 {
752 self.prefix
753 }
754 pub fn to_ipv4(&self) -> Result<Ipv4Addr, SubnetworkError> {
756 if self.prefix == 0 {
757 Ok((0 as u32).into())
758 } else {
759 if self.prefix > IPV4_PREFIX_MAX_LEN {
760 let msg = format!("prefix: {}", self.prefix);
761 Err(SubnetworkError::InvalidInput { msg })
762 } else {
763 Ok((u32::MAX << (IPV4_PREFIX_MAX_LEN - self.prefix)).into())
764 }
765 }
766 }
767 pub fn to_ipv6(&self) -> Result<Ipv6Addr, SubnetworkError> {
769 if self.prefix == 0 {
770 Ok((0 as u128).into())
771 } else {
772 if self.prefix > IPV6_PREFIX_MAX_LEN {
773 let msg = format!("prefix: {}", self.prefix);
774 Err(SubnetworkError::InvalidInput { msg })
775 } else {
776 Ok((u128::MAX << (IPV6_PREFIX_MAX_LEN - self.prefix)).into())
777 }
778 }
779 }
780}
781
782#[cfg(test)]
783mod tests {
784 use super::*;
785 #[test]
787 fn readme_example_1() {
788 let pool = Ipv4Pool::new(Ipv4Addr::new(192, 168, 1, 1), 24).unwrap();
789 for ipv4 in pool {
791 println!("{}", ipv4);
792 }
793
794 let pool = Ipv4Pool::from_str("192.168.1.0/24").unwrap();
795 for ipv4 in pool {
796 println!("{}", ipv4);
797 }
798
799 let pool: Ipv4Pool = "192.168.1.0/24".parse().unwrap();
800 for ipv4 in pool {
801 println!("{}", ipv4);
802 }
803
804 let test_ipv4 = Ipv4Addr::new(192, 168, 1, 233);
805 assert_eq!(pool.contain(test_ipv4), true);
806
807 let broadcast = Ipv4Addr::new(192, 168, 1, 255);
808 assert_eq!(pool.broadcast(), broadcast);
809
810 let network = Ipv4Addr::new(192, 168, 1, 0);
811 assert_eq!(pool.network(), network);
812
813 assert_eq!(pool.len(), 256);
814 assert_eq!(pool.to_string(), "192.168.1.0/24");
816 }
817 #[test]
818 fn readme_example_2() {
819 let start = Ipv4Addr::new(192, 168, 1, 16);
820 let end = Ipv4Addr::new(192, 168, 3, 200);
821 let pool = CrossIpv4Pool::new(start, end).unwrap();
822 for i in pool {
824 println!("{:?}", i);
825 }
826
827 let test_ipv4 = Ipv4Addr::new(192, 168, 1, 233);
828 assert_eq!(pool.contain(test_ipv4), true);
829 let test_ipv4 = Ipv4Addr::new(192, 168, 2, 0);
830 assert_eq!(pool.contain(test_ipv4), true);
831 let test_ipv4 = Ipv4Addr::new(192, 168, 3, 255);
832 assert_eq!(pool.contain(test_ipv4), false);
833 let test_ipv4 = Ipv4Addr::new(192, 168, 3, 200);
834 assert_eq!(pool.contain(test_ipv4), true);
835 }
836 #[test]
837 fn readme_example_3() {
838 let ip1 = Ipv4Addr::new(192, 168, 1, 0);
840 let ip2 = Ipv4Addr::new(192, 168, 1, 255);
841
842 let ip1ext: Ipv4AddrExt = ip1.into();
843 assert_eq!(ip1ext.largest_identical_prefix(ip2), 24);
844
845 let ip1 = Ipv4Addr::new(192, 168, 1, 136);
847 let ip2 = Ipv4Addr::new(192, 168, 1, 192);
848
849 let ip1ext: Ipv4AddrExt = ip1.into();
850 assert_eq!(ip1ext.largest_identical_prefix(ip2), 25);
851 }
852 #[test]
853 fn readme_example_4() {
854 let ipv6 = Ipv6Addr::from_str("::ffff:192.10.2.255").unwrap();
855 let ipv6_ext: Ipv6AddrExt = ipv6.into();
856
857 let ipv6_node_multicast = Ipv6Addr::from_str("ff01::1:ff0a:2ff").unwrap();
858 assert_eq!(ipv6_ext.node_multicast(), ipv6_node_multicast);
859
860 let ipv6_link_multicast = Ipv6Addr::from_str("ff02::1:ff0a:2ff").unwrap();
861 assert_eq!(ipv6_ext.link_multicast(), ipv6_link_multicast);
862
863 let ipv6_site_multicast = Ipv6Addr::from_str("ff05::1:ff0a:2ff").unwrap();
864 assert_eq!(ipv6_ext.site_multicast(), ipv6_site_multicast);
865 }
866 #[test]
867 fn readme_example_5() {
868 let netmask = NetmaskExt::new(24);
869 let netmask_addr = netmask.to_ipv4().unwrap();
870 assert_eq!(netmask_addr, Ipv4Addr::new(255, 255, 255, 0));
871
872 let netmask = NetmaskExt::new(26);
873 let netmask_addr = netmask.to_ipv4().unwrap();
874 assert_eq!(netmask_addr, Ipv4Addr::new(255, 255, 255, 192));
875 }
876 #[test]
877 fn netmask_ext() {
878 let addr = IpAddr::V4(Ipv4Addr::new(255, 255, 255, 0));
879 let netmask = NetmaskExt::from_addr(addr);
880 let prefix = netmask.get_prefix();
882 assert_eq!(prefix, 24);
883
884 let addr = IpAddr::V4(Ipv4Addr::new(255, 255, 255, 192));
885 let netmask = NetmaskExt::from_addr(addr);
886 let prefix = netmask.get_prefix();
888 assert_eq!(prefix, 26);
889
890 let addr = IpAddr::V4(Ipv4Addr::new(255, 255, 0, 0));
891 let netmask = NetmaskExt::from_addr(addr);
892 let prefix = netmask.get_prefix();
894 assert_eq!(prefix, 16);
895
896 let addr = IpAddr::V4(Ipv4Addr::new(255, 255, 192, 0));
897 let netmask = NetmaskExt::from_addr(addr);
898 let prefix = netmask.get_prefix();
900 assert_eq!(prefix, 18);
901 }
902 #[test]
904 fn ipv4_methods() {
905 let ipv4 = Ipv4Addr::new(192, 168, 1, 1);
906 if ipv4.is_private() {
907 println!("{} is private", ipv4);
908 } else {
909 println!("{} is not private", ipv4);
910 }
911 let ipv6 = Ipv6Addr::new(0xfe80, 0, 0, 0, 0x20c, 0x29ff, 0xfedd, 0xf57);
912 if ipv6.is_multicast() {
913 println!("{} is multicast", ipv6);
914 } else {
915 println!("{} is not multicast", ipv6);
916 }
917 }
918 #[test]
920 fn ipv4_pool_print() {
921 let test_str = "192.168.1.0/24";
922 let ipv4_pool = Ipv4Pool::from_str(test_str).unwrap();
923 let ipv4_pool_str = format!("{}", ipv4_pool);
924 println!("{}", ipv4_pool_str);
925 }
926 #[test]
927 fn ipv4_print() {
928 let test_str = "192.168.1.1";
929 let ipv4 = Ipv4AddrExt::from_str(test_str).unwrap();
930 let ipv4_str = format!("{}", ipv4);
931 assert_eq!(ipv4_str, test_str);
932 }
933 #[test]
934 fn ipv4() {
935 let ipv4 = Ipv4AddrExt::from_str("192.168.1.1").unwrap();
936 println!("{:8b}", ipv4.addr);
937 assert_eq!(ipv4.addr, 3232235777);
938 }
939 #[test]
941 fn ipv6() {
942 let ipv6 = Ipv6AddrExt::from_str("::ffff:192.10.2.255").unwrap();
943 println!("{:?}", ipv6);
944 assert_eq!(ipv6.addr, 281473903624959);
945 }
946 #[test]
947 fn test_github_issues_1() {
948 let _pool1 = Ipv4Pool::from_str("1.2.3.4/33");
950 let _pool2 = Ipv4Pool::from_str("1.2.3.4/");
951 let _pool3 = Ipv4Pool::from_str("nonip/24");
952 }
953}