udp端口扫描

llyjyzj

贡献于2013-06-14

字数:8678 关键词: 网络技术

 湖南文理学院计算机学院 课程设计报告册 2012 学年度上学期 专 业: 计算机科学与技术 课程名称: 计算机网络课程设计 姓 名: 学 号: 教师评语: 年 月 日 签名: 评分: 一.课程设计的目的 1 二.课程设计的要求 1 三.相关知识 2 1.关键技术 2 2.关键API函数 2 四.课程设计分析 4 1.关键算法 4 2.核心代码 5 五.运行结果 11 六.存在不足 11 七.心得体会 11 八.参考文献 12 一 课程设计的目的 UDP是TCP/IP协议族伟传输层设计的两个协议之一,它在进程与进程的通信过程中,提供了有限的差错校验功能,是一种无连接的,不可靠的协议。UDP在一个较低的水平上完成进程之间的通信,在收到分组的时候没有流量控制机制也没有确认机制,适用于可靠性比较高的局域网。由于UDP采用无连接的方式,因此协议简单,在一些特定的应用中协议运行效率高。 本次课程设计的目的主要是了解UDP协议的网络传输过程中的一些原理。 二 课程设计的要求 1) 开启一个IP包拦截处理线程,处理本机接收到的一切IP包。 2)用raw socket自己构建IP包对用户输入的填入的每个IP的每个端口发送两次UDP包,并把发送的IP和Port存到hashtable中,当发送完最后一个扫描端口后,开启UDPTimeOut线程,对没回应的IPPort对进行处理。 3)拦截线程处理每个拦截到的包。 若是UDP包,且该UDP包的IP和Port在hashtable中,则说明该IP的Port开放,在用户界面上显示,并删除hashtable中该项。 若是返回ICMP端口不可到达错误(类型3,代码3),且该包的IP和Port在hashtable中,则说明IP的Port关闭。在用户界面上显示,并删除hashtable中该项。 若是ICMP不可到达错误(类型3,代码1,2,9,10,或者13),且该包的IP和Port在hashtable中,则说明该IP的Port被过滤。在用户界面上显示,并删除hashtable中该项。 若是type为0,subcode为0的ICMP包,且该IP在ICMPHashTable中,则此IP存活,但没回应UDP包,说明此IP的Port开放或被过滤。 4)UDPTimeOut线程思路:等待一段时间后,hashtable中还存在的项就是长时间没回应的IPPort对,把这些IP及对应的Port List存到HashTable中。对这些IP发送type为8、subcode为0的ICMP包,看这些主机是否存活。若存活则说明探测的该IP包下的一些端口被过滤。 拦截处理线程函数是receiveUDP(),发送UDP包线程是UDPScan(object ipPort),对长时间没回应的IPPort对处理线程函数是UDPTimeOut()。 三 相关知识 1 关键技术 UDP 是User Datagram Protocol的简称, 中文名是用户数据包协议,是 OSI 参考模型中一种无连接的传输协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768是UDP的正式规范。 2 关键API函数 1.WSAStarup函数 WSAStarup函数的格式如下: int WSAStarup(WORD wVersionRequested, LPWSADATA lpWSAData ); 程序在使用Socket之前必须使用WSAStarup函数。该函数的第一个参数wVersionRequested:一个WORD(双字节)型数值,指定了应用程序需要使用的Winsock规范的最高版本 ;第二个参数lpWSAData: 指向WSADATA数据结构的指针,用来接收Windows Sockets实现的细节。函数执行成功后返回0. WSACleanup函数 WSACleanup函数的格式如下: int WSACleanup(void); 程序在完成对请求的Socket库的使用后,要调用WSACleanup函树来解除与Socket库的绑定并且释放Socket库所占用的系统资源。 socket函数 socket函数格式为: socket(int af,int type,int protocol) 第一个参数指定应用程序使用的通信协议的协议族,对于TCP/IP协议族,该参数置AF_INET; 第二个参数指定要创建的套接字类型,流套接字类型为SOCK_STREAM、数据报套接字类型为SOCK_DGRAM、原始套接字SOCK_RAW(WinSock接口并不适用某种特定的协议去封装它,而是由程序自行处理数据包以及协议首部); 第三个参数指定应用程序所使用的通信协议,此参数可以指定单个协议系列中的不同传输协议,在Internet通讯域中,此参数一般取值为0,系统会根据套接字的类型决定应使用的传输层协议。 closesocket函数 closesocket函数的格式为: closesocket( SOCKET s); closesocket函数用来关闭一个描述符为s的套接字。如果发生错误,则closesocket()返回0;否则的话,返回SOCKET_ERROR错误 。 5.sendto函数 sendto函数的格式为: sendto( SOCKET s, const char FAR* buf, int len, int flags,const struct sockaddr FAR* to, int tolen); sendto函数用来向某个端口发送数据。s:一个标识套接口的描述字;buf:包含待发送数据的缓冲区;len:buf缓冲区中数据的长度;flags:调用方式标志位;to:(可选)指针,指向目的套接口的地址;tolen:to所指地址的长度 。 recvfrom函数 recvfrom函数的格式为: recvfrom(int s,void *buf,int len,unsigned int flags, struct sockaddr *from,socket_t *fromlen) recvfrom函数用来接收返回的ICMP包。s:标识一个已连接套接口的描述字;buf:接收数据缓冲区;len:缓冲区长度;flags:调用操作方式;from:(可选)指针,指向装有源地址的缓冲区;fromlen:(可选)指针,指向from缓冲区长度值。 7bind函数 bind函数的格式为: int bind( SOCKET s, const struct sockaddr FAR* name,int namelen) bind函数用来给socket绑定一个IP地址和一个特定的端口号。s:标识一未捆绑套接口的描述字;name:赋予套接口的地址;sockaddr结构定义如下:   struct sockaddr{   u_short sa_family;   char sa_data[14];   };   namelen:name名字的长度。 四 课程设计分析 1 关键算法 USHORT checksum(USHORT *buffer, int size); //计数校验和 用以确保IP数据包数据的正确性 void UDP_scan( ULONG S_ADDRESS,char *D_ADDRESS,unsigned short default_spt); // 扫描UDP端口,确认端口的状态。 USHORT Send_UDPinfo(UINT S_ADR,UINT D_ADR,USHORT DF_SPT,USHORT SCAN_DPT); // 向目标IP发送UDP信息 USHORT Get_ICMPinfo(UINT ICMP_SOCK, LPSOCKADDR_IN SOURCE_ADDRESS); // 根据ICMP返回的信息,判断端口是否打开 ULONG Get_SHostip(void); //获得本机IP, 与校验值比对看IP是否正确 流程图如下: 2 核心代码 USHORT checksum(USHORT *buffer, int size) //校验和 { unsigned long cksum = 0; while(size > 1) { cksum += *buffer++; size -= sizeof(USHORT); } if(size ) { cksum += *(UCHAR*)buffer; } cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >>16); return (USHORT)(~cksum); } //end checksum(...) void UDP_scan( ULONG S_ADDRESS,char *D_ADDRESS,unsigned short default_spt) // UDP port to scan { USHORT retval; servent *Open_port; int stdsize = (sizeof(udpstd))/(sizeof(int));//算出待扫描端口的量 cout<<" UDP扫描开始! (载入中...)"<source_port = htons(DF_SPT); udpheader->dest_port = htons(SCAN_DPT); udpheader->checksum_UDP = 0; udpheader->UDP_size = htons(sizeof(UDPHEADER) + DATA_LEN); f_udpheader->dest_ip = D_ADR; f_udpheader->source_ip = S_ADR; f_udpheader->fill_field = 0; f_udpheader->protocol = IPPROTO_UDP; f_udpheader->UDP_size = udpheader->UDP_size; udpheader->checksum_UDP = checksum((USHORT *)f_udpheader,sizeof(UDPHEADER) + sizeof(F_UDPHEADER) + DATA_LEN);//计算UDP校验和 ipheader->h_len = 5; ipheader->h_ver = 4; ipheader->tos = 0x10; ipheader->total_len = sizeof(Packet_Buf); ipheader->frag_flags = 0; ipheader->ttl = 128; ipheader->proto = IPPROTO_UDP; ipheader->sourceIP = S_ADR; ipheader->destIP = D_ADR; ipheader->checksum_IP = 0; ipheader->checksum_IP = checksum((USHORT *)ipheader,sizeof(IPHEADER));//计算IP的校验和 Send_info = sendto(sock,Packet_Buf,ipheader->total_len,0,(struct sockaddr *)&DEST_ADDR,sizeof(DEST_ADDR)); if(Send_info == SOCKET_ERROR) { cout<<"Send massage fault! Error :"< 0) {//选择数据报的属性 if(FD_ISSET(ICMP_SOCK,&rset)) { RECV_MSG = recvfrom(ICMP_SOCK,(char *)&icmpheader,sizeof(I_IPDATA),0,//接收目标地址发送的ICMP报文 (LPSOCKADDR)&SOURCE_ADDRESS,&Recv_Slen); if(RECV_MSG <= 0) { dest_inaddr.S_un.S_addr = icmpheader.ip_msg.sourceIP; Dest_Address = inet_ntoa(dest_inaddr); RECV_TTL = icmpheader.ip_msg.ttl;//ttl IP头的一个参数 cout<h_addr_list[Addrlist] ; Addrlist++) { memcpy(&Host_ipaddr.sin_addr,pHostent->h_addr_list[Addrlist],pHostent->h_length); cout<<"本机IP为:"<

下载文档,方便阅读与编辑

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 3 金币 [ 分享文档获得金币 ]
4 人已下载

下载文档

相关文档