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