Improve the code by static code analysis [2/3]: Performance
[amule.git] / src / NetworkFunctions.cpp
blob831355e9bb691042d7a3ea61f88b5614a229b6f1
1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2004-2011 Angel Vidal ( kry@amule.org )
5 // Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org )
6 // Copyright (c) 2002-2011 Merkur ( devs@emule-project.net / http://www.emule-project.net )
7 //
8 // Any parts of this program derived from the xMule, lMule or eMule project,
9 // or contributed by third-party developers are copyrighted by their
10 // respective authors.
12 // This program is free software; you can redistribute it and/or modify
13 // it under the terms of the GNU General Public License as published by
14 // the Free Software Foundation; either version 2 of the License, or
15 // (at your option) any later version.
17 // This program is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU General Public License for more details.
22 // You should have received a copy of the GNU General Public License
23 // along with this program; if not, write to the Free Software
24 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "NetworkFunctions.h" // Interface declaration
28 #include "amuleIPV4Address.h"
30 bool StringIPtoUint32(const wxString &strIP, uint32& Ip)
32 // The current position in the current field, used to detect malformed fields (x.y..z).
33 unsigned digit = 0;
35 // The current field, used to ensure only IPs that looks like a.b.c.d are supported
36 unsigned field = 0;
38 // The value of the current field
39 unsigned value = 0;
41 // Stores the work-value of the IP, reference is not changed unless the str was valid
42 uint32 tmp_ip = 0;
44 wxString str = strIP.Strip( wxString::both );
45 for (size_t i = 0; i < str.Length(); i++) {
46 wxChar c = str.GetChar( i );
48 if ( c >= wxT('0') && c <= wxT('9') && (value >> 8) == 0) {
49 value = ( value * 10 ) + ( c - wxT('0') );
50 ++digit;
51 } else if ( c == wxT('.') ) {
52 if ( digit && (value >> 8) == 0) {
53 tmp_ip = tmp_ip | value << ( field * 8 );
55 // Rest the current field values
56 value = digit = 0;
57 ++field;
58 } else {
59 return false;
61 } else {
62 return false;
66 // Only set the referenced value if it was a valid IP
67 if ( field == 3 && digit && (value >> 8) == 0) {
68 Ip = tmp_ip | value << 24;
69 return true;
72 return false;
76 uint32 StringHosttoUint32(const wxString &Host)
78 if (Host.IsEmpty()) {
79 return 0;
81 amuleIPV4Address solver;
82 if (solver.Hostname(Host)) {
83 uint32 result = StringIPtoUint32(solver.IPAddress());
84 if (result != (uint32)-1) { // should not happen
85 return result;
88 // This actually happens on wrong hostname
89 return 0;
92 /**
93 * Used to store the ranges.
95 struct IPRange
97 const wxChar *addr;
98 unsigned int mask;
99 bool isLAN;
103 const IPRange ranges[] = {
104 // Here is reserved blocks from RFC 3330 at http://www.rfc-editor.org/rfc/rfc3330.txt
106 //Address Block Present Use Reference
107 //----------------------------------------------------------------------------------
108 { wxT("0.0.0.0"), 8, false }, // "This" Network [RFC1700, page 4]
109 { wxT("10.0.0.0"), 8, true }, // Private-Use Networks [RFC1918]
110 // Acording to RFC3330, 24.* and 14.* must be parsed as normal ips.
111 //{ wxT("14.0.0.0"), 8, false }, // Public-Data Networks [RFC1700, page 181]
112 //{ wxT("24.0.0.0"), 8, false }, // Cable Television Networks --
113 { wxT("39.0.0.0"), 8, false }, // Reserved but subject
114 // to allocation [RFC1797]
115 { wxT("127.0.0.0"), 8, false }, // Loopback [RFC1700, page 5]
116 { wxT("128.0.0.0"), 16, false }, // Reserved but subject
117 // to allocation --
118 { wxT("169.254.0.0"), 16, false }, // Link Local --
119 { wxT("172.16.0.0"), 12, true }, // Private-Use Networks [RFC1918]
120 { wxT("191.255.0.0"), 16, false }, // Reserved but subject
121 // to allocation --
122 { wxT("192.0.0.0"), 24, false }, // Reserved but subject
123 // to allocation --
124 { wxT("192.0.2.0"), 24, false }, // Test-Net
125 { wxT("192.88.99.0"), 24, false }, // 6to4 Relay Anycast [RFC3068]
126 { wxT("192.168.0.0"), 16, true }, // Private-Use Networks [RFC1918]
127 { wxT("198.18.0.0"), 15, false }, // Network Interconnect
128 // Device Benchmark Testing [RFC2544]
129 { wxT("223.255.255.0"), 24, false }, // Reserved but subject
130 // to allocation --
131 { wxT("224.0.0.0"), 4, false }, // Multicast [RFC3171]
132 { wxT("240.0.0.0"), 4, false } // Reserved for Future Use [RFC1700, page 4]
136 struct filter_st {
137 uint32 addr; // Address and mask in anti-host order.
138 uint32 mask;
141 const unsigned int number_of_ranges = sizeof(ranges) / sizeof(IPRange);
142 static filter_st filters[number_of_ranges];
145 // This function is used to initialize the IP filter
146 bool SetupFilter()
148 for (unsigned int i = 0; i < number_of_ranges; ++i) {
149 filters[i].addr = StringIPtoUint32( ranges[i].addr );
150 filters[i].mask = ~wxUINT32_SWAP_ALWAYS((1 << (32 - ranges[i].mask)) - 1);
152 return true;
156 // This is a little trick to ensure that the filter-list is initialized before
157 // it gets used, while not risking threading problems.
158 static bool filterSetup = SetupFilter();
161 bool IsGoodIP(uint32 IP, bool filterLAN)
163 for (unsigned int i = 0; i < number_of_ranges; ++i) {
164 if (((IP ^ filters[i].addr) & filters[i].mask) == 0) {
165 if ( filterLAN || !ranges[i].isLAN ) {
166 return false;
171 return true;
174 bool IsLanIP(uint32_t ip) throw()
176 for (unsigned int i = 0; i < number_of_ranges; i++) {
177 if (((ip ^ filters[i].addr) & filters[i].mask) == 0) {
178 return ranges[i].isLAN;
181 return false;
183 // File_checked_for_headers