linux c libpcap统计流量,在Linux C应用程序中的原始套接字VS Libpcap

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

lipcap本身对构建/分析TCP,UDP,ICMP(甚至IP)数据包的支持绝对为零。这根本不是它制造的。它可以设置过滤器匹配某些TCP/UDP等,但通过这一点,你必须做你自己的所有解析。

你应该看看PCAP官方教程:

转到节 “实际的嗅探”。看回调的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套接字?

最后,看这里和谷歌周围网络库,将最适合您的需要:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用socket来抓包,需要在程序创建一个原始套接字。下面是一个简单的示例程序,可以抓取指定IP地址和端口号的网络数据包: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> #include <netinet/tcp.h> #define BUFSIZE 65536 int main(int argc, char *argv[]) { int sock_raw, sock_tcp, recv_len; char buffer[BUFSIZE]; struct sockaddr_in saddr; struct iphdr *iph; struct tcphdr *tcph; if (argc != 3) { printf("Usage: %s <source IP> <destination IP>\n", argv[0]); exit(1); } // 创建原始套接字 sock_raw = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); if (sock_raw < 0) { perror("socket() error"); exit(1); } // 绑定原始套接字到指定源IP地址 saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = inet_addr(argv[1]); if (bind(sock_raw, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { perror("bind() error"); close(sock_raw); exit(1); } // 过滤指定目的IP地址和端口号的数据包 struct sockaddr_in daddr; daddr.sin_family = AF_INET; daddr.sin_addr.s_addr = inet_addr(argv[2]); struct sock_filter filter[] = { {0x28, 0, 0, 0x0000000c}, {0x15, 0, 5, 0x00000800}, {0x20, 0, 0, 0x0000001e}, {0x15, 0, 3, daddr.sin_addr.s_addr}, {0x20, 0, 0, 0x00000022}, {0x15, 0, 1, 0x0000006f}, {0x6, 0, 0, 0x0000ffff}, {0x6, 0, 0, 0x00000000}, }; struct sock_fprog fprog; fprog.len = sizeof(filter)/sizeof(filter[0]); fprog.filter = filter; if (setsockopt(sock_raw, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog)) < 0) { perror("setsockopt() error"); close(sock_raw); exit(1); } // 创建TCP套接字 sock_tcp = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock_tcp < 0) { perror("socket() error"); close(sock_raw); exit(1); } // 接收网络数据包并分析 while (1) { recv_len = recv(sock_raw, buffer, BUFSIZE, 0); if (recv_len < 0) { perror("recv() error"); close(sock_raw); close(sock_tcp); exit(1); } iph = (struct iphdr *)buffer; if (iph->protocol == IPPROTO_TCP) { tcph = (struct tcphdr *)(buffer + iph->ihl*4); if (ntohs(tcph->dest) == 80) { printf("Source IP: %s\n", inet_ntoa(*(struct in_addr *)&iph->saddr)); printf("Destination IP: %s\n", inet_ntoa(*(struct in_addr *)&iph->daddr)); printf("Source port: %d\n", ntohs(tcph->source)); printf("Destination port: %d\n", ntohs(tcph->dest)); } } } close(sock_raw); close(sock_tcp); return 0; } ``` 该示例程序使用了一个过滤器来过滤指定目的IP地址和端口号的数据包。过滤器是一个由一组过滤规则组成的程序,用于过滤网络数据包。在本示例,过滤器使用了Linux内核提供的BPF虚拟机进行解释和执行。可以通过修改过滤器规则来实现更复杂的过滤功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值