Warum repräsentiert / proc / net / tcp6 :: 1 als :: 100: 0?

13

Ich habe ein Hilfsprogramm geschrieben, um / proc / net / tcp und tcp6 auf aktive Verbindungen zu prüfen, da es schneller ist als das Parsen der netstat-Ausgabe.

Da ich ipv6 eigentlich nicht aktiviert habe, habe ich hauptsächlich localhost als Referenzpunkt verwendet. Hier ist eine Kopie von meinem / 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

Hier ist der passende 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      -      

Die Einträge 0-3 von tcp6 entsprechen den :: 's (alle ipv6), aber Eintrag 4 ist angeblich der entsprechende Eintrag für :: 1.

Hier bin ich verwirrt ...

000000000000000000000001000000 => 0000: 0000: 0000: 0000: 0000: 0000: 0100: 0000 => :: 100: 0

Wenn ich :: 1 durch einen Code starte, um die vollständige Hex-Darstellung zu generieren, erhalte ich:

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

Ich kann diese beiden Werte nicht programmgesteuert aneinanderreihen, da sie (offensichtlich) nicht übereinstimmen. Warum passen sie nicht zusammen? Warum denkt der Kernel :: 100: 0 ist :: 1?

Gregswift
quelle

Antworten:

11

Dies liegt an der nicht intuitiven Bytereihenfolge in /proc/net/tcp6. Die Adresse wird als vier Wörter mit jeweils vier Bytes behandelt. In jedem dieser vier Wörter werden die vier Bytes in umgekehrter Reihenfolge geschrieben.

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

Dies liegt wahrscheinlich an Endianness-Unterschieden. Die meisten PCs verwenden heutzutage IA32 oder AMD64, die das Gegenteil von dem verwenden, mit dem IP entworfen wurde. Ich habe keine anderen Systeme zum Testen, um herauszufinden, ob Sie sich darauf verlassen können, dass / proc / net / tcp6 immer so aussieht. Ich habe jedoch bestätigt, dass dies sowohl auf IA32- als auch auf AMD64-Architekturen der Fall ist.

Kasperd
quelle
Gute Antwort, aber es könnte besser sein, mehr Klarheit zu schaffen. Dein zweiter Satz ist nicht ganz so klar wie es sein könnte, ich denke, der einzige Grund, warum es Sinn machte, war, dass jemand anderes es mir gerade anders erklärt hatte.
Gregswift
@gregswift da das OP nie aktiv wurde, könntest du das vielleicht selbst bearbeiten? Dies ist eine gute Antwort auf eine gute Frage, und diese Information wäre wertvoll, IMO.
André Chalella
@kasperd hat es gestern bearbeitet. Ich habe gerade das Beispiel neu angeordnet und einige Formatierungen hinzugefügt, um hoffentlich einen zusätzlichen Kontext
bereitzustellen
3

Gefunden dieses Perl-Modul für das Parsen / proc / net / tcp bestimmt http://search.cpan.org/~salva/Linux-Proc-Net-TCP-0.05/lib/Linux/Proc/Net/TCP.pm Es zitiert die Kernel-Dokumentation wie unten gezeigt.

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
Sanxiago
quelle
0

Ich analysiere / proc / net / tcp, auch / tcp6, / udp6 auf Android und dies sind meine einfachen Methoden zur Konvertierung in Java. Danke kasperd, dass du mich zu dieser Lösung geführt hast.

/**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();
}
Jan Tancibok
quelle
Beantwortet dies die Frage?
Andrew Schulman
Soll ich es löschen? Vielleicht hilft es jemandem, der in Zukunft IPv6-Parsing durchführt, oder jemand kann sich ein besseres Verständnis verschaffen, wenn er echten Code betrachtet.
Jan Tancibok,
Niemand in der Zielgruppe wird wahrscheinlich in Java oder einer anderen Sprache programmieren.
Michael Hampton
@ MichaelHampton Das ist eine Übertreibung. Es gibt Leute, die sowohl die Systemadministration als auch die Entwicklung übernehmen. Ich bin einer von denen. (Obwohl es 9 Jahre her ist, seit ich Java das letzte Mal gemacht habe.)
Kasperd
@kasperd Der Punkt ist, dass die Leute nicht daran denken werden, für Codebeispiele zu Server Fault zu kommen . Das ist die andere Seite. :)
Michael Hampton