1use std::cmp::Ordering;
3use std::fmt;
4use std::net::AddrParseError;
5use std::net::IpAddr;
6use std::net::Ipv4Addr;
7use std::net::Ipv6Addr;
8use std::num::ParseIntError;
9use std::result;
10use std::str::FromStr;
11use std::u32;
12use thiserror::Error;
13
14const INIT_NEXT_VALUE: u8 = 0;
15const IPV4_PREFIX_MAX_LEN: u8 = 32;
16const IPV6_PREFIX_MAX_LEN: u8 = 128;
17
18pub type Result<T, E = SubnetworkError> = result::Result<T, E>;
19
20#[derive(Error, Debug)]
21pub enum SubnetworkError {
22 #[error("invalid input: {msg}")]
23 InvalidInput { msg: String },
24 #[error("ip addr parse error")]
25 AddrParseError(#[from] AddrParseError),
26 #[error("num parse error")]
27 ParseIntError(#[from] ParseIntError),
28}
29
30#[derive(Debug, Clone, Copy, Hash)]
31pub struct CrossIpv4Pool {
32 start: u32,
33 end: u32,
34 next: u32,
35}
36
37impl PartialEq for CrossIpv4Pool {
38 fn eq(&self, other: &Self) -> bool {
39 self.start == other.start && self.end == other.end
40 }
41}
42
43impl Eq for CrossIpv4Pool {}
44
45impl PartialOrd for CrossIpv4Pool {
46 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
47 if self.start < other.start {
48 return Some(Ordering::Less);
49 } else if self.start > other.start {
50 return Some(Ordering::Greater);
51 }
52
53 if self.end < other.end {
54 return Some(Ordering::Less);
55 } else if self.end > other.end {
56 return Some(Ordering::Greater);
57 }
58
59 if self.next > other.next {
60 return Some(Ordering::Greater);
61 } else if self.next < other.next {
62 return Some(Ordering::Less);
63 }
64
65 Some(Ordering::Equal)
66 }
67}
68
69impl Ord for CrossIpv4Pool {
70 fn cmp(&self, other: &Self) -> Ordering {
71 if self.start < other.start {
72 return Ordering::Less;
73 } else if self.start > other.start {
74 return Ordering::Greater;
75 }
76
77 if self.end < other.end {
78 return Ordering::Less;
79 } else if self.end > other.end {
80 return Ordering::Greater;
81 }
82
83 if self.next > other.next {
84 return Ordering::Greater;
85 } else if self.next < other.next {
86 return Ordering::Less;
87 }
88
89 Ordering::Equal
90 }
91}
92
93impl Iterator for CrossIpv4Pool {
94 type Item = Ipv4Addr;
95 fn next(&mut self) -> Option<Self::Item> {
96 if self.next <= self.end {
97 let ret = self.next;
98 self.next += 1;
99 Some(ret.into())
100 } else {
101 None
102 }
103 }
104}
105
106impl fmt::Display for CrossIpv4Pool {
107 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
108 let start: Ipv4Addr = self.start.into();
109 let end: Ipv4Addr = self.end.into();
110 let now: Ipv4Addr = self.next.into();
111 write!(f, "{}-{}, next {}", start, end, now)
112 }
113}
114
115impl CrossIpv4Pool {
116 pub fn new<T: Into<Ipv4AddrExt>>(
132 start: T,
133 end: Ipv4Addr,
134 ) -> Result<CrossIpv4Pool, SubnetworkError> {
135 let start_ip_ext: Ipv4AddrExt = start.into();
136 let end_ip_ext: Ipv4AddrExt = end.into();
137 let start_u32: u32 = start_ip_ext.addr;
138 let end_u32: u32 = end_ip_ext.addr;
139
140 if start_u32 <= end_u32 {
141 let cip = CrossIpv4Pool {
142 start: start_u32,
143 end: end_u32,
144 next: start_u32,
145 };
146 Ok(cip)
147 } else {
148 let error_range = format!("{}-{}", start_u32, end_u32);
149 Err(SubnetworkError::InvalidInput { msg: error_range })
150 }
151 }
152 pub fn to_vec(&self) -> Vec<Ipv4Addr> {
154 self.into_iter().collect()
155 }
156 pub fn contains(&self, addr: Ipv4Addr) -> bool {
158 let addr: u32 = addr.into();
159 if addr <= self.end && addr >= self.start {
160 true
161 } else {
162 false
163 }
164 }
165 pub fn len(&self) -> usize {
167 let length = self.end - self.start;
168 length as usize
169 }
170}
171
172#[derive(Debug, Clone, Copy, Hash)]
173pub struct Ipv4Pool {
174 prefix: u32,
175 mask: u32,
176 next: u32,
177 stop: u32,
178 addr: u32,
179}
180
181impl PartialEq for Ipv4Pool {
182 fn eq(&self, other: &Self) -> bool {
183 self.prefix == other.prefix
184 && self.mask == other.mask
185 && self.stop == other.stop
186 && self.addr == other.addr
187 }
188}
189
190impl Eq for Ipv4Pool {}
191
192impl PartialOrd for Ipv4Pool {
193 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
194 if self.prefix < other.prefix {
195 return Some(Ordering::Less);
196 } else if self.prefix > other.prefix {
197 return Some(Ordering::Greater);
198 }
199
200 if self.mask < other.mask {
201 return Some(Ordering::Less);
202 } else if self.mask > other.mask {
203 return Some(Ordering::Greater);
204 }
205
206 if self.stop < other.stop {
207 return Some(Ordering::Less);
208 } else if self.stop > other.stop {
209 return Some(Ordering::Greater);
210 }
211
212 if self.addr < other.addr {
213 return Some(Ordering::Less);
214 } else if self.addr > other.addr {
215 return Some(Ordering::Greater);
216 }
217
218 if self.next < other.next {
219 return Some(Ordering::Less);
220 } else if self.next > other.next {
221 return Some(Ordering::Greater);
222 }
223
224 Some(Ordering::Equal)
225 }
226}
227
228impl Ord for Ipv4Pool {
229 fn cmp(&self, other: &Self) -> Ordering {
230 if self.prefix < other.prefix {
231 return Ordering::Less;
232 } else if self.prefix > other.prefix {
233 return Ordering::Greater;
234 }
235
236 if self.mask < other.mask {
237 return Ordering::Less;
238 } else if self.mask > other.mask {
239 return Ordering::Greater;
240 }
241
242 if self.stop < other.stop {
243 return Ordering::Less;
244 } else if self.stop > other.stop {
245 return Ordering::Greater;
246 }
247
248 if self.addr < other.addr {
249 return Ordering::Less;
250 } else if self.addr > other.addr {
251 return Ordering::Greater;
252 }
253
254 if self.next < other.next {
255 return Ordering::Less;
256 } else if self.next > other.next {
257 return Ordering::Greater;
258 }
259
260 Ordering::Equal
261 }
262}
263
264impl Iterator for Ipv4Pool {
265 type Item = Ipv4Addr;
266 fn next(&mut self) -> Option<Self::Item> {
267 if self.next < self.stop {
268 let ret = self.prefix + self.next;
269 self.next += 1;
270 Some(ret.into())
271 } else {
272 None
273 }
274 }
275}
276
277impl fmt::Display for Ipv4Pool {
278 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
279 let prefix_addr: Ipv4Addr = self.prefix.into();
280 let mut prefix = 0;
281 let mut mask = self.mask;
282 while mask != 0 {
283 mask <<= 1;
284 prefix += 1;
285 }
286 write!(f, "{}/{}", prefix_addr, prefix)
287 }
288}
289
290impl FromStr for Ipv4Pool {
291 type Err = SubnetworkError;
292 fn from_str(addr: &str) -> Result<Self, Self::Err> {
293 if addr.contains("/") {
294 let addr_vec: Vec<&str> = addr.split("/").collect();
295 if addr_vec.len() == 2 {
296 let ip_addr = Ipv4Addr::from_str(addr_vec[0])?;
297 let prefix = u8::from_str(addr_vec[1])?;
298 if prefix <= IPV4_PREFIX_MAX_LEN {
299 let addr: u32 = ip_addr.into();
300 let mask: u32 = u32::MAX << (IPV4_PREFIX_MAX_LEN - prefix);
301 let next = INIT_NEXT_VALUE as u32;
302 let stop = 1 << (IPV4_PREFIX_MAX_LEN - prefix);
303 let prefix = addr & mask;
304 return Ok(Ipv4Pool {
305 prefix,
306 mask,
307 next,
308 stop,
309 addr,
310 });
311 }
312 }
313 }
314 Err(SubnetworkError::InvalidInput {
316 msg: addr.to_string(),
317 })
318 }
319}
320
321impl Ipv4Pool {
322 pub fn new<T: Into<Ipv4AddrExt>>(addr: T, prefix: u8) -> Result<Ipv4Pool, SubnetworkError> {
338 let addr_ext: Ipv4AddrExt = addr.into();
339 if prefix > IPV4_PREFIX_MAX_LEN {
340 let error_addr = format!("{}/{}", addr_ext, prefix);
341 Err(SubnetworkError::InvalidInput {
342 msg: error_addr.to_string(),
343 })
344 } else {
345 let addr: u32 = addr_ext.addr;
346 let mask: u32 = u32::MAX << (IPV4_PREFIX_MAX_LEN - prefix);
347 let next = INIT_NEXT_VALUE as u32;
348 let stop = 1 << (IPV4_PREFIX_MAX_LEN - prefix);
349 let prefix = addr & mask;
350 return Ok(Ipv4Pool {
351 prefix,
352 mask,
353 next,
354 stop,
355 addr,
356 });
357 }
358 }
359 pub fn to_vec(&self) -> Vec<Ipv4Addr> {
361 self.into_iter().collect()
362 }
363 pub fn contains(&self, addr: Ipv4Addr) -> bool {
378 let addr: u32 = addr.into();
379 if addr & self.mask == self.prefix {
380 true
381 } else {
382 false
383 }
384 }
385 pub fn network(&self) -> Ipv4Addr {
388 self.prefix.into()
389 }
390 pub fn broadcast(&self) -> Ipv4Addr {
393 let biggest = !self.mask;
394 let ret = self.prefix + biggest;
395 ret.into()
396 }
397 pub fn len(&self) -> usize {
399 let biggest = !self.mask + 1;
400 biggest as usize
401 }
402 pub fn addr(&self) -> Ipv4Addr {
404 self.addr.into()
405 }
406}
407
408#[derive(Debug, Clone, Copy, Hash)]
409pub struct CrossIpv6Pool {
410 start: u128,
411 end: u128,
412 next: u128,
413}
414
415impl PartialEq for CrossIpv6Pool {
416 fn eq(&self, other: &Self) -> bool {
417 self.start == other.start && self.end == other.end
418 }
419}
420
421impl Eq for CrossIpv6Pool {}
422
423impl PartialOrd for CrossIpv6Pool {
424 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
425 if self.start < other.start {
426 return Some(Ordering::Less);
427 } else if self.start > other.start {
428 return Some(Ordering::Greater);
429 }
430
431 if self.end < other.end {
432 return Some(Ordering::Less);
433 } else if self.end > other.end {
434 return Some(Ordering::Greater);
435 }
436
437 if self.next < other.next {
438 return Some(Ordering::Less);
439 } else if self.next > other.next {
440 return Some(Ordering::Greater);
441 }
442
443 Some(Ordering::Equal)
444 }
445}
446
447impl Ord for CrossIpv6Pool {
448 fn cmp(&self, other: &Self) -> Ordering {
449 if self.start < other.start {
450 return Ordering::Less;
451 } else if self.start > other.start {
452 return Ordering::Greater;
453 }
454
455 if self.end < other.end {
456 return Ordering::Less;
457 } else if self.end > other.end {
458 return Ordering::Greater;
459 }
460
461 if self.next < other.next {
462 return Ordering::Less;
463 } else if self.next > other.next {
464 return Ordering::Greater;
465 }
466
467 Ordering::Equal
468 }
469}
470
471impl Iterator for CrossIpv6Pool {
472 type Item = Ipv6Addr;
473 fn next(&mut self) -> Option<Self::Item> {
474 if self.next <= self.end {
475 let ret = self.next;
476 self.next += 1;
477 Some(ret.into())
478 } else {
479 None
480 }
481 }
482}
483
484impl fmt::Display for CrossIpv6Pool {
485 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
486 let start: Ipv6Addr = self.start.into();
487 let end: Ipv6Addr = self.end.into();
488 write!(f, "{}-{}", start, end)
489 }
490}
491
492impl CrossIpv6Pool {
493 pub fn new(start: Ipv6Addr, end: Ipv6Addr) -> Result<CrossIpv6Pool, SubnetworkError> {
510 let start_ipv6: Ipv6AddrExt = start.into();
511 let end_ipv6: Ipv6AddrExt = end.into();
512 if start_ipv6.addr <= end_ipv6.addr {
513 let cip = CrossIpv6Pool {
514 start: start_ipv6.addr,
515 end: end_ipv6.addr,
516 next: start_ipv6.addr,
517 };
518 Ok(cip)
519 } else {
520 let msg = format!("{}-{}", start, end);
521 Err(SubnetworkError::InvalidInput { msg })
522 }
523 }
524 pub fn to_vec(&self) -> Vec<Ipv6Addr> {
526 self.into_iter().collect()
527 }
528 pub fn contains(&self, addr: Ipv6Addr) -> bool {
530 let addr: u128 = addr.into();
531 if addr <= self.end && addr >= self.start {
532 true
533 } else {
534 false
535 }
536 }
537 pub fn len(&self) -> usize {
539 let length = self.end - self.start;
540 length as usize
541 }
542}
543
544#[derive(Debug, Clone, Copy, Hash)]
545pub struct Ipv6Pool {
546 prefix: u128,
547 mask: u128,
548 next: u128,
549 stop: u128,
550 addr: u128,
551}
552
553impl PartialEq for Ipv6Pool {
554 fn eq(&self, other: &Self) -> bool {
555 self.prefix == other.prefix
556 && self.mask == other.mask
557 && self.stop == other.stop
558 && self.addr == other.addr
559 }
560}
561
562impl Eq for Ipv6Pool {}
563
564impl PartialOrd for Ipv6Pool {
565 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
566 if self.prefix < other.prefix {
567 return Some(Ordering::Less);
568 } else if self.prefix > other.prefix {
569 return Some(Ordering::Greater);
570 }
571
572 if self.mask < other.mask {
573 return Some(Ordering::Less);
574 } else if self.mask > other.mask {
575 return Some(Ordering::Greater);
576 }
577
578 if self.stop < other.stop {
579 return Some(Ordering::Less);
580 } else if self.stop > other.stop {
581 return Some(Ordering::Greater);
582 }
583
584 if self.addr < other.addr {
585 return Some(Ordering::Less);
586 } else if self.addr > other.addr {
587 return Some(Ordering::Greater);
588 }
589
590 if self.next < other.next {
591 return Some(Ordering::Less);
592 } else if self.next > other.next {
593 return Some(Ordering::Greater);
594 }
595
596 Some(Ordering::Equal)
597 }
598}
599
600impl Ord for Ipv6Pool {
601 fn cmp(&self, other: &Self) -> Ordering {
602 if self.prefix < other.prefix {
603 return Ordering::Less;
604 } else if self.prefix > other.prefix {
605 return Ordering::Greater;
606 }
607
608 if self.mask < other.mask {
609 return Ordering::Less;
610 } else if self.mask > other.mask {
611 return Ordering::Greater;
612 }
613
614 if self.stop < other.stop {
615 return Ordering::Less;
616 } else if self.stop > other.stop {
617 return Ordering::Greater;
618 }
619
620 if self.addr < other.addr {
621 return Ordering::Less;
622 } else if self.addr > other.addr {
623 return Ordering::Greater;
624 }
625
626 if self.next < other.next {
627 return Ordering::Less;
628 } else if self.next > other.next {
629 return Ordering::Greater;
630 }
631
632 Ordering::Equal
633 }
634}
635
636impl Iterator for Ipv6Pool {
637 type Item = Ipv6Addr;
638 fn next(&mut self) -> Option<Self::Item> {
639 if self.next < self.stop {
640 let ret = self.prefix + self.next;
641 self.next += 1;
642 Some(ret.into())
643 } else {
644 None
645 }
646 }
647}
648
649impl fmt::Display for Ipv6Pool {
650 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
651 let prefix_addr: Ipv6Addr = self.prefix.into();
652 let mut prefix = 0;
653 let mut mask = self.mask;
654 while mask != 0 {
655 mask <<= 1;
656 prefix += 1;
657 }
658 write!(f, "{}/{}", prefix_addr, prefix)
659 }
660}
661
662impl FromStr for Ipv6Pool {
663 type Err = SubnetworkError;
664 fn from_str(addr: &str) -> Result<Self, Self::Err> {
665 if addr.contains("/") {
666 let addr_vec: Vec<&str> = addr.split("/").collect();
667 if addr_vec.len() == 2 {
668 let ip_addr = Ipv6Addr::from_str(addr_vec[0])?;
669 let prefix = u8::from_str(addr_vec[1])?;
670 if prefix <= IPV6_PREFIX_MAX_LEN {
671 let addr: u128 = ip_addr.into();
672 let mask: u128 = u128::MAX << (IPV6_PREFIX_MAX_LEN - prefix);
673 let next = INIT_NEXT_VALUE as u128;
674 let stop = 1 << (IPV6_PREFIX_MAX_LEN - prefix);
675 let prefix = addr & mask;
676 return Ok(Ipv6Pool {
677 prefix,
678 mask,
679 next,
680 stop,
681 addr,
682 });
683 }
684 }
685 }
686 Err(SubnetworkError::InvalidInput {
688 msg: addr.to_string(),
689 })
690 }
691}
692
693impl Ipv6Pool {
694 pub fn new(addr: Ipv6Addr, prefix: u8) -> Result<Ipv6Pool, SubnetworkError> {
711 if prefix > IPV6_PREFIX_MAX_LEN {
712 let error_addr = format!("{}/{}", addr, prefix);
713 Err(SubnetworkError::InvalidInput {
714 msg: error_addr.to_string(),
715 })
716 } else {
717 let addr: u128 = addr.into();
718 let mask: u128 = u128::MAX << (IPV6_PREFIX_MAX_LEN - prefix);
719 let next = INIT_NEXT_VALUE as u128;
720 let stop = 1 << (IPV6_PREFIX_MAX_LEN - prefix);
721 let prefix = addr & mask;
722 Ok(Ipv6Pool {
723 prefix,
724 mask,
725 next,
726 stop,
727 addr,
728 })
729 }
730 }
731 pub fn to_vec(&self) -> Vec<Ipv6Addr> {
733 self.into_iter().collect()
734 }
735 pub fn contains(&self, addr: Ipv6Addr) -> bool {
750 let addr: u128 = addr.into();
751 if addr & self.mask == self.prefix {
752 true
753 } else {
754 false
755 }
756 }
757 pub fn network(&self) -> Ipv6Addr {
760 self.prefix.into()
761 }
762 pub fn len(&self) -> usize {
764 let biggest = !self.mask + 1;
765 biggest as usize
766 }
767 pub fn addr(&self) -> Ipv6Addr {
769 self.addr.into()
770 }
771}
772
773#[derive(Debug, Clone, Copy, Hash)]
774pub enum IpPool {
775 V4(Ipv4Pool),
776 V6(Ipv6Pool),
777}
778
779impl PartialEq for IpPool {
780 fn eq(&self, other: &Self) -> bool {
781 match (self, other) {
782 (Self::V4(x), Self::V4(y)) => x == y,
783 (Self::V6(x), Self::V6(y)) => x == y,
784 _ => false,
785 }
786 }
787}
788
789impl Eq for IpPool {}
790
791impl PartialOrd for IpPool {
792 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
793 match (self, other) {
794 (Self::V4(x), Self::V4(y)) => x.partial_cmp(y),
795 (Self::V6(x), Self::V6(y)) => x.partial_cmp(y),
796 _ => None,
797 }
798 }
799}
800
801impl Ord for IpPool {
802 fn cmp(&self, other: &Self) -> Ordering {
803 match (self, other) {
804 (Self::V4(x), Self::V4(y)) => x.cmp(y),
805 (Self::V6(x), Self::V6(y)) => x.cmp(y),
806 _ => Ordering::Equal,
807 }
808 }
809}
810
811impl fmt::Display for IpPool {
812 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
813 let output = match self {
814 Self::V4(x) => format!("{}", x),
815 Self::V6(x) => format!("{}", x),
816 };
817 write!(f, "{}", output)
818 }
819}
820
821impl Iterator for IpPool {
822 type Item = IpAddr;
823 fn next(&mut self) -> Option<Self::Item> {
824 match self {
825 IpPool::V4(iter) => iter.next().map(IpAddr::V4),
826 IpPool::V6(iter) => iter.next().map(IpAddr::V6),
827 }
828 }
829}
830
831impl IpPool {
832 pub fn new(addr: IpAddr, prefix: u8) -> Result<Self, SubnetworkError> {
833 match addr {
834 IpAddr::V4(ipv4) => {
835 let pool = Ipv4Pool::new(ipv4, prefix)?;
836 Ok(IpPool::V4(pool))
837 }
838 IpAddr::V6(ipv6) => {
839 let pool = Ipv6Pool::new(ipv6, prefix)?;
840 Ok(IpPool::V6(pool))
841 }
842 }
843 }
844 pub fn contains(&self, addr: IpAddr) -> bool {
845 match (self, addr) {
846 (Self::V4(pool), IpAddr::V4(ip)) => pool.contains(ip),
847 (Self::V6(pool), IpAddr::V6(ip)) => pool.contains(ip),
848 _ => false,
849 }
850 }
851 pub fn to_vec(&self) -> Vec<IpAddr> {
852 match self {
853 Self::V4(pool) => pool.to_vec().into_iter().map(IpAddr::V4).collect(),
854 Self::V6(pool) => pool.to_vec().into_iter().map(IpAddr::V6).collect(),
855 }
856 }
857 pub fn len(&self) -> usize {
858 match self {
859 Self::V4(pool) => pool.len(),
860 Self::V6(pool) => pool.len(),
861 }
862 }
863 pub fn network(&self) -> IpAddr {
864 match self {
865 Self::V4(pool) => pool.network().into(),
866 Self::V6(pool) => pool.network().into(),
867 }
868 }
869 pub fn addr(&self) -> IpAddr {
870 match self {
871 Self::V4(pool) => pool.addr().into(),
872 Self::V6(pool) => pool.addr().into(),
873 }
874 }
875}
876
877#[derive(Debug, Clone, Copy, Hash)]
880pub struct Ipv4AddrExt {
881 addr: u32,
882}
883
884impl PartialEq for Ipv4AddrExt {
885 fn eq(&self, other: &Self) -> bool {
886 self.addr == other.addr
887 }
888}
889
890impl Eq for Ipv4AddrExt {}
891
892impl PartialOrd for Ipv4AddrExt {
893 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
894 self.addr.partial_cmp(&other.addr)
895 }
896}
897
898impl Ord for Ipv4AddrExt {
899 fn cmp(&self, other: &Self) -> Ordering {
900 self.addr.cmp(&other.addr)
901 }
902}
903
904impl fmt::Display for Ipv4AddrExt {
905 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
906 let addr: Ipv4Addr = self.addr.into();
907 write!(f, "{}", addr)
908 }
909}
910
911impl From<Ipv4Addr> for Ipv4AddrExt {
912 fn from(addr: Ipv4Addr) -> Self {
913 let addr: u32 = addr.into();
914 Ipv4AddrExt { addr }
915 }
916}
917
918impl From<Ipv4AddrExt> for Ipv4Addr {
919 fn from(addr: Ipv4AddrExt) -> Self {
920 let new_addr: u32 = addr.addr;
921 new_addr.into()
922 }
923}
924
925impl FromStr for Ipv4AddrExt {
926 type Err = SubnetworkError;
927 fn from_str(addr: &str) -> Result<Self, Self::Err> {
928 let new_addr = Ipv4Addr::from_str(addr)?;
929 let addr: u32 = new_addr.into();
930 Ok(Ipv4AddrExt { addr })
931 }
932}
933
934impl Ipv4AddrExt {
935 pub fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4AddrExt {
937 let a_fix = (a as u32) << 24;
938 let b_fix = (b as u32) << 16;
939 let c_fix = (c as u32) << 8;
940 let d_fix = d as u32;
941 let addr = a_fix + b_fix + c_fix + d_fix;
942 Ipv4AddrExt { addr }
943 }
944 pub fn largest_identical_prefix<T: Into<Ipv4AddrExt>>(&self, target: T) -> u8 {
960 let a = self.addr;
961 let b = target.into().addr;
962 let init_mask = 2u32.pow(31);
963 let mut mask = init_mask;
964
965 for c in 0..IPV4_PREFIX_MAX_LEN {
966 if a & mask != b & mask {
967 return c;
968 }
969 mask = (mask >> 1) + init_mask;
970 }
971 0
972 }
973}
974
975#[derive(Debug, Clone, Copy, Hash)]
976pub struct Ipv6AddrExt {
977 addr: u128,
978}
979
980impl PartialEq for Ipv6AddrExt {
981 fn eq(&self, other: &Self) -> bool {
982 self.addr == other.addr
983 }
984}
985
986impl Eq for Ipv6AddrExt {}
987
988impl PartialOrd for Ipv6AddrExt {
989 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
990 self.addr.partial_cmp(&other.addr)
991 }
992}
993
994impl Ord for Ipv6AddrExt {
995 fn cmp(&self, other: &Self) -> Ordering {
996 self.addr.cmp(&other.addr)
997 }
998}
999
1000impl fmt::Display for Ipv6AddrExt {
1001 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1002 let addr: Ipv6Addr = self.addr.into();
1003 write!(f, "{}", addr)
1004 }
1005}
1006
1007impl From<Ipv6Addr> for Ipv6AddrExt {
1008 fn from(addr: Ipv6Addr) -> Self {
1009 let addr: u128 = addr.into();
1010 Ipv6AddrExt { addr }
1011 }
1012}
1013
1014impl From<Ipv6AddrExt> for Ipv6Addr {
1015 fn from(addr: Ipv6AddrExt) -> Self {
1016 let new_addr: u128 = addr.addr;
1017 new_addr.into()
1018 }
1019}
1020
1021impl FromStr for Ipv6AddrExt {
1022 type Err = SubnetworkError;
1023 fn from_str(addr: &str) -> Result<Self, Self::Err> {
1024 let new_addr = Ipv6Addr::from_str(addr)?;
1025 let addr: u128 = new_addr.into();
1026 Ok(Ipv6AddrExt { addr })
1027 }
1028}
1029
1030impl Ipv6AddrExt {
1031 pub fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Ipv6AddrExt {
1033 let a_fix = (a as u128) << 112;
1034 let b_fix = (b as u128) << 96;
1035 let c_fix = (c as u128) << 80;
1036 let d_fix = (d as u128) << 64;
1037 let e_fix = (e as u128) << 48;
1038 let f_fix = (f as u128) << 32;
1039 let g_fix = (g as u128) << 16;
1040 let h_fix = h as u128;
1041 let addr = a_fix + b_fix + c_fix + d_fix + e_fix + f_fix + g_fix + h_fix;
1042 Ipv6AddrExt { addr }
1043 }
1044 pub fn node_multicast(&self) -> Ipv6Addr {
1046 let node = Ipv6Addr::new(
1047 0xff01, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0xff00, 0x0000,
1048 );
1049 let mask = Ipv6Addr::new(
1050 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00ff, 0xffff,
1051 );
1052 let node_u128: u128 = node.into();
1053 let mask_u128: u128 = mask.into();
1054 (node_u128 + (mask_u128 & self.addr)).into()
1055 }
1056 pub fn link_multicast(&self) -> Ipv6Addr {
1058 let link = Ipv6Addr::new(
1059 0xff02, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0xff00, 0x0000,
1060 );
1061 let mask = Ipv6Addr::new(
1062 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00ff, 0xffff,
1063 );
1064 let link_u128: u128 = link.into();
1065 let mask_u128: u128 = mask.into();
1066 (link_u128 + (mask_u128 & self.addr)).into()
1067 }
1068 pub fn site_multicast(&self) -> Ipv6Addr {
1070 let site = Ipv6Addr::new(
1071 0xff05, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0xff00, 0x0000,
1072 );
1073 let mask = Ipv6Addr::new(
1074 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00ff, 0xffff,
1075 );
1076 let site_u128: u128 = site.into();
1077 let mask_u128: u128 = mask.into();
1078 (site_u128 + (mask_u128 & self.addr)).into()
1079 }
1080 pub fn largest_identical_prefix<T: Into<Ipv6AddrExt>>(&self, target: T) -> u8 {
1081 let a = self.addr;
1082 let b = target.into().addr;
1083 let init_mask = 2u128.pow(127);
1084 let mut mask = init_mask;
1085
1086 for c in 0..IPV6_PREFIX_MAX_LEN {
1087 if a & mask != b & mask {
1088 return c;
1089 }
1090 mask = (mask >> 1) + init_mask;
1091 }
1092 0
1093 }
1094}
1095
1096#[derive(Debug, Clone, Copy)]
1097pub struct NetmaskExt {
1098 prefix: u8,
1099}
1100
1101impl NetmaskExt {
1102 pub fn new(prefix: u8) -> NetmaskExt {
1114 NetmaskExt { prefix }
1115 }
1116 pub fn from_addr(addr: IpAddr) -> NetmaskExt {
1132 let prefix = match addr {
1134 IpAddr::V4(ipv4) => {
1135 let mask = u32::from_be_bytes(ipv4.octets());
1136 let prefix = mask.count_ones() as u8;
1137 prefix
1138 }
1139 IpAddr::V6(ipv6) => {
1140 let mask = u128::from_be_bytes(ipv6.octets());
1141 let prefix = mask.count_ones() as u8;
1142 prefix
1143 }
1144 };
1145 NetmaskExt { prefix }
1146 }
1147 pub fn get_prefix(&self) -> u8 {
1149 self.prefix
1150 }
1151 pub fn to_ipv4(&self) -> Result<Ipv4Addr, SubnetworkError> {
1153 if self.prefix == 0 {
1154 Ok((0 as u32).into())
1155 } else {
1156 if self.prefix > IPV4_PREFIX_MAX_LEN {
1157 let msg = format!("prefix: {}", self.prefix);
1158 Err(SubnetworkError::InvalidInput { msg })
1159 } else {
1160 Ok((u32::MAX << (IPV4_PREFIX_MAX_LEN - self.prefix)).into())
1161 }
1162 }
1163 }
1164 pub fn to_ipv6(&self) -> Result<Ipv6Addr, SubnetworkError> {
1166 if self.prefix == 0 {
1167 Ok((0 as u128).into())
1168 } else {
1169 if self.prefix > IPV6_PREFIX_MAX_LEN {
1170 let msg = format!("prefix: {}", self.prefix);
1171 Err(SubnetworkError::InvalidInput { msg })
1172 } else {
1173 Ok((u128::MAX << (IPV6_PREFIX_MAX_LEN - self.prefix)).into())
1174 }
1175 }
1176 }
1177}
1178
1179#[cfg(test)]
1180mod tests {
1181 use super::*;
1182 #[test]
1184 fn readme_example_1() {
1185 let pool = Ipv4Pool::new(Ipv4Addr::new(192, 168, 1, 1), 24).unwrap();
1186 for ipv4 in pool {
1188 println!("{}", ipv4);
1189 }
1190
1191 let pool = Ipv4Pool::from_str("192.168.1.0/24").unwrap();
1192 for ipv4 in pool {
1193 println!("{}", ipv4);
1194 }
1195
1196 let pool: Ipv4Pool = "192.168.1.0/24".parse().unwrap();
1197 for ipv4 in pool {
1198 println!("{}", ipv4);
1199 }
1200
1201 let test_ipv4 = Ipv4Addr::new(192, 168, 1, 233);
1202 assert_eq!(pool.contains(test_ipv4), true);
1203
1204 let broadcast = Ipv4Addr::new(192, 168, 1, 255);
1205 assert_eq!(pool.broadcast(), broadcast);
1206
1207 let network = Ipv4Addr::new(192, 168, 1, 0);
1208 assert_eq!(pool.network(), network);
1209
1210 assert_eq!(pool.len(), 256);
1211 assert_eq!(pool.to_string(), "192.168.1.0/24");
1213 }
1214 #[test]
1215 fn readme_example_2() {
1216 let start = Ipv4Addr::new(192, 168, 1, 16);
1217 let end = Ipv4Addr::new(192, 168, 3, 200);
1218 let pool = CrossIpv4Pool::new(start, end).unwrap();
1219 for i in pool {
1221 println!("{:?}", i);
1222 }
1223
1224 let test_ipv4 = Ipv4Addr::new(192, 168, 1, 233);
1225 assert_eq!(pool.contains(test_ipv4), true);
1226 let test_ipv4 = Ipv4Addr::new(192, 168, 2, 0);
1227 assert_eq!(pool.contains(test_ipv4), true);
1228 let test_ipv4 = Ipv4Addr::new(192, 168, 3, 255);
1229 assert_eq!(pool.contains(test_ipv4), false);
1230 let test_ipv4 = Ipv4Addr::new(192, 168, 3, 200);
1231 assert_eq!(pool.contains(test_ipv4), true);
1232 }
1233 #[test]
1234 fn readme_example_3() {
1235 let ip1 = Ipv4Addr::new(192, 168, 1, 0);
1237 let ip2 = Ipv4Addr::new(192, 168, 1, 255);
1238
1239 let ip1ext: Ipv4AddrExt = ip1.into();
1240 assert_eq!(ip1ext.largest_identical_prefix(ip2), 24);
1241
1242 let ip1 = Ipv4Addr::new(192, 168, 1, 136);
1244 let ip2 = Ipv4Addr::new(192, 168, 1, 192);
1245
1246 let ip1ext: Ipv4AddrExt = ip1.into();
1247 assert_eq!(ip1ext.largest_identical_prefix(ip2), 25);
1248 }
1249 #[test]
1250 fn readme_example_4() {
1251 let ipv6 = Ipv6Addr::from_str("::ffff:192.10.2.255").unwrap();
1252 let ipv6_ext: Ipv6AddrExt = ipv6.into();
1253
1254 let ipv6_node_multicast = Ipv6Addr::from_str("ff01::1:ff0a:2ff").unwrap();
1255 assert_eq!(ipv6_ext.node_multicast(), ipv6_node_multicast);
1256
1257 let ipv6_link_multicast = Ipv6Addr::from_str("ff02::1:ff0a:2ff").unwrap();
1258 assert_eq!(ipv6_ext.link_multicast(), ipv6_link_multicast);
1259
1260 let ipv6_site_multicast = Ipv6Addr::from_str("ff05::1:ff0a:2ff").unwrap();
1261 assert_eq!(ipv6_ext.site_multicast(), ipv6_site_multicast);
1262 }
1263 #[test]
1264 fn readme_example_5() {
1265 let netmask = NetmaskExt::new(24);
1266 let netmask_addr = netmask.to_ipv4().unwrap();
1267 assert_eq!(netmask_addr, Ipv4Addr::new(255, 255, 255, 0));
1268
1269 let netmask = NetmaskExt::new(26);
1270 let netmask_addr = netmask.to_ipv4().unwrap();
1271 assert_eq!(netmask_addr, Ipv4Addr::new(255, 255, 255, 192));
1272 }
1273 #[test]
1274 fn netmask_ext() {
1275 let addr = IpAddr::V4(Ipv4Addr::new(255, 255, 255, 0));
1276 let netmask = NetmaskExt::from_addr(addr);
1277 let prefix = netmask.get_prefix();
1279 assert_eq!(prefix, 24);
1280
1281 let addr = IpAddr::V4(Ipv4Addr::new(255, 255, 255, 192));
1282 let netmask = NetmaskExt::from_addr(addr);
1283 let prefix = netmask.get_prefix();
1285 assert_eq!(prefix, 26);
1286
1287 let addr = IpAddr::V4(Ipv4Addr::new(255, 255, 0, 0));
1288 let netmask = NetmaskExt::from_addr(addr);
1289 let prefix = netmask.get_prefix();
1291 assert_eq!(prefix, 16);
1292
1293 let addr = IpAddr::V4(Ipv4Addr::new(255, 255, 192, 0));
1294 let netmask = NetmaskExt::from_addr(addr);
1295 let prefix = netmask.get_prefix();
1297 assert_eq!(prefix, 18);
1298 }
1299 #[test]
1301 fn ipv4_methods() {
1302 let ipv4 = Ipv4Addr::new(192, 168, 1, 1);
1303 if ipv4.is_private() {
1304 println!("{} is private", ipv4);
1305 } else {
1306 println!("{} is not private", ipv4);
1307 }
1308 let ipv6 = Ipv6Addr::new(0xfe80, 0, 0, 0, 0x20c, 0x29ff, 0xfedd, 0xf57);
1309 if ipv6.is_multicast() {
1310 println!("{} is multicast", ipv6);
1311 } else {
1312 println!("{} is not multicast", ipv6);
1313 }
1314 }
1315 #[test]
1317 fn ipv4_pool_print() {
1318 let test_str = "192.168.1.0/24";
1319 let ipv4_pool = Ipv4Pool::from_str(test_str).unwrap();
1320 let ipv4_pool_str = format!("{}", ipv4_pool);
1321 println!("{}", ipv4_pool_str);
1322 }
1323 #[test]
1324 fn ipv4_print() {
1325 let test_str = "192.168.1.1";
1326 let ipv4 = Ipv4AddrExt::from_str(test_str).unwrap();
1327 let ipv4_str = format!("{}", ipv4);
1328 assert_eq!(ipv4_str, test_str);
1329 }
1330 #[test]
1331 fn ipv4() {
1332 let ipv4 = Ipv4AddrExt::from_str("192.168.1.1").unwrap();
1333 println!("{:8b}", ipv4.addr);
1334 assert_eq!(ipv4.addr, 3232235777);
1335 }
1336 #[test]
1338 fn ipv6() {
1339 let ipv6 = Ipv6AddrExt::from_str("::ffff:192.10.2.255").unwrap();
1340 println!("{:?}", ipv6);
1341 assert_eq!(ipv6.addr, 281473903624959);
1342 }
1343 #[test]
1344 fn test_github_issues_1() {
1345 let _pool1 = Ipv4Pool::from_str("1.2.3.4/33");
1347 let _pool2 = Ipv4Pool::from_str("1.2.3.4/");
1348 let _pool3 = Ipv4Pool::from_str("nonip/24");
1349 }
1350}