我正在编写一个实用程序来检查/ proc / net / tcp和tcp6作为活动连接,因为它比parsingnetstat输出更快。
由于我实际上没有启用ipv6,我主要是利用本地主机作为我的参考点。 这里是我的/ proc / net / tcp6的副本
sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode 0: 00000000000000000000000000000000:006F 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 19587 1 ffff880262630000 100 0 0 10 -1 1: 00000000000000000000000000000000:0050 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 22011 1 ffff880261c887c0 100 0 0 10 -1 2: 00000000000000000000000000000000:0016 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 21958 1 ffff880261c88000 100 0 0 10 -1 3: 00000000000000000000000001000000:0277 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 28592 1 ffff88024eea0000 100 0 0 10 -1
这是匹配的netstat -6 -pant
Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp6 0 0 :::111 :::* LISTEN - tcp6 0 0 :::80 :::* LISTEN - tcp6 0 0 :::22 :::* LISTEN - tcp6 0 0 ::1:631 :::* LISTEN -
来自tcp6的条目0-3对应于::(全部ipv6),但是条目4被认为是对应于:: 1的条目。
这是我困惑的地方…
00000000000000000000000001000000 => 0000:0000:0000:0000:0000:0000:0100:0000 => :: 100:0
当我运行:: 1通过一些代码来生成完整的hex表示我得到:
import binascii import socket print binascii.hexlify(socket.inet_pton(socket.AF_INET6, '::1')) 00000000000000000000000000000001
我不能以编程的方式将这两个值alignment,因为它们不匹配(显然)。 他们为什么不匹配? 为什么内核认为:: 100:0是:: 1?
这是由于/proc/net/tcp6违反直觉的字节顺序。 地址被处理为四个字,每个字由四个字节组成。 在这四个字的每一个中,四个字节按相反的顺序写入。
2001:0db8 :: 0123:4567:89ab:cdef would thus come out as: B80D 0120 00000000 6745 2301 EFCD AB89 (with spaces inserted for clarity).
这可能是由于sorting差异。 现在大多数个人电脑都使用IA32或AMD64,它们采用与IPdevise相反的字节顺序。 我没有任何其他系统要testing,以确定是否可以依赖/ proc / net / tcp6总是看起来像这样。 但是我确认在IA32和AMD64架构上都是这种情况。
发现这个perl模块打算parsing/ proc / net / tcp http://search.cpan.org/~salva/Linux-Proc-Net-TCP-0.05/lib/Linux/Proc/Net/TCP.pm它引用内核文档如下所示。
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 (eg 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
我parsing/ proc / net / tcp,也是/ tcp6,/ udp6在Android上,这是我简单的Java转换方法。 感谢kasperd指导我解决这个问题。
/**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(); }