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

 

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的<Unix网络编程>第三版第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

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.

I was very confused, I tried to run the tcpdump to find out why. Tcpdump showed that traceroute was sending UDP packet. Oh, my gosh. I had always thought traceroute was implemented on ICMP. After I read the tcpdump manpage. I found traceroute default on using udp protocal, but user can switch to use icmp by indicating the -M icmp or -I(The capitalized i). Alternatively, you can also command traceroute to use raw packet of specified protocol for tracerouting by specifying -P(beware P is capitalized). When you use raw packet, the default protocol is 253 (rfc3692). So, I ran traceroute using the command as: traceroute -P ICMP www.the_host.com, everything worked fine.

COPYRIGHT WWW.DOGEYE.NET

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

1.基本通讯,不用太多选项睇睇基本的
tcpdump -nS

2.基本通迅,冗余输出。可以看到好多流量,
tcpdump -nnvvS

3. 深入一点查看流量。
tcpdump -nnvvXS // -X 选项必不会使tcpdump输出更多.

4. 看size大一点的包.
tcpdump -nnvvXSs 1514 // -s 1514 选项设定显示所有包内容。

下面的例子使用我们上文提到的选项抓取两个( -c2 )ICMP包(一个ping和一个pong)。请注意每个包我们都能看到些什么。

ykyi.net# tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 1514 bytes
00:20:39.722393 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto ICMP (1), length 84) 192.168.111.128 > 173.83.123.7: ICMP echo request, id 10621, seq 1, length 64
0x0000: 4500 0054 0000 4000 4001 e225 c0a8 6f80 E..T..@.@..%..o.
0x0010: ad53 7b07 0800 64e6 297d 0001 d745 cc4c .S{…d.)}…E.L
0x0020: d005 0b00 0809 0a0b 0c0d 0e0f 1011 1213 …………….
0x0030: 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 ………….!"#
0x0040: 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 $%&'()*+,-./0123
0x0050: 3435 3637 4567
00:20:40.064096 IP (tos 0x0, ttl 128, id 25296, offset 0, flags [none], proto ICMP (1), length 84) 173.83.123.7 > 192.168.111.128: ICMP echo reply, id 10621, seq 1, length 64
0x0000: 4500 0054 62d0 0000 8001 7f55 ad53 7b07 E..Tb……U.S{.
0x0010: c0a8 6f80 0000 6ce6 297d 0001 d745 cc4c ..o…l.)}…E.L
0x0020: d005 0b00 0809 0a0b 0c0d 0e0f 1011 1213 …………….
0x0030: 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 ………….!"#
0x0040: 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 $%&'()*+,-./0123
0x0050: 3435 3637 4567
2 packets captured
2 packets received by filter
0 packets dropped by kernel
ykyi.net#

表达式(Expressions)
使用表达式可以让你略去各种各样的流量而只得到你真正关注的。掌握表达式并且会创造性地使用组合技巧才使你真正发挥tcpdump的力量。有三种主要的表达式: type, dir 和 proto.

Type选项是host, net, 和 port. 方向用 dir 指示。可以这样 src, dst; src 或者 dst; 而且 src 和 dst。下面是一些你应该熟练掌握的例子。

host: 只查看指定IP或者指定主机的流量(当你使用 -n 选项时不可以指定主机名)
ykyi.net# tcpdump host 1.2.3.4

src, dst: 查看从 src 发出的,或者目的地是 dst 的流量(忽略会话的另一端)
•src, dst // find traffic from only a source or destination (eliminates one side of a host conversation)
ykyi.net# tcpdump src 2.3.4.5
ykyi.net# tcpdump dst 3.4.5.6

net: 使用无类别域间路由(CIDR,Classless Inter-Domain Routing)指定要抓包的网络。
# tcpdump net 1.2.3.0/24

proto: 指定要抓取的包的协议类型,可以指定tcp,udp,或icmp。可以不用敲入proto
# tcpdump icmp

port: 只查看从指定端口进出的流量
# tcpdump port 3389

src, dst port: 指定的源地址和端口号,或者目的地址和端口号。只抓取匹配指定地址端口的流量。
# tcpdump src port 1025
# tcpdump dst port 389

src,dst port, protocal : 组合三种指定条件.
# tcpdump src port 1025 and tcp
# tcpdump udp and src port 53

还有一个选项可以让你指定一个端口地址的范围
•Port Ranges
tcpdump portrange 21-23

指定包的大小
•Packet Size Filter // only see packets below or above a certain size (in bytes)
tcpdump less 32
tcpdump greater 128
tcpdump equal 64

tcpdump > 32 // 也可以使用数学符号
tcpdump

写入文件
用 -w 选项可以指定一个文件,把抓取到的内容存入该文件内。以后还可以用 -r 指定文件,把以前存入的内容再读回来。这是一个相当不错的方法,可以先抓取包,以后再用各种工具分析。

以这种形式抓到的流量是以tcpdump的格式储存的。这种格式在网络分析的工具之间非常通用。这意味着,像 Wireshark, Snort, 等工具也可以读取它。

把出入80端口的所有流量记录到文件中
# tcpdump -s 1514 port 80 -w capture_file

然后,在将来某个时候,你就能够把存在文件中的流量读回,比如:
# tcpdump -r capture_file

创造性的使用tcpdump
表达式确实不错,但是要真正发挥tcpdump的威力来自于创造性地组合使用各种表达式。这样就可以把你想要关注的信息单独抽出来。tcpdump有三种组合方式,如果你稍微懂点计算机,这简直太容易理解了。
1.与操作
and 或者 &&
2.或操作
or 或者 ||
3.非操作
not 或者 !

比如检测来自10.5.2.3去到端口3389的流量
# tcpdump -nnvvS tcp and src 10.5.2.3 and dst port 3389

检测来自网络 192.168.0.0/16 去到网络 10.0.0.0/8 或者网络 172.16.0.0/16 的流量
# tcpdump -nvX src net 192.168.0.0/16 and dst net 10.0.0.0/8 or 172.16.0.0/16

来自网络 172.16.16.0.0/16 去到主机 1292.168.0.2的 ICMP 流量.
# tcpdump -nvvXSs 1514 dst 192.168.0.2 and src net 172.16.0.0/16 and not icmp

从主机名为 Mars(火星) 或者 Pluto(冥王星) 发出的,目的地不是SSH端口的流量
# tcpdump -vv src mars or pluto and not dst port 22

你已经看到了,你可以创建不同的组合来完成不同的需要。关键在于你知道自己需要怎样的数据,然后就可以使用恰当的语法把它们提炼出来。

同时需要牢记在心的是,当你创建复杂的组合时,你可能会需要用单引号把几个选项括起来。使用单引号是为了告诉 tcpdump 忽略特殊字符(译者注: 同BASH一样)。比如这种情况, 一对小括号"()"。同样的技术可以用来把几个表达式括起来,比如 host, port, net 等。看看下面的例子:

要抓取从10.0.2.4出发去到端口3389或端口22的流量。
# tcpdump src 10.0.2.4 and (dst port 3389 or 22) // 错误的写法!

本应该是一个很有用的组合,但是你运行它,你却得到一个错误,因为小括号!你可以用两种方式纠正这个错误。要么在小括号前加上转义字符 \ 或者把整个组合命令用单引号括起来。

# tcpdump 'src 10.0.2.4 and (dst port 3389 or 22)' // 现在就对了!

进阶部分
你还可以根据包里面的某些字段来组合各种条件指定你要关注的包。这个功能在你想要查看SYNs和RSTs非常有用。

Show me all URG packets:
查看所有的紧急包(URG包)
# tcpdump 'tcp[13] & 32 != 0'

查看所有的确认包(ACK包)
# tcpdump 'tcp[13] & 16 != 0'

查看所有的PSH包
# tcpdump 'tcp[13] & 8 != 0'

查看所有的RST包
# tcpdump 'tcp[13] & 4 != 0'

查看所有的SYN包
# tcpdump 'tcp[13] & 2 != 0'

查看所有的FIN包
# tcpdump 'tcp[13] & 1 != 0'

查看所有的SYN-ACK包
# tcpdump 'tcp[13] = 18'

注意:只有PSH, RST, SYN 和 FIN 标志显示在tcpdump的标志域输出中。URG和ACK也会被显示,但显示在其它的地方而不是在标志位中(Flags Field).

你应该明白为什么以上的命令的写法。tcp[13]表示在tcp头的偏移量13字节的位置,然后作了一个布尔判断。

在神奇的Unix世界,一件事通常可以用好几种方式做到。tcpdump也不例外。下面的例子是另一个通过指定tcp包的标志位来查看包的命令。

Capturing TCP Flags Using the tcpflags Option
用 tcpflags 选项来指定 tcp 标志位。

查看SYN包.
# tcpdump 'tcp[tcpflags] & tcp-syn != 0

特殊流量
查看所有IPv6的流量
# tcpdump ip6

查看所有同时设置了SYN和RST位的流量(仅仅举例,实际上并不可能发生):
# tcpdump 'tcp[13] = 6'

查看所有的 evil 位被设置的流量
# tcpdump 'ip[6] & 128 != 0'

总结:
嗯,这篇文章应该能让你的技术变得更好,当然man手册永远是高手们的必备物品。我真诚希望这篇文章能够帮到你。如果有什么问题,不要犹豫,可以联系我。

copyright ykyi.net