1 /*
2 
3                           Firewall Builder
4 
5                  Copyright (C) 2010 NetCitadel, LLC
6 
7   Author:  Roman Bovsunivskiy     a2k0001@gmail.com
8 
9   $Id$
10 
11   This program is free software which we release under the GNU General Public
12   License. You may redistribute and/or modify this program under the terms
13   of that license as published by the Free Software Foundation; either
14   version 2 of the License, or (at your option) any later version.
15 
16   This program is distributed in the hope that it will be useful,
17   but WITHOUT ANY WARRANTY; without even the implied warranty of
18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   GNU General Public License for more details.
20 
21   To get a copy of the GNU General Public License, write to the Free Software
22   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23 
24 */
25 
26 #include "InetAddrMaskTest.h"
27 #include <fwbuilder/InetAddrMask.h>
28 
29 using namespace libfwbuilder;
30 using namespace std;
31 
32 
testIntToInetAddr()33 void InetAddrMaskTest::testIntToInetAddr()
34 {
35     InetAddr *sa1 = new InetAddr(0);
36     CPPUNIT_ASSERT_MESSAGE(sa1->toString(),  sa1->toString() == "0.0.0.0");
37 
38     sa1 = new InetAddr(AF_INET, 0);
39     CPPUNIT_ASSERT_MESSAGE(sa1->toString(),  sa1->toString() == "0.0.0.0");
40 
41     sa1 = new InetAddr(1);
42     CPPUNIT_ASSERT_MESSAGE(sa1->toString(),  sa1->toString() == "128.0.0.0");
43 
44     sa1 = new InetAddr(24);
45     CPPUNIT_ASSERT_MESSAGE(sa1->toString(),  sa1->toString() == "255.255.255.0");
46 }
47 
testStringToInetAddr()48 void InetAddrMaskTest::testStringToInetAddr()
49 {
50     InetAddr *sa1 = new InetAddr("0.0.0.1");
51     CPPUNIT_ASSERT_MESSAGE("0.0.0.1 -> " + sa1->toString(),  sa1->toString() == "0.0.0.1");
52 
53     sa1 = new InetAddr("0.0.0.0");
54     CPPUNIT_ASSERT_MESSAGE("0.0.0.0 -> " + sa1->toString(),  sa1->toString() == "0.0.0.0");
55 
56     sa1 = new InetAddr("1.2.3.4");
57     CPPUNIT_ASSERT_MESSAGE("1.2.3.4 -> " + sa1->toString(),  sa1->toString() == "1.2.3.4");
58 
59     sa1 = new InetAddr("0.0.1");
60     CPPUNIT_ASSERT_MESSAGE("0.0.1 -> " + sa1->toString(), sa1->toString() == "0.0.1.0");
61 
62     sa1 = new InetAddr("0.1");
63     CPPUNIT_ASSERT_MESSAGE("0.1 -> " + sa1->toString(), sa1->toString() == "0.1.0.0");
64 
65     // "1" ---> "128.0.0.0"   I am not sure this is correct
66     sa1 = new InetAddr("1");
67     CPPUNIT_ASSERT_MESSAGE("1 -> " + sa1->toString(), sa1->toString() == "128.0.0.0");
68 
69     sa1 = new InetAddr("1.0");
70     CPPUNIT_ASSERT_MESSAGE("1.0 -> " + sa1->toString(), sa1->toString() == "1.0.0.0");
71 
72     sa1 = new InetAddr("1.0.0");
73     CPPUNIT_ASSERT_MESSAGE("1.0.0 -> " + sa1->toString(), sa1->toString() == "1.0.0.0");
74 
75     sa1 = new InetAddr("255.255.255.255");
76     CPPUNIT_ASSERT_MESSAGE("255.255.255.255 -> " + sa1->toString(), sa1->toString() == "255.255.255.255");
77     CPPUNIT_ASSERT(sa1->isValidV4Netmask() == true);
78 
79     sa1 = new InetAddr("255.255.255.128");
80     CPPUNIT_ASSERT_MESSAGE("255.255.255.128 -> " + sa1->toString(), sa1->toString() == "255.255.255.128");
81     CPPUNIT_ASSERT(sa1->isValidV4Netmask() == true);
82 
83     sa1 = new InetAddr("255.255.255.0");
84     CPPUNIT_ASSERT_MESSAGE("255.255.255.0 -> " + sa1->toString(), sa1->toString() == "255.255.255.0");
85     CPPUNIT_ASSERT(sa1->isValidV4Netmask() == true);
86 
87     sa1 = new InetAddr("255.255.0.0");
88     CPPUNIT_ASSERT_MESSAGE("255.255.0.0 -> " + sa1->toString(), sa1->toString() == "255.255.0.0");
89     CPPUNIT_ASSERT(sa1->isValidV4Netmask() == true);
90 
91     sa1 = new InetAddr("255.0.0.0");
92     CPPUNIT_ASSERT_MESSAGE("255.0.0.0 -> " + sa1->toString(), sa1->toString() == "255.0.0.0");
93     CPPUNIT_ASSERT(sa1->isValidV4Netmask() == true);
94 
95     sa1 = new InetAddr("0.0.0.0");
96     CPPUNIT_ASSERT_MESSAGE("0.0.0.0 -> " + sa1->toString(), sa1->toString() == "0.0.0.0");
97     CPPUNIT_ASSERT(sa1->isValidV4Netmask() == true);
98 
99     sa1 = new InetAddr("255.0.255.0");
100     CPPUNIT_ASSERT_MESSAGE("255.0.255.0 -> " + sa1->toString(), sa1->toString() == "255.0.255.0");
101     CPPUNIT_ASSERT(sa1->isValidV4Netmask() == false);
102 
103 }
104 
testStringToInetAddrExceptions()105 void InetAddrMaskTest::testStringToInetAddrExceptions()
106 {
107     CPPUNIT_ASSERT_NO_THROW(new InetAddr("1.2.3.4"));
108     CPPUNIT_ASSERT_NO_THROW(new InetAddr("1.2.3.4/24"));
109     CPPUNIT_ASSERT_THROW(new InetAddr("1.2.3.4/40"), FWException);
110 
111     CPPUNIT_ASSERT_THROW(new InetAddr("300.300.300.300"), FWException);
112     CPPUNIT_ASSERT_THROW(new InetAddr("1.2.3.4.5"), FWException);
113     CPPUNIT_ASSERT_THROW(new InetAddr("foo.bar"), FWException);
114     CPPUNIT_ASSERT_THROW(new InetAddr("1.2.foo.bar"), FWException);
115 
116     CPPUNIT_ASSERT_THROW(new InetAddr(40), FWException);
117     CPPUNIT_ASSERT_NO_THROW(new InetAddr(24));
118     CPPUNIT_ASSERT_THROW(new InetAddr((char*)(NULL)), FWException);
119     CPPUNIT_ASSERT_NO_THROW(new InetAddr(0));
120 }
121 
testInetAddressOps()122 void InetAddrMaskTest::testInetAddressOps()
123 {
124     InetAddr x1("1.2.3.4");
125     InetAddr y1(24);
126     InetAddr z1 = x1 & y1;
127 
128     CPPUNIT_ASSERT(z1.toString() == "1.2.3.0");
129     CPPUNIT_ASSERT( (~y1).toString() == "0.0.0.255");
130 
131     InetAddr z2 = z1 | ~y1;
132     CPPUNIT_ASSERT(z2.toString() == "1.2.3.255");
133 
134     InetAddr z3 = z1 | ~y1;
135     CPPUNIT_ASSERT(z3.toString() == "1.2.3.255");
136 
137     InetAddr z4 = x1 + 1;
138     CPPUNIT_ASSERT(z4.toString() == "1.2.3.5");
139 
140     InetAddr z5 = z4 - 1;
141     CPPUNIT_ASSERT(z5.toString() == "1.2.3.4");
142 
143     CPPUNIT_ASSERT(z5 == x1);
144 
145     InetAddr x2("255.255.255.255");
146     InetAddr z6 = x2 + 1;
147     CPPUNIT_ASSERT(z6.toString() == "0.0.0.0");
148 
149     InetAddr x3("1.2.2.4");
150     CPPUNIT_ASSERT(x3 < x1);
151     CPPUNIT_ASSERT(x1 > x3);
152 
153 }
154 
testStringToInetAddrMask()155 void InetAddrMaskTest::testStringToInetAddrMask()
156 {
157     string sa;
158 
159     InetAddrMask *a1 = new InetAddrMask();
160     CPPUNIT_ASSERT(a1->toString() == "0.0.0.0/0.0.0.0");
161     sa = a1->getAddressPtr()->toString();
162     CPPUNIT_ASSERT(sa=="0.0.0.0");
163     // 0.0.0.0/0.0.0.0 has maximum dimension (represents all possible addresses)
164     CPPUNIT_ASSERT(a1->dimension() == (((unsigned int)1)<<31)-1);
165 
166     InetAddrMask *a2 = new InetAddrMask(InetAddr("1.1.1.1"), InetAddr("255.255.255.0"));
167     sa = a2->getAddressPtr()->toString();
168     CPPUNIT_ASSERT(sa=="1.1.1.0");
169     sa = a2->getNetmaskPtr()->toString();
170     CPPUNIT_ASSERT(sa=="255.255.255.0");
171     CPPUNIT_ASSERT(a2->dimension()==256);
172     CPPUNIT_ASSERT(a2->toString()=="1.1.1.0/255.255.255.0");
173 
174 
175     InetAddrMask *a3 = new InetAddrMask(string("1.1.1.1"));
176     sa = a3->getAddressPtr()->toString();
177     CPPUNIT_ASSERT(sa=="1.1.1.1");
178     sa = a3->getNetmaskPtr()->toString();
179     CPPUNIT_ASSERT(sa=="255.255.255.255");
180     CPPUNIT_ASSERT(a3->dimension()==1);
181 
182     CPPUNIT_ASSERT(a2->belongs( *(a3->getAddressPtr()) ));
183 
184     InetAddrMask *a4 = new InetAddrMask(*a3);
185     sa = a4->getAddressPtr()->toString();
186     CPPUNIT_ASSERT(sa=="1.1.1.1");
187     sa = a4->getNetmaskPtr()->toString();
188     CPPUNIT_ASSERT(sa=="255.255.255.255");
189     CPPUNIT_ASSERT(a4->dimension()==1);
190 
191     a4->setAddress(InetAddr("2.2.2.2"));
192     sa = a4->getAddressPtr()->toString();
193     CPPUNIT_ASSERT(sa=="2.2.2.2");
194     sa = a4->getNetmaskPtr()->toString();
195     CPPUNIT_ASSERT(sa=="255.255.255.255");
196     CPPUNIT_ASSERT(a4->dimension()==1);
197 
198     a4->setNetmask(InetAddr("255.255.0.0"));
199     sa = a4->getAddressPtr()->toString();
200     CPPUNIT_ASSERT(sa=="2.2.2.2");
201     sa = a4->getNetmaskPtr()->toString();
202     CPPUNIT_ASSERT(sa=="255.255.0.0");
203     CPPUNIT_ASSERT(a4->dimension()==256*256);
204 
205     a4->setNetmask(InetAddr("8"));
206     sa = a4->getAddressPtr()->toString();
207     CPPUNIT_ASSERT(sa=="2.2.2.2");
208     sa = a4->getNetmaskPtr()->toString();
209     CPPUNIT_ASSERT(sa=="255.0.0.0");
210     CPPUNIT_ASSERT(a4->dimension()==256*256*256);
211 
212     CPPUNIT_ASSERT_THROW(a4->setNetmask(InetAddr("40")), FWException);
213 
214     // a4 should not have changed
215     sa = a4->getAddressPtr()->toString();
216     CPPUNIT_ASSERT(sa=="2.2.2.2");
217     sa = a4->getNetmaskPtr()->toString();
218     CPPUNIT_ASSERT(sa=="255.0.0.0");
219     CPPUNIT_ASSERT(a4->dimension()==256*256*256);
220 
221     InetAddrMask *a5 = new InetAddrMask(string("1.1.1.1/24"));
222     sa = a5->getAddressPtr()->toString();
223     CPPUNIT_ASSERT(sa=="1.1.1.1");
224     sa = a5->getNetmaskPtr()->toString();
225     CPPUNIT_ASSERT(sa=="255.255.255.0");
226     CPPUNIT_ASSERT(a5->dimension()==256);
227 
228 }
229 
vectorInetAddrMaskToString(vector<InetAddrMask> vect)230 string InetAddrMaskTest::vectorInetAddrMaskToString(vector<InetAddrMask> vect)
231 {
232     string res;
233     vector<InetAddrMask>::iterator it;
234     for (it=vect.begin(); it!=vect.end(); ++it)
235     {
236         res += it->toString() + " ";
237     }
238     return res;
239 }
240 
testIPv4Overlap()241 void InetAddrMaskTest::testIPv4Overlap()
242 {
243     string res;
244 
245     res = vectorInetAddrMaskToString(
246         libfwbuilder::getOverlap(
247             InetAddrMask(InetAddr("10.0.0.0"), InetAddr("255.255.255.0")),
248             InetAddrMask(InetAddr("10.0.0.0"), InetAddr("255.255.255.0"))
249         )
250     );
251     CPPUNIT_ASSERT(res=="10.0.0.0/255.255.255.0 ");
252 
253     res = vectorInetAddrMaskToString(
254         libfwbuilder::getOverlap(
255             InetAddrMask(InetAddr("10.0.0.0"), InetAddr("255.255.255.0")),
256             InetAddrMask(InetAddr("10.0.0.255"), InetAddr("255.255.255.255"))
257         )
258     );
259     CPPUNIT_ASSERT(res=="10.0.0.255/255.255.255.255 ");
260 
261     res = vectorInetAddrMaskToString(
262         libfwbuilder::getOverlap(
263             InetAddrMask(InetAddr("10.0.0.255"), InetAddr("255.255.255.255")),
264             InetAddrMask(InetAddr("10.0.0.0"), InetAddr("255.255.255.0"))
265         )
266     );
267     CPPUNIT_ASSERT(res=="10.0.0.255/255.255.255.255 ");
268 
269     res = vectorInetAddrMaskToString(
270         libfwbuilder::getOverlap(
271             InetAddrMask(InetAddr("10.0.0.0"), InetAddr("255.255.255.254")),
272             InetAddrMask(InetAddr("10.0.0.0"), InetAddr("255.255.255.0"))
273         )
274     );
275     CPPUNIT_ASSERT(res=="10.0.0.0/255.255.255.254 ");
276 
277     res = vectorInetAddrMaskToString(
278         libfwbuilder::getOverlap(
279             InetAddrMask(InetAddr("10.0.0.0"), InetAddr("255.255.255.0")),
280             InetAddrMask(InetAddr("10.0.0.0"), InetAddr("255.255.255.254"))
281         )
282     );
283     CPPUNIT_ASSERT(res=="10.0.0.0/255.255.255.254 ");
284 
285     res = vectorInetAddrMaskToString(
286         libfwbuilder::getOverlap(
287             InetAddrMask(InetAddr("10.0.0.252"), InetAddr("255.255.255.252")),
288             InetAddrMask(InetAddr("10.0.0.0"), InetAddr("255.255.255.0"))
289         )
290     );
291     CPPUNIT_ASSERT(res=="10.0.0.252/255.255.255.252 ");
292 
293     res = vectorInetAddrMaskToString(
294         libfwbuilder::getOverlap(
295             InetAddrMask(InetAddr("10.0.0.0"), InetAddr("255.255.255.0")),
296             InetAddrMask(InetAddr("10.0.0.252"), InetAddr("255.255.255.252"))
297         )
298     );
299     CPPUNIT_ASSERT(res=="10.0.0.252/255.255.255.252 ");
300 
301     res = vectorInetAddrMaskToString(
302         libfwbuilder::getOverlap(
303             InetAddrMask(InetAddr("10.0.0.128"), InetAddr("255.255.255.252")),
304             InetAddrMask(InetAddr("10.0.0.0"), InetAddr("255.255.255.0"))
305         )
306     );
307     CPPUNIT_ASSERT(res=="10.0.0.128/255.255.255.252 ");
308 
309     res = vectorInetAddrMaskToString(
310         libfwbuilder::getOverlap(
311             InetAddrMask(InetAddr("10.0.0.0"), InetAddr("255.255.255.0")),
312             InetAddrMask(InetAddr("10.0.0.128"), InetAddr("255.255.255.252"))
313         )
314     );
315     CPPUNIT_ASSERT(res=="10.0.0.128/255.255.255.252 ");
316 
317     // test specifically for #1934
318     res = vectorInetAddrMaskToString(
319         libfwbuilder::getOverlap(
320             InetAddrMask(InetAddr("10.0.0.2"), InetAddr("255.255.255.254")),
321             InetAddrMask(InetAddr("10.0.0.0"), InetAddr("255.255.255.0")))
322     );
323     CPPUNIT_ASSERT(res=="10.0.0.2/255.255.255.254 ");
324 
325     res = vectorInetAddrMaskToString(
326         libfwbuilder::getOverlap(
327             InetAddrMask(InetAddr("10.0.0.2"), InetAddr("255.255.255.254")),
328             InetAddrMask(InetAddr("0.0.0.0"), InetAddr("0.0.0.0")))
329     );
330     CPPUNIT_ASSERT(res=="10.0.0.2/255.255.255.254 ");
331 
332 }
333