2012-04-02 94 views
0

有没有办法从struct sock或其他任何方式获得sockfd,以便我可以唯一地标识我在内核空间中使用的套接字/连接?如何从内核空间获取sockfd?

我需要在网络适配器的设备驱动程序的上下文中的这条信息。

+0

而这将如何唯一标识一个套接字/连接?它是哪种类型的连接?例如:TCP连接由(接口,源地址,源端口,目的地址,目标端口)元组唯一标识。 – ninjalj 2012-04-02 23:36:00

+0

实际上,我并没有自己建立连接,而是要求网卡执行此操作。 NIC正在返回对我的连接打开请求的确认,但本地端口将是NIC处理的端口,而不是主机堆栈处理的端口。我需要将链接到我的'sock'结构的文件句柄解复用传入的数据包。 – Asblarf 2012-04-03 00:20:13

回答

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

你当然会想检查空指针,从struct sock *sk在参数传递。

所以,基本上,这个想法是文件描述符(一个sockfd毕竟是一个常规文件描述符)的数值对应于其在进程打开文件表中的相应条目的索引。当指定struct sock *sk指针时,我们必须执行的操作是在当前进程的打开文件表上循环,直到sk->sk_socket->file指向的地址与表中的条目相匹配。