xorp

ipvx.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-2009 XORP, Inc.
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 // $XORP: xorp/libxorp/ipvx.hh,v 1.35 2009/01/05 18:30:58 jtc Exp $
00023 
00024 #ifndef __LIBXORP_IPVX_HH__
00025 #define __LIBXORP_IPVX_HH__
00026 
00027 #include "ipv4.hh"
00028 #include "ipv6.hh"
00029 
00030 
00034 class IPvX {
00035 public:
00042     IPvX();
00043 
00052     explicit IPvX(int family) throw (InvalidFamily);
00053 
00064     IPvX(int family, const uint8_t *from_uint8) throw (InvalidFamily);
00065 
00073     IPvX(const IPv4& ipv4);
00074 
00082     IPvX(const IPv6& ipv6);
00083 
00091     IPvX(const in_addr& from_in_addr);
00092 
00100     IPvX(const in6_addr& from_in6_addr);
00101 
00107     IPvX(const sockaddr& from_sockaddr) throw (InvalidFamily);
00108 
00114     IPvX(const sockaddr_storage& from_sockaddr_storage) throw (InvalidFamily);
00115 
00124     IPvX(const sockaddr_in& from_sockaddr_in) throw (InvalidFamily);
00125 
00134     IPvX(const sockaddr_in6& from_sockaddr_in6) throw (InvalidFamily);
00135 
00142     IPvX(const char *from_cstring) throw (InvalidString);
00143 
00150     size_t copy_out(uint8_t *to_uint8) const;
00151 
00160     size_t copy_out(in_addr& to_in_addr) const throw (InvalidFamily);
00161 
00170     size_t copy_out(in6_addr& to_in6_addr) const throw (InvalidFamily);
00171 
00183     size_t copy_out(sockaddr& to_sockaddr) const throw (InvalidFamily);
00184 
00196     size_t copy_out(sockaddr_storage& to_sockaddr_storage)
00197     const throw (InvalidFamily);
00198 
00211     size_t copy_out(sockaddr_in& to_sockaddr_in) const throw (InvalidFamily);
00212 
00225     size_t copy_out(sockaddr_in6& to_sockaddr_in6) const throw (InvalidFamily);
00226 
00235     size_t copy_in(int family, const uint8_t *from_uint8)
00236     throw (InvalidFamily);
00237 
00244     size_t copy_in(const in_addr& from_in_addr);
00245 
00252     size_t copy_in(const in6_addr& from_in6_addr);
00253 
00263     size_t copy_in(const sockaddr& from_sockaddr) throw (InvalidFamily);
00264 
00275     size_t copy_in(const sockaddr_storage& from_sockaddr_storage)
00276     throw (InvalidFamily);
00277 
00290     size_t copy_in(const sockaddr_in& from_sockaddr_in) throw (InvalidFamily);
00291 
00304     size_t copy_in(const sockaddr_in6& from_sockaddr_in6)
00305     throw (InvalidFamily);
00306 
00312     IPvX operator~() const;
00313 
00320     IPvX operator|(const IPvX& other) const throw (InvalidCast);
00321 
00328     IPvX operator&(const IPvX& other) const throw (InvalidCast);
00329 
00336     IPvX operator^(const IPvX& other) const throw (InvalidCast);
00337 
00344     IPvX operator<<(uint32_t left_shift) const;
00345 
00352     IPvX operator>>(uint32_t right_shift) const;
00353 
00361     bool operator<(const IPvX& other) const;
00362 
00370     bool operator==(const IPvX& other) const;
00371 
00379     bool operator!=(const IPvX& other) const;
00380 
00391     IPvX& operator--();
00392 
00403     IPvX& operator++();
00404 
00411     string str() const;
00412 
00418     bool is_zero() const;
00419 
00425     bool is_unicast() const;
00426 
00432     bool is_multicast() const;
00433 
00442     bool is_class_a() const;
00443 
00452     bool is_class_b() const;
00453 
00462     bool is_class_c() const;
00463 
00472     bool is_experimental() const;
00473 
00480     bool is_linklocal_unicast() const;
00481 
00491     bool is_interfacelocal_multicast() const;
00492 
00503     bool is_nodelocal_multicast() const { return is_interfacelocal_multicast(); }
00504 
00511     bool is_linklocal_multicast() const;
00512 
00518     bool is_loopback() const;
00519 
00531     static size_t addr_bytelen(int family) throw (InvalidFamily);
00532 
00543     size_t addr_bytelen() const { return IPvX::addr_bytelen(_af); }
00544 
00556     static uint32_t addr_bitlen(int family) throw (InvalidFamily) {
00557     return uint32_t(8 * sizeof(uint8_t) * addr_bytelen(family));
00558     }
00559 
00570     uint32_t addr_bitlen() const {
00571     return uint32_t(8 * sizeof(uint8_t) * addr_bytelen());
00572     }
00573 
00585     static uint32_t ip_multicast_base_address_mask_len(int family)
00586     throw (InvalidFamily);
00587 
00598     uint32_t ip_multicast_base_address_mask_len() const {
00599     return IPvX::ip_multicast_base_address_mask_len(_af);
00600     }
00601 
00614     static uint32_t ip_class_a_base_address_mask_len(int family)
00615     throw (InvalidFamily);
00616 
00628     uint32_t ip_class_a_base_address_mask_len() const throw (InvalidFamily) {
00629     return IPvX::ip_class_a_base_address_mask_len(_af);
00630     }
00631 
00644     static uint32_t ip_class_b_base_address_mask_len(int family)
00645     throw (InvalidFamily);
00646 
00658     uint32_t ip_class_b_base_address_mask_len() const throw (InvalidFamily) {
00659     return IPvX::ip_class_b_base_address_mask_len(_af);
00660     }
00661 
00674     static uint32_t ip_class_c_base_address_mask_len(int family)
00675     throw (InvalidFamily);
00676 
00688     uint32_t ip_class_c_base_address_mask_len() const throw (InvalidFamily) {
00689     return IPvX::ip_class_c_base_address_mask_len(_af);
00690     }
00691 
00704     static uint32_t ip_experimental_base_address_mask_len(int family)
00705     throw (InvalidFamily);
00706 
00718     uint32_t ip_experimental_base_address_mask_len() const throw (InvalidFamily) {
00719     return IPvX::ip_experimental_base_address_mask_len(_af);
00720     }
00721 
00729     static IPvX make_prefix(int family, uint32_t mask_len)
00730     throw (InvalidFamily, InvalidNetmaskLength);
00731 
00738     IPvX make_prefix(uint32_t mask_len) const throw (InvalidNetmaskLength) {
00739     return IPvX::make_prefix(_af, mask_len);
00740     }
00741 
00749     IPvX mask_by_prefix_len(uint32_t prefix_len) const throw (InvalidNetmaskLength);
00750 
00757     uint32_t mask_len() const;
00758 
00764     bool is_ipv4() const { return (_af == AF_INET); }
00765 
00771     bool is_ipv6() const { return (_af == AF_INET6); }
00772 
00778     IPv4 get_ipv4() const throw (InvalidCast);
00779 
00785     IPv6 get_ipv6() const throw (InvalidCast);
00786 
00793     void get(IPv4& to_ipv4) const throw (InvalidCast) {
00794     to_ipv4 = get_ipv4();
00795     }
00796 
00803     void get(IPv6& to_ipv6) const throw (InvalidCast) {
00804     to_ipv6 = get_ipv6();
00805     }
00806 
00812     int af() const { return (_af); }
00813 
00819     uint32_t ip_version() const throw (InvalidFamily);
00820 
00827     const string& ip_version_str() const throw (InvalidFamily);
00828 
00837     uint32_t bits(uint32_t lsb, uint32_t len) const throw (InvalidFamily);
00838 
00844     uint32_t bit_count() const;
00845 
00851     uint32_t leading_zero_count() const;
00852 
00856     static const IPvX& ZERO(int family)
00857     throw (InvalidFamily);
00858     static const IPvX& ANY(int family)
00859     throw (InvalidFamily);
00860     static const IPvX& ALL_ONES(int family)
00861     throw (InvalidFamily);
00862     static const IPvX& LOOPBACK(int family)
00863     throw (InvalidFamily);
00864     static const IPvX& MULTICAST_BASE(int family)
00865     throw (InvalidFamily);
00866     static const IPvX& MULTICAST_ALL_SYSTEMS(int family)
00867     throw (InvalidFamily);
00868     static const IPvX& MULTICAST_ALL_ROUTERS(int family)
00869     throw (InvalidFamily);
00870     static const IPvX& DVMRP_ROUTERS(int family)
00871     throw (InvalidFamily);
00872     static const IPvX& OSPFIGP_ROUTERS(int family)
00873     throw (InvalidFamily);
00874     static const IPvX& OSPFIGP_DESIGNATED_ROUTERS(int family)
00875     throw (InvalidFamily);
00876     static const IPvX& RIP2_ROUTERS(int family)
00877     throw (InvalidFamily);
00878     static const IPvX& PIM_ROUTERS(int family)
00879     throw (InvalidFamily);
00880     static const IPvX& SSM_ROUTERS(int family)
00881     throw (InvalidFamily);
00882     static const IPvX& CLASS_A_BASE(int family)
00883     throw (InvalidFamily);
00884     static const IPvX& CLASS_B_BASE(int family)
00885     throw (InvalidFamily);
00886     static const IPvX& CLASS_C_BASE(int family)
00887     throw (InvalidFamily);
00888     static const IPvX& EXPERIMENTAL_BASE(int family)
00889     throw (InvalidFamily);
00890 
00891 private:
00892     friend class IPv4;
00893     friend class IPv6;
00894 
00895     uint32_t _addr[4];  // Underlay address value for casting to IPv4 and IPv6
00896     int _af;        // The address family AF_INET or AF_INET6
00897 };
00898 
00899 inline IPv4
00900 IPvX::get_ipv4() const throw (InvalidCast)
00901 {
00902     if (_af == AF_INET)
00903     return IPv4(_addr[0]);
00904     xorp_throw(InvalidCast, "Miscast as IPv4");
00905 }
00906 
00907 inline IPv6
00908 IPvX::get_ipv6() const throw (InvalidCast)
00909 {
00910     if (_af == AF_INET6)
00911     return IPv6(&_addr[0]);
00912     xorp_throw(InvalidCast, "Miscast as IPv6");
00913 }
00914 
00915 inline uint32_t
00916 IPvX::bits(uint32_t lsb, uint32_t len) const throw (InvalidFamily)
00917 {
00918     uint32_t mask = ~(0xffffffffU << len);
00919 
00920     if (len >= 32)
00921     mask = 0xffffffffU; // XXX: shifting with >= 32 bits is undefined
00922 
00923     if (_af == AF_INET)
00924     return ntohl((*this >> lsb)._addr[0]) & mask;
00925     if (_af == AF_INET6)
00926     return ntohl((*this >> lsb)._addr[3]) & mask;
00927 
00928     xorp_throw(InvalidFamily, _af);
00929     return (0x0U);
00930 }
00931 
00932 inline uint32_t
00933 IPvX::bit_count() const
00934 {
00935     if (_af == AF_INET)
00936     return get_ipv4().bit_count();
00937     return get_ipv6().bit_count();
00938 }
00939 
00940 inline uint32_t
00941 IPvX::leading_zero_count() const
00942 {
00943     if (_af == AF_INET)
00944     return get_ipv4().leading_zero_count();
00945     return get_ipv6().leading_zero_count();
00946 }
00947 
00948 //
00949 // Front-end functions that can be used by C programs.
00950 // TODO: this is not the right place for this.
00951 // We need a system for exporting API to C programs.
00952 //
00953 inline size_t
00954 family2addr_bytelen(const int family)
00955 {
00956     return IPvX::addr_bytelen(family);
00957 }
00958 
00959 inline uint32_t
00960 family2addr_bitlen(const int family)
00961 {
00962     return IPvX::addr_bitlen(family);
00963 }
00964 
00965 #endif // __LIBXORP_IPVX_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations