Net-Libdnet6-0.27000755001750001750 012462230514 13265 5ustar00gomorgomor000000000000Net-Libdnet6-0.27/MANIFEST000444001750001750 64312462230514 14536 0ustar00gomorgomor000000000000Build.PL Changes examples/addr_net6.pl examples/intf_get6.pl examples/intf_get_dst6.pl examples/route_get6.pl lib/Net/Libdnet6.pm LICENSE LICENSE.Artistic Makefile.PL MANIFEST This list of files README t/01-use.t t/02-test-pod.t t/03-pod-coverage.t META.yml Module YAML meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker) Net-Libdnet6-0.27/README000444001750001750 73112462230514 14263 0ustar00gomorgomor000000000000Net::Libdnet6 ============= INSTALLATION To install this module type the following: perl Makefile.PL make make test make install DEPENDENCIES This module requires these other modules and libraries: Perl v5.6.1 Net::Libdnet Net::IPv6Addr COPYRIGHT AND LICENSE You may distribute this module under the terms of the Artistic license. See LICENSE.Artistic file in the source distribution archive. Copyright (c) 2006-2015, Patrice Auffret Net-Libdnet6-0.27/Makefile.PL000444001750001750 66212462230514 15360 0ustar00gomorgomor000000000000# # $Id: Makefile.PL 2005 2015-01-28 18:59:42Z gomor $ # use ExtUtils::MakeMaker; require v5.6.1; WriteMakefile( NAME => 'Net::Libdnet6', LICENSE => 'artistic', VERSION_FROM => 'lib/Net/Libdnet6.pm', ABSTRACT_FROM => 'lib/Net/Libdnet6.pm', AUTHOR => 'GomoR ', PREREQ_PM => { Net::Libdnet => 0, Net::IPv6Addr => 0, }, MIN_PERL_VERSION => '5.6.1', ); Net-Libdnet6-0.27/Build.PL000444001750001750 75512462230514 14705 0ustar00gomorgomor000000000000# # $Id: Build.PL 2005 2015-01-28 18:59:42Z gomor $ # use strict; use warnings; use Module::Build; my $builder = Module::Build->new( module_name => 'Net::Libdnet6', license => 'artistic', dist_author => 'GomoR ', dist_version_from => 'lib/Net/Libdnet6.pm', requires => { 'perl' => '5.6.1', 'Net::Libdnet' => '0', 'Net::IPv6Addr' => '0', }, configure_requires => { 'Module::Build' => 0, }, ); $builder->create_build_script; Net-Libdnet6-0.27/LICENSE000444001750001750 26512462230514 14412 0ustar00gomorgomor000000000000LICENSE This program is free software. You can redistribute it and/or modify it under the following terms: - the Perl Artistic License (in the file LICENSE.Artistic), Net-Libdnet6-0.27/Changes000444001750001750 200112462230514 14706 0ustar00gomorgomor000000000000Revision history for Perl extension Net::Libdnet6. 0.27 Wed Jan 28 19:57:50 CET 2015 - bugfix: finding default route under FreeBSD > 9.x systems - update: copyright notice 0.26 Fri Nov 16 16:37:22 CET 2012 - bugfix: Perl kwalitee 0.25 Wed Sep 12 20:21:04 CEST 2012 - bugfix: on finding the default gateway IPv6 on BSD systems - update: error message scheme - update: copyright notice 0.24 Thu Jan 13 11:09:35 CET 2011 - bugfix: parsing of ifconfig for recent Linux systems - bugfix: in auto-search for good network infertace - update: copyright notice 0.23 Tue Mar 13 21:01:07 CET 2007 - bugfix: removed a nasty warning on IPv6 address gathering 0.22 Sun Feb 4 15:21:02 CET 2007 - bugfix: when a route has no IPv6 address, skip it 0.21 Thu Dec 28 17:13:47 CET 2006 - error checking patchs 0.20 Thu Dec 28 11:02:24 CET 2006 - NEW: route_get6() - better support for *BSD systems - all subs now ends with '6' - exports Net::Libdnet subs 0.10 - first public release Net-Libdnet6-0.27/META.yml000444001750001750 114512462230514 14674 0ustar00gomorgomor000000000000--- abstract: 'adds IPv6 support to Net::Libdnet' author: - 'GomoR ' build_requires: {} configure_requires: Module::Build: '0' dynamic_config: 1 generated_by: 'Module::Build version 0.421, CPAN::Meta::Converter version 2.143240' license: artistic meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Net-Libdnet6 provides: Net::Libdnet6: file: lib/Net/Libdnet6.pm version: '0.27' requires: Net::IPv6Addr: '0' Net::Libdnet: '0' perl: v5.6.1 resources: license: http://opensource.org/licenses/artistic-license.php version: '0.27' Net-Libdnet6-0.27/META.json000444001750001750 167112462230514 15050 0ustar00gomorgomor000000000000{ "abstract" : "adds IPv6 support to Net::Libdnet", "author" : [ "GomoR " ], "dynamic_config" : 1, "generated_by" : "Module::Build version 0.421", "license" : [ "artistic_1" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "Net-Libdnet6", "prereqs" : { "configure" : { "requires" : { "Module::Build" : "0" } }, "runtime" : { "requires" : { "Net::IPv6Addr" : "0", "Net::Libdnet" : "0", "perl" : "v5.6.1" } } }, "provides" : { "Net::Libdnet6" : { "file" : "lib/Net/Libdnet6.pm", "version" : "0.27" } }, "release_status" : "stable", "resources" : { "license" : [ "http://opensource.org/licenses/artistic-license.php" ] }, "version" : "0.27" } Net-Libdnet6-0.27/LICENSE.Artistic000444001750001750 1373412462230514 16240 0ustar00gomorgomor000000000000 The "Artistic License" Preamble The intent of this document is to state the conditions under which a Package may be copied, such that the Copyright Holder maintains some semblance of artistic control over the development of the package, while giving the users of the package the right to use and distribute the Package in a more-or-less customary fashion, plus the right to make reasonable modifications. Definitions: "Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through textual modification. "Standard Version" refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright Holder as specified below. "Copyright Holder" is whoever is named in the copyright or copyrights for the package. "You" is you, if you're thinking about copying or distributing this Package. "Reasonable copying fee" is whatever you can justify on the basis of media cost, duplication charges, time of people involved, and so on. (You will not be required to justify it to the Copyright Holder, but only to the computing community at large as a market that must bear the fee.) "Freely Available" means that no fee is charged for the item itself, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they received it. 1. You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may apply bug fixes, portability fixes and other modifications derived from the Public Domain or from the Copyright Holder. A Package modified in such a way shall still be considered the Standard Version. 3. You may otherwise modify your copy of this Package in any way, provided that you insert a prominent notice in each changed file stating how and when you changed that file, and provided that you do at least ONE of the following: a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or placing the modifications on a major archive site such as uunet.uu.net, or by allowing the Copyright Holder to include your modifications in the Standard Version of the Package. b) use the modified Package only within your corporation or organization. c) rename any non-standard executables so the names do not conflict with standard executables, which must also be provided, and provide a separate manual page for each non-standard executable that clearly documents how it differs from the Standard Version. d) make other distribution arrangements with the Copyright Holder. 4. You may distribute the programs of this Package in object code or executable form, provided that you do at least ONE of the following: a) distribute a Standard Version of the executables and library files, together with instructions (in the manual page or equivalent) on where to get the Standard Version. b) accompany the distribution with the machine-readable source of the Package with your modifications. c) give non-standard executables non-standard names, and clearly document the differences in manual pages (or equivalent), together with instructions on where to get the Standard Version. d) make other distribution arrangements with the Copyright Holder. 5. You may charge a reasonable copying fee for any distribution of this Package. You may charge any fee you choose for support of this Package. You may not charge a fee for this Package itself. However, you may distribute this Package in aggregate with other (possibly commercial) programs as part of a larger (possibly commercial) software distribution provided that you do not advertise this Package as a product of your own. You may embed this Package's interpreter within an executable of yours (by linking); this shall be construed as a mere form of aggregation, provided that the complete Standard Version of the interpreter is so embedded. 6. The scripts and library files supplied as input to or produced as output from the programs of this Package do not automatically fall under the copyright of this Package, but belong to whoever generated them, and may be sold commercially, and may be aggregated with this Package. If such scripts or library files are aggregated with this Package via the so-called "undump" or "unexec" methods of producing a binary executable image, then distribution of such an image shall neither be construed as a distribution of this Package nor shall it fall under the restrictions of Paragraphs 3 and 4, provided that you do not represent such an executable image as a Standard Version of this Package. 7. C subroutines (or comparably compiled subroutines in other languages) supplied by you and linked into this Package in order to emulate subroutines and variables of the language defined by this Package shall not be considered part of this Package, but are the equivalent of input as in Paragraph 6, provided these subroutines do not change the language in any way that would cause it to fail the regression tests for the language. 8. Aggregation of this Package with a commercial distribution is always permitted provided that the use of this Package is embedded; that is, when no overt attempt is made to make this Package's interfaces visible to the end user of the commercial distribution. Such use shall not be construed as a distribution of this Package. 9. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. 10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. The End Net-Libdnet6-0.27/lib000755001750001750 012462230514 14033 5ustar00gomorgomor000000000000Net-Libdnet6-0.27/lib/Net000755001750001750 012462230514 14561 5ustar00gomorgomor000000000000Net-Libdnet6-0.27/lib/Net/Libdnet6.pm000444001750001750 2556212462230514 16755 0ustar00gomorgomor000000000000# # $Id: Libdnet6.pm 2005 2015-01-28 18:59:42Z gomor $ # package Net::Libdnet6; use strict; use warnings; our $VERSION = '0.27'; use base qw(Exporter); # We also export Net::Libdnet subs (those without 6 at the end) our @EXPORT = qw( addr_cmp6 addr_bcast6 addr_net6 arp_add6 arp_delete6 arp_get6 intf_get6 intf_get_src6 intf_get_dst6 intf_set6 route_add6 route_delete6 route_get6 addr_cmp addr_bcast addr_net arp_add arp_delete arp_get intf_get intf_get_src intf_get_dst intf_set route_add route_delete route_get ); use Net::Libdnet; use Net::IPv6Addr; my $_pathIfconfig; my $_pathNetstat; BEGIN { sub _getPathIfconfig { my @pathList = qw( /sbin/ifconfig /usr/sbin/ifconfig /bin/ifconfig /usr/bin/ifconfig ); for (@pathList) { (-f $_) && ($_pathIfconfig = $_) && return 1; } return; } sub _getPathNetstat { my @pathList = qw( /bin/netstat /usr/bin/netstat /sbin/netstat /usr/sbin/netstat ); for (@pathList) { (-f $_) && ($_pathNetstat = $_) && return 1; } return; } my $osname = { linux => [ \&_get_routes_linux, ], freebsd => [ \&_get_routes_bsd, ], openbsd => [ \&_get_routes_bsd, ], netbsd => [ \&_get_routes_bsd, ], darwin => [ \&_get_routes_bsd, ], }; *_get_routes = $osname->{$^O}->[0] || \&_get_routes_other; # XXX: No support under Windows for now unless ($^O =~ /mswin32|cygwin/i) { _getPathIfconfig() or die("[-] ".__PACKAGE__.": Unable to find ifconfig command\n"); _getPathNetstat() or die("[-] ".__PACKAGE__.": Unable to find netstat command\n"); } } sub arp_add6 { die("[-] ".__PACKAGE__.": arp_add6: Not supported\n") } sub arp_delete6 { die("[-] ".__PACKAGE__.": arp_delete6: Not supported\n") } sub arp_get6 { die("[-] ".__PACKAGE__.": arp_get6: Not supported\n") } sub intf_set6 { die("[-] ".__PACKAGE__.": intf_set6: Not supported\n") } sub intf_get_src6 { die("[-] ".__PACKAGE__.": intf_get_src6: Not supported\n") } sub route_add6 { die("[-] ".__PACKAGE__.": route_add6: Not supported\n") } sub route_delete6 { die("[-] ".__PACKAGE__.": route_delete6: Not supported\n") } sub addr_cmp6 { die("[-] ".__PACKAGE__.": addr_cmp6: Not supported\n") } sub addr_bcast6 { die("[-] ".__PACKAGE__.": addr_bcast6: Not supported\n") } sub _to_string_preferred { Net::IPv6Addr->new(shift())->to_string_preferred } sub _to_string_compressed { Net::IPv6Addr->new(shift())->to_string_compressed } sub addr_net6 { my $ip6 = shift; confess('Usage: addr_net6("$ipv6Address/$prefixlen")'."\n") if (! $ip6 || $ip6 !~ /\/\d+/); my ($ip, $mask) = split('/', $ip6); $ip = _to_string_preferred($ip); $mask /= 8; # Convert to number of bytes my $subnet; my $count = 0; for (split(':', $ip)) { if ($count < $mask) { $subnet .= $_.':'; $count += 2; # Each element takes two bytes } else { $subnet .= '0:'; } } $subnet =~ s/:$//; return _to_string_compressed($subnet); } sub _get_ip6 { my $dev = shift; return unless $_pathIfconfig; my $buf = `$_pathIfconfig $dev 2> /dev/null`; return unless $buf; my @ip6 = (); for (split('\n', $buf)) { my $prefixLenFound; my $lastIp6; for (split(/\s+/)) { s/(?:%[a-z0-9]+)$//; # This removes %lnc0 on BSD systems # Some Linux systems do not put the prefix with /number if (/^[0-9a-f:]+$/i && Net::IPv6Addr::is_ipv6($_)) { $lastIp6 = lc($_); } # Some newer Linux systems do it elsif (/^[0-9a-f:]+\/(\d+)$/i && Net::IPv6Addr::is_ipv6($_)) { $lastIp6 = lc($_); } # Gather prefixlen on *BSD systems if (/^\d+$/ && $prefixLenFound) { $lastIp6 .= '/'.$_; --$prefixLenFound; } ++$prefixLenFound if /^prefixlen$/i; } push @ip6, $lastIp6 if $lastIp6; } # We return the first IP as the main address, others as aliases if (@ip6 > 1) { return $ip6[0], [ @ip6[1..$#ip6] ]; } elsif (@ip6 == 1) { return $ip6[0]; } return; } sub intf_get6 { my $dev = shift; confess('Usage: intf_get6($networkInterface)'."\n") unless $dev; my $dnet = intf_get($dev) or return; my ($ip, $aliases) = _get_ip6($dev); $dnet->{addr6} = $ip if $ip; $dnet->{aliases6} = $aliases if $aliases; return $dnet; } # XXX: not supported yet sub _get_routes_other { return; } sub _get_routes_linux { return unless $_pathNetstat; my $buf = `$_pathNetstat -rnA inet6 2> /dev/null`; return unless $buf; my @ifRoutes = (); my %devIps; for (split('\n', $buf)) { my @elts = split(/\s+/); if ($elts[0]) { if ($elts[0] eq '::/0') { # Default route my $route = { destination => 'default', interface => $elts[-1], }; if (Net::IPv6Addr::is_ipv6($elts[1])) { $route->{nextHop} = $elts[1]; } push @ifRoutes, $route; } elsif (Net::IPv6Addr::is_ipv6($elts[0])) { my $route = { destination => $elts[0], interface => $elts[-1], }; if (Net::IPv6Addr::is_ipv6($elts[1])) { $route->{nextHop} = $elts[1]; } push @ifRoutes, $route; } } } if (@ifRoutes > 1) { return \@ifRoutes; } return; } sub _get_routes_bsd { return unless $_pathNetstat; my $buf = `$_pathNetstat -rnf inet6 2> /dev/null`; return unless $buf; my @ifRoutes = (); my %devIps; for (split('\n', $buf)) { my @elts = split(/\s+/); my $destination = $elts[0] || undef; my $gateway = $elts[1] || undef; my $flags = $elts[2] || undef; my $if = $elts[3] || undef; if (defined($destination)) { $destination =~ s/%[a-z]+[0-9]+//; } if (defined($gateway)) { $gateway =~ s/%[a-z]+[0-9]+//; } next if ! defined($destination); # FreeBSD > 9.x has a new scheme for default routes: # it uses the MAC address of default interface if ($gateway && $gateway =~ /^[a-z0-9]{2}:[a-z0-9]{2}:[a-z0-9]{2}:[a-z0-9]{2}:[a-z0-9]{2}:[a-z0-9]{2}$/i) { my $route = { destination => 'default', interface => $if, }; if (Net::IPv6Addr::is_ipv6($elts[1])) { $route->{nextHop} = $destination; } push @ifRoutes, $route; } elsif (Net::IPv6Addr::is_ipv6($destination)) { my $route = { destination => $destination, interface => $if, }; if (Net::IPv6Addr::is_ipv6($gateway)) { $route->{nextHop} = $gateway; } push @ifRoutes, $route; } elsif ($destination eq 'default') { my $route = { destination => $destination, interface => $if, }; if (Net::IPv6Addr::is_ipv6($gateway)) { $route->{nextHop} = $gateway; } push @ifRoutes, $route; } } if (@ifRoutes > 1) { return \@ifRoutes; } return; } sub _is_in_network { my ($src, $net, $mask) = @_; my $net1 = addr_net6($src.'/'.$mask); my $net2 = addr_net6($net.'/'.$mask); return $net1 eq $net2; } sub intf_get_dst6 { my $dst = shift; confess('Usage: intf_get_dst6($targetIpv6Address)'."\n") unless $dst; $dst = _to_string_preferred($dst); my $routes = _get_routes() or return; # Search network device list for target6 my @devList = (); for my $r (@$routes) { my ($net, $mask) = split('/', $r->{destination}); # If the route is unicast, stop here unless ($mask) { if ($dst eq $r->{destination}) { push @devList, $r->{interface}; last; } } else { $net = _to_string_preferred($net); if (_is_in_network($dst, $net, $mask)) { push @devList, $r->{interface}; } } } my @devs; if (@devList > 0) { @devs = map { intf_get6($_) } @devList; } else { # Not on same network, should use default gw for my $r (@$routes) { if ($r->{destination} eq 'default') { push @devs, intf_get6($r->{interface}); } } } return unless @devs > 0; # Now, search the correct source IP, if multiple found my @finalDevs = (); for (@devs) { # Skip if interface has no IPv6 address next unless exists $_->{addr6}; # If it has multiple IPv6 address, choose the good one if (exists $_->{aliases6}) { my @ipList = ( $_->{addr6}, @{$_->{aliases6}} ); for my $i (@ipList) { my ($net, $mask) = split('/', $i); if (_is_in_network($dst, $net, $mask)) { my @ipNotMain = grep {!/^$i$/} @ipList; $_->{addr6} = $i; $_->{aliases6} = \@ipNotMain; } } } if ($_->{name} =~ /^lo\d*$/ && $dst !~ /^0:0:0:0:0:0:0:1$/) { next; } push @finalDevs, $_; } wantarray ? @finalDevs : $finalDevs[0]; } sub _search_next_hop { my $dev = shift; my ($dst, $hops) = @_; return unless exists $dev->{addr6}; my ($net, $mask) = split('/', $dev->{addr6}); for my $h (@$hops) { if (! _is_in_network($dst, $net, $mask)) { for my $i ($dev->{addr6}, @{$dev->{aliases6}}) { my ($iNet, $iMask) = split('/', $i); if (_is_in_network($h, $iNet, $iMask)) { return $h; } } } } return; } sub route_get6 { my $dst = shift; confess('Usage: route_get6($targetIpv6Address)'."\n") unless $dst; $dst = _to_string_preferred($dst); my @devs = intf_get_dst6($dst) or return; return unless @devs > 0; my @nextHops = (); my $routes = _get_routes() or return; for my $r (@$routes) { push @nextHops, $r->{nextHop} if $r->{nextHop}; } return unless @nextHops > 0; my $nextHop; for my $d (@devs) { $nextHop = _search_next_hop($d, $dst, \@nextHops); } return $nextHop; } 1; __END__ =head1 NAME Net::Libdnet6 - adds IPv6 support to Net::Libdnet =head1 DESCRIPTION =head1 SUBROUTINES =over 4 =item B =item B =item B =item B =item B =item B =item B =item B =item B =item B =item B =item B =item B =back =head1 SEE ALSO L =head1 AUTHOR Patrice EGomoRE Auffret =head1 COPYRIGHT AND LICENSE Copyright (c) 2006-2015, Patrice EGomoRE Auffret You may distribute this module under the terms of the Artistic license. See LICENSE.Artistic file in the source distribution archive. =cut Net-Libdnet6-0.27/t000755001750001750 012462230514 13530 5ustar00gomorgomor000000000000Net-Libdnet6-0.27/t/03-pod-coverage.t000444001750001750 27412462230514 16630 0ustar00gomorgomor000000000000eval "use Test::Pod::Coverage tests => 1"; if ($@) { use Test; plan(tests => 1); skip("Test::Pod::Coverage required for testing"); } else { pod_coverage_ok("Net::Libdnet6"); } Net-Libdnet6-0.27/t/02-test-pod.t000444001750001750 23112462230514 16004 0ustar00gomorgomor000000000000eval "use Test::Pod 1.00"; if ($@) { use Test; plan(tests => 1); skip("Test::Pod 1.00 required for testing"); } else { all_pod_files_ok(); } Net-Libdnet6-0.27/t/01-use.t000444001750001750 10112462230514 15034 0ustar00gomorgomor000000000000use Test; BEGIN { plan(tests => 1) } use Net::Libdnet6; ok(1); Net-Libdnet6-0.27/examples000755001750001750 012462230514 15103 5ustar00gomorgomor000000000000Net-Libdnet6-0.27/examples/intf_get_dst6.pl000444001750001750 41412462230514 20313 0ustar00gomorgomor000000000000#!/usr/bin/perl use strict; use warnings; my $dst = shift || die("Specify target host\n"); use Net::Frame::Layer qw(:subs); $dst = getHostIpv6Addr($dst) or die("Lookup\n"); use Data::Dumper; use Net::Libdnet6; my @h = intf_get_dst6($dst); print Dumper(\@h)."\n"; Net-Libdnet6-0.27/examples/intf_get6.pl000444001750001750 27112462230514 17442 0ustar00gomorgomor000000000000#!/usr/bin/perl use strict; use warnings; my $dev = shift || die("Specify network interface\n"); use Data::Dumper; use Net::Libdnet6; my $h = intf_get6($dev); print Dumper($h)."\n"; Net-Libdnet6-0.27/examples/route_get6.pl000444001750001750 41012462230514 17633 0ustar00gomorgomor000000000000#!/usr/bin/perl use strict; use warnings; my $dst = shift || die("Specify target host\n"); use Net::Frame::Layer qw(:subs); $dst = getHostIpv6Addr($dst) or die("Lookup\n"); use Data::Dumper; use Net::Libdnet6; my $h = route_get6($dst); print Dumper($h)."\n"; Net-Libdnet6-0.27/examples/addr_net6.pl000444001750001750 16412462230514 17424 0ustar00gomorgomor000000000000#!/usr/bin/perl use strict; use warnings; use Net::Libdnet6; print addr_net6("fe80::213:a9ff:fe2c:5ba3/64")."\n";