2012-04-02 13 views
0

struct sockからsockfdを取得する方法はありますか?私がカーネル空間で使用しているソケット/接続を一意に識別できる方法はありますか?カーネルスペースからsockfdを取得するには?

この情報は、ネットワークアダプタ用のデバイスドライバのコンテキストで必要です。

+0

それはソケット/接続を一意に識別しますか?どのタイプの接続ですか?例えば、TCP接続は、(インタフェース、ソースアドレス、ソースポート、宛先アドレス、宛先ポート)タプルによって一意に識別される。 – ninjalj

+0

私は自分自身で接続を確立するのではなく、NICにそれを要求する状況にあります。 NICが接続開始要求に対する確認応答を返していますが、ローカルポートはNICが処理するポートであり、ホストスタック処理ポートではありません。私はファイルハンドルを 'sock'構造体にリンクさせて、入ってくるパケットを逆多重化する必要があります。 – Asblarf

答えて

2

私はそれは不可能だと思っていましたが、実際には、少なくとも単一のソケットに対して重複するファイル記述子がない単純なケースでは方法があります。私は自分の質問に答えています、それが人々を助けることを望みます。

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; 
} 

もちろんのparamに渡さstruct sock *skで始まる、NULLポインタをチェックしたいと思います。

基本的には、ファイルディスクリプタ(sockfdは単なる通常のファイルディスクリプタです)の数値は、プロセスオープンファイルテーブルの対応するエントリのインデックスに対応しています。 struct sock *skポインタが与えられたときに行わなければならないのは、sk->sk_socket->fileが指し示すアドレスがテーブルのエントリと一致するまで、現在のプロセスのオープンファイルテーブルをループすることだけです。