1 /*
2  * main.cxx
3  *
4  * PWLib application source file for dtmftest
5  *
6  * Main program entry point.
7  *
8  * Copyright (C) 2004 Post Increment
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.0 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17  * the License for the specific language governing rights and limitations
18  * under the License.
19  *
20  * The Original Code is Portable Windows Library.
21  *
22  * The Initial Developer of the Original Code is Post Increment
23  *
24  * Contributor(s): ______________________________________.
25  *
26  * $Revision: 24704 $
27  * $Author: willamowius $
28  * $Date: 2010-09-15 01:36:57 -0500 (Wed, 15 Sep 2010) $
29  */
30 
31 #include "precompile.h"
32 #include "main.h"
33 #include "version.h"
34 
35 #include <ptlib/sockets.h>
36 #include <ptclib/url.h>
37 #include <ptbuildopts.h>
38 
39 PCREATE_PROCESS(IPV6Test);
40 
41 
IPV6Test()42 IPV6Test::IPV6Test()
43   : PProcess("Post Increment", "ipv6test", MAJOR_VERSION, MINOR_VERSION, BUILD_TYPE, BUILD_NUMBER)
44 {
45 }
46 
47 
Main()48 void IPV6Test::Main()
49 {
50   PArgList & args = GetArguments();
51 
52   args.Parse(
53              "-isrfc1918."
54              "4-ipv4."
55              "d-dns:"
56              "h-help."
57              "v-version."
58 
59 #if PTRACING
60              "o-output:"             "-no-output."
61              "t-trace."              "-no-trace."
62 #endif
63        );
64 
65 #if PTRACING
66   PTrace::Initialise(args.GetOptionCount('t'),
67                      args.HasOption('o') ? (const char *)args.GetOptionString('o') : NULL,
68          PTrace::Blocks | PTrace::Timestamp | PTrace::Thread | PTrace::FileAndLine);
69 #endif
70 
71   if (args.HasOption('h')) {
72     cout << "usage: ipv6test -v                display version information\n"
73             "       ipv6test --isrfc1918 addr  check if specified address is RFC1918\n"
74             "       ipv6test [-4] -d name      perform DNS lookup of hostname (with optional IPV4 force)\n"
75             "       ipv6test                   perform a variety of IPV6 tests\n";
76     return;
77   }
78 
79   if (args.HasOption('v')) {
80     cout << "Product Name: " << GetName() << endl
81          << "Manufacturer: " << GetManufacturer() << endl
82          << "Version     : " << GetVersion(PTrue) << endl
83          << "System      : " << GetOSName() << '-'
84          << GetOSHardware() << ' '
85          << GetOSVersion() << endl;
86     return;
87   }
88 
89 #if ! P_HAS_IPV6
90   cout << "error: IPV6 not included in PWLib" << endl;
91 #else
92 
93   if (args.HasOption('4')) {
94     cout << "forcing IPV4 mode" << endl;
95     PIPSocket::SetDefaultIpAddressFamilyV4();
96   }
97 
98   if (args.HasOption('d')) {
99     PString name = args.GetOptionString('d');
100     PIPSocket::Address addr;
101     if (!PIPSocket::GetHostAddress(name, addr))
102       PError << "error: hostname \"" << name << "\" not found" << endl;
103     else
104       cout << addr << endl;
105     return;
106   }
107 
108   if (args.HasOption("isrfc1918")) {
109     if (args.GetCount() == 0)
110       PError << "error: must supply IP address as argument" << endl;
111     else {
112       PIPSocket::Address addr(args[0]);
113       cout << addr << " is " << (addr.IsRFC1918() ? "" : "not ") << "an RFC1918 address" << endl;
114     }
115     return;
116   }
117 
118   {
119     // test #1 - check PIPSocket::IsIpAddressFamilyV6Supported
120     cout << "test #1: PIPSocket::IsIpAddressFamilyV6Supported ";
121     if (PIPSocket::IsIpAddressFamilyV6Supported())
122         cout << "OK";
123     else
124         cout << "failed";
125     cout << endl;
126   }
127 
128 
129   // this is an IPV6 compatibility address
130   const BYTE ipv6Data[] = { 0x00, 0x00, 0x00, 0x00,
131                             0x00, 0x00, 0x00, 0x00,
132                             0x00, 0x00, 0xff, 0xff,
133                             220,  244,  81,   10 };
134   const PIPSocket::Address ipv6Addr1(sizeof(ipv6Data), ipv6Data);
135   {
136     // test #2 - check V6 constructor
137     cout << "test #2: PIPSocket::Address(int, const BYTE *) ";
138     if (ipv6Addr1.GetVersion() == 6)
139         cout << "OK";
140     else
141         cout << "failed";
142     cout << endl;
143   }
144 
145   PIPSocket::Address ipv6Addr2("::ffff:220.244.81.10");
146   {
147     // test #3 - check V6 constructor
148     cout << "test #3: PIPSocket::Address(const PString & str) ";
149     if (ipv6Addr1.GetVersion() == 6)
150         cout << "OK";
151     else
152         cout << "failed - " << ipv6Addr1 << " <-> " << ipv6Addr2;
153     cout << endl;
154   }
155 
156   {
157     // test #4 - check comparison for equality
158     cout << "test #4: PIPSocket::operator == ";
159     if (ipv6Addr1 == ipv6Addr2)
160         cout << "OK";
161     else
162         cout << "failed - " << ipv6Addr1 << " <-> " << ipv6Addr2;
163     cout << endl;
164   }
165 
166   PIPSocket::Address ipv6Addr3("::ffff:220.244.81.09");
167   {
168     // test #5 - check comparison for non-equality
169     cout << "test #5: PIPSocket::operator != ";
170     if (ipv6Addr1 != ipv6Addr3)
171         cout << "OK";
172     else
173         cout << "failed";
174     cout << endl;
175   }
176 
177   PIPSocket::Address ipv4Addr("220.244.81.10");
178   {
179     // test #6 - check IPV6 comparison to IPV4
180     cout << "test #6: PIPSocket::operator == with IPV4 (should fail) ";
181     if (ipv6Addr1 == ipv4Addr)
182         cout << "OK";
183     else
184         cout << "failed";
185     cout << endl;
186   }
187   {
188     // test #6a - check IPV6 comparison to IPV4
189     cout << "test #6a: PIPSocket::operator == with IPV4 (should fail) ";
190     if (ipv6Addr3 == ipv4Addr)
191         cout << "OK";
192     else
193         cout << "failed";
194     cout << endl;
195   }
196 
197   {
198     // test #7 - check IPV6 comparison to IPV4
199     cout << "test #7: PIPSocket::operator *= with IPV4 ";
200     if (ipv6Addr1 *= ipv4Addr)
201         cout << "OK";
202     else
203         cout << "failed";
204     cout << endl;
205   }
206   {
207     // test #7a - check IPV6 comparison to IPV4
208     cout << "test #7a: PIPSocket::operator *= with IPV4 (should fail) ";
209     if (ipv6Addr3 *= ipv4Addr)
210         cout << "OK";
211     else
212         cout << "failed";
213     cout << endl;
214   }
215   {
216     // test #8 - check if interface table contains IPV6 addresses
217     cout << "test #8: check if interface table contains IPV6 addresses";
218 
219     PIPSocket::InterfaceTable if_table;
220     PIPSocket::GetInterfaceTable( if_table );
221 
222     // Display the interface table
223     cout << endl;
224     cout << "The interface table has " << if_table.GetSize()
225          <<" entries" << endl;
226 
227     for (PINDEX i=0; i < if_table.GetSize(); i++) {
228       PIPSocket::InterfaceEntry if_entry = if_table[i];
229       cout << i << " " << if_entry << endl;
230     }
231     cout << "Please do manual check ...";
232     cout << endl;
233   }
234   {
235     // test #8b - check if route table contains IPV6 addresses
236     cout << "test #8b: check if route table contains IPV6 addresses";
237 
238     PIPSocket::RouteTable rt_table;
239     PIPSocket::GetRouteTable( rt_table );
240 
241     // Display the route table
242     cout << endl;
243     cout << "The route table has " << rt_table.GetSize()
244          <<" entries" << endl;
245 
246     for (PINDEX i=0; i < rt_table.GetSize(); i++) {
247       PIPSocket::RouteEntry rt_entry = rt_table[i];
248       cout << i << "\t" << rt_entry.GetNetwork() << "\t" << rt_entry.GetNetMask() << "\t" << rt_entry.GetDestination() << "\t" << rt_entry.GetInterface() << endl;
249     }
250     cout << "Please do manual check ...";
251     cout << endl;
252   }
253   {
254     // test #9 - see if URLs decode correctly
255     cout << "test #9: Please do manual check if parsing IPV6 URLs works" << endl;
256 
257     PURL url("h323:@[::ffff:220.244.81.10]:1234");
258     PString addrStr = url.GetHostName();
259     PIPSocket::Address addr;
260     PIPSocket::GetHostAddress(addrStr, addr);
261     WORD port = url.GetPort();
262     cout << "  host string = " << addrStr << " (should be [::ffff:220.244.81.10])\n"
263          << "  address     = " << addr    << " (should be ::ffff:220.244.81.10)\n"
264          << "  port        = " << port    << " (should be 1234)\n";
265   }
266 #endif
267 }
268 
269 // End of File ///////////////////////////////////////////////////////////////
270