Как получить sockfd из пространства ядра? - PullRequest
0 голосов
/ 02 апреля 2012

Есть ли способ получить sockfd из struct sock или любой другой способ, который позволил бы мне однозначно идентифицировать сокет / соединение, с которым я работаю, в пространстве ядра?

Мне нужноэта часть информации в контексте драйвера устройства для сетевого адаптера.

1 Ответ

2 голосов
/ 20 марта 2014

Я думал, что это невозможно, но на самом деле есть способ, по крайней мере для простых случаев, когда у нас нет дубликатов файловых дескрипторов для одного сокета.Я отвечаю на свой вопрос, надеясь, что это поможет людям.

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

Вы, конечно, захотите проверить NULL-указатели, начиная с struct sock *sk, переданного в параметре.

Итак, в принципе, идея заключается в том, что числовое значение дескриптора файла (в конце концов, sockfd - это обычный дескриптор файла) соответствует индексу соответствующей записи в таблице открытых файлов процесса.Все, что нам нужно делать, когда указатель struct sock *sk - это цикл по таблице открытых файлов текущего процесса, пока адреса, на которые указывает sk->sk_socket->file, не совпадут с записью в таблице.

...