packet captured和packet received by filter到底有什么区别

我用的是linux. 结论是 packet received by filter是tcpdump从内核中拿到的且匹配命令上行指定的过滤条件的包, packet captured是经由pcap_loop, 或 pcap_dispatch 或 pcap_next,把包交给回调处理过的包的数量。这两个数字的差值是tcpdump抓到的,还来不及处理的包。 下面是讨论的一些细节: ///////////// tcpdump的最后输出. 592个包captured,  1184个包received by filter。。这个差值是不是表示有多少包tcpdump没来得及处理. man tcpdump上写得好复杂,received by filter的数字取决于OS… 1. 包匹配不匹配命令行上指定的filter都算,如果匹配,有没有被tcpdump读出都算..   2. 只有匹配命令行上指定的filter的包才算,有没有被tcpdump读出都算.   3. 只有匹配filter才算,只有被tcpdump读出才算. 我的理解是:如果是第3种,那captured的数字和received by filter的数字就是一样的。 第2种的差值表示tcpdump来不及处理的包数量,理想状态上差值能为0.   第1种情况,基本上总是有差值。 我猜测我用的linux上应该是第2种情况.  wangbin579() 10:18:54  应该是匹配的才算received by filter,但奇怪的是,为啥你的系统,captured怎么少? wangbin579() 10:19:30  [root@hz0-12-157 ~]# tcpdump -i any tcp and port 36524 or 3306 -w all.pcap tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes 10757 packets captured 11171 packets received by filter 334 packets dropped by kernel wangbin579() 10:20:07  我们这边系统,基本可以认为packets received by filter=packets captured + packets dropped by kernel siu¹ººººººº() 10:23:38  /homemus/tmp # time time tcpdump -i tunl0:1  -w tmp tcpdump: listening on tunl0:1, link-type RAW (Raw IP), capture size 96 bytes 19508 packets captured 39021 packets received by filter 0 packets dropped by kernel 0.01user 0.02system 0:17.04elapsed 0%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (0major+506minor)pagefaults 0swaps real    0m17.139s user    0m0.012s sys     0m0.028s wangbin579() 10:26:03  如果是差是丢包,那么通过查看抓包文件,应该能看出很多不完整的session siu¹ººººººº() 10:28:46  我觉得差值是来不及写入磁盘的包. siu¹ººººººº() 10:29:04  再研究看看了。。谢谢啦/.. wangbin579() 10:30:03  packets captured是pcap_loop所设置的回调函数所调用的,一旦调用回调函数,就用统计 wangbin579() 10:30:37  有可能内核态部分和用户态部分,速度上不匹配,有延迟导致的? siu¹ººººººº() 10:32:33  我现在理解, received by filter是pcap库从内核中拿到的又匹配命令行上filter的包的数量, packets captured是经由pcap_loop, pcap_dispatch之类通过callback交付出去的包数量. 差值就是还没来得及处理的. wangbin579() 10:32:48  17s,每秒也就2000多个,不算多,用户态程序应该来得及处理 wangbin579() 10:33:58  我这边系统很破,处理速度也比这个快,也没有来不及处理 wangbin579() 10:34:45  看看我的: wangbin579() 10:34:47  [root@hz0-12-157 ~]# time tcpdump -i any tcp and port 36524 or 3306 -w 3306.pcap          tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes 294663 packets captured 295432 packets received by filter 693 packets dropped by kernel real    0m17.676s user    0m0.897s sys     0m3.502s wangbin579() 10:35:52  量比你大7倍多,也没有出现来不及处理啊,当然我的是物理机,3G内存, siu¹ººººººº() 10:36:59  呃 那你觉得这个差值不是来不及处理的包么?。我觉得应该还是来不及处理的。我在想,可能是写到的磁盘文件系统是NFS之类的 ….我继续排查一下。 wangbin579() 10:37:43  有可能,我的是写入本地磁盘。 wangbin579() 10:37:58  你这种情况,我还是第一次碰到 siu¹ººººººº() 10:39:05  我先去运维那边了解下情况…多谢啦  wangbin579() 10:39:18  算涨见识了,还以为一般dropped by kernel为0就代表不丢包呢,居然还有你这种情况。 你可以看看抓包文件,session是不是很多不完整,如果不完整,你的推测是对的 siu¹ººººººº() 10:39:58  嗯。呵呵~~ 做IT,每天都会碰到挑战宇宙规律的现象。 siu¹ººººººº() 10:40:07  мe(~ o мe(632813052) 10:41:09  呵呵 wangbin579() 10:41:24  其实,网络方面的问题,最复杂了。 我现在已经陷入到网络的汪洋大海之中了,各种各样的问题都会有,而且没有尽头。 早知道如此,3年前我就不搞这一块了 siu¹ººººººº() 10:42:30  同感。写一点点代码,都非常难以调试。各种认为理所当然的假设,通通是bug的温床 @wangbin579  麻烦你在tcpdump前加个time,。。把输出贴出来。我好像看出问题来了。 [root@hz0-12-157 ~]# time tcpdump -i any tcp and port 36524 or 3306 -w 3306.pcap          tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes 294663 packets captured 295432 packets received by filter 693 packets dropped by kernel real    0m17.676s user    0m0.897s sys     0m3.502s wangbin579() 10:56:03  不是加了time了吗? wangbin579() 10:57:15  [root@hz0-12-157 ~]# time time tcpdump -i any tcp and port 36524 or 3306 -w 3306.pcap tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes ^C202061 packets captured 202523 packets received by filter 369 packets dropped by kernel 0.66user 2.50system 0:11.99elapsed 26%CPU (0avgtext+0avgdata 24208maxresident)k 0inputs+105656outputs (0major+660minor)pagefaults 0swaps real    0m11.999s user    0m0.661s sys     0m2.506s wangbin579() 10:57:26  加两个,结果如上 siu¹ººººººº() 10:59:29  问题找到的。我这边运行的tcpdump,根本就没有抢到cpu时间来处理. wangbin579() 11:00:05  siu¹ººººººº() 11:00:06  Real  0m3.914s User  0m0.008s Sys   0m0.000s 跑了4秒钟,用户空间才抢到0.008秒,内核态几乎是0 …. siu¹ººººººº() 11:00:25  那个差值确实是没有来得及处理的包的数量。 wangbin579() 11:00:41  奥,那你系统这么繁忙啊 siu¹ººººººº() 11:02:22  所以,解决了一个问题又会有新的颠覆宇宙规律的问题…系统负载很高,但cpu使用率很低。。 copyright ykyi.net  

November 22, 2013 · 1 min · kamus

Linux抓包技术简介

Linux抓包技术简介 Author: zausiu@gmail.com 1. 简介 大多数应用常景下,我们在IP层上用AF_INET或AF_INET6作为socket的第一个参数,SOCK_STREAM或SOCK_DGRAM作为socket的第二个参数创建最为常见的IPv4或IPv6的TCP或UDP套接字。这样的套接字满足了绝大多数网络应用常景。   本文简单介绍三种Linux平台下抓包,截获包的技术。它们提供一些更酷的功能。每种技术的水都很深,作者个人水平有限,按照自己的理解做一般的介绍。仅仅旨在起到科谱的作用。   2. RAW SOCKET 参数SOCK_RAW可以作为socket函数的第二个参数传入,这样创建的套接字称为原始套接字。设置Socket的第一个参数可以让指定原始套接字开在数据链路层上或者网络层。   下面的语句创建在数据链路层上的原始socket。 Socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));   在负载不大的情况下,读这个socket可以拿到本机收到的所有数据包。写入这个socket需要程序员负责填充各种包头的数据。   Socket(AF_INET, SOCK_RAW, xxxxx协议号); 在IP层上创建IPv4的RAW socket,可以拿到各种经由IPv4的数据包,比如ICMP包,IGMP包等。Steven的第三版第28.4节,第二段:“系统收到的UDP包和TCP包不会传给原始套接字”。但读tcpcopy的源代码时,确实用了原始套接字在网络层读UDP和TCP包。难道书上写的过时了。见代码,来自tcpcopy: #if (TCPCOPY_UDP)         fd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP); #else         fd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); #endif 另外,在IP层上创建的原始套接字有一个选项:IP_HDRINCL,它被开启时,则内核帮助填充IP包头。Linux默认没有开启这个选项。   3. NF_Queue NF_Queue是用户空间的一个库,需要内核模块NETFILTER_NETLINK_QUEUE的支持。官方网址:http://www.netfilter.org。通过这个库可以在数据包被发往用户空间处理前截获数据包,或者在数据包被发往网卡前截获数据库。截获后,可以修改数据包的内容,并决定是否丢充这个数据库。 NF_Queue可以用来编写防火墙等安全软件。 Tcpcopy使用NF_Queue丢弃测试中的程序回复给真实客户程序的数据包,使测试中程序回复的报文不影响真实客户程序。 另一个提供类似功能的库是IP_Queue,它已经被废弃。NF_Queue可以完全取代IP_Queue。我们用的tlinux,内核中built-in了NF_Queue模块。   4. libpcap 大名鼎鼎的Libpcap是一个古老的可以工作在所有Unix-like平台上的抓包库,比linux年纪更大。Tcpdump的广泛使用让libpcap成为事实上的行业标准。它可以很方便的编写抓取数据链路层上的数据包,并可以设置过滤条件在内核级别只复制关心的数据包,而数据链路层上的原始套接字会尽最大努力复制所有的包,所以libpcap的工作效率高。而且,pcap使用方便。下面是一个很简单的使用pcap抓到发往80端口的tcp包并打印源IP,目的IP,和目的端口号的程序。非常短,很容易看,起到介绍libpcap的作用。  int main(int argc, char *argv[])  { pcap_t *handle; // pcap用的句柄,和其它各种句柄一样。 char *dev;         // 网络接口名,如eth0, eth1, tunl0 之类 char errbuf[PCAP_ERRBUF_SIZE]; // 存描述出错原因的缓冲 struct bpf_program fp;         // pcap用来过滤数据包用 char filter_exp[] = "tcp and dst port 80"; // 过滤字符串,和tcpdump的写法一样 struct pcap_pkthdr header;      // pcap自己用的包头 const u_char *packet;         // pcap包头后的数据,即抓到的数据   int len_of_iphdr;         // ip头的长度 struct in_addr src_ip;    // 源IP地址 struct in_addr dst_ip;    // 目的IP const u_char *ip_hdr_addr; // IP头的首地址 const u_char *tcp_hdr_addr;     // tcp头的首地址 struct tcphdr *tcp_hdr;         // tcp头结构体 u_short dst_port;             // 目的端口   // 如果命令行指定网卡名 if (argv[1]) dev = argv[1]; //就用指定的网卡 else dev = "eth0"; //否则用eth0   }                  // 用pcap打开这个网卡 handle = pcap_open_live(dev, BUFSIZ, 0, 1000, errbuf); if (handle == NULL) {  // 打开网卡出错 fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf); return(2); }                // 编译过滤文件 if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) { fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle)); return(2); }         // 设置过滤条件 if (pcap_setfilter(handle, &fp) == -1) { fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle)); return(2); }           // 抓包 packet = pcap_next(handle, &header);   // 至此packet指向抓到的一个目标端口号是80的数据链路层的包 // 它的包结构是 14字节以太网包头 + 可变IPv4包头 + TCP包头 ip_hdr_addr = (u_char*)(packet + sizeof(struct ethernet_hdr)); src_ip.s_addr = ((struct iphdr*)ip_hdr_addr)->saddr; dst_ip.s_addr = ((struct iphdr*)ip_hdr_addr)->daddr; len_of_iphdr = ((struct iphdr*)ip_hdr_addr)->ihl * 4; tcp_hdr_addr = ip_hdr_addr + len_of_iphdr; tcp_hdr = (struct tcphdr*)tcp_hdr_addr; dst_port = tcp_hdr->dest;   // 经过上面的各种指针偏移,下面打印源IP和目标IP和目标端口. printf("src addr %s\n", inet_ntoa(src_ip)); printf("dst addr %s\n", inet_ntoa(dst_ip)); printf("dst_port %d\n", ntohs(dst_port));   /* And close the session */ pcap_close(handle);   return(0);  }   5. 总结 本文只是一个非常简单的介绍。如需要进阶学习,Stevens的网络编译有更详细地关于Raw Socket的内容,研究NF_Queue技术则需要读源代码和收集散在社区各个角落的资料了,而讲libpcap有两篇很好的文章: "Programming with Libpcap – Sniffing the network from our own application "用Libpcap编程,在我们的程序中嗅探网络。非常漂亮的pdf文档。 http://recursos.aldabaknocking.com/libpcapHakin9LuisMartinGarcia.pdf The Sniffer’s Guide to Raw Traffic 嗅探器教程。斯坦福大学的Geek于大概2001年写的。 http://yuba.stanford.edu/~casado/pcap/section1.html copyright ykyi.net

September 10, 2013 · 1 min · kamus

traceroute failed.Specify protocal traceroute used manually to fix it.

Today, I ran the traceroute program on a machine running FreeBSD. It failed once and again. Traceroute complained: traceroute: sendto: Permission denied. So I tried to ping. Ping failed, too. I then checked out the configuration of the firewall, which actually denied the pass through of ICMP packet. So I set it to allow ICMP pacakges to pass through the firewall. Ping worked as I expected. But traceroute still failed. ...

June 20, 2012 · 1 min · kamus

tcpdump基础教程

英文原文出自: A tcpdump Tutorial and Primer 翻译: ykyi.net Tcpdump是信息安全专业人士最重要的一个网络分析工具。对这个工具有一个深入的理解对于每一个喜欢透彻理解tcp/ip协议栈的人来话都是必须的。但很多人选择一个更高级别的工级,比如Ethereal Wireshark,但是我认为这是一个错误! 不应该机械的反复记忆概念而应该做到真正的理解,因为对tcp/ip协议簇保持清醒的认知非常的重要。如果对该协议簇能够完全精通,那你调试网络的能力则能比同行们高出几个档次。但是,要学精神tcp/ip协议簇,只有不够的实践剖析它们才能做到。 当你使用某种工具来显示网络中的原始流量信息时,人类,而不是机器,就要承担起分析这些流量的重任了。用这种方法就可以不断地加深对tcp/ip的理解。并且,用这种学习方法的时候,我在任何可能的情况下都强烈主张使用tcpdump而不是其它工具。 选项 下面将列出一些用例子的选项,这样可以在你使用这个工具时对你有很大的帮助。这些选项很容易淡忘或与其它类型的滤镜(Filter,笔者认为这里的滤镜实际上指的是其它网络工具)混淆。比如, ethereal。所以,希望这篇文章可以作为一个参考文档,我就是这样使用它的。 首先,我要先介绍几个我认为很方便的tcpdump的选项。第一个是 -n, 这样的话域名就不会被解析了,而是用数字IP的形式显示地址(译者注: 同netstat的-n是一样的喔)。第二个是 -X, 这样就会同时把包的内容以ASCII码和十六制的形式显示。最后一个是 -S, 它个选项会显示绝对序号而不是相对序号。因为当包被隐藏起来的话,你也不会看到奇怪的序号。请谨记,tcpdump较之其它工具的优势之一就是可以与包(packets)手工交互。 值得注意的是,tcpdump默认只会从packet中取出前96个字节。如果你想要多一些的话,那就需要需要把 -s xxxx 加上。这里的xxxx是你确切想要抓取的总字节数。如果我使用这个选项的话,我通常会把这个数字设定为1514而得到所有的数据。下面是一个简短的列表列出我经常使用的选项。 -i any: 监听所有的介面。这样你就知道是不是有流量产生。 -n: 不要解决主机名,以IP数字形式显示主机。 -nn: 不要解析主机名或端口名字。 -A: 以ASCII字符显示包的数据。 -X: 同时以十六进制和ASCII字符显示包的数据。 -XX: 同-X,但也会显示 Ethernet头部。 -v, -vv, -vvv: 详细,更详细,再详细些! 冗余输出得到的包信息。 -c: 抓取 x 个包后就停下。 -S: 打印绝对序号。 -e: 同时得到Ethernet头部。 -q: 显示少一点协议信息。 -E: 用提供的密钥解密 IPSEC 流量。 -s: 设置显示前多少个字节的包内容(snaplength)。 tcpdump 4.0的snaplength的长度从68字节改成了96字节,这样你就可以看到多些内容了。但仍然看不到所有的内容,指定 -s 1514 得到包的所有内容。 http://ykyi.net 一些基本的应用 根据我要查看的不同流量,我使用不同的选项组合,如下: 1.Basic communication // see the basics without many options tcpdump -nS ...

October 31, 2010 · 4 min · kamus