Pourquoi / proc / net / tcp6 représente :: 1 comme :: 100: 0

13

J'écrivais un utilitaire pour vérifier / proc / net / tcp et tcp6 pour les connexions actives car il est plus rapide que l'analyse de la sortie netstat.

Comme je n'ai pas activé ipv6, j'utilisais principalement localhost comme point de référence. Voici une copie de mon / 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

Voici le pantalon netstat -6 assorti

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      -      

Les entrées 0-3 de tcp6 correspondent aux :: (tous ipv6), mais l'entrée 4 est censée être l'entrée correspondante pour :: 1.

C'est là que je suis confus ...

00000000000000000000000001000000 => 0000: 0000: 0000: 0000: 0000: 0000: 0100: 0000 => :: 100: 0

Lorsque je lance :: 1 à travers du code pour générer la représentation hexadécimale complète que j'obtiens:

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

Je ne peux pas aligner ces deux valeurs par programme, car elles ne correspondent pas (évidemment). Pourquoi ne correspondent-ils pas? Pourquoi le noyau pense-t-il que :: 100: 0 est :: 1?

gregswift
la source

Réponses:

11

Cela est dû à un ordre d'octets contre-intuitif dans /proc/net/tcp6. L'adresse est traitée comme quatre mots composés de quatre octets chacun. Dans chacun de ces quatre mots, les quatre octets sont écrits dans l'ordre inverse.

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

Cela est probablement dû aux différences d'endianité. De nos jours, la plupart des PC utilisent IA32 ou AMD64 qui utilisent l'endianisme opposé à celui avec lequel IP a été conçu. Je n'ai pas d'autres systèmes avec lesquels tester pour savoir si vous pouvez compter sur / proc / net / tcp6 toujours comme ça. Mais j'ai vérifié que c'est le cas sur les architectures IA32 et AMD64.

kasperd
la source
Bonne réponse, mais il serait peut-être préférable de fournir plus de précisions. Votre deuxième phrase n'est pas aussi claire qu'elle pourrait l'être, je pense que la seule raison pour laquelle cela avait du sens était que quelqu'un d'autre venait de m'expliquer différemment.
gregswift
@gregswift puisque l'OP n'a jamais pris de mesures, peut-être pourriez-vous le modifier vous-même? C'est une bonne réponse à une bonne question et cette information serait précieuse à l'OMI.
André Chalella
@kasperd l'a modifié hier. J'ai juste réorganisé l'exemple et ajouté une mise en forme pour, espérons-le, fournir un contexte supplémentaire
gregswift
3

Trouvé ce module perl destiné à l'analyse / proc / net / tcp http://search.cpan.org/~salva/Linux-Proc-Net-TCP-0.05/lib/Linux/Proc/Net/TCP.pm Il cite le documentation du noyau comme indiqué ci-dessous.

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
la source
0

Im parsing / proc / net / tcp, également / tcp6, / udp6 sur Android et ce sont mes méthodes simples de conversion, en Java. Merci kasperd de me guider vers cette 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();
}
Jan Tancibok
la source
Est-ce que cela répond à la question?
Andrew Schulman
Dois-je le supprimer? Peut-être que cela aide quelqu'un qui fera de l'analyse IPv6 à l'avenir ou quelqu'un peut mieux comprendre en regardant le vrai code.
Jan Tancibok
Personne dans le public cible ne fera probablement de programmation en Java ou dans un autre langage.
Michael Hampton
@MichaelHampton C'est une exagération. Il y a des gens qui font à la fois l'administration et le développement du système. Je suis l'un d'eux. (Bien que cela fait 9 ans que je n'ai pas fait Java pour la dernière fois.)
kasperd
@kasperd Le fait est que les gens ne penseront pas à venir à Server Fault pour des exemples de code. C'est l' autre site. :)
Michael Hampton