xorp

asnum.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/asnum.hh,v 1.20 2008/10/02 21:57:28 bms Exp $
00023 
00024 #ifndef __LIBXORP_ASNUM_HH__
00025 #define __LIBXORP_ASNUM_HH__
00026 
00027 #include "libxorp/xorp.h"
00028 #include "libxorp/exceptions.hh"
00029 
00030 #ifdef HAVE_INTTYPES_H
00031 #include <inttypes.h>
00032 #endif
00033 
00034 #include "c_format.hh"
00035 
00036 
00066 class AsNum {
00067 public:
00068     static const uint16_t AS_INVALID = 0;   // XXX IANA-reserved
00069     static const uint16_t AS_TRAN = 23456;  // IANA
00070 
00075     explicit AsNum(const uint32_t value) : _as(value)   {
00076     }
00077  
00078     explicit AsNum(const uint16_t value) : _as(value)   {}
00079 
00080     explicit AsNum(int value)               {
00081     assert(value >= 0 && value <= 0xffff);
00082     _as = value;
00083     }
00084 
00088     explicit AsNum(const uint8_t *d)            {
00089     _as = (d[0] << 8) + d[1];
00090     }
00091 
00099     explicit AsNum(const uint8_t *d, bool fourbyte) {
00100     if (fourbyte) {
00101         // 4 byte version
00102         memcpy(&_as, d, 4);
00103         _as = htonl(_as);
00104     } else {
00105         // 2 byte version
00106         _as = (d[0] << 8) + d[1];
00107     }
00108     }
00109 
00115     explicit AsNum(const string& as_str) throw(InvalidString) {
00116     bool four_byte = false;
00117     bool seen_digit = false;
00118     for (uint32_t i = 0; i < as_str.size(); i++) {
00119         if (as_str[i] == '.') {
00120         if (four_byte || seen_digit == false) {
00121             // more than one dot, or no number before the first dot.
00122             xorp_throw(InvalidString, c_format("Bad AS number \"%s\"",
00123                                as_str.c_str()));
00124         } else {
00125             four_byte = true;
00126             seen_digit = false;
00127         }
00128         } else if (!isdigit(as_str[i])) {
00129         // got some disallowed character
00130         xorp_throw(InvalidString, c_format("Bad AS number \"%s\"",
00131                            as_str.c_str()));
00132         } else {
00133         seen_digit = true;
00134         }
00135     }
00136     if (seen_digit == false) {
00137         // either no digit here, or no digit after the dot
00138         xorp_throw(InvalidString, c_format("Bad AS number \"%s\"",
00139                            as_str.c_str()));
00140     }
00141     
00142     // got here, so the text is in the right format
00143     if (!four_byte) {
00144         _as = atoi(as_str.c_str());
00145         if (_as < 1 || _as > 65535) {
00146         // out of range
00147         xorp_throw(InvalidString, c_format("Bad AS number \"%s\"",
00148                            as_str.c_str()));
00149         }
00150     } else {
00151         uint32_t upper = strtoul(as_str.c_str(), NULL, 10);
00152         uint32_t lower = strtoul(strchr(as_str.c_str(), '.') + 1, 
00153                      NULL, 10);
00154         if  (upper > 65535 || lower > 65535) {
00155         // out of range
00156         xorp_throw(InvalidString, c_format("Bad AS number \"%s\"",
00157                            as_str.c_str()));
00158         }
00159         _as = (upper << 16) | lower;
00160     }
00161     }
00162 
00163 
00169     uint16_t as() const                 {
00170     return extended() ? AS_TRAN : _as;
00171     }
00172 
00178     uint32_t as4() const                { return _as; }
00179 
00183     void copy_out(uint8_t *d) const         {
00184     uint16_t x = as();
00185     d[0] = (x >> 8) & 0xff;
00186     d[1] = x & 0xff;
00187     }
00188 
00192     void copy_out4(uint8_t *d) const            {
00193     // note - buffer may be unaligned, so use memcpy
00194     uint32_t x = htonl(_as);
00195     memcpy(d, &x, 4);
00196     }
00197 
00203     bool extended() const               { return _as>0xffff;};
00204     
00212     bool operator==(const AsNum& x) const       { return _as == x._as; }
00213 
00219     bool operator<(const AsNum& x) const        { return _as < x._as; }
00220     
00227     string str() const                  {
00228     if (extended())
00229         return c_format("AS/%u.%u", (_as >> 16)&0xffff, _as&0xffff);
00230     else 
00231         return c_format("AS/%u", XORP_UINT_CAST(_as));
00232     }
00233 
00234     string short_str() const                    {
00235     if (extended())
00236         return c_format("%u.%u", (_as >> 16)&0xffff, _as&0xffff);
00237     else
00238         return c_format("%u", XORP_UINT_CAST(_as));
00239     }
00240 
00241     string fourbyte_str() const {
00242     // this version forces the long canonical format
00243     return c_format("%u.%u", (_as >> 16)&0xffff, _as&0xffff);
00244     }
00245     
00246 private:
00247     uint32_t _as;       // The value of the AS number
00248 
00249 #ifdef XORP_USE_USTL
00250 public:
00251     AsNum() { };
00252 #else
00253     AsNum(); // forbidden
00254 #endif
00255 
00256 };
00257 #endif // __LIBXORP_ASNUM_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations