]>
Commit | Line | Data |
---|---|---|
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 | ||
24 | package Network; | |
25 | ||
5428eeee MT |
26 | require "/var/ipfire/general-functions.pl"; |
27 | ||
69d90c36 | 28 | use experimental 'smartmatch'; |
4e9a2b57 MT |
29 | use Socket; |
30 | ||
eea288bc LAH |
31 | # System ethernet configuration |
32 | our %ethernet_settings = (); | |
33 | &General::readhash("${General::swroot}/ethernet/settings", \%ethernet_settings); | |
34 | ||
35 | # List of all possible network zones that can be configured | |
36 | our @known_network_zones = ("red", "green", "orange", "blue"); | |
37 | ||
38 | # IPv4 netmask CIDR to dotted decimal notation conversion table | |
4e9a2b57 MT |
39 | my %PREFIX2NETMASK = ( |
40 | 32 => "255.255.255.255", | |
41 | 31 => "255.255.255.254", | |
42 | 30 => "255.255.255.252", | |
43 | 29 => "255.255.255.248", | |
44 | 28 => "255.255.255.240", | |
45 | 27 => "255.255.255.224", | |
46 | 26 => "255.255.255.192", | |
47 | 25 => "255.255.255.128", | |
48 | 24 => "255.255.255.0", | |
49 | 23 => "255.255.254.0", | |
50 | 22 => "255.255.252.0", | |
51 | 21 => "255.255.248.0", | |
52 | 20 => "255.255.240.0", | |
53 | 19 => "255.255.224.0", | |
54 | 18 => "255.255.192.0", | |
55 | 17 => "255.255.128.0", | |
56 | 16 => "255.255.0.0", | |
57 | 15 => "255.254.0.0", | |
58 | 14 => "255.252.0.0", | |
59 | 13 => "255.248.0.0", | |
60 | 12 => "255.240.0.0", | |
61 | 11 => "255.224.0.0", | |
62 | 10 => "255.192.0.0", | |
63 | 9 => "255.128.0.0", | |
64 | 8 => "255.0.0.0", | |
65 | 7 => "254.0.0.0", | |
66 | 6 => "252.0.0.0", | |
67 | 5 => "248.0.0.0", | |
68 | 4 => "240.0.0.0", | |
69 | 3 => "224.0.0.0", | |
70 | 2 => "192.0.0.0", | |
71 | 1 => "128.0.0.0", | |
72 | 0 => "0.0.0.0" | |
73 | ); | |
74 | ||
75 | my %NETMASK2PREFIX = reverse(%PREFIX2NETMASK); | |
76 | ||
77 | # Takes an IP address in dotted decimal notation and | |
78 | # returns a 32 bit integer representing that IP addresss. | |
79 | # Will return undef for invalid inputs. | |
80 | sub ip2bin($) { | |
81 | my $address = shift; | |
82 | ||
83 | # This function returns undef for undefined input. | |
84 | if (!defined $address) { | |
85 | return undef; | |
86 | } | |
87 | ||
88 | my $address_bin = &Socket::inet_pton(AF_INET, $address); | |
89 | if ($address_bin) { | |
90 | $address_bin = unpack('N', $address_bin); | |
91 | } | |
92 | ||
93 | return $address_bin; | |
94 | } | |
95 | ||
96 | # Does the reverse of ip2bin(). | |
97 | # Will return undef for invalid inputs. | |
98 | sub bin2ip($) { | |
99 | my $address_bin = shift; | |
100 | ||
101 | # This function returns undef for undefined input. | |
102 | if (!defined $address_bin) { | |
103 | return undef; | |
104 | } | |
105 | ||
106 | my $address = pack('N', $address_bin); | |
107 | if ($address) { | |
108 | $address = &Socket::inet_ntop(AF_INET, $address); | |
109 | } | |
110 | ||
111 | return $address; | |
112 | } | |
113 | ||
8f23ce8e MT |
114 | # Takes two network addresses, compares them against each other |
115 | # and returns true if equal or false if not | |
116 | sub network_equal { | |
ff6cc711 AM |
117 | my $network1 = shift; |
118 | my $network2 = shift; | |
8f23ce8e | 119 | |
1047805d AM |
120 | my @bin1 = &network2bin($network1); |
121 | my @bin2 = &network2bin($network2); | |
8f23ce8e | 122 | |
3f3974b7 AM |
123 | if (!defined $bin1 || !defined $bin2) { |
124 | return undef; | |
125 | } | |
126 | ||
6386584b | 127 | if ($bin1[0] == $bin2[0] && $bin1[1] == $bin2[1]) { |
ff6cc711 AM |
128 | return 1; |
129 | } | |
8f23ce8e | 130 | |
ff6cc711 AM |
131 | return 0; |
132 | } | |
133 | ||
4e9a2b57 MT |
134 | # Takes a network in either a.b.c.d/a.b.c.d or a.b.c.d/e notation |
135 | # and will return an 32 bit integer representing the start | |
136 | # address and an other one representing the network mask. | |
137 | sub network2bin($) { | |
138 | my $network = shift; | |
139 | ||
140 | my ($address, $netmask) = split(/\//, $network, 2); | |
141 | ||
142 | if (&check_prefix($netmask)) { | |
143 | $netmask = &convert_prefix2netmask($netmask); | |
144 | } | |
145 | ||
146 | my $address_bin = &ip2bin($address); | |
147 | my $netmask_bin = &ip2bin($netmask); | |
148 | ||
3f3974b7 AM |
149 | if (!defined $address_bin || !defined $netmask_bin) { |
150 | return undef; | |
151 | } | |
152 | ||
4e9a2b57 MT |
153 | my $network_start = $address_bin & $netmask_bin; |
154 | ||
155 | return ($network_start, $netmask_bin); | |
156 | } | |
157 | ||
f770b728 AM |
158 | # Deletes leading zeros in ip address |
159 | sub ip_remove_zero{ | |
160 | my $address = shift; | |
161 | my @ip = split (/\./, $address); | |
162 | ||
163 | foreach my $octet (@ip) { | |
164 | $octet = int($octet); | |
165 | } | |
166 | ||
167 | $address = join (".", @ip); | |
168 | ||
169 | return $address; | |
170 | } | |
4e9a2b57 MT |
171 | # Returns True for all valid IP addresses |
172 | sub check_ip_address($) { | |
173 | my $address = shift; | |
174 | ||
175 | # Normalise the IP address and compare the result with | |
176 | # the input - which should obviously the same. | |
177 | my $normalised_address = &_normalise_ip_address($address); | |
178 | ||
179 | return ((defined $normalised_address) && ($address eq $normalised_address)); | |
180 | } | |
181 | ||
182 | # Returns True for all valid prefixes. | |
183 | sub check_prefix($) { | |
184 | my $prefix = shift; | |
185 | ||
186 | return (exists $PREFIX2NETMASK{$prefix}); | |
187 | } | |
188 | ||
189 | # Returns True for all valid subnet masks. | |
190 | sub check_netmask($) { | |
191 | my $netmask = shift; | |
192 | ||
193 | return (exists $NETMASK2PREFIX{$netmask}); | |
194 | } | |
195 | ||
196 | # Returns True for all valid inputs like a.b.c.d/a.b.c.d. | |
197 | sub check_ip_address_and_netmask($$) { | |
198 | my $network = shift; | |
199 | ||
200 | my ($address, $netmask) = split(/\//, $network, 2); | |
201 | ||
202 | # Check if the IP address is fine. | |
cc9eb2d3 | 203 | # |
4e9a2b57 MT |
204 | my $result = &check_ip_address($address); |
205 | unless ($result) { | |
206 | return $result; | |
207 | } | |
208 | ||
209 | return &check_netmask($netmask); | |
210 | } | |
211 | ||
883c5453 MT |
212 | # Returns True for all valid subnets like a.b.c.d/e or a.b.c.d/a.b.c.d |
213 | sub check_subnet($) { | |
214 | my $subnet = shift; | |
215 | ||
216 | my ($address, $network) = split(/\//, $subnet, 2); | |
217 | ||
218 | # Check if the IP address is fine. | |
219 | my $result = &check_ip_address($address); | |
220 | unless ($result) { | |
221 | return $result; | |
222 | } | |
223 | ||
224 | return &check_prefix($network) || &check_netmask($network); | |
225 | } | |
226 | ||
4e9a2b57 MT |
227 | # For internal use only. Will take an IP address and |
228 | # return it in a normalised style. Like 8.8.8.010 -> 8.8.8.8. | |
229 | sub _normalise_ip_address($) { | |
230 | my $address = shift; | |
231 | ||
232 | my $address_bin = &ip2bin($address); | |
233 | if (!defined $address_bin) { | |
234 | return undef; | |
235 | } | |
236 | ||
237 | return &bin2ip($address_bin); | |
238 | } | |
239 | ||
240 | # Returns the prefix for the given subnet mask. | |
241 | sub convert_netmask2prefix($) { | |
242 | my $netmask = shift; | |
243 | ||
244 | if (exists $NETMASK2PREFIX{$netmask}) { | |
245 | return $NETMASK2PREFIX{$netmask}; | |
246 | } | |
247 | ||
248 | return undef; | |
249 | } | |
250 | ||
251 | # Returns the subnet mask for the given prefix. | |
252 | sub convert_prefix2netmask($) { | |
253 | my $prefix = shift; | |
254 | ||
255 | if (exists $PREFIX2NETMASK{$prefix}) { | |
256 | return $PREFIX2NETMASK{$prefix}; | |
257 | } | |
258 | ||
259 | return undef; | |
260 | } | |
261 | ||
262 | # Takes an IP address and an offset and | |
263 | # will return the offset'th IP address. | |
264 | sub find_next_ip_address($$) { | |
265 | my $address = shift; | |
266 | my $offset = shift; | |
267 | ||
268 | my $address_bin = &ip2bin($address); | |
269 | $address_bin += $offset; | |
270 | ||
271 | return &bin2ip($address_bin); | |
272 | } | |
273 | ||
274 | # Returns the network address of the given network. | |
275 | sub get_netaddress($) { | |
276 | my $network = shift; | |
277 | my ($network_bin, $netmask_bin) = &network2bin($network); | |
278 | ||
279 | if (defined $network_bin) { | |
280 | return &bin2ip($network_bin); | |
281 | } | |
282 | ||
283 | return undef; | |
284 | } | |
285 | ||
286 | # Returns the broadcast of the given network. | |
287 | sub get_broadcast($) { | |
288 | my $network = shift; | |
289 | my ($network_bin, $netmask_bin) = &network2bin($network); | |
290 | ||
291 | return &bin2ip($network_bin ^ ~$netmask_bin); | |
292 | } | |
293 | ||
294 | # Returns True if $address is in $network. | |
295 | sub ip_address_in_network($$) { | |
296 | my $address = shift; | |
297 | my $network = shift; | |
298 | ||
299 | my $address_bin = &ip2bin($address); | |
300 | return undef unless (defined $address_bin); | |
301 | ||
302 | my ($network_bin, $netmask_bin) = &network2bin($network); | |
303 | ||
304 | # Find end address | |
01d61d15 | 305 | my $broadcast_bin = $network_bin ^ (~$netmask_bin % 2 ** 32); |
4e9a2b57 | 306 | |
6386584b | 307 | return (($address_bin >= $network_bin) && ($address_bin <= $broadcast_bin)); |
4e9a2b57 MT |
308 | } |
309 | ||
b52a84dd AB |
310 | # Returns True if $ipaddress is within $ipstart and $ipend range. |
311 | sub ip_address_in_range($$) { | |
312 | my $ipaddress = shift; | |
313 | my $ipstart = shift; | |
314 | my $ipend = shift; | |
315 | ||
316 | my $ipaddress_bin = &ip2bin($ipaddress); | |
317 | return undef unless (defined $ipaddress_bin); | |
318 | ||
319 | my $ipstart_bin = &ip2bin($ipstart); | |
320 | return undef unless (defined $ipstart_bin); | |
321 | ||
322 | my $ipend_bin = &ip2bin($ipend); | |
323 | return undef unless (defined $ipend_bin); | |
324 | ||
325 | return (($ipaddress_bin >= $ipstart_bin) && ($ipaddress_bin <= $ipend_bin)); | |
326 | } | |
327 | ||
5428eeee MT |
328 | sub setup_upstream_proxy() { |
329 | my %proxysettings = (); | |
330 | &General::readhash("${General::swroot}/proxy/settings", \%proxysettings); | |
331 | ||
332 | if ($proxysettings{'UPSTREAM_PROXY'}) { | |
333 | my $credentials = ""; | |
334 | ||
335 | if ($proxysettings{'UPSTREAM_USER'}) { | |
336 | $credentials = $proxysettings{'UPSTREAM_USER'}; | |
337 | ||
338 | if ($proxysettings{'UPSTREAM_PASSWORD'}) { | |
339 | $credentials .= ":" . $proxysettings{'UPSTREAM_PASSWORD'}; | |
340 | } | |
341 | ||
342 | $credentials .= "@"; | |
343 | } | |
344 | ||
345 | my $proxy = "http://" . $credentials . $proxysettings{'UPSTREAM_PROXY'}; | |
346 | ||
347 | $ENV{'http_proxy'} = $proxy; | |
348 | $ENV{'https_proxy'} = $proxy; | |
349 | $ENV{'ftp_proxy'} = $proxy; | |
350 | } | |
351 | } | |
352 | ||
6395bed8 MT |
353 | sub get_red_interfaces() { |
354 | my $default = &General::get_red_interface(); | |
355 | ||
356 | my @intfs = ( | |
357 | $default, | |
358 | ); | |
359 | ||
360 | opendir(INTERFACES, "/sys/class/net"); | |
361 | ||
362 | while (my $intf = readdir(INTERFACES)) { | |
363 | if ($intf =~ m/^red[0-9]+$/) { | |
364 | push(@intfs, $intf); | |
365 | } | |
366 | } | |
367 | ||
368 | closedir(INTERFACES); | |
369 | ||
370 | return &General::uniq(@intfs); | |
371 | } | |
372 | ||
45b1fc5c MT |
373 | sub list_wireless_interfaces() { |
374 | my %interfaces = (); | |
375 | ||
376 | opendir(INTERFACES, "/sys/class/net"); | |
377 | ||
378 | my $intf; | |
379 | while ($intf = readdir(INTERFACES)) { | |
380 | # Is this a wireless interface? | |
381 | opendir(PHY80211, "/sys/class/net/$intf/phy80211") or next; | |
382 | closedir(PHY80211); | |
383 | ||
384 | # Read the MAC address | |
385 | my $address = &get_nic_property($intf, "address"); | |
386 | ||
387 | $interfaces{$address} = "$address ($intf)"; | |
388 | } | |
389 | ||
390 | closedir(INTERFACES); | |
391 | ||
392 | return %interfaces; | |
393 | } | |
394 | ||
c335b0cd MT |
395 | my %wireless_status = (); |
396 | ||
397 | sub _get_wireless_status($) { | |
398 | my $intf = shift; | |
399 | ||
400 | if (!$wireless_status{$intf}) { | |
b9a0d706 | 401 | $wireless_status{$intf} = join('\n', &General::system_output("iwconfig", "$intf")); |
c335b0cd MT |
402 | } |
403 | ||
404 | return $wireless_status{$intf}; | |
405 | } | |
406 | ||
407 | sub wifi_get_essid($) { | |
408 | my $status = &_get_wireless_status(shift); | |
409 | ||
410 | my ($essid) = $status =~ /ESSID:\"(.*)\"/; | |
411 | ||
412 | return $essid; | |
413 | } | |
414 | ||
415 | sub wifi_get_frequency($) { | |
416 | my $status = &_get_wireless_status(shift); | |
417 | ||
418 | my ($frequency) = $status =~ /Frequency:(\d+\.\d+ GHz)/; | |
419 | ||
420 | return $frequency; | |
421 | } | |
422 | ||
423 | sub wifi_get_access_point($) { | |
424 | my $status = &_get_wireless_status(shift); | |
425 | ||
426 | my ($access_point) = $status =~ /Access Point: ([0-9A-F:]+)/; | |
427 | ||
428 | return $access_point; | |
429 | } | |
430 | ||
431 | sub wifi_get_bit_rate($) { | |
432 | my $status = &_get_wireless_status(shift); | |
433 | ||
434 | my ($bit_rate) = $status =~ /Bit Rate=(\d+ [GM]b\/s)/; | |
435 | ||
436 | return $bit_rate; | |
437 | } | |
438 | ||
439 | sub wifi_get_link_quality($) { | |
440 | my $status = &_get_wireless_status(shift); | |
441 | ||
442 | my ($cur, $max) = $status =~ /Link Quality=(\d+)\/(\d+)/; | |
443 | ||
6dd084c2 LAH |
444 | if($max > 0) { |
445 | return sprintf('%.0f', ($cur * 100) / $max); | |
446 | } | |
447 | ||
448 | return 0; | |
c335b0cd MT |
449 | } |
450 | ||
451 | sub wifi_get_signal_level($) { | |
452 | my $status = &_get_wireless_status(shift); | |
453 | ||
454 | my ($signal_level) = $status =~ /Signal level=(\-\d+ dBm)/; | |
455 | ||
456 | return $signal_level; | |
457 | } | |
dbfd2622 MT |
458 | |
459 | sub get_hardware_address($) { | |
460 | my $ip_address = shift; | |
461 | my $ret; | |
462 | ||
463 | open(FILE, "/proc/net/arp") or die("Could not read ARP table"); | |
464 | ||
465 | while (<FILE>) { | |
466 | my ($ip_addr, $hwtype, $flags, $hwaddr, $mask, $device) = split(/\s+/, $_); | |
467 | if ($ip_addr eq $ip_address) { | |
468 | $ret = $hwaddr; | |
469 | last; | |
470 | } | |
471 | } | |
472 | ||
473 | close(FILE); | |
474 | ||
475 | return $ret; | |
476 | } | |
477 | ||
1dcf513a FB |
478 | sub get_nic_property { |
479 | my $nicname = shift; | |
480 | my $property = shift; | |
481 | my $result; | |
482 | ||
45b1fc5c | 483 | open(FILE, "/sys/class/net/$nicname/$property") or die("Could not read property $property for $nicname"); |
1dcf513a FB |
484 | $result = <FILE>; |
485 | close(FILE); | |
486 | ||
487 | chomp($result); | |
488 | ||
489 | return $result; | |
490 | } | |
491 | ||
492 | sub valid_mac($) { | |
493 | my $mac = shift; | |
494 | ||
495 | return $mac =~ /^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$/; | |
496 | } | |
497 | ||
92d8c1f7 LAH |
498 | # Compares two MAC addresses and returns true if they are equal |
499 | sub is_mac_equal { | |
500 | my $mac_1 = uc shift; # convert to upper case | |
501 | my $mac_2 = uc shift; | |
502 | ||
503 | if(valid_mac($mac_1) && valid_mac($mac_2) && ($mac_1 eq $mac_2)) { | |
504 | return 1; | |
505 | } | |
506 | ||
507 | return 0; | |
508 | } | |
509 | ||
1dcf513a FB |
510 | sub random_mac { |
511 | my $address = "02"; | |
512 | ||
513 | for my $i (0 .. 4) { | |
514 | $address = sprintf("$address:%02x", int(rand(255))); | |
515 | } | |
516 | ||
517 | return $address; | |
518 | } | |
519 | ||
520 | sub get_mac_by_name($) { | |
521 | my $mac = shift; | |
522 | ||
523 | if ((!&valid_mac($mac)) && ($mac ne "")) { | |
524 | if (-e "/sys/class/net/$mac/") { | |
525 | $mac = get_nic_property($mac, "address"); | |
526 | } | |
527 | } | |
528 | ||
529 | return $mac; | |
530 | } | |
531 | ||
45b1fc5c MT |
532 | sub get_intf_by_address($) { |
533 | my $address = shift; | |
534 | ||
535 | opendir(INTERFACES, "/sys/class/net"); | |
536 | ||
537 | while (my $intf = readdir(INTERFACES)) { | |
538 | next if ($intf eq "." or $intf eq ".."); | |
539 | ||
540 | my $intf_address = &get_nic_property($intf, "address"); | |
541 | ||
542 | # Skip interfaces without addresses | |
543 | next if ($intf_address eq ""); | |
544 | ||
545 | # Return a match | |
546 | return $intf if ($intf_address eq $address); | |
547 | } | |
548 | ||
549 | closedir(INTERFACES); | |
550 | ||
551 | return undef; | |
552 | } | |
553 | ||
abffcc99 LAH |
554 | # |
555 | ## Function to get a list of all available network zones. | |
556 | # | |
557 | sub get_available_network_zones () { | |
abffcc99 | 558 | # Obtain the configuration type from the netsettings hash. |
eea288bc | 559 | my $config_type = $ethernet_settings{'CONFIG_TYPE'}; |
abffcc99 LAH |
560 | |
561 | # Hash which contains the conversation from the config mode | |
562 | # to the existing network interface names. They are stored like | |
563 | # an array. | |
564 | # | |
565 | # Mode "0" red is a modem and green | |
566 | # Mode "1" red is a netdev and green | |
567 | # Mode "2" red, green and orange | |
568 | # Mode "3" red, green and blue | |
569 | # Mode "4" red, green, blue, orange | |
570 | my %config_type_to_interfaces = ( | |
571 | "0" => [ "red", "green" ], | |
572 | "1" => [ "red", "green" ], | |
573 | "2" => [ "red", "green", "orange" ], | |
574 | "3" => [ "red", "green", "blue" ], | |
575 | "4" => [ "red", "green", "blue", "orange" ] | |
576 | ); | |
577 | ||
578 | # Obtain and dereference the corresponding network interaces based on the read | |
579 | # network config type. | |
580 | my @network_zones = @{ $config_type_to_interfaces{$config_type} }; | |
581 | ||
582 | # Return them. | |
583 | return @network_zones; | |
584 | } | |
585 | ||
eea288bc LAH |
586 | # |
587 | ## Function to check if a network zone is available in the current configuration | |
588 | # | |
589 | sub is_zone_available() { | |
590 | my $zone = lc shift; | |
591 | ||
592 | # Make sure the zone is valid | |
593 | die("Unknown network zone '$zone'") unless ($zone ~~ @known_network_zones); | |
594 | ||
595 | # Get available zones and return result | |
596 | my @available_zones = get_available_network_zones(); | |
597 | return ($zone ~~ @available_zones); | |
598 | } | |
599 | ||
600 | # | |
601 | ## Function to determine if the RED zone is in standard IP (or modem, PPP, VDSL, ...) mode | |
602 | # | |
603 | sub is_red_mode_ip() { | |
604 | # Obtain the settings from the netsettings hash | |
605 | my $config_type = $ethernet_settings{'CONFIG_TYPE'}; | |
606 | my $red_type = $ethernet_settings{'RED_TYPE'}; | |
607 | ||
608 | # RED must be a network device (configuration 1-4) with dynamic or static IP | |
609 | return (($config_type ~~ [1..4]) && ($red_type ~~ ["DHCP", "STATIC"])); | |
610 | } | |
611 | ||
4e9a2b57 MT |
612 | 1; |
613 | ||
614 | # Remove the next line to enable the testsuite | |
615 | __END__ | |
616 | ||
cc9eb2d3 PM |
617 | sub assert($$) { |
618 | my $tst = shift; | |
4e9a2b57 MT |
619 | my $ret = shift; |
620 | ||
621 | if ($ret) { | |
622 | return; | |
623 | } | |
624 | ||
cc9eb2d3 | 625 | print "ASSERTION ERROR - $tst\n"; |
4e9a2b57 MT |
626 | exit(1); |
627 | } | |
628 | ||
629 | sub testsuite() { | |
630 | my $result; | |
631 | ||
632 | my $address1 = &ip2bin("8.8.8.8"); | |
cc9eb2d3 | 633 | assert('ip2bin("8.8.8.8")', $address1 == 134744072); |
4e9a2b57 MT |
634 | |
635 | my $address2 = &bin2ip($address1); | |
cc9eb2d3 | 636 | assert("bin2ip($address1)", $address2 eq "8.8.8.8"); |
4e9a2b57 MT |
637 | |
638 | # Check if valid IP addresses are correctly recognised. | |
639 | foreach my $address ("1.2.3.4", "192.168.180.1", "127.0.0.1") { | |
640 | if (!&check_ip_address($address)) { | |
641 | print "$address is not correctly recognised as a valid IP address!\n"; | |
642 | exit 1; | |
643 | }; | |
644 | } | |
645 | ||
646 | # Check if invalid IP addresses are correctly found. | |
647 | 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") { | |
648 | if (&check_ip_address($address)) { | |
649 | print "$address is recognised as a valid IP address!\n"; | |
650 | exit 1; | |
651 | }; | |
652 | } | |
653 | ||
654 | $result = &check_ip_address_and_netmask("192.168.180.0/255.255.255.0"); | |
cc9eb2d3 | 655 | assert('check_ip_address_and_netmask("192.168.180.0/255.255.255.0")', $result); |
4e9a2b57 MT |
656 | |
657 | $result = &convert_netmask2prefix("255.255.254.0"); | |
cc9eb2d3 | 658 | assert('convert_netmask2prefix("255.255.254.0")', $result == 23); |
4e9a2b57 MT |
659 | |
660 | $result = &convert_prefix2netmask(8); | |
cc9eb2d3 | 661 | assert('convert_prefix2netmask(8)', $result eq "255.0.0.0"); |
4e9a2b57 MT |
662 | |
663 | $result = &find_next_ip_address("1.2.3.4", 2); | |
cc9eb2d3 | 664 | assert('find_next_ip_address("1.2.3.4", 2)', $result eq "1.2.3.6"); |
4e9a2b57 | 665 | |
3713af1e | 666 | $result = &network_equal("192.168.0.0/24", "192.168.0.0/255.255.255.0"); |
cc9eb2d3 | 667 | assert('network_equal("192.168.0.0/24", "192.168.0.0/255.255.255.0")', $result); |
3713af1e MT |
668 | |
669 | $result = &network_equal("192.168.0.0/24", "192.168.0.0/25"); | |
cc9eb2d3 | 670 | assert('network_equal("192.168.0.0/24", "192.168.0.0/25")', !$result); |
3713af1e MT |
671 | |
672 | $result = &network_equal("192.168.0.0/24", "192.168.0.128/25"); | |
cc9eb2d3 | 673 | assert('network_equal("192.168.0.0/24", "192.168.0.128/25")', !$result); |
3713af1e MT |
674 | |
675 | $result = &network_equal("192.168.0.1/24", "192.168.0.XXX/24"); | |
cc9eb2d3 | 676 | assert('network_equal("192.168.0.1/24", "192.168.0.XXX/24")', !$result); |
3713af1e | 677 | |
4e9a2b57 | 678 | $result = &ip_address_in_network("10.0.1.4", "10.0.0.0/8"); |
cc9eb2d3 | 679 | assert('ip_address_in_network("10.0.1.4", "10.0.0.0/8"', $result); |
4e9a2b57 | 680 | |
01d61d15 | 681 | $result = &ip_address_in_network("192.168.30.11", "192.168.30.0/255.255.255.0"); |
cc9eb2d3 PM |
682 | assert('ip_address_in_network("192.168.30.11", "192.168.30.0/255.255.255.0")', $result); |
683 | ||
684 | $result = &ip_address_in_network("192.168.30.11", "0.0.0.0/8"); | |
685 | assert('ip_address_in_network("192.168.30.11", "0.0.0.0/8")', !$result); | |
01d61d15 | 686 | |
b52a84dd AB |
687 | $result = &ip_address_in_range("192.168.30.11", "192.168.30.10", "192.168.30.20"); |
688 | assert('ip_address_in_range("192.168.30.11", "192.168.30.10", "192.168.30.20")', $result); | |
689 | ||
690 | $result = &ip_address_in_range("192.168.30.21", "192.168.30.10", "192.168.30.20"); | |
691 | assert('ip_address_in_range("192.168.30.21", "192.168.30.10", "192.168.30.20")', !$result); | |
692 | ||
3713af1e MT |
693 | print "Testsuite completed successfully!\n"; |
694 | ||
4e9a2b57 MT |
695 | return 0; |
696 | } | |
697 | ||
698 | &testsuite(); |