2014-01-24 57 views
4

給定一個已建立的TCP會話的本地IP和端口,我可以找出哪一方發送了初始SYN?也就是說,這種聯繫是主動還是被動地打開?我需要一些在Linux上用C/C++工作的東西。一個怪異的方式可能是套接字()/聽()並抓住EADDRINUSE,但我希望有更清潔的東西。我甚至不確定一旦會話建立後內核是否會跟蹤這一點。確定誰打開了一個TCP會話

編輯:我也不想打電話給netstat(甚至是ss),因爲兩個都打開很多套接字太慢。這段代碼會經常被調用。

+0

有趣的問題(+1) – NPE

+1

這裏有什麼用? – EJP

+1

@EJP:識別給定流是源自本機還是遠程機器。 – markdrayton

回答

2

始終客戶端通過發送SYN(到服務器)進行活動連接。所以,對於一個本地IP和端口號,檢查是否使用以下命令它監聽套接字:

netstat --listening | grep given_ip:given_port 

如果沒有列在這裏,那麼它是一個客戶端套接字,從而啓動SYN。如果它在那裏,那麼它是一個監聽插座,因此它已經收到SYN

相應的代碼如下:

system("netstat --listening | grep given_ip:given_port > tmp.txt"); 
int fd = open("tmp.txt", O_RDONLY); 
char buf[100] ; 
if(read(fd,buf,100)>0) 
    printf("The socket has received a SYN!"); 
else 
    printf("The socket has sent a SYN!"); 

編輯:

如果你覺得netstat有速度差掃描整個港口,然後再實現牢度的唯一方法是打開一個raw socket並將其設置爲接收所有TCP數據包。

只處理其中包含SYN的數據包。現在,將source address:portdestination address:port都存儲到兩個表中。一個是SYN的發件人,另一個是收件人。

現在,當您獲得端口和IP地址時,對迄今爲止存儲的數據製作一個scan。您也可以使用STL mapC++來實現更快的結果。

由於可能有很多請求,因此map可能會被快速填滿,從而使查找速度變慢。我建議你也處理FIN數據包,並基於該數據包從表中刪除相應的條目。

+2

感謝您的支持。我希望得到除netstat之外的東西,因爲它在打開數千個套接字時速度很慢。我會用這個更新這個問題。 – markdrayton

+0

@markdrayton我希望編輯能夠幫助你。 :) – nitish712

+1

當偵聽套接字的TCP服務器接受客戶端連接時,accept調用返回一個單獨的套接字/端口,它本身並不處於偵聽狀態 - 這是一個點對點連接:不是找出該狀態下的套接字是由服務器接受還是傳出客戶端連接創建的? 'netstat --listening'對此沒有幫助。 –