linux下网络调试工具,主要包括tcpdump、netstat和lsof工具。
1. tcpdump (dump traffic on a network)
tcpdump打印指定网络接口中与布尔表达式匹配的报头信息。
tcpdump的表达式是一个正则表达式,tcpdump利用它作为过滤报文的条件,如果一个报文满足表达式的条件,则这个报文将被捕获。如果没有给出任何条件,则网络上的所有的信息包将会被截获。
表达式中一般有如下几个类型的关键字。
(1) 关于类型的关键字,主要包括host、net、port,例如:
host 210.27.48.2 //指明210.27.48.2主机
net 202.0.0.0 //指明网络地址202.0.0.0
port 23 //指明端口号为23
如果没有指定类型,默认的类型是host。
(2) 确定传输方向的关键字,主要包括src、dst、dst or src、dst and src,
src 210.27.48.2 //指明IP包源地址为210.27.48.2
dst net 202.0.0.0 //指明目的网络地址为202.0.0.0
如果没有指明方向关键字,则默认是src或dst关键字。
(3) 协议关键字,主要包括fddi、ip、arp、rarp、tcp、udp等类型。指明了监听的包的协议内容。如果没有指定任何协议,则tcpdump将会监听所有协议的信息包。
除了这3类型的关键字,重要的关键字还有gateway、broadcast、less、greater。另外还有3中逻辑运算:
‘not’或’!’ //非运算
‘and’或’&&’ //与
‘or’或’||’ //或
应用示例:
(1) 想要截获所有210.27.48.1的主机收到和发出的所有数据包
$tcpdump host 210.27.48.1
(2) 想要截获210.27.48.1和主机210.27.48.2和210.27.48.3的通信,使用命令
(在命令行中使用括号时,一定要\):
$tcpdump host 210.27.48.1 and \(210.27.48.2 or 210.27.48.3 \)
(3) 如果想要获取主机210.27.48.1除了和主机210.27.48.2之外的所有主机通信的ip包
$tcpdump ip host 210.27.48.1 and !210.27.28.2
(4) 如果要获取主机210.27.48.1接受或发出的telnet包,使用如下命令:
$tcpdump tcp port 23 host 210.27.48.1
TCP包的输出信息:
使用tcpdump捕获的tcp包的一般输出信息格式是:
src.port > dst.port: flags data-seqno ack window urgent options
内容分析如下:
l src.port >dst.port:源到目的地,刚好标识一对连接
l flags是tcp包中的标志信息:S是SYN标志,F(FIN)、P(PUSH)、R(RST)、“.”(没有标志)。
l data-seqno数据包中的数据的顺序号
l ack是下一次期望的顺序号
l win是接收缓存的窗口大小
l urgent表明数据包中是否有紧急指针
l options是选项
tcpdump常用选项:
l -a:将网络地址和广播地址转变成名字
l -d:将匹配信息包的代码以能够理解的汇编格式给出
l -dd:将匹配信息包的代码以C语言程序段的格式给出
l -ddd:将匹配信息包的代码以十进制的形式给出
l -e:在输出行打印出数据链路层的头部信息
l -f:将外部地址以数字的形式打印出来
l -l:使标准输出变为缓冲形式
l -n:不把网络地址转换成名字
l -t:在输出行的每一行不打印时间戳
l -v:输出一个稍微详细的信息
l -vv:输出详细的报文信息
l -c:在收到指定数目的数据包后,tcpdump就会停止
l -F:从指定的文件中读取表达式,忽略其他的表达式
l -i:指定监听的网络接口
l -r:从指定的文件中读取包(这些包一般通过-w选项产生)
l -w:直接将包写入文件中,并不分析和打印出来
l -T:将监听到的包直接解释为指定的类型的报文,常见的类型有rpc和snmp
tcpdump能抓取网络包,并分析。
这里,我直接用tcpdump抓到包并保存在文件中(syn.log),找到相应字段的bit区域,通过查tcp/ip协议个字段,反向解包。并与tcpdump的分析结果对比。
tcp服务器:192.168.0.50:48500
tcp客户端:192.168.0.100:59684
IPv4
先启动服务器,然后打开tcpdump监听,将抓包指定保存到文件syn.log。然后,客户端主动连接上来,这样,最开始抓到的为tcp的三次握手。
使用od将数据以16进制显示,以一个字节为单位(8bits)。
除了网络数据包之外,产生的文件中还有些数据是tcpdump文件特用的数据,例如最开始的d4c3 b2a1表示该文件是tcpdump产生的文件,具体tcpdump文件格式,网上搜的到,这里我只圈出三次握手的网络数据包,如图。将上图中的输出,重定向到另外文件中,为了方便阅读,将其重新排列(但不改变字节序)。
这里,我拿第一个SYN包来反解
目的MAC:08:90:00:a0:02:10
源MAC:3c:97:0e:8f:c8:be
协议类型:0800(IP协议包)
IP头:
版本:0x4(IPv4),对于IPv6,该值为6
首部长度:0x5,这个长度以字为单位。(5*4=20字节)
服务类型(TOS):0x00
总长度:0x003c(60)
标识:0x41bf(16831)
标志:0x2
偏移:0
生存时间:0x40(64)
协议:0x06(TCP协议包)
首部校检和:0x7716(30486)
源IP地址:c0(192).a8(168).00(0).64(100)
目的IP地址:c0(192).a8(168).00(0).32(50)
TCP头:
源端口号:0xe924(59684)
目的端口号:0xbd74(48500)
序号:0xcab64ff2(3400945650)
确认序号:0(第一个SYN,没有需要回应的序号)
首部长度:0xa(10字)(10*4=40字节,从后面可以看到选项暂用了20字节)
保留位:0
URG(0),ACK(0),PSH(0),RST(0),SYN(1),FIN(0)
窗口大小:0x3908(14600)
校检和:0x8215
紧急指针:0
选项:
02 04 05 b4:MSS为1460
04 02:SACK
08 0a 00 02 0e 4d 00 00 00 00:时间戳 TS val:0x00020e4d(134733),Tsecr:0
01:nop
03 03 07:窗口扩大因子wscale:7
使用tcpdump分析:
对比,结果一致
2. netstat工具使用
netstat命令的功能是显示网络连接、路由表和网络接口信息,可以让用户得知哪些网络连接正在工作,及其工作状态。
$man netstat
print network connections,routing tables, interface statistics, masquerade connections, and multicastmemberships
该命令一般格式为:
netstat [-a] [-e] [-n] [-o] [-p Protocol] [-r] [-s] [Interval]
从整体上看,netstat的输出结果可以分为两个部分:
一个是Active internet connections,其中Recv-Q和Send-Q指接收队列和发送队列。这些数字一般都应该是0。如果不是则表示软件包正在队列中堆积。
另一个是Active UNIX domain sockets,(unix域套接字,和网络套接字一样,但只能用于本机通信,性能可以提高一倍)。
Proto显示连接使用的协议,RefCnt表示连接到本套接口上的进程号,Types显示套接口的类型,State显示套接口当前的状态,Path表示连接到套接口的其他进程使用的路径名。
常见参数:
-a (all)显示所有选项,默认不显示Listening相关、udp相关
-t (tcp)仅仅显示tcp相关选项
-u (udp)仅仅显示udp相关选,结合-a使用
-n (numeric)拒绝显示别名,能显示数字的全部转化成数字
-l (listening)仅仅列出Listening状态的服务
-p (program)显示套接字所述的进程名及其PID
-r (route)显示路由信息,路由表
-e (extend)显示扩展信息,例如uid等
-s 按各协议进行统计
-c (continuous)每隔一个固定时间,执行该netstat命令
LISTEN和LISTENING的状态只有用-a或者-l才能看到
列出所有端口:(包括监听状态的)
$netstat –a
列出所有tcp端口:
$netstat –at
列出所有udp端口:
$netstat –au
列出所有udp端口,并显示所属进程(仅显示该用户的,要看所有用户需要root):
$netstat –aup
只显示监听端口:
$netstat –l
显示系统不支持的地址族:
$netstat --verbose
显示内核IP路由表:
$netstat –r
3. lsof工具使用
lsof全名为list opened files,即列出系统中已经被打开的文件。
查看套接字:
$lsof –i