]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - config/cfgroot/network-functions.pl
kernel: Update pcengines apu led patch for x86_64
[people/pmueller/ipfire-2.x.git] / config / cfgroot / network-functions.pl
CommitLineData
4e9a2b57
MT
1#!/usr/bin/perl -w
2############################################################################
3# #
4# This file is part of the IPFire Firewall. #
5# #
6# IPFire is free software; you can redistribute it and/or modify #
7# it under the terms of the GNU General Public License as published by #
8# the Free Software Foundation; either version 2 of the License, or #
9# (at your option) any later version. #
10# #
11# IPFire is distributed in the hope that it will be useful, #
12# but WITHOUT ANY WARRANTY; without even the implied warranty of #
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14# GNU General Public License for more details. #
15# #
16# You should have received a copy of the GNU General Public License #
17# along with IPFire; if not, write to the Free Software #
18# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #
19# #
20# Copyright (C) 2014 IPFire Team <info@ipfire.org>. #
21# #
22############################################################################
23
24package Network;
25
5428eeee
MT
26require "/var/ipfire/general-functions.pl";
27
4e9a2b57
MT
28use Socket;
29
30my %PREFIX2NETMASK = (
31 32 => "255.255.255.255",
32 31 => "255.255.255.254",
33 30 => "255.255.255.252",
34 29 => "255.255.255.248",
35 28 => "255.255.255.240",
36 27 => "255.255.255.224",
37 26 => "255.255.255.192",
38 25 => "255.255.255.128",
39 24 => "255.255.255.0",
40 23 => "255.255.254.0",
41 22 => "255.255.252.0",
42 21 => "255.255.248.0",
43 20 => "255.255.240.0",
44 19 => "255.255.224.0",
45 18 => "255.255.192.0",
46 17 => "255.255.128.0",
47 16 => "255.255.0.0",
48 15 => "255.254.0.0",
49 14 => "255.252.0.0",
50 13 => "255.248.0.0",
51 12 => "255.240.0.0",
52 11 => "255.224.0.0",
53 10 => "255.192.0.0",
54 9 => "255.128.0.0",
55 8 => "255.0.0.0",
56 7 => "254.0.0.0",
57 6 => "252.0.0.0",
58 5 => "248.0.0.0",
59 4 => "240.0.0.0",
60 3 => "224.0.0.0",
61 2 => "192.0.0.0",
62 1 => "128.0.0.0",
63 0 => "0.0.0.0"
64);
65
66my %NETMASK2PREFIX = reverse(%PREFIX2NETMASK);
67
68# Takes an IP address in dotted decimal notation and
69# returns a 32 bit integer representing that IP addresss.
70# Will return undef for invalid inputs.
71sub ip2bin($) {
72 my $address = shift;
73
74 # This function returns undef for undefined input.
75 if (!defined $address) {
76 return undef;
77 }
78
79 my $address_bin = &Socket::inet_pton(AF_INET, $address);
80 if ($address_bin) {
81 $address_bin = unpack('N', $address_bin);
82 }
83
84 return $address_bin;
85}
86
87# Does the reverse of ip2bin().
88# Will return undef for invalid inputs.
89sub bin2ip($) {
90 my $address_bin = shift;
91
92 # This function returns undef for undefined input.
93 if (!defined $address_bin) {
94 return undef;
95 }
96
97 my $address = pack('N', $address_bin);
98 if ($address) {
99 $address = &Socket::inet_ntop(AF_INET, $address);
100 }
101
102 return $address;
103}
104
105# Takes a network in either a.b.c.d/a.b.c.d or a.b.c.d/e notation
106# and will return an 32 bit integer representing the start
107# address and an other one representing the network mask.
108sub network2bin($) {
109 my $network = shift;
110
111 my ($address, $netmask) = split(/\//, $network, 2);
112
113 if (&check_prefix($netmask)) {
114 $netmask = &convert_prefix2netmask($netmask);
115 }
116
117 my $address_bin = &ip2bin($address);
118 my $netmask_bin = &ip2bin($netmask);
119
120 my $network_start = $address_bin & $netmask_bin;
121
122 return ($network_start, $netmask_bin);
123}
124
125# Returns True for all valid IP addresses
126sub check_ip_address($) {
127 my $address = shift;
128
129 # Normalise the IP address and compare the result with
130 # the input - which should obviously the same.
131 my $normalised_address = &_normalise_ip_address($address);
132
133 return ((defined $normalised_address) && ($address eq $normalised_address));
134}
135
136# Returns True for all valid prefixes.
137sub check_prefix($) {
138 my $prefix = shift;
139
140 return (exists $PREFIX2NETMASK{$prefix});
141}
142
143# Returns True for all valid subnet masks.
144sub check_netmask($) {
145 my $netmask = shift;
146
147 return (exists $NETMASK2PREFIX{$netmask});
148}
149
150# Returns True for all valid inputs like a.b.c.d/a.b.c.d.
151sub check_ip_address_and_netmask($$) {
152 my $network = shift;
153
154 my ($address, $netmask) = split(/\//, $network, 2);
155
156 # Check if the IP address is fine.
157 #
158 my $result = &check_ip_address($address);
159 unless ($result) {
160 return $result;
161 }
162
163 return &check_netmask($netmask);
164}
165
883c5453
MT
166# Returns True for all valid subnets like a.b.c.d/e or a.b.c.d/a.b.c.d
167sub check_subnet($) {
168 my $subnet = shift;
169
170 my ($address, $network) = split(/\//, $subnet, 2);
171
172 # Check if the IP address is fine.
173 my $result = &check_ip_address($address);
174 unless ($result) {
175 return $result;
176 }
177
178 return &check_prefix($network) || &check_netmask($network);
179}
180
4e9a2b57
MT
181# For internal use only. Will take an IP address and
182# return it in a normalised style. Like 8.8.8.010 -> 8.8.8.8.
183sub _normalise_ip_address($) {
184 my $address = shift;
185
186 my $address_bin = &ip2bin($address);
187 if (!defined $address_bin) {
188 return undef;
189 }
190
191 return &bin2ip($address_bin);
192}
193
194# Returns the prefix for the given subnet mask.
195sub convert_netmask2prefix($) {
196 my $netmask = shift;
197
198 if (exists $NETMASK2PREFIX{$netmask}) {
199 return $NETMASK2PREFIX{$netmask};
200 }
201
202 return undef;
203}
204
205# Returns the subnet mask for the given prefix.
206sub convert_prefix2netmask($) {
207 my $prefix = shift;
208
209 if (exists $PREFIX2NETMASK{$prefix}) {
210 return $PREFIX2NETMASK{$prefix};
211 }
212
213 return undef;
214}
215
216# Takes an IP address and an offset and
217# will return the offset'th IP address.
218sub find_next_ip_address($$) {
219 my $address = shift;
220 my $offset = shift;
221
222 my $address_bin = &ip2bin($address);
223 $address_bin += $offset;
224
225 return &bin2ip($address_bin);
226}
227
228# Returns the network address of the given network.
229sub get_netaddress($) {
230 my $network = shift;
231 my ($network_bin, $netmask_bin) = &network2bin($network);
232
233 if (defined $network_bin) {
234 return &bin2ip($network_bin);
235 }
236
237 return undef;
238}
239
240# Returns the broadcast of the given network.
241sub get_broadcast($) {
242 my $network = shift;
243 my ($network_bin, $netmask_bin) = &network2bin($network);
244
245 return &bin2ip($network_bin ^ ~$netmask_bin);
246}
247
248# Returns True if $address is in $network.
249sub ip_address_in_network($$) {
250 my $address = shift;
251 my $network = shift;
252
253 my $address_bin = &ip2bin($address);
254 return undef unless (defined $address_bin);
255
256 my ($network_bin, $netmask_bin) = &network2bin($network);
257
258 # Find end address
259 my $broadcast_bin = $network_bin ^ ~$netmask_bin;
260
261 return (($address_bin ge $network_bin) && ($address_bin le $broadcast_bin));
262}
263
5428eeee
MT
264sub setup_upstream_proxy() {
265 my %proxysettings = ();
266 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
267
268 if ($proxysettings{'UPSTREAM_PROXY'}) {
269 my $credentials = "";
270
271 if ($proxysettings{'UPSTREAM_USER'}) {
272 $credentials = $proxysettings{'UPSTREAM_USER'};
273
274 if ($proxysettings{'UPSTREAM_PASSWORD'}) {
275 $credentials .= ":" . $proxysettings{'UPSTREAM_PASSWORD'};
276 }
277
278 $credentials .= "@";
279 }
280
281 my $proxy = "http://" . $credentials . $proxysettings{'UPSTREAM_PROXY'};
282
283 $ENV{'http_proxy'} = $proxy;
284 $ENV{'https_proxy'} = $proxy;
285 $ENV{'ftp_proxy'} = $proxy;
286 }
287}
288
4e9a2b57
MT
2891;
290
291# Remove the next line to enable the testsuite
292__END__
293
294sub assert($) {
295 my $ret = shift;
296
297 if ($ret) {
298 return;
299 }
300
301 print "ASSERTION ERROR";
302 exit(1);
303}
304
305sub testsuite() {
306 my $result;
307
308 my $address1 = &ip2bin("8.8.8.8");
309 assert($address1 == 134744072);
310
311 my $address2 = &bin2ip($address1);
312 assert($address2 eq "8.8.8.8");
313
314 # Check if valid IP addresses are correctly recognised.
315 foreach my $address ("1.2.3.4", "192.168.180.1", "127.0.0.1") {
316 if (!&check_ip_address($address)) {
317 print "$address is not correctly recognised as a valid IP address!\n";
318 exit 1;
319 };
320 }
321
322 # Check if invalid IP addresses are correctly found.
323 foreach my $address ("456.2.3.4", "192.768.180.1", "127.1", "1", "a.b.c.d", "1.2.3.4.5", "1.2.3.4/12") {
324 if (&check_ip_address($address)) {
325 print "$address is recognised as a valid IP address!\n";
326 exit 1;
327 };
328 }
329
330 $result = &check_ip_address_and_netmask("192.168.180.0/255.255.255.0");
331 assert($result);
332
333 $result = &convert_netmask2prefix("255.255.254.0");
334 assert($result == 23);
335
336 $result = &convert_prefix2netmask(8);
337 assert($result eq "255.0.0.0");
338
339 $result = &find_next_ip_address("1.2.3.4", 2);
340 assert($result eq "1.2.3.6");
341
342 $result = &ip_address_in_network("10.0.1.4", "10.0.0.0/8");
343 assert($result);
344
345 return 0;
346}
347
348&testsuite();