linux下端口扫描的实现(TCP connect、TCP SYN、TCP FIN、UDP四种方式)6 UDP扫描

一、原理

给一个端口发送UDP报文,如果端口是开放的,则没有响应,如果端口是关闭的,对方会回复一个ICMP端口不可达报文(对应ICMP首部前两个字段:类型3 代码3)。这种方式扫描速度慢;不可靠(udp和icmp都是不可靠协议)。

二、实现方式及遇到的问题

每个扫描线程(udpIcmpScanPort)会建立一个线程池,对每个要扫描的端口都创建一个线程udpIcmpScanEach(线程配置成detach属性)。udpIcmpScanEach负责发送UDP包到各端口,另有一个线程udpIcmpScanRecv负责处理所有收到的数据包。发送的数据包要自己组装,协议可以使用原始套接字,协议选择UDP,接收时另建立一个socket,也是使用原始套接字,协议选择ICMP.

1.发送频率太快会大量丢包

按照SYN或者FIN的频率发送UDP包的话,会出现大量ICMP或者UDP丢包现象。频率的大小和扫描端口的数量有关系,需要扫描的数量越大,用来记录目前存在线程数的全局变量udpCnt越容易超过上限,程序就卡死在这里了

我想到两种解决方法,一个是把频率调低,频率降为原来的1/2时扫描1000个包还行。但是总觉得这种方法有侥幸的感觉。我尝试使用第二种方法,还是原来的频率,加了一个定时器(信号ALARM实现),在规定的时间内(我设置的是30秒)如果程序卡死在这里,则重新发送UDP包,速度可以做到跟FIN差不多,程序也没有卡死。

2.选择icmp有关数据结构的问题

linux提供的有关icmp的数据结构有两种,icmp与icmphdr,我用sizeof测了一下,前者是20字节,后者是8字节。因为抓包来看,接收到的ICMP报文是IP首部(20字节)+ICMP首部(8字节)+发送的IP层的UDP报文,所以其实是IP首部(20字节,目的端口方)+ICMP首部(8字节)+IP首部(20字节,端口扫描方)+UDP首部+UDP数据,所以我用的是icmphdr。

三、实现代码

#ifndef UDPICMPSCAN_H_H
#define UDPICMPSCAN_H_H

#include "mysock.h"


int udpCnt;
static pthread_mutex_t udp_printf_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t udp_num_mutex = PTHREAD_MUTEX_INITIALIZER;
//extern pthread_mutex_t udp_printf_mutex; 
//extern pthread_mutex_t udp_num_mutex;

void* udpIcmpScanPort(void *arg);
void* udpIcmpScanEach(void *arg);
void* udpIcmpScanRecv(void *arg);
void alarm_u
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值