Mengapa / proc / net / tcp6 mewakili :: 1 sebagai :: 100: 0

13

Saya sedang menulis sebuah utilitas untuk memeriksa / proc / net / tcp dan tcp6 untuk koneksi aktif karena lebih cepat dari parsing output netstat.

Karena saya sebenarnya tidak mengaktifkan ipv6, saya terutama menggunakan localhost sebagai titik referensi saya. Ini adalah salinan dari my / 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

Berikut ini adalah netstat -6 -pant yang cocok

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      -      

Entri 0-3 dari tcp6 sesuai dengan :: (semua ipv6), tetapi entri 4 seharusnya entri yang sesuai untuk :: 1.

Di sinilah aku bingung ...

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

Ketika saya menjalankan :: 1 melalui beberapa kode untuk menghasilkan representasi hex penuh saya mendapatkan:

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

Saya tidak bisa secara sistematis menyejajarkan kedua nilai ini, karena tidak cocok (jelas). Kenapa mereka tidak cocok? Mengapa kernel berpikir :: 100: 0 adalah :: 1?

gregswift
sumber

Jawaban:

11

Ini disebabkan urutan byte yang berlawanan dengan intuisi di /proc/net/tcp6. Alamat ditangani sebagai empat kata yang masing-masing terdiri dari empat byte. Dalam masing-masing dari empat kata tersebut, empat byte ditulis dalam urutan terbalik.

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

Ini mungkin karena perbedaan endianness. Sebagian besar PC saat ini menggunakan IA32 atau AMD64 yang menggunakan endianness yang berlawanan dengan apa IP dirancang. Saya tidak memiliki sistem lain untuk menguji dengan mencari tahu apakah Anda dapat mengandalkan / proc / net / tcp6 selalu terlihat seperti itu. Tetapi saya memverifikasi bahwa ini adalah kasus pada arsitektur IA32 dan AMD64.

kasperd
sumber
Jawaban yang bagus tetapi mungkin lebih baik untuk memberikan lebih banyak klarifikasi. Kalimat kedua Anda tidak sejelas mungkin, saya pikir satu-satunya alasan yang masuk akal adalah bahwa orang lain baru saja menjelaskannya kepada saya secara berbeda.
gregswift
@gregswift karena OP tidak pernah mengambil tindakan, mungkin Anda bisa mengeditnya sendiri? Ini adalah jawaban yang bagus untuk pertanyaan yang bagus dan sedikit informasi ini akan menjadi IMO yang berharga.
André Chalella
@kasperd memang mengeditnya kemarin. Saya baru saja memesan ulang contoh dan menambahkan beberapa format untuk semoga memberikan konteks tambahan
gregswift
3

Menemukan modul perl ini ditujukan untuk parsing / proc / net / tcp http://search.cpan.org/~salva/Linux-Proc-Net-TCP-0.05/lib/Linux/Proc/Net/TCP.pm Ini mengutip dokumentasi kernel seperti yang ditunjukkan di bawah ini.

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
sumber
0

Saya parsing / proc / net / tcp, juga / tcp6, / udp6 di Android dan ini adalah metode sederhana saya untuk konversi, di Jawa. Terima kasih kasperd untuk membimbing saya untuk solusi ini.

/**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
sumber
Apakah ini menjawab pertanyaan?
Andrew Schulman
Haruskah saya menghapusnya? Mungkin ini membantu seseorang yang akan melakukan parsing ipv6 di masa depan atau seseorang bisa mendapatkan pemahaman yang lebih baik melihat kode nyata.
Jan Tancibok
Tidak seorang pun di audiens target yang kemungkinan melakukan pemrograman apa pun di Jawa atau bahasa lainnya.
Michael Hampton
@MichaelHampton Itu berlebihan. Ada orang yang melakukan administrasi dan pengembangan sistem. Saya salah satunya. (Meskipun sudah 9 tahun sejak saya terakhir kali melakukan Jawa.)
kasperd
@kasperd Intinya adalah, orang tidak akan berpikir untuk datang ke Server Fault untuk sampel kode. Itu situs lain . :)
Michael Hampton