Windows下基于原始套接字的回射客户端
来源:互联网 发布:java发送图片 编辑:程序博客网 时间:2024/06/05 07:33
根据使用的场合的不同,我们可以使用TCP、UDP和原始套接字来实现这个功能,今天就说一下基于基于原始套接字的回射客户端源代码。跟前面提过的工程一样,这个工程里面也包含着SocketFrame.cpp和SocketFrame.h这两个文件,所以就在之前的基础上添加使用原始套接字的回射客户端的功能文件就可以了。该功能源代码如下:
// EchoUDPClientRaw.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include "winsock2.h"#include "ws2tcpip.h"#include "stdio.h"#include "SocketFrame.h"#pragma pack(push,1)#defineMAXLINE 200// 发送和接收缓冲区的长度#defineINPUTLINE100// 输入文本的长度 #define ECHOPORT 7210//回射服务器的端口号/********************************************************函数名:UDP_MakeProbePkt输入参数:char *pUDPData:待填充的缓冲区指针,应填充包括IP首部在内的数据 char *pInputData:存储用户输入的字符串 UINT uSrcIP:源IP地址 UINT uDstIP:目的IP地址 USHORT uSrcPort:源端口号 USHORT uDestPort:目的端口号输出参数:构造后的缓冲区有效字节长度。功能:构造UDP协议的回射报文*********************************************************/int UDP_MakeProbePkt(char *pUDPData, char *pInputData, UINT uSrcIP, UINT uDestIP, USHORT uSrcPort, USHORT uDestPort){IPHDR*IPhdr;//基本IP头定义UDPHDR*UDPhdr;//UDP头定义FHDRFhdr;//伪头charbuf[MAXLINE];//数据缓冲char *data;int iRet=0;char *lpbuf = buf;CSocketFrame frame;/////////设置IP头ZeroMemory(buf,sizeof(buf));IPhdr=(IPHDR *)pUDPData;IPhdr->version = 4;IPhdr->hdr_len = 5;IPhdr->TOS = 0;IPhdr->TotLen = htons(sizeof(IPHDR)+sizeof(UDPHDR)+strlen(pInputData));IPhdr->ID = (USHORT)GetCurrentThreadId();IPhdr->FlagOff = 0;IPhdr->TTL = 0xff;IPhdr->Protocol = IPPROTO_UDP;IPhdr->Checksum = 0x0;//源地址为本机地址IPhdr->IPSrc = uSrcIP;//目的地址为入参,可能变化IPhdr->IPDst = uDestIP;////////// 构造UDP包UDPhdr=(UDPHDR *)(pUDPData+sizeof(IPHDR));UDPhdr->dst_portno = htons(uDestPort);UDPhdr->src_portno = htons(uSrcPort);UDPhdr->udp_checksum = 0;//UDPhdr->udp_length = htons(sizeof(UDPHDR));data=pUDPData+sizeof(IPHDR)+sizeof(UDPHDR);int ii=strlen(pInputData);memcpy(data,pInputData,strlen(pInputData));UDPhdr->udp_length = htons(sizeof(UDPHDR)+strlen(pInputData));//设置伪头Fhdr.IPDst = IPhdr->IPDst;Fhdr.IPSrc = IPhdr->IPSrc;Fhdr.protocol = IPPROTO_UDP;Fhdr.udp_length = UDPhdr->udp_length;Fhdr.zero = 0x00;//计算UDP校验和//校验和计算范围包括:UDP头,伪首部和用户数据char *ptmp = buf;memcpy(ptmp,&Fhdr,sizeof(Fhdr));ptmp += sizeof(Fhdr);memcpy(ptmp,UDPhdr,sizeof(UDPHDR));ptmp +=sizeof(UDPHDR);memcpy(ptmp,data,strlen(pInputData));UDPhdr->udp_checksum = frame.check_sum((USHORT*)buf,sizeof(Fhdr)+sizeof(UDPHDR)+strlen(pInputData));iRet = sizeof(IPHDR) + sizeof(UDPHDR)+strlen(pInputData);return iRet;}/********************************************************函数名:UDP_Filter输入参数:char *pUDPData:待填充的缓冲区指针,应填充包括IP首部在内的数据 UINT uServerIP:目标IP地址 USHORT uServerPort:目标端口号输出参数:true表示找到回射应答,false表示当前收到的数据报并不是服务器的回射应答。功能:对接收到的数据报进行过滤,获得由回射服务器发回的应答*********************************************************/BOOL UDP_Filter(char *pUDPData, UINT uServerIP,USHORT uServerPort){IPHDR*pIPhdr;//基本IP头定义UDPHDR*pUDPhdr;//UDP头定义char *pData;UINT uSourceIP; //接收到包的源IP地址USHORT uSourcePort; //接收到包的源端口pIPhdr=(IPHDR *)pUDPData;uSourceIP = pIPhdr->IPSrc;pUDPhdr=(UDPHDR *)(pUDPData+sizeof(IPHDR));uSourcePort = ntohs(pUDPhdr->src_portno);pData = pUDPData +sizeof(IPHDR) +sizeof(UDPHDR);if ( pIPhdr->Protocol ==17 && uSourceIP == uServerIP && uSourcePort == uServerPort){//服务器返回的应答 printf("客户端接收到数据:%s \r\n", pData );return true;}elsereturn false;}/********************************************************函数名:UDP_Echo输入参数:SOCKET sockSendRaw:用于发送UDP报文的原始套接字 SOCKET sockRecvRaw:用于接收响应的原始套接字 UINT uSrcIP:源IP地址 UINT uDstIP:目的IP地址 USHORT uSrcPort:源端口号 USHORT uDestPort:目的端口号输出参数:0:成功,1:失败功能:回射客户端的具体功能函数*********************************************************/BOOL UDP_Echo(SOCKET sockSendRaw,SOCKET sockRecvRaw, UINT uSrcIP,UINT uDstIP,USHORT uSrcPort,USHORT uDestPort){//初始化参数SOCKADDR_IN saDest;int len; int iResult=0;int bResult=FALSE;//申请缓冲区 char sendline[MAXLINE],recvline[MAXLINE],inputline[INPUTLINE];memset(sendline,0,MAXLINE);memset(recvline,0,MAXLINE); memset(inputline,0,INPUTLINE);//设置目的地址memset(&saDest,0 ,sizeof(saDest));saDest.sin_family = AF_INET;saDest.sin_addr.s_addr = uDstIP;//构造分析数据报文//循环发送用户的输入数据,并接收服务器返回的应答,直到用户输入"Q"结束fflush(stdin);gets_s(inputline,INPUTLINE);if( *inputline == 'Q'){printf("input end!\n");return 0;}while(strlen(inputline)!=0){ len = UDP_MakeProbePkt(sendline, inputline, uSrcIP,uDstIP,uSrcPort,uDestPort);//发送回射请求iResult = sendto(sockSendRaw,sendline,len,0,(SOCKADDR *)&saDest,sizeof(saDest));if(iResult == SOCKET_ERROR){printf("sendto 函数调用错误,错误号: %ld\n", WSAGetLastError());return 1;}printf("\r\n客户端发送%d字节数据\r\n", iResult); memset(recvline,0,MAXLINE);while((iResult = recvfrom( sockRecvRaw, recvline, MAXLINE, 0, NULL, NULL )) >0){//过滤出来自服务器端点地址的UDP回射应答并显示bResult = UDP_Filter(recvline,uDstIP,uDestPort);if( bResult == TRUE ) break;else{ memset(recvline,0,MAXLINE); continue;}}if (iResult == SOCKET_ERROR){ printf("recvfrom 函数调用错误,错误号: %d\n", WSAGetLastError());}//接收新的回射内容memset(sendline,0,MAXLINE);memset(inputline,0,INPUTLINE);printf("\n请输入回射字符串:");fflush(stdin); gets_s(inputline,INPUTLINE);if( *inputline == 'Q'){printf("input end!\n");return 0;}}return iResult;}int main(int argc, char* argv[]){CSocketFrame frame; int iResult;SOCKET sockSendRaw,sockRecvRaw;sockaddr_in localaddr;//初始化参数if (argc != 2) {fprintf(stderr,"\nUsage: EchoUDPClientRaw ***.***.***.***\n");return 0; }//Windows Sockets Dll初始化frame.start_up();//创建原始套接字,并设置相应的选项sockSendRaw = frame.raw_socket( TRUE, FALSE, IPPROTO_IP, NULL);if ( sockSendRaw == 0 )return -1; sockRecvRaw = frame.raw_socket( FALSE, TRUE, IPPROTO_IP, &localaddr);if ( sockRecvRaw == 0 )return -1;printf("套接字创建成功\n请输入回射字符串:");//开始回射请求的发送与接收//发送从构造IP头开始的UDP数据包,接收过滤,输出结果iResult = UDP_Echo( sockSendRaw,sockRecvRaw, localaddr.sin_addr.S_un.S_addr ,inet_addr(argv[1]),ECHOPORT, ECHOPORT);if ( iResult ==1 ) printf("回射过程出错!\n");//结束socket,释放资源iResult = closesocket(sockSendRaw); if (iResult == SOCKET_ERROR){ printf("closesocket 函数调用错误,错误号:%d\n", WSAGetLastError()); return 1; } frame.quit( sockRecvRaw );return iResult;}
0 0
- Windows下基于原始套接字的回射客户端
- Windows下基于原始套接字的回射客户端的源码
- Windows 7 环境下基于原始套接字和ICMP的路由探测开发的问题【1】
- 基于数据流的原始套接字
- 基于数据包的原始套接字
- 基于原始套接字的嗅探器
- linux下的原始套接字
- 基于原始套接字编程
- windows原始套接字接受
- Windows下利用原始套接字实现的一个抓包程序Demo
- Windows下利用原始套接字实现的一个抓包程序Demo
- 基于嗅探原理的原始套接字木马
- 基于嗅探原理的原始套接字木马
- 基于socket原始套接字的网络嗅探器
- 链路层原始套接字编程-客户端
- Linux网络编程:原始套接字的魔力【下】
- Linux网络编程:原始套接字的魔力【下】
- Linux网络编程:原始套接字的魔力【下】
- 【微服务架构】需要掌握知识
- 在Spring MVC中使用Apache Shiro安全框架
- Jquery选择器大全
- 集合框架_HashSet存储自定义对象并遍历练习
- C#实现高精度定时器
- Windows下基于原始套接字的回射客户端
- 锁Lock 那点事儿
- Java内存模型——基础
- 随笔
- 使用基于注解的mybatis时,利用反射和注解生成sql语句
- String中的equals和==
- 浏览器内核
- win10系统 CAJ文件打不开 老弹出 File doesn't existed or can't be visited normally! 文件不存在或不能正常访问
- 各种API记录(待续)