您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 管理学资料 > 网络程序设计 原始套接字
21:10:441第六章原始套接字21:10:442内容提要概述ICMP编程使用IP头包含选项网络嗅探器实例21:10:443概述利用原始套接字(RawSocket),可访问底层传输协议。使用原始套接字可以做什么?实现一些实用工具(ping,traceroute)。可对IP头,TCP头,UDP头,ICMP头等进行操作。原始套接字使用SOCK_RAW套接字类型来创建的,目前只有Winsock2提供了对它的支持。无论MicrosoftWindowsCE还是老版本的Windows95(无Winsock2升级)均不能利用原始套接字。21:10:444创建原始套接字原始套接字类型在IP头中使用预定义的协议(如ICMP)在IP头中使用自定义的协议(使用IP头包含选项)创建原始套接字使用socket()或WSASocket()创建原始套接字。协议地址族套接口类型套接口类型使用的值协议字段互联网协议(IP)AF_INETTCPSOCK_STREAMIPPROTO_TCPUDPSOCK_DGRAMIPPROTO_UDPRawSOCK_RAWIPPROTO_RAWIPPROTO_ICMP……21:10:445例:创建原始套接字使用预定义协议:SOCKETs;S=socket(AF_INEF,SOCK_RAM,IPPROTO_ICMP);//ORS=WSAsocket(AF_INEF,SOCK_RAM,IPPROTO_ICMP,NULL,0,WSA_FLAG_OVERLAPPED);21:10:446使用自定义协议使用IGMP、UDP、IP或者原始IP,只需分别设置IPPROTO_IGMP、IPPROTO_UDP、IPPROTO_IP或IPPROTO_RAW即可。注意:在WindowsNT4、Windows98以及Windows95(安装Winsock2)操作系统中,创建原始套接字时,只能使用ICMP。协议标志IPPROTO_UDP、IPPROTO_IP以及IPPROTO_RAW均要求使用套接字选项IP_HDRINCL,而该选项在上述平台下都是不支持的。Windows2000提供了对IP_HDRINCL选项的支持,所以能够处理IP头(IPPROTO_RAW)、TCP头(IPPROTO_TCP)以及UDP头(IPPROTO_UDP)。无论是否设置IP_HDRINCL选项,原始套接字上接收到的数据都会包含IP头。21:10:447使用原始套接字可以对底层传输机制加以控制,所以有些人将其用于不法用途,从而造成了WindowsNT潜在的安全漏洞。因此,只有属于“管理员”(Administrator)组的成员,才有权创建类型为SOCK_RAW的套接字。而Windows95和Windows98均未施加这方面的限制。在WindowsNT中可以修改注册表,禁止对原始套接字的安全检查绕过该限制。方法:在注册表创建变量,并将其值设为1(DWORD类型)。HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Afd\Parameters\DisableRawSecurity更改注册表后重新启动计算机。21:10:448ICMP编程ICMP协议PING程序分析TRACEROUTE程序分析21:10:449Internet控制消息协议Internet控制消息协议(ICMP)主要用于在主机间传递简短消息的一种机制。ICMP报文的种类有两种,即ICMP差错报告报文和ICMP询问报文。ICMP协议采用IP定址机制,因为它本身就是封装在IP数据报内的一种协议。21:10:4410ICMP报文格式和类型ICMP报文的前4个字节是统一的格式,共有三个字段:即类型、代码和检验和。接着的4个字节的内容与ICMP的类型有关。21:10:4411类型代码TypeDescription0EchoResponse,(CODE=0)3DestinationUnreachable(CODE=0)4SourceQuench5Redirection8EchoRequest,(CODE=0)9RouterAdvertisement10RouterSolicitation11DatagramTimeout(TTL=0)(CODE=0)12DatagramParameterError13TimestampRequest14TimestampResponse15InformationRequest(outofdate)16InformationResponse(outofdate)17AddressMaskRequest18AddressMaskResponse可达性测试报告无法找到目的抑制源站发送路由已发生改变路由器间协调过长路由(超时)报文格式错时间同步作废掩码维护21:10:4412校验和的计算将数据以字为单位累加到一个双字中,如果数据长度为奇数,最后一个字节单独相加,累加结果是一个双字,最后这个双字的高16位和低16位相加后取反得到校验和。21:10:4413//计算校验和的标准例程USHORTchecksum(USHORT*buffer,intsize){unsignedlongcksum=0;//将数据以字为单位累加到cksum中while(size1){cksum=cksum+(*buffer);buff++;size=size-sizeof(USHORT);}//如果总字节数为奇数,将单独处理最后一个字节,累加到cksum中if(size){cksum=cksum+(*(UCHAR*)buffer);}//将cksum的高16位和低16位相加,取反后得到校验和cksum=(cksum16)+(cksum&oxffff);cksum=cksum+(cksum16);return(USHORT)(~cksum);}21:10:4414Ping常用Ping来判断特定主机是否处于活动状态,并且是否可以通过网络访问。通过生成一个ICMP“回应请求”(EchoRequest),并将其定向至打算查询的目标主机。发出ICMP回应请求以后,远程机器收到这个请求,然后生成一条回应答复消息(EchoResponse),再通过网络传回。出于某些原因,不能抵达目标主机,就会生成对应的ICMP错误消息,由原先打算建立通信的那个路径上某个路由器返回。假定与远程主机的物理性连接并不存在问题,但远程主机已经关机或没有设置对网络事件作出响应(防火墙),此时需由程序来执行超时检测。21:10:4415编写Ping程序的步骤:1)创建类型为SOCK_RAW的套接字,同时设定协议IPPROTO_ICMP。2)创建并初始化ICMP包(包括ICMP头和数据)。3)调用sendto或WSASendto,将ICMP请求发给远程主机。4)调用recvfrom或WSARecvfrom接收任何ICMP响应包。5)解析收到的ICMP响应包。21:10:4416例:ping程序:发送ICMPEchoRequest包接收ICMP包并解析需要的EchoResponse包通过IP_OPTIONS套接字选项,实现记录路由选项。指定发送的数据包大小21:10:4417ICMPheaderstructure//ICMPheaderstructuretypedefstruct_icmphdr{BYTEi_type;BYTEi_code;//TypesubcodeUSHORTi_cksum;USHORTi_id;USHORTi_seq;//Thisisnotthestandardheader,butwereservespacefortimeULONGtimestamp;}IcmpHeader;0or80校验和报文标识符(整数)顺序号可选数据21:10:4418IPoptionheaderstructure//IPoptionheader-usewithsocketoptionIP_OPTIONStypedefstruct_ipoptionhdr{unsignedcharcode;//Optiontypeunsignedcharlen;//Lengthofoptionhdrunsignedcharptr;//Offsetintooptionsunsignedlongaddr[9];//ListofIPaddrs}IpOptionHeader;21:10:441921:10:4420Traceroute(追踪路由)利用Traceroute可侦测出到达网络内特定主机,中途需经过哪些路由器(IP)。利用Ping,使用IP选项头内的记录路由选项,侦测中途经过的路由器IP地址,但Ping最多只支持9跳。若网络较大,穿过的路由器不止9个,应换用Traceroute。21:10:4421实现Traceroute程序的方法基本思想:多次发送数据包,TTL递增,TTL为0时返回一条ICMP报文。两种方法:发UDP数据报和ICMP数据包。例:路由跟踪程序(采用发送UDP数据包)创建两个套接字:sRaw用于接收ICMP数据包sSend用于发送TTL不断增加的UDP数据报21:10:4422使用IP头包含选项创建原始套接字后使用IP_HDRINCL套接字选项可对IP头进行操作,同时也能操作TCP或UDP头(或封装在IP内的其他任何协议)。使用IP_HDRINCL选项时,必须针对每一次发送调用,向IP头内自行填充内容。同时还需填写封装在其中的其他协议头。相关协议报文格式21:10:4423IP数据报格式typedefstruct_IPHeader//20字节的IP头{UCHARiphVerLen;//版本号和头长度(各占4位)UCHARipTOS;//服务类型USHORTipLength;//整个IP报文长度USHORTipID;//封包标识USHORTipFlags;//标志UCHARipTTL;//生存时间TTLUCHARipProtocol;//协议(TCP、UDP、ICMP等)USHORTipChecksum;//校验和ULONGipSource;//源IP地址ULONGipDestination;//目标IP地址}IPHeader,*PIPHeader;21:10:442421:10:4425UDP头简单。长度仅为8个字节,而且只包含了四个字段,格式如图所示。源端口(16位)目标端口(16位)UDP长度(16位)UDP校验和(16位)由于UDP是一种不能保证数据可靠传输的协议,所以校验和的计算是可选的。UDP校验和除覆盖了UDP头之外,还同时覆盖了实际的数据,此外还包括IP头的一部分。typedefstruct_UDPHeader{USHORTsourcePort;//源端口号USHORTdestinationPort;//目的端口号USHORTlen;//封包长度USHORTchecksum;//校验和}UDPHeader,*PUDPHeader;21:10:442621:10:4427计算UDP校验和的附加字段叫作“伪首部”。UDP校验和基于如下几个域:32位源IP地址(IP头)32位目标IP地址(IP头)8位字段(全零)8位协议16位UDP长度16位源端口号16位目标端口号16位UDP长度16位UDP校验和UDP数据21:10:4428发送原始UDP封包的步骤首先以IPPOTO_UDP为协议类型创建一个原始套接字,打开原始套接字上的IP_HDRINCL选项;然后构建UDP封包(先设置IP头,再设置UDP头,最后设置数据);初始化完整的UDP封包之后,调用sendto函数即可将它发送。例:发送原始UDP封包注意:windowsXPSP2以前可使用假的源IP,但在windowsXPSP2中
本文标题:网络程序设计 原始套接字
链接地址:https://www.777doc.com/doc-3264304 .html