2017-05-16 40 views
1

有沒有辦法在內核中從struct sock類型的對象獲取套接字fd?快速查看struct sock並不能幫助找到類似套接字描述符的內容。基本上我需要什麼socket()系統調用返回,它不存儲在'襪子'?從'struct sock'派生套接字fd

我需要得到fd在數據包命中IP堆棧之前。

謝謝。

+2

FD號碼只在每個進程的基礎存在,因此目前還不清楚是什麼你需要在內核中要求FD時。 – Martin

+0

@Martin,感謝您的評論。基本上,當我有'struct sock'對象時,我想能夠知道它對應的用戶空間中的哪個'fd'。 – Mark

+1

我的意思是,你可能需要以其他方式開始。採取特定進程的文件描述符表,遍歷它並檢查一些記錄是否指向有問題的套接字。在一個或多個用戶空間任務中,同一個套接字可以被更多的fds引用。 (對不起,現在沒有詳細的答案,因爲我需要檢查一些細節,現在沒有時間,也許以後如果沒有人會更快回答。) – Martin

回答

3

對於每個進程,都有一個表文件描述符,它將文件描述符映射到struct file對象。您可以使用iterate_fd()函數遍歷此表。

對於任何struct file您可以使用sock_from_file()函數確定其對應的struct sock對象。

總數:

/* 
* 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 
} 
+0

請注意,完全有可能會有沒有打開套接字的進程,打開套接字的多個進程,甚至具有多次打開相同套接字的進程。 –

+0

@Tsyvarev,謝謝你的回答。我是否正確,您所建議的代碼只能在流程環境中使用?否則,我將如何獲得'task_struct'指針?我需要在數據包進入IP堆棧之前獲得'fd'。 – Mark

+0

這不需要是*進程上下文*。你可以在前面某處存儲'task_struct',並在這裏使用它。或者遍歷所有找到的任務,其中包含給定的'sock'對象。無論如何,你需要'task_struct'對象,因爲文件描述符*沒有意義。在評論中對你的問題和我的回答確實如此。 – Tsyvarev