/ proc / net / tcp6이 :: 1을 :: 100 : 0으로 나타내는 이유는 무엇입니까?


13

netstat 출력을 구문 분석하는 것보다 빠른 속도로 / proc / net / tcp 및 tcp6에서 활성 연결을 확인하는 유틸리티를 작성 중이었습니다.

실제로 ipv6을 사용하도록 설정하지 않았으므로 주로 localhost를 내 참조 지점으로 사용했습니다. 내 / 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

전체 16 진수 표현을 생성하기 위해 일부 코드를 통해 :: 1을 실행하면 다음과 같은 결과를 얻습니다.

import binascii
import socket
print binascii.hexlify(socket.inet_pton(socket.AF_INET6, '::1'))
00000000000000000000000000000001

이 두 값이 (명확하게) 일치하지 않기 때문에 프로그래밍 방식 으로이 두 값을 정렬 할 수 없습니다. 왜 일치하지 않습니까? 커널이 :: 100 : 0이 :: 1이라고 생각하는 이유는 무엇입니까?

답변:


11

이는의 반 직관적 인 바이트 순서 때문입니다 /proc/net/tcp6. 주소는 각각 4 바이트로 구성된 4 워드로 처리됩니다. 이 4 개의 단어 각각에서 4 바이트는 역순으로 기록됩니다.

2001:0db8       :: 0123:4567:89ab:cdef would thus come out as:
B80D 0120 00000000 6745 2301 EFCD AB89 (with spaces inserted for clarity).

아마도 엔디안 차이로 인한 것일 수 있습니다. 요즘 대부분의 PC는 IA32 또는 AMD64를 사용하는데, 이는 IP가 설계 한 것과 반대 엔디안을 사용합니다. 항상 / proc / net / tcp6에 의존 할 수 있는지 알아 내기 위해 테스트 할 다른 시스템이 없습니다. 그러나 IA32 및 AMD64 아키텍처 모두에 해당되는 것을 확인했습니다.


좋은 답변이지만 더 명확한 설명을 제공하는 것이 좋습니다. 두 번째 문장은 그다지 명확하지 않습니다. 다른 사람이 방금 다른 설명을했기 때문이라고 생각합니다.
gregswift

OP가 조치를 취하지 않은 이후 @gregswift는 직접 편집 할 수 있습니까? 이것은 좋은 질문에 대한 정답이며이 정보는 귀중한 IMO가 될 것입니다.
André Chalella 2016 년

@kasperd는 어제 편집했습니다. 난 그냥 예를 재정렬 어떤 희망 추가 컨텍스트를 제공하기 위해 포맷 추가
gregswift

3

이 펄 모듈은 구문 분석 / proc 디렉토리 / 그물위한 찾을 수 / 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 (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

0

안드로이드에서 / proc / net / tcp, / tcp6, / udp6 구문 분석하고 Java로 변환하는 간단한 방법입니다. 이 솔루션으로 안내해 주셔서 감사합니다.

/**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();
}

이 질문에 대답합니까?
Andrew Schulman

삭제해야합니까? 아마도 미래에 ipv6 구문 분석을 수행하는 사람에게 도움이되거나 실제 코드를 보면서 더 잘 이해할 수 있습니다.
Jan Tancibok

대상 독자 중 누구도 Java 또는 다른 언어로 프로그래밍을 수행하지 않을 것입니다.
Michael Hampton

@MichaelHampton 과장입니다. 시스템 관리와 ​​개발을 모두하는 사람들이 있습니다. 나는 그들 중 하나입니다. (내가 지난 자바 않았기 때문에 구년있다지만.)
kasperd

@kasperd 요점은 사람들이 코드 샘플 을 위해 서버 결함 을 생각하지 않을 것 입니다. 그것은 다른 사이트입니다. :)
Michael Hampton
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.