最近一周为了实验室项目的测试,用libnet写了几个测试发包程序,在大流量发包的时候会遇到一些问题。
问题一: No Buffer Space Available
测试程序libnet_init的时候,是RAW4模式的,随机生成一些数据包来发送给我的服务器程序,当流量一大之后,libnet_write()就会出现错误,提示:
libnet_write_raw_ipv4(): -1 bytes written (No buffer space available)
原因一:发包速度太快,导致驱动中Buffer满了
当然出现这种问题的原因,还有一个就是发包频率过高,导致出现的问题,这个时候,需要适当的进行usleep,然后resend即可。
原因二:arp缓存满了
换用LINK模式进行libnet_init,build ethernet进行发包就没有问题,感觉很奇怪,以前用libnet的时候就没有出现这样的问题。
我前天晚上,查了libnet的源代码也没有发现什么问题,只发现RAW4模式libnet_write()调用的是sendto()原始套接字;LINK模式下调用的是putmsg()。
今天,在写一个漏洞探测程序的时候,有出现了同样的问题。上次,通过libnet_autobuild_ethernet()来实现,是因为我们的报文直接通过对等线发送给服务器,没有传播到网络上。
这次,也想这么解决,但是这次是需要跟对端交互的,mac一定需要正确的,也就是需要进行arp解析了,但是发了将近4个C类网段就出现问题了。
。。。。。。
忽 然想起,测试程序的目标地址都是局域网机器,都需要进行arp解析,而arp缓存表大小是有限的,随机的内网ip的arp解析,会占用大量的arp缓存空 间,状态为incomplete。对于大量随机的外网ip是没有这个问题的,因为这些数据包都是通过网关来走的,只需要占用一条arp缓存空间即可。
arp缓存默认为1024,可以通过一些内核参数调整:
#cat /proc/sys/net/ipv4/neigh/default/gc_thresh3
1024
#echo 65535 > /proc/sys/net/ipv4/neigh/default/gc_thresh3
同理设置gc_thresh1和gc_thresh2,再进行测试,好多了,不再有错误了,但是还是很慢,原因就在于我每发送一个数据包,都要进行arp解析,再在里面进行查询,这都是比较耗时的;而且随着扫描网段的增加,arp缓存将会十分巨大。
另外,我们可以减小arp中旧条目的保存时间:
#cat /proc/sys/net/ipv4/neigh/default/gc_thresh3
60
#echo 10 > /proc/sys/net/ipv4/neigh/default/gc_thresh3
总算弄明白了,不是我程序的问题,只是在测试的时候,没有考虑周全,以后使用公网进行测试就好了;-)
写了一个check_localnet()函数,将随机生成的本地子网ip踢除。
问题二:Invalid Argment
libnet_write: libnet_write_raw_ipv4(): -1 bytes written (Invalid argument)
这个问题,跟踪发现是ip地址非法导致,因为ip地址是随机生成的,就会导致出现,例如240.1.2.3就会有问题。
查了一下资料没有找到什么网段是不可以使用的,这个好像跟通常的保留网段不同,192.168.0.0是可以的,我测试了一下,当地址为0.0.0.0/8和240-255.0.0.0/8都是不行的,不太清楚有没有官方的文档描述这个问题,RFC太多了,找不过来~~
就写了一个简单的check_invalidip()的函数,将这些不可用的保留网段都踢除。
问题一: No Buffer Space Available
测试程序libnet_init的时候,是RAW4模式的,随机生成一些数据包来发送给我的服务器程序,当流量一大之后,libnet_write()就会出现错误,提示:
libnet_write_raw_ipv4(): -1 bytes written (No buffer space available)
原因一:发包速度太快,导致驱动中Buffer满了
当然出现这种问题的原因,还有一个就是发包频率过高,导致出现的问题,这个时候,需要适当的进行usleep,然后resend即可。
原因二:arp缓存满了
换用LINK模式进行libnet_init,build ethernet进行发包就没有问题,感觉很奇怪,以前用libnet的时候就没有出现这样的问题。
我前天晚上,查了libnet的源代码也没有发现什么问题,只发现RAW4模式libnet_write()调用的是sendto()原始套接字;LINK模式下调用的是putmsg()。
今天,在写一个漏洞探测程序的时候,有出现了同样的问题。上次,通过libnet_autobuild_ethernet()来实现,是因为我们的报文直接通过对等线发送给服务器,没有传播到网络上。
这次,也想这么解决,但是这次是需要跟对端交互的,mac一定需要正确的,也就是需要进行arp解析了,但是发了将近4个C类网段就出现问题了。
。。。。。。
忽 然想起,测试程序的目标地址都是局域网机器,都需要进行arp解析,而arp缓存表大小是有限的,随机的内网ip的arp解析,会占用大量的arp缓存空 间,状态为incomplete。对于大量随机的外网ip是没有这个问题的,因为这些数据包都是通过网关来走的,只需要占用一条arp缓存空间即可。
arp缓存默认为1024,可以通过一些内核参数调整:
#cat /proc/sys/net/ipv4/neigh/default/gc_thresh3
1024
#echo 65535 > /proc/sys/net/ipv4/neigh/default/gc_thresh3
同理设置gc_thresh1和gc_thresh2,再进行测试,好多了,不再有错误了,但是还是很慢,原因就在于我每发送一个数据包,都要进行arp解析,再在里面进行查询,这都是比较耗时的;而且随着扫描网段的增加,arp缓存将会十分巨大。
另外,我们可以减小arp中旧条目的保存时间:
#cat /proc/sys/net/ipv4/neigh/default/gc_thresh3
60
#echo 10 > /proc/sys/net/ipv4/neigh/default/gc_thresh3
总算弄明白了,不是我程序的问题,只是在测试的时候,没有考虑周全,以后使用公网进行测试就好了;-)
写了一个check_localnet()函数,将随机生成的本地子网ip踢除。
问题二:Invalid Argment
libnet_write: libnet_write_raw_ipv4(): -1 bytes written (Invalid argument)
这个问题,跟踪发现是ip地址非法导致,因为ip地址是随机生成的,就会导致出现,例如240.1.2.3就会有问题。
查了一下资料没有找到什么网段是不可以使用的,这个好像跟通常的保留网段不同,192.168.0.0是可以的,我测试了一下,当地址为0.0.0.0/8和240-255.0.0.0/8都是不行的,不太清楚有没有官方的文档描述这个问题,RFC太多了,找不过来~~
就写了一个简单的check_invalidip()的函数,将这些不可用的保留网段都踢除。