Reputation: 6484
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
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