1 // $Id$ 2 // Copyright (c) 2001,2002 RIPE NCC 3 // 4 // All Rights Reserved 5 // 6 // Permission to use, copy, modify, and distribute this software and its 7 // documentation for any purpose and without fee is hereby granted, 8 // provided that the above copyright notice appear in all copies and that 9 // both that copyright notice and this permission notice appear in 10 // supporting documentation, and that the name of the author not be 11 // used in advertising or publicity pertaining to distribution of the 12 // software without specific, written prior permission. 13 // 14 // THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 15 // ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL 16 // AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY 17 // DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 18 // AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19 // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20 // 21 // 22 // Copyright (c) 1994 by the University of Southern California 23 // All rights reserved. 24 // 25 // Permission is hereby granted, free of charge, to any person obtaining a copy 26 // of this software and associated documentation files (the "Software"), to deal 27 // in the Software without restriction, including without limitation the rights 28 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 29 // copies of the Software, and to permit persons to whom the Software is 30 // furnished to do so, subject to the following conditions: 31 // 32 // The above copyright notice and this permission notice shall be included in 33 // all copies or substantial portions of the Software. 34 // 35 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 36 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 37 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 38 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 39 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 40 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 41 // THE SOFTWARE. 42 // 43 // Questions concerning this software should be directed to 44 // irrtoolset@cs.usc.edu. 45 // 46 // Author(s): Cengiz Alaettinoglu <cengiz@ISI.EDU> 47 // Katie Petrusha <katie@ripe.net> 48 49 #ifndef PREFIX_HH 50 #define PREFIX_HH 51 52 #include "config.h" 53 #include <sys/types.h> 54 #include <vector> 55 #include <sstream> 56 #include <ostream> 57 58 typedef unsigned long long int ip_v6word_t; 59 60 // ipv6 address unit + operations 61 class ipv6_addr_t { 62 public: 63 ip_v6word_t high; 64 ip_v6word_t low; 65 bool xbit; 66 67 public: 68 friend int operator<(ipv6_addr_t one, ipv6_addr_t two); 69 friend int operator==(ipv6_addr_t one, ipv6_addr_t two); 70 friend int operator!=(ipv6_addr_t one, ipv6_addr_t two); 71 int operator!() const; 72 73 friend ipv6_addr_t& operator&(ipv6_addr_t one, ipv6_addr_t two); 74 friend ipv6_addr_t& operator|(ipv6_addr_t one, ipv6_addr_t two); 75 ipv6_addr_t& operator|(ip_v6word_t i); 76 ipv6_addr_t& operator+(ip_v6word_t i); 77 ipv6_addr_t& operator=(ip_v6word_t i); 78 int operator==(ip_v6word_t i); 79 80 ipv6_addr_t& operator<<(unsigned int i); 81 ipv6_addr_t& operator>>(unsigned int i); 82 ipv6_addr_t& operator~() const; 83 84 bool operator&&(bool b); 85 bool is_true() const; 86 87 ipv6_addr_t& getbits(unsigned int len); 88 ipv6_addr_t& getmask(unsigned int len); 89 90 friend std::ostream& operator<<(std::ostream& stream, const ipv6_addr_t& p); 91 92 public: ipv6_addr_t()93 ipv6_addr_t() {} 94 ipv6_addr_t(ip_v6word_t i,ip_v6word_t j)95 ipv6_addr_t(ip_v6word_t i, ip_v6word_t j) : 96 high(i), low(j), xbit(false) {} 97 ipv6_addr_t(ip_v6word_t i,ip_v6word_t j,bool _xbit)98 ipv6_addr_t(ip_v6word_t i, ip_v6word_t j, bool _xbit) : 99 high(i), low(j), xbit(_xbit) {} 100 ~ipv6_addr_t()101 ~ipv6_addr_t() {} 102 103 }; 104 105 #define IPV6_LENGTH 40 106 107 char* int2quad(char *buffer, unsigned int i); 108 char* ipv62hex(ipv6_addr_t *ip, char *buffer); 109 ipv6_addr_t* hex2ipv6(char *hex); 110 char *compact(ipv6_addr_t *ip, char *buffer); 111 112 extern class PrefixRange NullPrefixRange; 113 extern class IPAddr NullIPAddr; 114 extern class PrefixRange MulticastPrefixRange; 115 extern class IPv6PrefixRange NullIPv6PrefixRange; 116 extern class IPv6Prefix NullIPv6Prefix; 117 extern class IPv6Addr NullIPv6Addr; 118 extern class ipv6_addr_t NullIPv6; 119 extern class IPv6PrefixRange MulticastIPv6PrefixRange; 120 121 class PrefixRange { 122 123 friend class MPPrefix; 124 125 protected: 126 static char formattingbuffer[128]; 127 128 unsigned int ipaddr; 129 unsigned char length; 130 unsigned char n; 131 unsigned char m; 132 133 public: 134 PrefixRange(void); 135 PrefixRange(const PrefixRange &p); 136 PrefixRange(unsigned int ipaddr, unsigned char length, 137 unsigned char n, unsigned char m); 138 139 PrefixRange(const char *name); 140 141 void define(unsigned int ipaddr, unsigned char length, 142 unsigned char n, unsigned char m); 143 144 // return false if it is an invalid operation and do nothing, 145 // or make the prefix more specific 146 bool makeMoreSpecific(int code, int n, int m); 147 148 void print(void); 149 int valid(void); 150 isNull() const151 bool isNull() const { 152 return (*this) == NullPrefixRange; 153 } 154 155 PrefixRange& operator=(const PrefixRange& other); 156 int operator<(const PrefixRange& other) const; 157 int operator<=(const PrefixRange& other) const; 158 int operator==(const PrefixRange& other) const; operator !=(const PrefixRange & other) const159 int operator!=(const PrefixRange& other) const { 160 return ! (*this == other); 161 } 162 int compare(const PrefixRange& other) const; 163 int contains(const PrefixRange& other) const; 164 165 char *get_text(char *buffer = formattingbuffer) const; 166 char *get_ip_text(char *buffer = formattingbuffer) const; get_ipaddr() const167 unsigned int get_ipaddr() const { return ipaddr; } get_length() const168 unsigned int get_length() const { return length; } get_n() const169 unsigned int get_n() const { return n; } get_m() const170 unsigned int get_m() const { return m; } 171 unsigned int get_mask() const; 172 unsigned long long int get_range() const; 173 174 friend std::ostream& operator<<(std::ostream& stream, const PrefixRange& p); 175 176 void parse(const char *name); 177 }; 178 179 class Prefix : public PrefixRange { 180 public: Prefix()181 Prefix() : PrefixRange(0, 0, 0, 0) { 182 } Prefix(unsigned int ipaddr,unsigned char length)183 Prefix(unsigned int ipaddr, unsigned char length) : 184 PrefixRange(ipaddr, length, length, length) { 185 } 186 Prefix(char *name); define(unsigned int ipaddr,unsigned char length)187 void define(unsigned int ipaddr, unsigned char length) { 188 PrefixRange::define(ipaddr, length, length, length); 189 } 190 char *get_text(char *buffer = formattingbuffer) const; 191 }; 192 193 class IPAddr : public Prefix { 194 public: IPAddr()195 IPAddr() : Prefix(0, 0) { 196 } IPAddr(unsigned int ipaddr)197 IPAddr(unsigned int ipaddr) : 198 Prefix(ipaddr, 32) { 199 } 200 IPAddr(const char *name); define(unsigned int ipaddr)201 void define(unsigned int ipaddr) { 202 Prefix::define(ipaddr, 32); 203 } 204 char *get_text(char *buffer = formattingbuffer) const; 205 }; 206 207 class IPv6PrefixRange { 208 209 friend class MPPrefix; 210 211 protected: 212 static char formattingbuffer[256]; 213 214 ipv6_addr_t *ipaddr; 215 unsigned char length; 216 217 unsigned char n; 218 unsigned char m; 219 220 public: 221 IPv6PrefixRange(void); 222 IPv6PrefixRange(const IPv6PrefixRange &p); 223 IPv6PrefixRange(ipv6_addr_t *ipaddr, unsigned char length, 224 unsigned char n, unsigned char m); 225 226 IPv6PrefixRange(const char *name); 227 228 void define(ipv6_addr_t *ipaddr, unsigned char length, 229 unsigned char n, unsigned char m); 230 231 // return false if it is an invalid operation and do nothing, 232 // or make the prefix more specific 233 bool makeMoreSpecific(int code, int n, int m); 234 235 void print(void); 236 int valid(void); 237 isNull() const238 bool isNull() const { 239 return (*this) == NullIPv6PrefixRange; 240 } 241 242 IPv6PrefixRange& operator=(const IPv6PrefixRange& other); 243 int operator<(const IPv6PrefixRange& other) const; 244 int operator<=(const IPv6PrefixRange& other) const; 245 int operator==(const IPv6PrefixRange& other) const; operator !=(const IPv6PrefixRange & other) const246 int operator!=(const IPv6PrefixRange& other) const { 247 return ! (*this == other); 248 } 249 int compare(const IPv6PrefixRange& other) const; 250 int contains(const IPv6PrefixRange& other) const; 251 252 char *get_text(char *buffer = formattingbuffer) const; 253 char *get_ip_text(char *buffer = formattingbuffer) const; get_ipaddr() const254 ipv6_addr_t *get_ipaddr() const { return ipaddr; } get_length() const255 unsigned int get_length() const { return length; } get_n() const256 unsigned int get_n() const { return n; } get_m() const257 unsigned int get_m() const { return m; } 258 ipv6_addr_t get_mask() const; 259 ipv6_addr_t get_range() const; 260 261 friend std::ostream& operator<<(std::ostream& stream, 262 const IPv6PrefixRange& p); 263 264 void parse(const char *name); 265 266 }; 267 268 class IPv6Prefix : public IPv6PrefixRange { 269 public: IPv6Prefix()270 IPv6Prefix() : IPv6PrefixRange(NULL, 0, 0, 0) { 271 } IPv6Prefix(ipv6_addr_t * ipaddr,unsigned char length)272 IPv6Prefix(ipv6_addr_t *ipaddr, unsigned char length) : 273 IPv6PrefixRange(ipaddr, length, length, length) { 274 } 275 IPv6Prefix(const char *name); 276 define(ipv6_addr_t * ipaddr,unsigned char length)277 void define(ipv6_addr_t *ipaddr, unsigned char length) { 278 IPv6PrefixRange::define(ipaddr, length, length, length); 279 } 280 char *get_text(char *buffer = formattingbuffer) const; 281 282 friend std::ostream& operator<<(std::ostream& stream, 283 const IPv6Prefix& p); 284 }; 285 286 class IPv6Addr : public IPv6Prefix { 287 public: IPv6Addr()288 IPv6Addr() : IPv6Prefix(NULL, 128) { 289 } IPv6Addr(ipv6_addr_t * ipaddr)290 IPv6Addr(ipv6_addr_t *ipaddr) : 291 IPv6Prefix(ipaddr, 128) { 292 } 293 IPv6Addr(const char *name); define(ipv6_addr_t * ipaddr)294 void define(ipv6_addr_t *ipaddr) { 295 IPv6Prefix::define(ipaddr, 128); 296 } 297 char *get_text(char *buffer = formattingbuffer) const; 298 friend std::ostream& operator<<(std::ostream& stream, const IPv6Addr& p); 299 }; 300 301 // metaclass for type isolation (ipv4, ipv6) 302 303 class MPPrefix { 304 public: 305 PrefixRange *ipv4; 306 IPv6PrefixRange *ipv6; 307 308 public: MPPrefix(void)309 MPPrefix(void) : 310 ipv4(NULL), 311 ipv6(NULL) 312 { 313 } 314 MPPrefix(PrefixRange * _ipv4)315 MPPrefix(PrefixRange *_ipv4 ) : 316 ipv4(_ipv4), 317 ipv6(NULL) 318 { 319 } 320 MPPrefix(IPv6PrefixRange * _ipv6)321 MPPrefix(IPv6PrefixRange *_ipv6 ) : 322 ipv4(NULL), 323 ipv6(_ipv6) 324 { 325 } 326 // create from string 327 MPPrefix (char *name); 328 329 unsigned int get_length() const; 330 unsigned int get_n(); 331 unsigned int get_m(); 332 void define (unsigned int masklen); 333 // Those are used by IPV6 only 334 ipv6_addr_t get_mask() const; 335 ipv6_addr_t get_range() const; 336 ipv6_addr_t get_ipaddr() const; 337 char *get_text() const; 338 char *get_ip_text() const; 339 char *get_afi() const; 340 // interface to makeMoreSpecific 341 bool makeMoreSpecific(int code, int n, int m); 342 operator ==(const MPPrefix & t) const343 int operator==(const MPPrefix &t) const { 344 if (ipv4 && t.ipv4) 345 return (*ipv4 == *(t.ipv4)); 346 if (ipv6 && t.ipv6) 347 return (*ipv6 == *(t.ipv6)); 348 return false; 349 } operator <(const MPPrefix & t) const350 int operator<(const MPPrefix &t) const { 351 if (ipv4 && t.ipv4) 352 return (*ipv4 < *(t.ipv4)); 353 if (ipv6 && t.ipv6) 354 return (*ipv6 < *(t.ipv6)); 355 return false; 356 } 357 isNull() const358 bool isNull() const { 359 if (ipv4) { 360 return (*ipv4 == NullPrefixRange); 361 } 362 if (ipv6) { 363 return (*ipv6 == NullIPv6PrefixRange); 364 } 365 return true; 366 } 367 368 friend std::ostream& operator<<(std::ostream& stream, const MPPrefix& p); 369 370 }; 371 372 class MPPrefixRanges : public std::vector<MPPrefix> 373 { 374 public: MPPrefixRanges()375 MPPrefixRanges() {}; MPPrefixRanges(void * t)376 MPPrefixRanges(void *t) { 377 this->append_list((MPPrefixRanges *) t); 378 } 379 380 void append_list(const MPPrefixRanges *src); // join 381 void _and(MPPrefixRanges *src); // intersection 382 void except(MPPrefixRanges *src); // exception 383 bool contains(IPAddr ip) const; 384 bool contains(IPv6Addr ip) const; 385 bool contains(MPPrefix ip) const; 386 387 friend std::ostream& operator<<(std::ostream& stream, const MPPrefixRanges& p); 388 389 }; 390 391 392 #endif // PREFIX_HH 393