高分求RAW SOCKET直接向目的地址发数据的代码??

lwglucky 2006-08-10 09:44:19
高分求RAW SOCKET直接向目的地址发数据的代码??
高分求RAW SOCKET直接向目的地址发数据的代码??
...全文
216 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
睡在床板下_ 2006-08-11
  • 打赏
  • 举报
回复
发送 ICMP 就是一个raw socket。ping 程序就是个好例子:
//
// Ping.h
//

#pragma pack(1)

#define ICMP_ECHOREPLY 0
#define ICMP_ECHOREQ 8

// IP Header -- RFC 791
typedef struct tagIPHDR
{
u_char VIHL; // Version and IHL
u_char TOS; // Type Of Service
short TotLen; // Total Length
short ID; // Identification
short FlagOff; // Flags and Fragment Offset
u_char TTL; // Time To Live
u_char Protocol; // Protocol
u_short Checksum; // Checksum
struct in_addr iaSrc; // Internet Address - Source
struct in_addr iaDst; // Internet Address - Destination
}IPHDR, *PIPHDR;


// ICMP Header - RFC 792
typedef struct tagICMPHDR
{
u_char Type; // Type
u_char Code; // Code
u_short Checksum; // Checksum
u_short ID; // Identification
u_short Seq; // Sequence
char Data; // Data
}ICMPHDR, *PICMPHDR;


#define REQ_DATASIZE 32 // Echo Request Data size

// ICMP Echo Request
typedef struct tagECHOREQUEST
{
ICMPHDR icmpHdr;
DWORD dwTime;
char cData[REQ_DATASIZE];
}ECHOREQUEST, *PECHOREQUEST;


// ICMP Echo Reply
typedef struct tagECHOREPLY
{
IPHDR ipHdr;
ECHOREQUEST echoRequest;
char cFiller[256];
}ECHOREPLY, *PECHOREPLY;


#pragma pack()

//
// PING.C -- Ping program using ICMP and RAW Sockets
//

#include <stdio.h>
#include <stdlib.h>
#include <winsock.h>

#include "ping.h"

// Internal Functions
void Ping(LPCSTR pstrHost);
void ReportError(LPCSTR pstrFrom);
int WaitForEchoReply(SOCKET s);
u_short in_cksum(u_short *addr, int len);

// ICMP Echo Request/Reply functions
int SendEchoRequest(SOCKET, LPSOCKADDR_IN);
DWORD RecvEchoReply(SOCKET, LPSOCKADDR_IN, u_char *);


// main()
void main(int argc, char **argv)
{
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(1,1);
int nRet;

// Check arguments
if (argc != 2)
{
fprintf(stderr,"\nUsage: ping hostname\n");
return;
}

// Init WinSock
nRet = WSAStartup(wVersionRequested, &wsaData);
if (nRet)
{
fprintf(stderr,"\nError initializing WinSock\n");
return;
}

// Check version
if (wsaData.wVersion != wVersionRequested)
{
fprintf(stderr,"\nWinSock version not supported\n");
return;
}

// Go do the ping
Ping(argv[1]);

// Free WinSock
WSACleanup();
}


// Ping()
// Calls SendEchoRequest() and
// RecvEchoReply() and prints results
void Ping(LPCSTR pstrHost)
{
SOCKET rawSocket;
LPHOSTENT lpHost;
struct sockaddr_in saDest;
struct sockaddr_in saSrc;
DWORD dwTimeSent;
DWORD dwElapsed;
u_char cTTL;
int nLoop;
int nRet;

// Create a Raw socket
rawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (rawSocket == SOCKET_ERROR)
{
ReportError("socket()");
return;
}

// Lookup host
lpHost = gethostbyname(pstrHost);
if (lpHost == NULL)
{
fprintf(stderr,"\nHost not found: %s\n", pstrHost);
return;
}

// Setup destination socket address
//saDest.sin_addr.s_addr = *((u_long FAR *) (lpHost->h_addr));
saDest.sin_addr.s_addr =inet_addr("127.0.0.1");
saDest.sin_family = AF_INET;
saDest.sin_port = 0;

// Tell the user what we're doing
printf("\nPinging %s [%s] with %d bytes of data:\n",
pstrHost,
inet_ntoa(saDest.sin_addr),
REQ_DATASIZE);

// Ping multiple times
for (nLoop = 0; nLoop < 4; nLoop++)
{
// Send ICMP echo request
SendEchoRequest(rawSocket, &saDest);

// Use select() to wait for data to be received
nRet = WaitForEchoReply(rawSocket);
if (nRet == SOCKET_ERROR)
{
ReportError("select()");
break;
}
if (!nRet)
{
printf("\nTimeOut");
break;
}

// Receive reply
dwTimeSent = RecvEchoReply(rawSocket, &saSrc, &cTTL);

// Calculate elapsed time
dwElapsed = GetTickCount() - dwTimeSent;
printf("\nReply from: %s: bytes=%d time=%ldms TTL=%d",
inet_ntoa(saSrc.sin_addr),
REQ_DATASIZE,
dwElapsed,
cTTL);
}
printf("\n");
nRet = closesocket(rawSocket);
if (nRet == SOCKET_ERROR)
ReportError("closesocket()");
}


// SendEchoRequest()
// Fill in echo request header
// and send to destination
int SendEchoRequest(SOCKET s,LPSOCKADDR_IN lpstToAddr)
{
static ECHOREQUEST echoReq;
static nId = 1;
static nSeq = 1;
int nRet;

// Fill in echo request
echoReq.icmpHdr.Type = ICMP_ECHOREQ;
echoReq.icmpHdr.Code = 0;
echoReq.icmpHdr.Checksum = 0;
echoReq.icmpHdr.ID = nId++;
echoReq.icmpHdr.Seq = nSeq++;

// Fill in some data to send
for (nRet = 0; nRet < REQ_DATASIZE; nRet++)
echoReq.cData[nRet] = ' '+nRet;

// Save tick count when sent
echoReq.dwTime = GetTickCount();

// Put data in packet and compute checksum
echoReq.icmpHdr.Checksum = in_cksum((u_short *)&echoReq, sizeof(ECHOREQUEST));

// Send the echo request
nRet = sendto(s, /* socket */
(LPSTR)&echoReq, /* buffer */
sizeof(ECHOREQUEST),
0, /* flags */
(LPSOCKADDR)lpstToAddr, /* destination */
sizeof(SOCKADDR_IN)); /* address length */

if (nRet == SOCKET_ERROR)
ReportError("sendto()");
return (nRet);
}


// RecvEchoReply()
// Receive incoming data
// and parse out fields
DWORD RecvEchoReply(SOCKET s, LPSOCKADDR_IN lpsaFrom, u_char *pTTL)
{
ECHOREPLY echoReply;
int nRet;
int nAddrLen = sizeof(struct sockaddr_in);

// Receive the echo reply
nRet = recvfrom(s, // socket
(LPSTR)&echoReply, // buffer
sizeof(ECHOREPLY), // size of buffer
0, // flags
(LPSOCKADDR)lpsaFrom, // From address
&nAddrLen); // pointer to address len

// Check return value
if (nRet == SOCKET_ERROR)
ReportError("recvfrom()");

// return time sent and IP TTL
*pTTL = echoReply.ipHdr.TTL;
return(echoReply.echoRequest.dwTime);
}

// What happened?
void ReportError(LPCSTR pWhere)
{
fprintf(stderr,"\n%s error: %d\n",
WSAGetLastError());
}


// WaitForEchoReply()
// Use select() to determine when
// data is waiting to be read
int WaitForEchoReply(SOCKET s)
{
struct timeval Timeout;
fd_set readfds;

readfds.fd_count = 1;
readfds.fd_array[0] = s;
Timeout.tv_sec = 5;
Timeout.tv_usec = 0;

return(select(1, &readfds, NULL, NULL, &Timeout));
}


//
// Mike Muuss' in_cksum() function
// and his comments from the original
// ping program
//
// * Author -
// * Mike Muuss
// * U. S. Army Ballistic Research Laboratory
// * December, 1983

/*
* I N _ C K S U M
*
* Checksum routine for Internet Protocol family headers (C Version)
*
*/
u_short in_cksum(u_short *addr, int len)
{
register int nleft = len;
register u_short *w = addr;
register u_short answer;
register int sum = 0;

/*
* Our algorithm is simple, using a 32 bit accumulator (sum),
* we add sequential 16 bit words to it, and at the end, fold
* back all the carry bits from the top 16 bits into the lower
* 16 bits.
*/
while( nleft > 1 ) {
sum += *w++;
nleft -= 2;
}

/* mop up an odd byte, if necessary */
if( nleft == 1 ) {
u_short u = 0;

*(u_char *)(&u) = *(u_char *)w ;
sum += u;
}

/*
* add back carry outs from top 16 bits to low 16 bits
*/
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* truncate to 16 bits */
return (answer);
}
「已注销」 2006-08-11
  • 打赏
  • 举报
回复
WIN XP SP2下无法发送RAW...

#include <stdio.h>

#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")

#include <ws2tcpip.h>

#define SOURCE_PORT 7234
#define MAX_RECEIVEBYTE 255

typedef struct ip_hdr //定义IP首部
{
unsigned char h_verlen; //4位首部长度,4位IP版本号
unsigned char tos; //8位服务类型TOS
unsigned short total_len; //16位总长度(字节)
unsigned short ident; //16位标识
unsigned short frag_and_flags; //3位标志位
unsigned char ttl; //8位生存时间 TTL
unsigned char proto; //8位协议 (TCP, UDP 或其他)
unsigned short checksum; //16位IP首部校验和
unsigned int sourceIP; //32位源IP地址
unsigned int destIP; //32位目的IP地址
}IPHEADER;

typedef struct tsd_hdr //定义TCP伪首部
{
unsigned long saddr; //源地址
unsigned long daddr; //目的地址
char mbz;
char ptcl; //协议类型
unsigned short tcpl; //TCP长度
}PSDHEADER;

typedef struct tcp_hdr //定义TCP首部
{
USHORT th_sport; //16位源端口
USHORT th_dport; //16位目的端口
unsigned int th_seq; //32位序列号
unsigned int th_ack; //32位确认号
unsigned char th_lenres; //4位首部长度/6位保留字
unsigned char th_flag; //6位标志位
USHORT th_win; //16位窗口大小
USHORT th_sum; //16位校验和
USHORT th_urp; //16位紧急数据偏移量
}TCPHEADER;

//计算校验和的子函数
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);
}

void useage()
{
printf("***********************************************\n");
printf("Useage: TCPPing.exe Target_ip Target_port\n");
printf("***********************************************\n");
}

int main(int argc,char* argv[])
{
WSADATA WSAData;
SOCKET sock;
SOCKADDR_IN addr_in;
IPHEADER ipHeader;
TCPHEADER tcpHeader;
PSDHEADER psdHeader;

char szSendBuf[60]={0};
BOOL flag;
int rect,nTimeOver;

useage();

if(argc!=3)
{
return false;
}

if(WSAStartup(MAKEWORD(2,2),&WSAData)!=0)
{
printf("WSAStartup Error!\n");
return false;
}

if((sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,0,WSA_FLAG_OVERLAPPED))==INVALID_SOCKET)
{
printf("Socket Setup Error!\n");
return false;
}
flag=true;
if (setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char*)&flag,sizeof(flag))==SOCKET_ERROR)
{
printf("setsockopt IP_HDRINCL error!\n");
return false;
}

nTimeOver=1000;
if(setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(char*)&nTimeOver,sizeof(nTimeOver))==SOCKET_ERROR)
{
printf("setsockopt SO_SNDTIMEO error!\n");
return false;
}

addr_in.sin_family=AF_INET;
addr_in.sin_port=htons(atoi(argv[2]));
addr_in.sin_addr.S_un.S_addr=inet_addr(argv[1]);

//填充IP首部
ipHeader.h_verlen=(4<<4 | sizeof(ipHeader)/sizeof(unsigned long));
ipHeader.tos=0;
ipHeader.total_len=htons(sizeof(ipHeader)+sizeof(tcpHeader));
ipHeader.ident=1;
ipHeader.frag_and_flags=0;
ipHeader.ttl=128;
ipHeader.proto=IPPROTO_TCP;
ipHeader.checksum=0;
ipHeader.sourceIP=inet_addr("127.0.0.1");
ipHeader.destIP=inet_addr(argv[1]);

//填充TCP首部
tcpHeader.th_dport=htons(atoi(argv[2]));
tcpHeader.th_sport=htons(SOURCE_PORT); //源端口号
tcpHeader.th_seq=htonl(0x12345678);
tcpHeader.th_ack=0;
tcpHeader.th_lenres=(sizeof(tcpHeader)/4<<4|0);
tcpHeader.th_flag=2; //修改这里来实现不同的标志位探测,2是SYN,1是FIN,16是ACK探测 等等
tcpHeader.th_win=htons(512);
tcpHeader.th_urp=0;
tcpHeader.th_sum=0;

psdHeader.saddr=ipHeader.sourceIP;
psdHeader.daddr=ipHeader.destIP;
psdHeader.mbz=0;
psdHeader.ptcl=IPPROTO_TCP;
psdHeader.tcpl=htons(sizeof(tcpHeader));

//计算校验和
memcpy(szSendBuf, &psdHeader, sizeof(psdHeader));
memcpy(szSendBuf+sizeof(psdHeader), &tcpHeader,sizeof(tcpHeader));
tcpHeader.th_sum=checksum((USHORT *)szSendBuf,sizeof(psdHeader)+sizeof(tcpHeader));

memcpy(szSendBuf, &ipHeader, sizeof(ipHeader));
memcpy(szSendBuf+sizeof(ipHeader),&tcpHeader,sizeof(tcpHeader));
memset(szSendBuf+sizeof(ipHeader)+sizeof(tcpHeader),0,4);
ipHeader.checksum=checksum((USHORT *)szSendBuf,sizeof(ipHeader)+sizeof(tcpHeader));

memcpy(szSendBuf,&ipHeader,sizeof(ipHeader));

rect=sendto(sock,szSendBuf,sizeof(ipHeader)+sizeof(tcpHeader),0,(struct sockaddr*)&addr_in,sizeof(addr_in));
if (rect==SOCKET_ERROR)
{
printf("send error!:%d\n",WSAGetLastError());
return false;
}
else
printf("send ok!\n");

closesocket(sock);

WSACleanup();

return 0;
}
DentistryDoctor 2006-08-10
  • 打赏
  • 举报
回复
http://www.codeguru.com/Cpp/I-N/network/winsocksolutions/article.php/c2449

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧