2015-10-08 44 views
1

我正在開發一種類似於traceroute,發送TCP/UDP數據包並監聽傳入TCP/UDP應答數據包或ICMP超時消息的Linux C應用程序。在Linux C應用程序中的原始套接字VS Libpcap

我想它應該比使用原始套接字更容易使用libpcap,但是有沒有點選擇原始套接字而不是libpcap?

是否有在

  • 性能方面的差異(我的應用程序是如何快速獲取傳入數據包)通過我的主人,但沒有收到

  • CPU使用率

  • 丟包(包我的應用 - 由於延遲,超時或其他原因 - 特別是在CPU使用率高,網絡流量高和網絡性能低的情況下)?

我沒有考慮到其他差異嗎?

如果應用程序在Android而不是Linux上運行,是否還有其他優點和缺點?

謝謝。

回答

1

是的,有一個非常大 con:libpcap不是你要找的。

lipcap本身對構建/分析TCP,UDP,ICMP(甚至IP)數據包的支持絕對爲零。這根本不是它製造的。它可以設置過濾器匹配某些TCP/UDP等,但通過這一點,你必須做你自己的所有解析。

你應該看看PCAP官方教程:

http://www.tcpdump.org/pcap.html

轉到節 「實際的嗅探」。看回調的libpcap的原型將調用時,它會捕捉數據包匹配過濾:

void got_packet(u_char *args, 
       const struct pcap_pkthdr *header, 
       const u_char *packet); 

您將收到的數據包只是一個字符指針。你必須自己完成所有的解析。隨着教程繼續:

但你如何使用這個變量(在我們的 原型中命名爲「數據包」)?一個數據包包含許多屬性,所以你可以想象,它不是一個真正的字符串,而是實際上是一個結構集合 (例如,一個TCP/IP數據包將有一個以太網報頭,一個IP報頭,一個IP報頭,一個TCP報頭,最後是數據包的有效載荷)。這個u_char指針指向這些結構的序列化版本。要使 有任何用處,我們必須做一些有趣的類型轉換。

然後你有一些代碼可以做到這一點(有一些簡化,以便它不是10公里長,就像「以太網標頭總是正好14個字節」 - 嘗試在VLAN上!)。從那時起,對於這個數據包解析,沒有任何代碼是由pcap提供的。

看看pcap API。你看到任何與IP/TCP/UDP/ICMP相關的東西嗎?

pcap_activate (3pcap) - activate a capture handle 
pcap_breakloop (3pcap) - force a pcap_dispatch() or pcap_loop() call to return 
pcap_can_set_rfmon (3pcap) - check whether monitor mode can be set for a not-yet-activated capture handle 
pcap_close (3pcap) - close a capture device or savefile 
pcap_compile (3pcap) - compile a filter expression 
pcap_create (3pcap) - create a live capture handle 
pcap_datalink (3pcap) - get the link-layer header type 
pcap_datalink_name_to_val (3pcap) - get the link-layer header type value corresponding to a header type name 
pcap_datalink_val_to_description (3pcap) - get a name or description for a link-layer header type value 
pcap_datalink_val_to_name (3pcap) - get a name or description for a link-layer header type value 
pcap_dispatch (3pcap) - process packets from a live capture or savefile 
pcap_dump (3pcap) - write a packet to a capture file 
pcap_dump_close (3pcap) - close a savefile being written to 
pcap_dump_file (3pcap) - get the standard I/O stream for a savefile being written 
pcap_dump_flush (3pcap) - flush to a savefile packets dumped 
pcap_dump_fopen (3pcap) - open a file to which to write packets 
pcap_dump_ftell (3pcap) - get the current file offset for a savefile being written 
pcap_dump_open (3pcap) - open a file to which to write packets 
pcap_file (3pcap) - get the standard I/O stream for a savefile being read 
pcap_fileno (3pcap) - get the file descriptor for a live capture 
pcap_findalldevs (3pcap) - get a list of capture devices, and free that list 
pcap_fopen_offline (3pcap) - open a saved capture file for reading 
pcap_fopen_offline_with_tstamp_precision (3pcap) - open a saved capture file for reading 
pcap_free_datalinks (3pcap) - get a list of link-layer header types supported by a capture device, and free that list 
pcap_free_tstamp_types (3pcap) - get a list of time stamp types supported by a capture device, and free that list 
pcap_freealldevs (3pcap) - get a list of capture devices, and free that list 
pcap_freecode (3pcap) - free a BPF program 
pcap_get_selectable_fd (3pcap) - get a file descriptor on which a select() can be done for a live capture 
pcap_get_tstamp_precision (3pcap) - get the time stamp precision returned in captures 
pcap_geterr (3pcap) - get or print libpcap error message text 
pcap_getnonblock (3pcap) - set or get the state of non-blocking mode on a capture device 
pcap_inject (3pcap) - transmit a packet 
pcap_is_swapped (3pcap) - find out whether a savefile has the native byte order 
pcap_lib_version (3pcap) - get the version information for libpcap 
pcap_list_datalinks (3pcap) - get a list of link-layer header types supported by a capture device, and free that list 
pcap_list_tstamp_types (3pcap) - get a list of time stamp types supported by a capture device, and free that list 
pcap_lookupdev (3pcap) - find the default device on which to capture 
pcap_lookupnet (3pcap) - find the IPv4 network number and netmask for a device 
pcap_loop (3pcap) - process packets from a live capture or savefile 
pcap_major_version (3pcap) - get the version number of a savefile 
pcap_minor_version (3pcap) - get the version number of a savefile 
pcap_next (3pcap) - read the next packet from a pcap_t 
pcap_next_ex (3pcap) - read the next packet from a pcap_t 
pcap_offline_filter (3pcap) - check whether a filter matches a packet 
pcap_open_dead (3pcap) - open a fake pcap_t for compiling filters or opening a capture for output 
pcap_open_dead_with_tstamp_precision (3pcap) - open a fake pcap_t for compiling filters or opening a capture for output 
pcap_open_live (3pcap) - open a device for capturing 
pcap_open_offline (3pcap) - open a saved capture file for reading 
pcap_open_offline_with_tstamp_precision (3pcap) - open a saved capture file for reading 
pcap_perror (3pcap) - get or print libpcap error message text 
pcap_sendpacket (3pcap) - transmit a packet 
pcap_set_buffer_size (3pcap) - set the buffer size for a not-yet-activated capture handle 
pcap_set_datalink (3pcap) - set the link-layer header type to be used by a capture device 
pcap_set_immediate_mode (3pcap) - set immediate mode for a not-yet-activated capture handle 
pcap_set_promisc (3pcap) - set promiscuous mode for a not-yet-activated capture handle 
pcap_set_rfmon (3pcap) - set monitor mode for a not-yet-activated capture handle 
pcap_set_snaplen (3pcap) - set the snapshot length for a not-yet-activated capture handle 
pcap_set_timeout (3pcap) - set the read timeout for a not-yet-activated capture handle 
pcap_set_tstamp_precision (3pcap) - set the time stamp precision returned in captures 
pcap_set_tstamp_type (3pcap) - set the time stamp type to be used by a capture device 
pcap_setdirection (3pcap) - set the direction for which packets will be captured 
pcap_setfilter (3pcap) - set the filter 
pcap_setnonblock (3pcap) - set or get the state of non-blocking mode on a capture device 
pcap_snapshot (3pcap) - get the snapshot length 
pcap_stats (3pcap) - get capture statistics 
pcap_statustostr (3pcap) - convert a PCAP_ERROR_ or PCAP_WARNING_ value to a string 
pcap_strerror (3pcap) - convert an errno value to a string 
pcap_tstamp_type_name_to_val (3pcap) - get the time stamp type value corresponding to a time stamp type name 
pcap_tstamp_type_val_to_description (3pcap) - get a name or description for a time stamp type value 
pcap_tstamp_type_val_to_name (3pcap) - get a name or description for a time stamp type value 

(和BTW沒有什麼要麼構建包,只是爲了發送一些)

現在,關於原始套接字的想法:

如果你想發送和接收TCP和UDP,爲什麼不直接使用TCP和UDP套接字?

最後,看這裏和谷歌周圍網絡庫,將最適合您的需要:

Best C/C++ Network Library

+0

謝謝JBM,還有在服務表現的任何差異,也? 我有一個使用libpcap的同一應用程序的舊版本,而我的使用原始套接字。 我已經實現了,我的速度更快,並且比舊的顯示更多的數據包(特別是當有很多流量時),但我不確定這是否是圖書館或其他實施選擇的問題。 –

+0

「表現」問題不在話題中。你說「我想種西紅柿」,並問:「我打算使用沙拉或馬鈴薯種子,會有性能差異嗎?」 – jbm