Mark
Mark

Reputation: 6484

derive socket fd from 'struct sock'

Is there a way to obtain a socket fd from object of type struct sock in the kernel? Quick look inside of struct sock doesn't help to find something that looks like socket descriptor. Basically I need what socket() syscall returns, is it not stored in 'sock' ?

I need to get fd at the point before a packet hits IP stack.

Thanks.

Upvotes: 1

Views: 1363

Answers (1)

Tsyvarev
Tsyvarev

Reputation: 66061

For each process there is a table of file descriptors, which maps file descriptors to struct file objects. You may iterate over this table using iterate_fd() function.

For any struct file you may determine which struct sock object it corresponds using sock_from_file() function.

In total:

/*
 * Callback for iterate_fd().
 *
 * If given file corresponds to the given socket, return fd + 1.
 * Otherwise return 0.
 *
 * Note, that returning 0 is needed for continue the search.
 */
static int check_file_is_sock(void* s, struct file* f, int fd)
{
    int err;
    struct sock* real_sock = sock_from_file(f, &err);
    if(real_sock == s)
        return fd + 1;
    else
        return 0;
}
// Return file descriptor for given socket in given process.
int get_fd_for_sock(struct sock* s, struct task* p)
{
    int search_res;
    task_lock(p);
    // This returns either (fd + 1) or 0 if not found.
    search_res = iterate_fd(p->files, 0, &check_file_is_sock, s);
    task_unlock(p);

    if(search_res)
        return search_res - 1;
    else
        return -1; // Not found
}

Upvotes: 3

Related Questions