<%attr> title => 'ipv6 visualization' section => 'Management' % % %####################################################################### %# %# Args section %# %####################################################################### <%args> $input_addrs => undef $parent_addr_id => 0 $old_prefix => 0 $prefix => 0 $new_addr => undef $new_prefix => undef $new_parent => undef $create_addr => undef $create_prefix => undef $create_parent => undef @old_ipblock_array => undef <%init> use Data::Dumper; use Netdot::IPVisual; use bigint; my @ipblock_array; my @input_addresses = (); my @input_sub = (); my $min_prefix = 0; my $prefix_addr = 0; my $n_addr_bits = 128; if($create_addr){ my $new_parent_id; #we are inserting a new address block eval{ $new_parent_id = Ipblock->insert({address=>$create_addr, prefix=>$create_prefix, parent=>$create_parent}); }; if($@){ # && $@ != "Error while inserting Ipblock: Some values are duplicated."){ print "$@"; return; } # else{ #actually it looks like all of this is handled already by netdot, how convient! # #since we can assume the new block was sucessfully made, we'll now need to update the parent fields # #of all of the containers in @old_ipblock_array, since we've inserted a container infront of them and their # #old parent # if(scalar @old_ipblock_array > 0){ # for my $ip (@old_ipblock_array){ # #Ipblock->retrieve({id => $ip})->parent = $new_parent_id; # } # } # } } #we're displaying only the root addresses in this case, which means we look at the entire address range if(!$input_addrs && !$new_addr){ print "Displaying Addresses ".Ipblock->int2ip(0,6)." to ".Ipblock->int2ip(2 ** 16 -1 << (128-16),6)."
"; @ipblock_array = Ipblock->get_roots(6); } #we're displaying a specific address and prefix elsif($new_addr && $new_prefix){ $prefix_addr = Ipblock->ip2int($new_addr, 6); $prefix = $new_prefix; $parent_addr_id = $new_parent; print generate_addr_range($prefix, $prefix_addr, $n_addr_bits); } #we have input address(es) else{ my @parent_array = split(" ", $input_addrs); foreach my $p (@parent_array){ push(@input_addresses, Ipblock->retrieve(id => $p)); } #If we only have 1 parent_address, we can look at its children if(scalar @parent_array == 1){ #we just have 1 parent. This means we clicked on a section of the tree that contained #a single subnet. We will get all of the children in this subnet and display them #we should set the prefix address to the parent $prefix_addr = ($input_addresses[0]->address_numeric+0); $prefix = ($input_addresses[0]->prefix+0); my $child_iter = Ipblock->search(parent => $parent_array[0]); #ipblock_array will hold the children we want to display while(my $c = $child_iter->next){ push(@ipblock_array, $c); } #if we only have 1 input address, then we want to look at its children $parent_addr_id = $input_addresses[0]->id + 0; } #if we have two parent addresses, that means the user clicked on a section of the quad #tree that contained two subnets. We must "drill down" into the quad tree before the subnets #can be distinguished. This can be overridden by supplying a prefix value in the url argument else{ foreach my $i (@input_addresses){ push(@ipblock_array, $i); } my $temp_prefix = 0; for(my $i = 1; $i < 128; $i++){ if($prefix){ last; } my $temp = 1 << (128 - $i); my $all_zeros = 1; my $all_ones = 1; foreach my $addr (@input_addresses){ if(($addr->address_numeric + 0) & $temp){ #the bit we are at is a '1', this means we flip off the all_zeros #variable since it can't possibly be all zeros $all_zeros = 0; } else{ #the bit we are at is a '0', this means we flip off the all_ones #variable since it can't possibly be all ones $all_ones = 0; } } if(!($all_zeros | $all_ones)){ last; } else{ $temp_prefix += 1; } } if(!$prefix){ $prefix = $temp_prefix; } #since the prefix must be even we need to do a bit of formatting here if($prefix == 1){ $prefix = 0; } elsif($prefix % 2 != 0){ $prefix -= 1; } #since we're positive that the first $prefix number of bits in all of the addresses #we are considering are the same, we can just take the first $prefix number of bits #from the first address in @input_addresses. $prefix_addr = (($input_addresses[0]->address_numeric+0) >> (128-$prefix) << (128-$prefix)); }#end else print generate_addr_range($prefix, $prefix_addr, $n_addr_bits); } if($prefix_addr && !Ipblock->search({address=>$prefix_addr, prefix=>$prefix})->first){ my $subnet_name = get_subnet_name($prefix, $prefix_addr, $n_addr_bits); print qq[ ]; } my $htmlz = Netdot::IPVisual->create_tree( \@ipblock_array, 16, 1024, $prefix, $prefix_addr, $n_addr_bits, $parent_addr_id, "/netdot/management/ipv6.html" ); print $htmlz; sub get_subnet_name{ my ($prefix, $prefix_addr, $n_addr_bits) = @_; my $subnet_size = 128 - $n_addr_bits + $prefix; my $current_subnet = Ipblock->int2ip($prefix_addr,6)."/".$subnet_size; return $current_subnet; } sub generate_addr_range{ my ($prefix, $prefix_addr, $n_addr_bits) = @_; my $lower_range = $prefix_addr; my $upper_range_bit_mask = 65535 << (128 - $prefix - 16); my $upper_range = $lower_range | $upper_range_bit_mask; my $subnet_size = 128 - $n_addr_bits + $prefix; my $current_subnet = get_subnet_name($prefix, $prefix_addr, $n_addr_bits); return "
Displaying $current_subnet
Addresses ".Ipblock->int2ip($lower_range,6)." to ".Ipblock->int2ip($upper_range, 6)."
"; } sub num_bits{ my ($num) = @_; my $b = 0; while($num > (2 ** $b)){ $b++; } return $b; }