xorp

ipv4.hh

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__
 All Classes Namespaces Functions Variables Typedefs Enumerations