Why does /proc/net/tcp6 represents ::1 as ::100:0
Solution 1:
This is due to counterintuitive byte order in /proc/net/tcp6
. The address is handled as four words consisting of four bytes each. In each of those four words the four bytes are written in reverse order.
2001:0db8 :: 0123:4567:89ab:cdef would thus come out as:
B80D 0120 00000000 6745 2301 EFCD AB89 (with spaces inserted for clarity).
This is probably due to endianness differences. Most PCs these days use IA32 or AMD64 which are using the opposite endianness from what IP was designed with. I don't have any other systems to test with to figure out if you can rely on /proc/net/tcp6 always looking like that. But I verified that it is the case on both IA32 and AMD64 architectures.
Solution 2:
Found this perl module intended for parsing /proc/net/tcp http://search.cpan.org/~salva/Linux-Proc-Net-TCP-0.05/lib/Linux/Proc/Net/TCP.pm It quotes the kernel documentation as shown below.
This document describes the interfaces /proc/net/tcp and
/proc/net/tcp6. Note that these interfaces are deprecated in favor
of tcp_diag.
These /proc interfaces provide information about currently active TCP
connections, and are implemented by tcp4_seq_show() in
net/ipv4/tcp_ipv4.c and tcp6_seq_show() in net/ipv6/tcp_ipv6.c,
respectively.
It will first list all listening TCP sockets, and next list all
established TCP connections. A typical entry of /proc/net/tcp would
look like this (split up into 3 parts because of the length of the
line):
46: 010310AC:9C4C 030310AC:1770 01
| | | | | |--> connection state
| | | | |------> remote TCP port number
| | | |-------------> remote IPv4 address
| | |--------------------> local TCP port number
| |---------------------------> local IPv4 address
|----------------------------------> number of entry
00000150:00000000 01:00000019 00000000
| | | | |--> number of unrecovered RTO timeouts
| | | |----------> number of jiffies until timer expires
| | |----------------> timer_active (see below)
| |----------------------> receive-queue
|-------------------------------> transmit-queue
1000 0 54165785 4 cd1e6040 25 4 27 3 -1
| | | | | | | | | |--> slow start size threshold,
| | | | | | | | | or -1 if the threshold
| | | | | | | | | is >= 0xFFFF
| | | | | | | | |----> sending congestion window
| | | | | | | |-------> (ack.quick<<1)|ack.pingpong
| | | | | | |---------> Predicted tick of soft clock
| | | | | | (delayed ACK control data)
| | | | | |------------> retransmit timeout
| | | | |------------------> location of socket in memory
| | | |-----------------------> socket reference count
| | |-----------------------------> inode
| |----------------------------------> unanswered 0-window probes
|---------------------------------------------> uid
timer_active:
0 no timer is pending
1 retransmit-timer is pending
2 another timer (e.g. delayed ack or keepalive) is pending
3 this is a socket in TIME_WAIT state. Not all fields will contain
data (or even exist)
4 zero window probe timer is pending
Solution 3:
Im parsing /proc/net/tcp, also /tcp6,/udp6 on Android and this are my simple methods for conversion, in Java. Thanks kasperd for guide me to this solution.
/**B80D01200000000067452301EFCDAB89 -> 2001:0db8:0000:0000:0123:4567:89ab:cdef
* */
public static String toRegularHexa(String hexaIP){
StringBuilder result = new StringBuilder();
for(int i=0;i<hexaIP.length();i=i+8){
String word = hexaIP.substring(i,i+8);
for (int j = word.length() - 1; j >= 0; j = j - 2) {
result.append(word.substring(j - 1, j + 1));
result.append((j==5)?":":"");//in the middle
}
result.append(":");
}
return result.substring(0,result.length()-1).toString();
}
/**0100A8C0 -> 192.168.0.1*/
public static String hexa2decIPv4 (String hexa) {
StringBuilder result = new StringBuilder();
//reverse Little to Big
for (int i = hexa.length() - 1; i >= 0; i = i - 2) {
String wtf = hexa.substring(i - 1, i + 1);
result.append(Integer.parseInt(wtf, 16));
result.append(".");
}
//remove last ".";
return result.substring(0,result.length()-1).toString();
}
/**0000000000000000FFFF00008370E736 -> 0.0.0.0.0.0.0.0.0.0.255.255.54.231.112.131
0100A8C0 -> 192.168.0.1
*/
public static String hexa2decIP (String hexa) {
StringBuilder result = new StringBuilder();
if(hexa.length()==32){
for(int i=0;i<hexa.length();i=i+8){
result.append(hexa2decIPv4(hexa.substring(i, i + 8)));
result.append(".");
}
}else {
if(hexa.length()!=8){return "0.0.0.0";}
return hexa2decIPv4(hexa);
}
//remove last ".";
return result.substring(0,result.length()-1).toString();
}
/**Simple hexa to dec, for ports
* 01BB -> 403
* */
public static String hexa2decPort(String hexa) {
StringBuilder result = new StringBuilder();
result.append(Integer.parseInt(hexa, 16));
return result.toString();
}