|
xorp
|
00001 // -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*- 00002 // vim:set sts=4 ts=8: 00003 00004 // Copyright (c) 2001-2011 XORP, Inc and Others 00005 // 00006 // This program is free software; you can redistribute it and/or modify 00007 // it under the terms of the GNU Lesser General Public License, Version 00008 // 2.1, June 1999 as published by the Free Software Foundation. 00009 // Redistribution and/or modification of this program under the terms of 00010 // any other version of the GNU Lesser General Public License is not 00011 // permitted. 00012 // 00013 // This program is distributed in the hope that it will be useful, but 00014 // WITHOUT ANY WARRANTY; without even the implied warranty of 00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details, 00016 // see the GNU Lesser General Public License, Version 2.1, a copy of 00017 // which can be found in the XORP LICENSE.lgpl file. 00018 // 00019 // XORP, Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA; 00020 // http://xorp.net 00021 00022 00023 #ifndef __LIBXORP_IPV4_HH__ 00024 #define __LIBXORP_IPV4_HH__ 00025 00026 #include "libxorp/xorp.h" 00027 #include "libxorp/exceptions.hh" 00028 #include "libxorp/range.hh" 00029 #include "libxorp/utils.hh" 00030 00031 00032 struct in_addr; 00033 00041 class IPv4 { 00042 public: 00043 typedef in_addr InAddrType; 00044 typedef sockaddr_in SockAddrType; 00045 00046 public: 00052 IPv4() { _addr = 0; } 00053 00059 IPv4(const IPv4& ipv4) : _addr(ipv4._addr) {} 00060 00066 explicit IPv4(uint32_t value) { _addr = value; } 00067 00074 explicit IPv4(const uint8_t *from_uint8); 00075 00081 IPv4(const in_addr& from_in_addr); 00082 00088 IPv4(const sockaddr& sa) throw (InvalidFamily); 00089 00095 IPv4(const sockaddr_storage& ss) throw (InvalidFamily); 00096 00102 IPv4(const sockaddr_in& sin) throw (InvalidFamily); 00103 00110 IPv4(const char *from_string) throw (InvalidString); 00111 00118 size_t copy_out(uint8_t *to_uint8) const; 00119 00126 size_t copy_out(in_addr& to_in_addr) const; 00127 00138 size_t copy_out(sockaddr& to_sockaddr) const; 00139 00150 size_t copy_out(sockaddr_storage& to_sockaddr_storage) const; 00151 00162 size_t copy_out(sockaddr_in& to_sockaddr_in) const; 00163 00171 size_t copy_in(const uint8_t *from_uint8); 00172 00179 size_t copy_in(const in_addr& from_in_addr); 00180 00190 size_t copy_in(const sockaddr& from_sockaddr) throw (InvalidFamily); 00191 00202 size_t copy_in(const sockaddr_storage& from_sockaddr_storage) 00203 throw (InvalidFamily); 00204 00214 size_t copy_in(const sockaddr_in& from_sockaddr_in) throw (InvalidFamily); 00215 00221 IPv4 operator~() const { return IPv4(~_addr); } 00222 00229 IPv4 operator|(const IPv4& other) const { 00230 return IPv4(_addr | other._addr); 00231 } 00232 00239 IPv4 operator&(const IPv4& other) const { 00240 return IPv4(_addr & other._addr); 00241 } 00242 00248 IPv4 operator^(const IPv4& other) const { 00249 return IPv4(_addr ^ other._addr); 00250 } 00251 00258 IPv4 operator<<(uint32_t left_shift) const; 00259 00266 IPv4 operator>>(uint32_t right_shift) const; 00267 00275 bool operator<(const IPv4& other) const; 00276 00284 bool operator==(const IPv4& other) const { return (_addr == other._addr); } 00285 00293 bool operator!=(const IPv4& other) const { return (_addr != other._addr); } 00294 00302 bool operator==(const IPv4Range& rhs) const { 00303 return (_addr >= rhs.low().addr() && _addr <= rhs.high().addr()); 00304 } 00305 00313 bool operator!=(const IPv4Range& rhs) const { 00314 return (_addr < rhs.low().addr() || _addr > rhs.high().addr()); 00315 } 00316 00324 bool operator<(const IPv4Range& rhs) const { 00325 return (_addr < rhs.low().addr()); 00326 } 00327 00335 bool operator<=(const IPv4Range& rhs) const { 00336 return (_addr <= rhs.high().addr()); 00337 } 00338 00346 bool operator>(const IPv4Range& rhs) const { 00347 return (_addr > rhs.high().addr()); 00348 } 00349 00357 bool operator>=(const IPv4Range& rhs) const { 00358 return (_addr >= rhs.low().addr()); 00359 } 00360 00371 IPv4& operator--(); 00372 00383 IPv4& operator++(); 00384 00391 string str() const; 00392 00398 bool is_zero() const { return (_addr == 0); } 00399 00407 bool is_unicast() const; 00408 00414 bool is_multicast() const; 00415 00422 bool is_class_a() const; 00423 00430 bool is_class_b() const; 00431 00438 bool is_class_c() const; 00439 00446 bool is_experimental() const; 00447 00454 bool is_linklocal_unicast() const; 00455 00467 bool is_interfacelocal_multicast() const; 00468 00481 bool is_nodelocal_multicast() const { return is_interfacelocal_multicast(); } 00482 00489 bool is_linklocal_multicast() const; 00490 00496 bool is_loopback() const; 00497 00508 static size_t addr_bytelen() { 00509 x_static_assert(sizeof(IPv4) == sizeof(uint32_t)); 00510 return sizeof(IPv4); 00511 } 00512 00523 static uint32_t addr_bitlen() { 00524 return uint32_t(8 * sizeof(uint8_t) * addr_bytelen()); 00525 } 00526 00537 static uint32_t ip_multicast_base_address_mask_len() { 00538 #define IP_MULTICAST_BASE_ADDRESS_MASK_LEN_IPV4 4 00539 return (IP_MULTICAST_BASE_ADDRESS_MASK_LEN_IPV4); 00540 #undef IP_MULTICAST_BASE_ADDRESS_MASK_LEN_IPV4 00541 } 00542 00553 static uint32_t ip_class_a_base_address_mask_len() { 00554 #define IP_CLASS_A_BASE_ADDRESS_MASK_LEN_IPV4 1 00555 return (IP_CLASS_A_BASE_ADDRESS_MASK_LEN_IPV4); 00556 #undef IP_CLASS_A_BASE_ADDRESS_MASK_LEN_IPV4 00557 } 00558 00569 static uint32_t ip_class_b_base_address_mask_len() { 00570 #define IP_CLASS_B_BASE_ADDRESS_MASK_LEN_IPV4 2 00571 return (IP_CLASS_B_BASE_ADDRESS_MASK_LEN_IPV4); 00572 #undef IP_CLASS_B_BASE_ADDRESS_MASK_LEN_IPV4 00573 } 00574 00585 static uint32_t ip_class_c_base_address_mask_len() { 00586 #define IP_CLASS_C_BASE_ADDRESS_MASK_LEN_IPV4 3 00587 return (IP_CLASS_C_BASE_ADDRESS_MASK_LEN_IPV4); 00588 #undef IP_CLASS_C_BASE_ADDRESS_MASK_LEN_IPV4 00589 } 00590 00601 static uint32_t ip_experimental_base_address_mask_len() { 00602 #define IP_EXPERIMENTAL_BASE_ADDRESS_MASK_LEN_IPV4 4 00603 return (IP_EXPERIMENTAL_BASE_ADDRESS_MASK_LEN_IPV4); 00604 #undef IP_EXPERIMENTAL_BASE_ADDRESS_MASK_LEN_IPV4 00605 } 00606 00613 static IPv4 make_prefix(uint32_t mask_len) throw (InvalidNetmaskLength); 00614 00622 IPv4 mask_by_prefix_len(uint32_t mask_len) const 00623 throw (InvalidNetmaskLength) { 00624 return (*this) & make_prefix(mask_len); 00625 } 00626 00633 uint32_t mask_len() const; 00634 00640 uint32_t addr() const { return _addr; } 00641 00647 void set_addr(uint32_t value) { _addr = value; } 00648 00652 enum { AF = AF_INET }; 00653 00657 enum { IPV = 4 }; 00658 00664 static int af() { return AF; } 00665 00671 static uint32_t ip_version() { return IPV; } 00672 00679 static const string& ip_version_str(); 00680 00689 uint32_t bits(uint32_t lsb, uint32_t len) const; 00690 00696 uint32_t bit_count() const; 00697 00703 uint32_t leading_zero_count() const; 00704 00708 static const IPv4& ZERO(int af = AF_INET); 00709 static const IPv4& ANY(int af = AF_INET); 00710 static const IPv4& ALL_ONES(int af = AF_INET); 00711 static const IPv4& LOOPBACK(int af = AF_INET); 00712 static const IPv4& MULTICAST_BASE(int af = AF_INET); 00713 static const IPv4& MULTICAST_ALL_SYSTEMS(int af = AF_INET); 00714 static const IPv4& MULTICAST_ALL_ROUTERS(int af = AF_INET); 00715 static const IPv4& DVMRP_ROUTERS(int af = AF_INET); 00716 static const IPv4& OSPFIGP_ROUTERS(int af = AF_INET); 00717 static const IPv4& OSPFIGP_DESIGNATED_ROUTERS(int af = AF_INET); 00718 static const IPv4& RIP2_ROUTERS(int af = AF_INET); 00719 static const IPv4& PIM_ROUTERS(int af = AF_INET); 00720 static const IPv4& SSM_ROUTERS(int af = AF_INET); 00721 static const IPv4& CLASS_A_BASE(int af = AF_INET); 00722 static const IPv4& CLASS_B_BASE(int af = AF_INET); 00723 static const IPv4& CLASS_C_BASE(int af = AF_INET); 00724 static const IPv4& EXPERIMENTAL_BASE(int af = AF_INET); 00725 00729 static const uint32_t ADDR_BITLEN = 32; 00730 00734 static const uint32_t ADDR_BYTELEN = ADDR_BITLEN / 8; 00735 00736 private: 00737 uint32_t _addr; // The address value (in network-order) 00738 }; 00739 00740 inline uint32_t 00741 IPv4::bits(uint32_t lsb, uint32_t len) const 00742 { 00743 uint32_t mask = ~(0xffffffffU << len); 00744 00745 if (len >= 32) 00746 mask = 0xffffffffU; // XXX: shifting with >= 32 bits is undefined 00747 return (ntohl(_addr) >> lsb) & mask; 00748 } 00749 00750 inline uint32_t 00751 IPv4::bit_count() const 00752 { 00753 // XXX: no need for ntohl() 00754 return (xorp_bit_count_uint32(_addr)); 00755 } 00756 00757 inline uint32_t 00758 IPv4::leading_zero_count() const 00759 { 00760 return (xorp_leading_zero_count_uint32(ntohl(_addr))); 00761 } 00762 00763 struct IPv4Constants { 00764 static const IPv4 zero, 00765 any, 00766 all_ones, 00767 loopback, 00768 multicast_base, 00769 multicast_all_systems, 00770 multicast_all_routers, 00771 dvmrp_routers, 00772 ospfigp_routers, 00773 ospfigp_designated_routers, 00774 rip2_routers, 00775 pim_routers, 00776 ssm_routers, 00777 class_a_base, 00778 class_b_base, 00779 class_c_base, 00780 experimental_base; 00781 }; 00782 00783 inline const IPv4& IPv4::ZERO(int) { 00784 return IPv4Constants::zero; 00785 } 00786 00787 inline const IPv4& IPv4::ANY(int) { 00788 return IPv4Constants::any; 00789 } 00790 00791 inline const IPv4& IPv4::ALL_ONES(int) { 00792 return IPv4Constants::all_ones; 00793 } 00794 00795 inline const IPv4& IPv4::LOOPBACK(int) { 00796 return IPv4Constants::loopback; 00797 } 00798 00799 inline const IPv4& IPv4::MULTICAST_BASE(int) { 00800 return IPv4Constants::multicast_base; 00801 } 00802 00803 inline const IPv4& IPv4::MULTICAST_ALL_SYSTEMS(int) { 00804 return IPv4Constants::multicast_all_systems; 00805 } 00806 00807 inline const IPv4& IPv4::MULTICAST_ALL_ROUTERS(int) { 00808 return IPv4Constants::multicast_all_routers; 00809 } 00810 00811 inline const IPv4& IPv4::DVMRP_ROUTERS(int) { 00812 return IPv4Constants::dvmrp_routers; 00813 } 00814 00815 inline const IPv4& IPv4::OSPFIGP_ROUTERS(int) { 00816 return IPv4Constants::ospfigp_routers; 00817 } 00818 00819 inline const IPv4& IPv4::OSPFIGP_DESIGNATED_ROUTERS(int) { 00820 return IPv4Constants::ospfigp_designated_routers; 00821 } 00822 00823 inline const IPv4& IPv4::RIP2_ROUTERS(int) { 00824 return IPv4Constants::rip2_routers; 00825 } 00826 00827 inline const IPv4& IPv4::PIM_ROUTERS(int) { 00828 return IPv4Constants::pim_routers; 00829 } 00830 00831 inline const IPv4& IPv4::SSM_ROUTERS(int) { 00832 return IPv4Constants::ssm_routers; 00833 } 00834 00835 inline const IPv4& IPv4::CLASS_A_BASE(int) { 00836 return IPv4Constants::class_a_base; 00837 } 00838 00839 inline const IPv4& IPv4::CLASS_B_BASE(int) { 00840 return IPv4Constants::class_b_base; 00841 } 00842 00843 inline const IPv4& IPv4::CLASS_C_BASE(int) { 00844 return IPv4Constants::class_c_base; 00845 } 00846 00847 inline const IPv4& IPv4::EXPERIMENTAL_BASE(int) { 00848 return IPv4Constants::experimental_base; 00849 } 00850 00851 #endif // __LIBXORP_IPV4_HH__