2012-04-02 8 views
0

Gibt es eine Möglichkeit, die sockfd von einer struct sock oder eine andere Möglichkeit zu bekommen, die es mir ermöglichen würde, den Socket/die Verbindung, mit der ich arbeite, eindeutig im Kernel zu identifizieren?Wie bekomme ich Sockfd aus Kernel-Space?

Ich brauche diese Information im Zusammenhang mit einem Gerätetreiber für einen Netzwerkadapter.

+0

Und wie würde das eindeutig eine Buchse/Verbindung identifizieren? Welche Art von Verbindung ist das? Beispielsweise werden TCP-Verbindungen durch Tupel (Schnittstelle, Quelladresse, Quellport, Zieladresse, Zielport) eindeutig identifiziert. – ninjalj

+0

Ich bin tatsächlich in einer Situation, in der ich die Verbindung nicht selbst herstellen werde, sondern die NIC darum ersuche. Die NIC gibt eine Bestätigung für meine Verbindungsöffnungsanforderung zurück, aber der lokale Port ist ein NIC-behandelter Port, kein Host-Stack-behandelter Port. Ich muss das Datei-Handle mit meiner "Sock" -Struktur verknüpfen, um eingehende Pakete zu demultiplexen. – Asblarf

Antwort

2

Ich dachte, es sei unmöglich, aber tatsächlich gibt es einen Weg, zumindest für einfache Fälle, wo wir keine doppelten Dateideskriptoren für einen einzelnen Sockel haben. Ich beantworte meine eigene Frage und hoffe, dass es den Leuten da draußen helfen wird.

int get_sockfd(struct sock *sk) 
{ 
    int sockfd; 
    unsigned int i; 
    struct files_struct *current_files; 
    struct fdtable *files; 
    struct socket *sock; 
    struct file *sock_filp; 

    sockfd = -1; 

    sock = sk->sk_socket; 
    sock_filp = sock->file; 

    current_files = current->files; 
    files = files_fdtable(current_files); 

    for (i = 0; files->fd[i] != NULL; i++) { 
      if (sock_filp == files->fd[i]) { 
        sockfd = i; 
        break; 
      } 
    } 

    return sockfd; 
} 

Sie würden natürlich wollen für NULL-Zeiger zu überprüfen, mit struct sock *sk in param geben zu starten.

Also, im Grunde ist die Idee, dass der numerische Wert eines Dateideskriptors (ein Sockfd ist nur ein regulärer Dateideskriptor, immerhin) dem Index seines entsprechenden Eintrags in einer Prozess-Datei-Tabelle entspricht. Alles, was wir tun müssen, wenn ein Zeiger struct sock *sk gegeben wird, ist eine Schleife über die geöffnete Dateitabelle des aktuellen Prozesses, bis die Adressen, auf die sk->sk_socket->file zeigt, mit einem Eintrag in der Tabelle übereinstimmen.

Verwandte Themen