I am working on code, and trying to add ipv6 support. The following code is in the current code base for ipv4 support. The code takes a ipv4 ip address and gets the subnet mask for the address on a /32.
// string of ip address
networkInterface["ip_address"] = v.IpAddress[0]
m := net.CIDRMask(v.IpConfig.IpAddress[0].PrefixLength, 32)
subnetMask := net.IPv4(m[0], m[1], m[2], m[3])
networkInterface["subnet_mask"] = subnetMask.String()
I know that net.CIDRMask works with ipv6, I am uncertain how to use it with an ipv6 address.
I am now testing the ip address to determine if the address is ipv4 or ipv6:
testInput := net.ParseIP(v.IpAddress[0])
if testInput.To4() != nil {
// find ipv4 subnet mask
}
if testInput.To16() != nil {
// do ipv6 subnet mask
}
The unit tests for net.CIDRMask have examples working with ipv6 located here: https://golang.org/src/net/ip_test.go
But it is beyond both my golang experience and ipv6 knowledge.
While RTFM'ing the docs https://golang.org/pkg/net/#CIDRMask mention:
func CIDRMask(ones, bits int) IPMask
CIDRMask returns an IPMask consisting of `ones' 1 bits followed by 0s
up to a total length of `bits' bits. For a mask of this form, CIDRMask
is the inverse of IPMask.Size.
So what values do I use for ones and bits?
This is what is comming back from the api:
$ govc vm.info -json vcsa | jq .VirtualMachines[0].Guest.Net[0].IpConfig.IpAddress [ {
"IpAddress": "10.20.128.218",
"PrefixLength": 22,
"Origin": "",
"State": "preferred",
"Lifetime": null } ]
Thanks in advance!
I'm not sure what PrefixLength is, it may be some field defined in one of your structs, but it doesn't appear to be a field on anything in the net package, or in fact anywhere in the standard library: https://golang.org/search?q=PrefixLength.
So I'm not sure what PrefixLength is expected to give, but, I can tell you:
IPv4 addresses consist of 32 bits of data (256 x 256 x 256 x 256 total IPs), so when dealing with IPv4, the value for the bits argument to net.CIDRMask should be 32.
IPv4 addresses have 128 bits of data, so the bits argument is 128.
The subnet mask for a CIDR range corresponding to a single IP will have the maximum number of ones, so the ones value is 32 or 128, depending on whether you're talking IPv4 or IPv6.
Therefore, for IPv4, you should call net.CIDRMask(32, 32), and for IPv6, net.CIDRMask(128, 128). Since these will be the exact same calculations every time, you have the option to simply set the values up front as constants in your code. The correct values are:
For IPv4: https://golang.org/src/net/ip_test.go#L307
For IPv6: https://golang.org/src/net/ip_test.go#L311
Related
I'm currently experimenting with a little bash script.
I have an IPv6 address (via mysql query) in a variable and want to increment it by 1 (by also honoring the IPv6 rules [hex]). Any hint how to achieve this?
Is there a simple way in bash to increment a given address by 1? (this is to avoid duplicates).
Basically:
2001::0000:fe04 is given and I want the script to manipulate the variable to output 2001::0000:fe05, 2001::0000:fe06 and after 2001::0000:fe09 it should be 2001::0000:fe0a - 2001::0000:fe0f followed by 2001::0000:fe10 (hex count). If all ip's are full (2001::0:ffff) it should use the next IP subnet by honoring IPv6 subnetting.
So after 2001::0:ffff the next address would be 2001::0001:0001
Hope you understand what I mean ;)
This will add 1 to your ip6 address using the Net::IP perl package.
#!/usr/bin/env perl
use strict;
use Net::IP qw(ip_inttobin ip_bintoip);
my $ip = Net::IP->new('2001::0000:fe05') || die;
print ("IP : ".$ip->ip()."\n");
print ("Sho : ".$ip->short()."\n");
print ("Int : ".$ip->intip()."\n");
# add 1 to the address
my $next_bin = ip_inttobin($ip->intip + 1, $ip->version);
my $next = Net::IP->new(ip_bintoip($next_bin, $ip->version));
print "\nAfter incrementing by 1\n";
print ("IP : ".$next->ip()."\n");
print ("Sho : ".$next->short()."\n");
$ perl ip6_test.pl
IP : 2001:0000:0000:0000:0000:0000:0000:fe05
Sho : 2001::fe05
Int : 42540488161975842760550356425300311557
After incrementing by 1
IP : 2001:0000:0000:0000:0000:0000:0000:fe06
Sho : 2001::fe06
In system-verilog i have a random number generator like this:
task set_rand_value(output bit [7:0] rand_frms, output bit [13:0] rand_bcnt);
begin
bit [7:0] rand_num;
// Set the random value between 2 and 254
rand_num=$urandom_range(254,2);
rand_bcnt=$urandom_range(2047,1);
// Check to ensure number is even
if ((rand_num/2)*2 != rand_num) begin
rand_num=rand_num+1;
$display("Generated %d frames. 8'h%h", rand_num, rand_num);
$display("Packets generated with 0x%4h bytes.", rand_bcnt);
end
// Set the random frame number
else begin
rand_frms = rand_num;
$display("Generated %d frames. 8'h%h", rand_num, rand_num);
$display("Packets generated with 0x%4h bytes.", rand_bcnt);
end
end
endtask // set_rand_value
For some reason the first time I run this (and the third and fifth... etc) it returns a value of zero even though a number is properly generated.
I am calling it like this:
bit [ 7:0] num_frms;
bit [13:0] size_val;
// Generate random values
set_rand_value(num_frms, size_val); // Run twice to correct initial write error
$display("Error correction for packets sent: 0x%h", num_frms);
set_rand_value(num_frms, size_val);
$display("The number of packets being sent: 0x%h", num_frms);
Which gives me this output:
Generated 214 frames. 8'hd6
Packets generated with 0x05b2 bytes.
Error correction for packets sent: 0x00
Generated 252 frames. 8'hfc
Packets generated with 0x011f bytes.
The number of packets being sent: 0xfc
0x80fc011f // Expected number
I have tried quite a few things to correct it but for some reason the only way i can get it to behave the way i expect it to is to just run it twice every time i need to use it.
You only set num_frms if the random number is even. Why not just do
function void set_rand_value(output bit [7:0] rand_frms, output bit [13:0] rand_bcnt);
begin
// Set the random value between 2 and 254
rand_frms=$urandom*2;
rand_bcnt=$urandom_range(2047,1);
endfunction
P.S Only use tasks for routines that may block.
The reason why the code above did not work was you were not assigning rand_frms = rand_num; in the first half of the if condition . So only for 50% of the times read_frm would have a value in it. [ 50 % just been approximate ] .
I have created a snmp manager which will calculate the traffic of a list of ip address.
Here is the snmp walk cammand :
walk snmpwalk = new walk(" 192.168.30.172" ,". 1.3.6.1.2.1.2.2.1.10", "");
System.out.println(",,,,,,,,,,,,,,,," + snmpwalk.doSnmpwalk());
Here is the output:
1.3.6.1.2.1.2.2.1.10.1=0
1.3.6.1.2.1.2.2.1.10.2=0
1.3.6.1.2.1.2.2.1.10.3=0
1.3.6.1.2.1.2.2.1.10.4=0
1.3.6.1.2.1.2.2.1.10.5=0
1.3.6.1.2.1.2.2.1.10.6=0
1.3.6.1.2.1.2.2.1.10.7=0
1.3.6.1.2.1.2.2.1.10.8=0
1.3.6.1.2.1.2.2.1.10.9=0
1.3.6.1.2.1.2.2.1.10.10=0
1.3.6.1.2.1.2.2.1.10.11=0
1.3.6.1.2.1.2.2.1.10.12=0
1.3.6.1.2.1.2.2.1.10.13=0
1.3.6.1.2.1.2.2.1.10.14=163292301
1.3.6.1.2.1.2.2.1.10.15=0
1.3.6.1.2.1.2.2.1.10.16=0
1.3.6.1.2.1.2.2.1.10.17=0
1.3.6.1.2.1.2.2.1.10.18=0
1.3.6.1.2.1.2.2.1.10.19=0
1.3.6.1.2.1.2.2.1.10.20=0
1.3.6.1.2.1.2.2.1.10.21=0
1.3.6.1.2.1.2.2.1.10.22=0
1.3.6.1.2.1.2.2.1.10.23=0
1.3.6.1.2.1.2.2.1.10.24=163292301
1.3.6.1.2.1.2.2.1.10.25=163292301
1.3.6.1.2.1.2.2.1.10.26=163292301
1.3.6.1.2.1.2.2.1.10.27=163292301
1.3.6.1.2.1.2.2.1.10.28=163292301
1.3.6.1.2.1.2.2.1.10.29=0
1.3.6.1.2.1.2.2.1.10.30=0
1.3.6.1.2.1.2.2.1.10.31=0
1.3.6.1.2.1.2.2.1.10.32=0
1.3.6.1.2.1.2.2.1.10.33=0
1.3.6.1.2.1.2.2.1.10.34=0
1.3.6.1.2.1.2.2.1.10.35=0
1.3.6.1.2.1.2.2.1.10.36=0
1.3.6.1.2.1.2.2.1.10.37=0
1.3.6.1.2.1.2.2.1.10.38=0
1.3.6.1.2.1.2.2.1.10.39=0
Now my question is it possible to calculate the traffic(monthly data usage) at the end of the month of this IP device?
if possible then how can i do that? What is the formula and calculation process?
On Linux I would use awk, e.g.:
awk 'BEGIN{RS="\r"} /::if(In|Out)Octets/{i=$1; sub(/^.*\./,"",i); t[i]+=$4} /::ifDescr/{i=$1; sub(/^.*\./,"",i); d[i]=$4}; END{for(i in t) if(t[i]>0) printf "%s %.2fMB\n",d[i],t[i]/1048576}' Cisco_3750_snmpwalk.txt
It sums ifInOctets and ifOutOctets counters, and displays the sum in MB next to ifDescr string if it is greater than 0. Output for your file looks like this:
Vlan66 0.00MB
Vlan100 2829.20MB
Vlan117 780.88MB
Vlan230 40.42MB
Vlan237 28.77MB
Vlan242 0.01MB
Vlan302 1902.10MB
Vlan312 181.48MB
Vlan325 738.01MB
Vlan328 253.37MB
Vlan330 0.08MB
Vlan331 590.89MB
Vlan337 320.17MB
Vlan356 3247.89MB
Vlan358 1360.38MB
Vlan362 45.38MB
Vlan364 2179.56MB
Vlan400 0.00MB
Vlan404 105.89MB
Vlan413 157.37MB
Vlan466 3487.25MB
Vlan467 0.00MB
Vlan510 2547.83MB
Vlan548 3033.33MB
Vlan603 0.01MB
Vlan624 0.00MB
Vlan667 0.01MB
Vlan725 1.58MB
Vlan776 103.93MB
Vlan875 29.90MB
Vlan908 15.19MB
Vlan910 27.36MB
Vlan936 13.78MB
Vlan956 13.91MB
Vlan965 68.12MB
Vlan966 298.39MB
Vlan967 167.47MB
Vlan1000 0.00MB
GigabitEthernet1/0/1 5629.52MB
GigabitEthernet1/0/2 4220.78MB
GigabitEthernet1/0/3 6369.15MB
GigabitEthernet1/0/9 3866.67MB
GigabitEthernet1/0/15 5511.63MB
GigabitEthernet1/0/16 6030.57MB
GigabitEthernet1/0/18 4251.62MB
I got this in output so I just want to know what is BP, Blk? Can you explain me what each thing means in this output? I know the
BP-929597290-192.0.0.2-1439573305237:blk_1074084574_344316 len=2 repl=3 [DatanodeInfoWithStorage[192.0.0.9:1000,DS-730a75d3-046c-4254-990a-4eee9520424f,DISK], DatanodeInfoWithStorage[192.0.0.1:1000,DS-fc6ee5c7-e76b-4faa-b663-58a60240de4c,DISK], DatanodeInfoWithStorage[192.0.0.3:1000,DS-8ab81b26-309e-42d6-ae14-26eb88387cad,DISK]]
I guess 192.0.0.9:1000 this is the Ip of first replication of data
BP-929597290-192.0.0.2-1439573305237
This is Block Pool ID. Block pool is a set of blocks that belong to single name space. For simplicity, you can say that all the blocks managed by a Name Node are under the same Block Pool.
The Block Pool is formed as:
String bpid = "BP-" + rand + "-"+ ip + "-" + Time.now();
Where:
rand = Some random number
ip = IP address of the Name Node
Time.now() - Current system time
Read about Block Pools here: https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/Federation.html
blk_1074084574_344316:
Block number of the block. Each block in HDFS is given a unique identifier.
The block ID is formed as:
blk_<blockid>_<genstamp>
Where:
blockid = ID of the block
genstamp = an incrementing integer that records the version of a particular block
Read about generation stamp here: http://blog.cloudera.com/blog/2009/07/file-appends-in-hdfs/
len=2
Length of the block: Number of bytes in the block
repl=3
There are 3 replicas of this block
DatanodeInfoWithStorage[192.0.0.9:1000,DS-730a75d3-046c-4254-990a-4eee9520424f,DISK
Where:
192.0.0.9 => IP address of the Data Node holding this block
1000 => Data streaming port
DS-730a75d3-046c-4254-990a-4eee9520424f => Storage ID. It is an internal ID of the Data Node. It is assigned, when the Data Node registers with Name Node
DISK => storageType. It is DISK here. Storage type can be: RAM_DISK, SSD, DISK and ARCHIVE
The description of point 5 applies to remaining 2 blocks:
DatanodeInfoWithStorage[192.0.0.1:1000,DS-fc6ee5c7-e76b-4faa-b663-58a60240de4c,DISK],
DatanodeInfoWithStorage[192.0.0.3:1000,DS-8ab81b26-309e-42d6-ae14-26eb88387cad,DISK]]
This is a difficult one to extrapolate what I need, so bear with me. Let's say we have this subnet 10.4.x.0/28 which iterates itself across multiple subnets that look the same, i.e
10.4.0.0/28
10.4.0.16/28
10.4.0.32/28 etc...
and we have a single address in these subnets that we need to extract that will always be +12 of the current subnet. i.e
10.4.0.0/28 -> 10.4.0.12
10.4.0.16/28 -> 10.4.0.28
10.4.0.32/28 -> 10.4.0.44
How would I go about writing a shell script to loop through all of the subnets from
10.4.0.0/28 to 10.4.255.240 to get the single address in each subnet?
Hard to tell what format you want exactly, but ...
for I in $(seq 12 16 256); do echo 10.4.{0..255}.$I; done
Gives 16 lines with 4096 values like this...
10.4.0.12 10.4.1.12 10.4.2.12 10.4.3.12 10.4.4.12 10.4.5.12 10.4.6.12 10.4.7.12 10.4.8.12 10.4.9.12 10.4.10.12 10.4.11.12 10.4.12.12 10.4.13.12 10.4.14.12 10.4.15.12 10.4.16.12 10.4.17.12 ...
10.4.0.28 10.4.1.28 10.4.2.28 10.4.3.28 10.4.4.28 10.4.5.28 10.4.6.28 10.4.7.28 10.4.8.28 10.4.9.28 10.4.10.28 10.4.11.28 10.4.12.28 10.4.13.28 10.4.14.28 10.4.15.28 10.4.16.28 10.4.17.28 ...
[...]
10.4.235.252 10.4.236.252 10.4.237.252 10.4.238.252 10.4.239.252 10.4.240.252 10.4.241.252 10.4.242.252 10.4.243.252 10.4.244.252 10.4.245.252 10.4.246.252 10.4.247.252 10.4.248.252 10.4.249.252 10.4.250.252 10.4.251.252 10.4.252.252 10.4.253.252 10.4.254.252 10.4.255.252
If you want to change the top-level addresses on the fly, you could make a function...
iterateIP(){
for I in $(seq 12 16 256); do echo $1.{0..255}.$I; done
}
And call like this:
iterateIP 10.4