2016-01-26 124 views
3

是否可以在以下情況下提取目標IP地址和源IP地址?我能夠從in_buffer中提取以太網源和目標地址。任何建議,如果有可能做到這一點?從C++緩衝區中提取IP地址(Linux套接字)

sockaddr_ll sockaddr = sockaddr_ll(); 

sockaddr.sll_family = PF_PACKET; 
sockaddr.sll_protocol = htons(ETH_P_ALL); 
// is the interface index of the interface 
sockaddr.sll_ifindex = if_nametoindex(argv[1]); 
sockaddr.sll_hatype = 1; 

boost::asio::io_service io_service; 

raw_protocol_t::socket socket(io_service, raw_protocol_t(PF_PACKET, SOCK_RAW)); 
socket.bind(raw_endpoint_t(&sockaddr, sizeof(sockaddr))); 

boost::asio::generic::raw_protocol::socket::receive_buffer_size option; 
socket.get_option(option); 

std::string in_buffer(option.value(), '\0'); 

raw_endpoint_t rep = raw_endpoint_t(); 

while (true) 
{ 
    size_t len = socket.receive_from(boost::asio::buffer(&in_buffer[0], in_buffer.size()), rep); 
} 
+0

對不起,如果這是從你的代碼顯而易見,但是二進制或可讀形式的IP地址? – Downvoter

+0

以及我不知道。我試圖提取它們 – Mazzy

+0

如果你不知道,那麼提取它們是不可能的。你至少要知道地址的格式。你能打印出來沒有任何進一步的轉換?如果是的話,它們是字符串,即可讀。 – Downvoter

回答

1

是的,您可以從原始數據包緩衝區讀取IP地址。當然只有在數據包中有IP地址的情況下。如果協議是IP,存儲在in_buffer中的數據包含完整的數據包,包括IP報頭。

注意收到的數據可能包含任何協議。它可以是IPv4,然後你可以在那裏找到IP地址,但是它可以是IPv6或者沒有IP地址的更加模糊的協議。

假設接收到的數據包是包含IPv4數據的Ethernet-II數據包。然後你就可以輕鬆獲得IP地址:

// Source addr 
    printf("%d.%d.%d.%d", (unsigned char)(in_buffer[26]), 
         (unsigned char)(in_buffer[27]), 
         (unsigned char)(in_buffer[28]), 
         (unsigned char)(in_buffer[29])); 
    // Destination addr 
    printf("%d.%d.%d.%d", (unsigned char)(in_buffer[30]), 
         (unsigned char)(in_buffer[31]), 
         (unsigned char)(in_buffer[32]), 
         (unsigned char)(in_buffer[33])); 

當然這是不是很好,你需要檢查緩衝區包含的期望是什麼,但它是由你。

什麼是幻數意味着26 - 32?

以太網II標頭的大小爲14個字節。前6個字節是目標MAC,接下來的6個字節是源MAC和最後2個字節ethertype。以太網類型0x0800表示數據包含IPv4。源IPv4地址在IP報頭的偏移12處,目的IP在偏移16處。因此,幻數26意味着從數據包開始和其14(ethernetHeaderSize)+12(offsetInIPHeader)的偏移。

+0

和源端口和目標端口? – Mazzy

+0

端口更復雜。它們位於UDP或TCP標頭中。您需要確定IP頭的長度(通常爲20個字節,但可能更長),確定有效負載的類型(IP頭中偏移9處的1個字節),如果它是TCP或UDP讀取端口,則爲'unsigned short' s從UDP或TCP報頭。請參閱RFC中的標題定義或https://en.wikipedia.org/wiki/IPv4,https://en.wikipedia.org/wiki/Transmission_Control_Protocol https://en.wikipedia.org/wiki/User_Datagram_Protocol。或者你可以使用現有的庫進行頭部處理,如http://research.wand.net.nz/software/libtrace.php –

+1

@ZabojCampula我確信緩衝區索引中存在錯誤。當你重新索引目標地址時,你需要從緩衝區中的相同位置獲取最後兩個八位字節。 – Croolman