modules/up/src/rpsl/rpsl/prefix.cc
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- int2quad
- quad2int
- PrefixRange
- PrefixRange
- PrefixRange
- PrefixRange
- parse
- define
- makeMoreSpecific
- print
- valid
- compare
- contains
- get_mask
- get_text
- get_range
- get_text
- get_text
- Prefix
- 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");