modules/up/src/rpsl/rpsl/prefix.cc

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. int2quad
  2. quad2int
  3. PrefixRange
  4. PrefixRange
  5. PrefixRange
  6. PrefixRange
  7. parse
  8. define
  9. makeMoreSpecific
  10. print
  11. valid
  12. compare
  13. contains
  14. get_mask
  15. get_text
  16. get_range
  17. get_text
  18. get_text
  19. Prefix
  20. IPAddr

   1 //  $Id: prefix.cc,v 1.1.1.1 2000/03/10 16:32:24 engin Exp $
   2 //
   3 //  Copyright (c) 1994 by the University of Southern California
   4 //  All rights reserved.
   5 //
   6 //  Permission to use, copy, modify, and distribute this software and its
   7 //  documentation in source and binary forms for lawful non-commercial
   8 //  purposes and without fee is hereby granted, provided that the above
   9 //  copyright notice appear in all copies and that both the copyright
  10 //  notice and this permission notice appear in supporting documentation,
  11 //  and that any documentation, advertising materials, and other materials
  12 //  related to such distribution and use acknowledge that the software was
  13 //  developed by the University of Southern California, Information
  14 //  Sciences Institute. The name of the USC may not be used to endorse or
  15 //  promote products derived from this software without specific prior
  16 //  written permission.
  17 //
  18 //  THE UNIVERSITY OF SOUTHERN CALIFORNIA DOES NOT MAKE ANY
  19 //  REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY
  20 //  PURPOSE.  THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
  21 //  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  22 //  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
  23 //  TITLE, AND NON-INFRINGEMENT.
  24 //
  25 //  IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
  26 //  SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT, TORT,
  27 //  OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH, THE USE
  28 //  OR PERFORMANCE OF THIS SOFTWARE.
  29 //
  30 //  Questions concerning this software should be directed to 
  31 //  ratoolset@isi.edu.
  32 //
  33 //  Author(s): Cengiz Alaettinoglu <cengiz@ISI.EDU>
  34 
  35 #include "config.h"
  36 #include <cstdio>
  37 #include <cstring>
  38 #include <iostream.h>
  39 #include "prefix.hh"
  40 
  41 char PrefixRange::formattingbuffer[128];
  42 
  43 char* int2quad(char *buffer, unsigned int i) {
     /* [<][>][^][v][top][bottom][index][help] */
  44    sprintf(buffer, "%d.%d.%d.%d", 
  45            (i >> 24) & 0xFF, (i >> 16) & 0xFF, (i >> 8)  & 0xFF, i & 0xFF);
  46    return buffer;
  47 }
  48 
  49 unsigned int quad2int(char *quad) {
     /* [<][>][^][v][top][bottom][index][help] */
  50    unsigned int i;
  51    unsigned int i1, i2, i3, i4;
  52 
  53    sscanf(quad, "%u.%u.%u.%u", &i1, &i2, &i3, &i4);
  54    i = i4 + (i3 << 8) + (i2 << 16) + (i1 << 24);
  55    return i;
  56 }
  57 
  58 ostream& operator<<(ostream& stream, const PrefixRange& p) {
  59    stream << p.get_text();
  60    return stream;
  61 }
  62 
  63 /*
  64 // Added const to PrefixRange& p by wlee@isi.edu
  65 const ostream& operator<<(ostream& stream, const PrefixRange& p) {
  66   stream << p.get_text();
  67    return stream;
  68 }
  69 */
  70 
  71 PrefixRange::PrefixRange(void) : 
     /* [<][>][^][v][top][bottom][index][help] */
  72   ipaddr(0), 
  73   length(0), 
  74   n(0), 
  75   m(0)
  76 {
  77 }
  78 
  79 // Added by wlee@isi.edu
  80 PrefixRange::PrefixRange(const PrefixRange &p) :
     /* [<][>][^][v][top][bottom][index][help] */
  81   ipaddr(p.ipaddr),
  82   length(p.length),
  83   n(p.n),
  84   m(p.m)
  85 {
  86 }
  87 
  88 PrefixRange::PrefixRange(unsigned int ipaddr, unsigned char length, 
     /* [<][>][^][v][top][bottom][index][help] */
  89                  unsigned char n, unsigned char m) :
  90   ipaddr(ipaddr),
  91   length(length),
  92   n(n),
  93   m(m)
  94 {
  95 }
  96 
  97 PrefixRange::PrefixRange(char *name) : 
     /* [<][>][^][v][top][bottom][index][help] */
  98   ipaddr(0), 
  99   length(0), 
 100   n(0), 
 101   m(0)
 102 {
 103   parse(name);
 104 }
 105 
 106 void PrefixRange::parse(char *name)
     /* [<][>][^][v][top][bottom][index][help] */
 107 {
 108   unsigned int i1, i2, i3, i4, uiLength = 0, uiN = 0, uiM = 0;
 109   unsigned int mask;
 110   char ch = ' ';
 111 
 112   char *p;
 113   if (strstr(name, "^+"))
 114     // Inclusive more specific operation
 115     sscanf(name, "%u.%u.%u.%u/%u^%c", &i1, &i2, &i3, &i4, &uiLength, &ch);
 116   else if (p = strstr(name, "^-"))
 117      sscanf(name, "%u.%u.%u.%u/%u^%c", &i1, &i2, &i3, &i4, &uiLength, &ch);
 118   else if (p = strchr(name, '-')) 
 119      sscanf(name, "%u.%u.%u.%u/%u^%u-%u", 
 120             &i1, &i2, &i3, &i4, &uiLength, &uiN, &uiM);
 121   else if (p = strchr(name, '^')) {
 122      sscanf(name, "%u.%u.%u.%u/%u^%u", 
 123             &i1, &i2, &i3, &i4, &uiLength, &uiN);
 124      uiM = uiN;
 125   } else
 126      sscanf(name, "%u.%u.%u.%u/%u", &i1, &i2, &i3, &i4, &uiLength);
 127 
 128   length = uiLength;
 129   n      = uiN;
 130   m      = uiM;
 131 
 132   switch (ch)
 133     {
 134     case '+':
 135       // inclusive more specifics operator
 136       n = length;
 137       m = 32;
 138       break;
 139     case '-':
 140       // exclusive more specifics operator
 141       n = length + 1;
 142       m = 32;
 143       break;
 144     default:
 145       if (n == 0) n = length;
 146       if (m == 0) m = n;
 147       break;
 148     }
 149 
 150   ipaddr = i4 + (i3 << 8) + (i2 << 16) + (i1 << 24);
 151   
 152   if (length == 0)
 153     mask = 0;
 154   else 
 155     mask = ~ (0u) << (32 - length);
 156   
 157   ipaddr &= mask;
 158 }
 159 
 160 void PrefixRange::define(unsigned int ipaddr, unsigned char length, 
     /* [<][>][^][v][top][bottom][index][help] */
 161                      unsigned char n, unsigned char m)
 162 {
 163   this->ipaddr = ipaddr;
 164   this->length = length;
 165   this->n      = n;
 166   this->m      = m;
 167 }
 168 
 169 bool PrefixRange::makeMoreSpecific(int code, int _n, int _m) {
     /* [<][>][^][v][top][bottom][index][help] */
 170    // we got ipaddr/length ^n-m  ^_n-_m
 171    // not defined if m < n 
 172    // ipaddr/length^max(n,_n)-_m othewise
 173 
 174    switch (code) {
 175    case 0: // ^-
 176       n++;
 177       m = 32;
 178       break;
 179    case 1: // ^+
 180       m = 32;
 181       break;
 182    default: // ^n-m
 183       if (_m < n || _m < n)
 184          return false;
 185       n = (_n >? n);
 186       m = _m;
 187    }
 188 
 189    return true;
 190 }
 191 
 192 void PrefixRange::print(void)
     /* [<][>][^][v][top][bottom][index][help] */
 193 {
 194   cout << get_text();
 195 }
 196 
 197 int PrefixRange::valid(void)
     /* [<][>][^][v][top][bottom][index][help] */
 198 {
 199   if ((length <= n) && (n <= m)) return 1;
 200   return 0;
 201 }
 202 
 203 PrefixRange& PrefixRange::operator=(const PrefixRange& other)
 204 {
 205   ipaddr = other.ipaddr;
 206   length = other.length;
 207   n      = other.n;
 208   m      = other.m;
 209 }
 210 
 211 // Does it make sense for the more/less specifics operators???
 212 int PrefixRange::operator<(const PrefixRange& other) const
 213 {
 214   return ipaddr < other.ipaddr || 
 215     (ipaddr == other.ipaddr && length < other.length);
 216 }
 217 
 218 // Does it make sense for the more/less specifics operators???
 219 int PrefixRange::operator<=(const PrefixRange& other) const
 220 {
 221   return ipaddr < other.ipaddr || 
 222     (ipaddr == other.ipaddr && length <= other.length);
 223 }
 224 
 225 int PrefixRange::operator==(const PrefixRange& other) const
 226 {
 227   return ipaddr == other.ipaddr && length == other.length &&
 228          n == other.n && m == other.m;
 229 }
 230 
 231 int PrefixRange::compare(const PrefixRange& other) const
     /* [<][>][^][v][top][bottom][index][help] */
 232 {
 233   if (*this < other)  return -1;
 234   if (*this == other) return 0;
 235   return 1;
 236 }
 237 
 238 int PrefixRange::contains(const PrefixRange& other) const
     /* [<][>][^][v][top][bottom][index][help] */
 239 {
 240    return (length <= other.length && n <= other.n && m >= other.m
 241            && ipaddr == (other.ipaddr & get_mask()));
 242 }
 243 
 244 unsigned int PrefixRange::get_mask() const
     /* [<][>][^][v][top][bottom][index][help] */
 245 {  
 246   int mask;
 247 
 248   if (length == 0)
 249     mask = 0;
 250   else 
 251     mask = ~ (0u) << (32 - length);
 252   
 253   return mask;
 254 }
 255 
 256 char *PrefixRange::get_text(char *buffer) const
     /* [<][>][^][v][top][bottom][index][help] */
 257 {
 258   int2quad(buffer, ipaddr);
 259   sprintf(buffer + strlen(buffer), "/%u", length);
 260 
 261   if ((length == n) && (n == m))
 262     // just one route
 263     ;
 264   else
 265     if ((length == n) && (m == 32))
 266       // inclusive more specifics operator
 267       strcat(buffer, "^+");
 268     else
 269       if ((length == n - 1) && (m == 32))
 270         // exclusive more specifics operator
 271         strcat(buffer, "^-");
 272       else
 273         if (n == m)
 274           sprintf(buffer + strlen(buffer), "^%u", n);
 275         else
 276           sprintf(buffer + strlen(buffer), "^%u-%u", n, m);
 277   return buffer;
 278 }
 279 
 280 static unsigned long long int bits[] = { 0x100000000ULL,
 281                      0x080000000, 0x040000000, 0x020000000, 0x010000000,
 282                      0x008000000, 0x004000000, 0x002000000, 0x001000000,
 283                      0x000800000, 0x000400000, 0x000200000, 0x000100000,
 284                      0x000080000, 0x000040000, 0x000020000, 0x000010000,
 285                      0x000008000, 0x000004000, 0x000002000, 0x000001000,
 286                      0x000000800, 0x000000400, 0x000000200, 0x000000100,
 287                      0x000000080, 0x000000040, 0x000000020, 0x000000010,
 288                      0x000000008, 0x000000004, 0x000000002, 0x000000001
 289 };
 290 
 291 unsigned long long int PrefixRange::get_range() const {
     /* [<][>][^][v][top][bottom][index][help] */
 292    unsigned long long int range = 0;
 293    for (int i = n; i <= m; ++i)
 294       range |= bits[i];
 295    return range;
 296 }
 297 
 298 
 299 char *Prefix::get_text(char *buffer) const {
     /* [<][>][^][v][top][bottom][index][help] */
 300   int2quad(buffer, ipaddr);
 301   sprintf(buffer + strlen(buffer), "/%u", length);
 302   return buffer;  
 303 }
 304 
 305 char *IPAddr::get_text(char *buffer) const {
     /* [<][>][^][v][top][bottom][index][help] */
 306   int2quad(buffer, ipaddr);
 307   return buffer;  
 308 }
 309 
 310 Prefix::Prefix(char *name) {
     /* [<][>][^][v][top][bottom][index][help] */
 311    unsigned int i1, i2, i3, i4, i5;
 312 
 313    sscanf(name, "%u.%u.%u.%u/%u", &i1, &i2, &i3, &i4, &i5);
 314    ipaddr = i4 + (i3 << 8) + (i2 << 16) + (i1 << 24);
 315    length = n = m = i5;
 316 
 317    int mask;
 318    if (length == 0)
 319       mask = 0;
 320    else 
 321       mask = ~ (0u) << (32 - length);
 322   
 323    ipaddr &= mask;
 324 }
 325 
 326 IPAddr::IPAddr(char *name) {
     /* [<][>][^][v][top][bottom][index][help] */
 327    unsigned int i1, i2, i3, i4;
 328 
 329    sscanf(name, "%u.%u.%u.%u", &i1, &i2, &i3, &i4);
 330    ipaddr = i4 + (i3 << 8) + (i2 << 16) + (i1 << 24);
 331    length = n = m = 32;
 332 }
 333 
 334 PrefixRange NullPrefixRange("0.0.0.0/32^32-32");
 335 Prefix      NullPrefix("0.0.0.0/32");
 336 IPAddr      NullIPAddr("0.0.0.0");

/* [<][>][^][v][top][bottom][index][help] */