xorp

ipv6.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 // $XORP: xorp/libxorp/ipv6.hh,v 1.41 2008/10/02 21:57:31 bms Exp $
00023 
00024 #ifndef __LIBXORP_IPV6_HH__
00025 #define __LIBXORP_IPV6_HH__
00026 
00027 #include "libxorp/xorp.h"
00028 #include "libxorp/exceptions.hh"
00029 #include "libxorp/range.hh"
00030 #include "libxorp/utils.hh"
00031 
00032 
00033 struct in6_addr;
00034 
00042 class IPv6 {
00043 public:
00044     typedef struct in6_addr         InAddrType;
00045     typedef struct sockaddr_in6     SockAddrType;
00046 
00047 public:
00053     IPv6() { _addr[0] = _addr[1] = _addr[2] = _addr[3] = 0; }
00054 
00061     explicit IPv6(const uint8_t *from_uint8);
00062 
00069     explicit IPv6(const uint32_t *from_uint32);
00070 
00076     IPv6(const in6_addr& from_in6_addr);
00077 
00083     IPv6(const sockaddr& sa) throw (InvalidFamily);
00084 
00090     IPv6(const sockaddr_storage& ss) throw (InvalidFamily);
00091 
00097     IPv6(const sockaddr_in6& sin6) throw (InvalidFamily);
00098 
00105     IPv6(const char *from_cstring) throw (InvalidString);
00106 
00113     size_t copy_out(uint8_t *to_uint8) const;
00114 
00121     size_t copy_out(in6_addr& to_in6_addr) const;
00122 
00133     size_t copy_out(sockaddr& to_sockaddr) const;
00134 
00145     size_t copy_out(sockaddr_storage& to_sockaddr_storage) const;
00146 
00157     size_t copy_out(sockaddr_in6& to_sockaddr_in6) const;
00158 
00166     size_t copy_in(const uint8_t *from_uint8);
00167 
00174     size_t copy_in(const in6_addr& from_in6_addr);
00175 
00185     size_t copy_in(const sockaddr& from_sockaddr) throw (InvalidFamily);
00186 
00197     size_t copy_in(const sockaddr_storage& from_sockaddr_storage) throw (InvalidFamily);
00198 
00208     size_t copy_in(const sockaddr_in6& from_sockaddr_in6)
00209     throw (InvalidFamily);
00210 
00216     IPv6 operator~() const;
00217 
00224     IPv6 operator|(const IPv6& other) const;
00225 
00232     IPv6 operator&(const IPv6& other) const;
00233 
00240     IPv6 operator^(const IPv6& other) const;
00241 
00248     IPv6 operator<<(uint32_t left_shift) const;
00249 
00256     IPv6 operator>>(uint32_t right_shift) const;
00257 
00265     bool operator<(const IPv6& other) const;
00266 
00274     bool operator==(const IPv6& other) const;
00275 
00283     bool operator!=(const IPv6& other) const;
00284 
00292     bool operator==(const IPv6Range& rhs) const {
00293     return (*this >= rhs.low() && *this <= rhs.high());
00294     }
00295 
00303     bool operator!=(const IPv6Range& rhs) const {
00304     return (*this < rhs.low() || *this > rhs.high());
00305     }
00306 
00314     bool operator<(const IPv6Range& rhs) const {
00315     return (*this < rhs.low());
00316     }
00317 
00325     bool operator<=(const IPv6Range& rhs) const {
00326     return (*this <= rhs.high());
00327     }
00328 
00336     bool operator>(const IPv6Range& rhs) const {
00337     return (*this > rhs.high());
00338     }
00339 
00347     bool operator>=(const IPv6Range& rhs) const {
00348     return (*this >= rhs.low());
00349     }
00350 
00361     IPv6& operator--();
00362 
00373     IPv6& operator++();
00374 
00381     string str() const;
00382 
00388     bool is_zero() const        { return *this == ZERO(); }
00389 
00397     bool is_unicast() const;
00398 
00404     bool is_multicast() const;
00405 
00412     bool is_linklocal_unicast() const;
00413 
00423     bool is_interfacelocal_multicast() const;
00424 
00435     bool is_nodelocal_multicast() const { return is_interfacelocal_multicast(); }
00436 
00443     bool is_linklocal_multicast() const;
00444 
00450     bool is_loopback() const;
00451 
00462     static size_t addr_bytelen() {
00463     x_static_assert(sizeof(IPv6) == 4 * sizeof(uint32_t));
00464     return sizeof(IPv6);
00465     }
00466 
00477     static uint32_t addr_bitlen() {
00478     return uint32_t(8 * sizeof(uint8_t) * addr_bytelen());
00479     }
00480 
00491     static uint32_t ip_multicast_base_address_mask_len() {
00492 #define IP_MULTICAST_BASE_ADDRESS_MASK_LEN_IPV6 8
00493     return (IP_MULTICAST_BASE_ADDRESS_MASK_LEN_IPV6);
00494 #undef IP_MULTICAST_BASE_ADDRESS_MASK_LEN_IPV6
00495     }
00496 
00503     static const IPv6& make_prefix(uint32_t mask_len) throw (InvalidNetmaskLength);
00504 
00512     IPv6 mask_by_prefix_len(uint32_t prefix_len) const
00513     throw (InvalidNetmaskLength) {
00514     return (*this) & make_prefix(prefix_len);
00515     }
00516 
00523     uint32_t mask_len() const;
00524 
00531     const uint32_t *addr() const { return _addr; }
00532 
00539     void set_addr(const uint8_t *from_uint8) { memcpy(_addr, from_uint8, 16); }
00540 
00544     enum { AF = AF_INET6 };
00545 
00549     enum { IPV = 6 };
00550 
00556     static int af() { return AF; }
00557 
00563     static uint32_t ip_version() { return IPV; }
00564 
00571     static const string& ip_version_str();
00572 
00581     uint32_t bits(uint32_t lsb, uint32_t len) const;
00582 
00588     uint32_t bit_count() const;
00589 
00595     uint32_t leading_zero_count() const;
00596 
00600     static const IPv6& ZERO(int af = AF_INET6);
00601     static const IPv6& ANY(int af = AF_INET6);
00602     static const IPv6& ALL_ONES(int af = AF_INET6);
00603     static const IPv6& LOOPBACK(int af = AF_INET6);
00604     static const IPv6& MULTICAST_BASE(int af = AF_INET6);
00605     static const IPv6& MULTICAST_ALL_SYSTEMS(int af = AF_INET6);
00606     static const IPv6& MULTICAST_ALL_ROUTERS(int af = AF_INET6);
00607     static const IPv6& DVMRP_ROUTERS(int af = AF_INET6);
00608     static const IPv6& OSPFIGP_ROUTERS(int af = AF_INET6);
00609     static const IPv6& OSPFIGP_DESIGNATED_ROUTERS(int af = AF_INET6);
00610     static const IPv6& RIP2_ROUTERS(int af = AF_INET6);
00611     static const IPv6& PIM_ROUTERS(int af = AF_INET6);
00612     static const IPv6& SSM_ROUTERS(int af = AF_INET6);
00613 
00617     static const uint32_t ADDR_BITLEN = 128;
00618 
00622     static const uint32_t ADDR_BYTELEN = ADDR_BITLEN / 8;
00623 
00624 private:
00625     uint32_t _addr[4];      // The address value (in network-order)
00626 };
00627 
00628 inline uint32_t
00629 IPv6::bits(uint32_t lsb, uint32_t len) const
00630 {
00631     uint32_t mask = ~(0xffffffffU << len);
00632 
00633     if (len >= 32)
00634     mask = 0xffffffffU; // XXX: shifting with >= 32 bits is undefined
00635 
00636     return ntohl((*this >> lsb)._addr[3]) & mask;
00637 }
00638 
00639 inline uint32_t
00640 IPv6::bit_count() const
00641 {
00642     // XXX: no need for ntohl()
00643     return (xorp_bit_count_uint32(_addr[0])
00644         + xorp_bit_count_uint32(_addr[1])
00645         + xorp_bit_count_uint32(_addr[2])
00646         + xorp_bit_count_uint32(_addr[3]));
00647 }
00648 
00649 inline uint32_t
00650 IPv6::leading_zero_count() const
00651 {
00652     uint32_t r = 0;
00653 
00654     for (int i = 0; i < 4; i++) {
00655     if (_addr[i] != 0) {
00656         r += xorp_leading_zero_count_uint32(ntohl(_addr[i]));
00657         break;
00658     }
00659     r += 32;
00660     }
00661     return (r);
00662 }
00663 
00664 struct IPv6Constants {
00665     static const IPv6 zero,
00666     any,
00667     all_ones,
00668     loopback,
00669     multicast_base,
00670     multicast_all_systems,
00671     multicast_all_routers,
00672     dvmrp_routers,
00673     ospfigp_routers,
00674     ospfigp_designated_routers,
00675     rip2_routers,
00676     pim_routers,
00677     ssm_routers;
00678 };
00679 
00680 inline const IPv6& IPv6::ZERO(int) {
00681     return IPv6Constants::zero;
00682 }
00683 
00684 inline const IPv6& IPv6::ANY(int) {
00685     return IPv6Constants::any;
00686 }
00687 
00688 inline const IPv6& IPv6::ALL_ONES(int) {
00689     return IPv6Constants::all_ones;
00690 }
00691 
00692 inline const IPv6& IPv6::LOOPBACK(int) {
00693     return IPv6Constants::loopback;
00694 }
00695 
00696 inline const IPv6& IPv6::MULTICAST_BASE(int) {
00697     return IPv6Constants::multicast_base;
00698 }
00699 
00700 inline const IPv6& IPv6::MULTICAST_ALL_SYSTEMS(int) {
00701     return IPv6Constants::multicast_all_systems;
00702 }
00703 
00704 inline const IPv6& IPv6::MULTICAST_ALL_ROUTERS(int) {
00705     return IPv6Constants::multicast_all_routers;
00706 }
00707 
00708 inline const IPv6& IPv6::DVMRP_ROUTERS(int) {
00709     return IPv6Constants::dvmrp_routers;
00710 }
00711 
00712 inline const IPv6& IPv6::OSPFIGP_ROUTERS(int) {
00713     return IPv6Constants::ospfigp_routers;
00714 }
00715 
00716 inline const IPv6& IPv6::OSPFIGP_DESIGNATED_ROUTERS(int) {
00717     return IPv6Constants::ospfigp_designated_routers;
00718 }
00719 
00720 inline const IPv6& IPv6::RIP2_ROUTERS(int) {
00721     return IPv6Constants::rip2_routers;
00722 }
00723 
00724 inline const IPv6& IPv6::PIM_ROUTERS(int) {
00725     return IPv6Constants::pim_routers;
00726 }
00727 
00728 inline const IPv6& IPv6::SSM_ROUTERS(int) {
00729     return IPv6Constants::ssm_routers;
00730 }
00731 
00732 inline IPv6 IPv6::operator~() const {
00733     uint32_t tmp_addr[4];
00734     tmp_addr[0] = ~_addr[0];
00735     tmp_addr[1] = ~_addr[1];
00736     tmp_addr[2] = ~_addr[2];
00737     tmp_addr[3] = ~_addr[3];
00738     return IPv6(tmp_addr);
00739 }
00740 
00741 inline IPv6 IPv6::operator|(const IPv6& other) const {
00742     uint32_t tmp_addr[4];
00743     tmp_addr[0] = _addr[0] | other._addr[0];
00744     tmp_addr[1] = _addr[1] | other._addr[1];
00745     tmp_addr[2] = _addr[2] | other._addr[2];
00746     tmp_addr[3] = _addr[3] | other._addr[3];
00747     return IPv6(tmp_addr);
00748 }
00749 
00750 inline IPv6 IPv6::operator&(const IPv6& other) const {
00751     uint32_t tmp_addr[4];
00752     tmp_addr[0] = _addr[0] & other._addr[0];
00753     tmp_addr[1] = _addr[1] & other._addr[1];
00754     tmp_addr[2] = _addr[2] & other._addr[2];
00755     tmp_addr[3] = _addr[3] & other._addr[3];
00756     return IPv6(tmp_addr);
00757 }
00758 
00759 inline IPv6 IPv6::operator^(const IPv6& other) const {
00760     uint32_t tmp_addr[4];
00761     tmp_addr[0] = _addr[0] ^ other._addr[0];
00762     tmp_addr[1] = _addr[1] ^ other._addr[1];
00763     tmp_addr[2] = _addr[2] ^ other._addr[2];
00764     tmp_addr[3] = _addr[3] ^ other._addr[3];
00765     return IPv6(tmp_addr);
00766 }
00767 
00768 #endif // __LIBXORP_IPV6_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations