我想在数据包发出去之前把IP数据报的源地址给换成别的,于是我就采取了这样的方法
... ... ...
sockRaw = WSASocket (AF_INET,
SOCK_RAW,
IPPROTO_ICMP,
NULL,0,0);
... ... ...
bread = setsockopt(sockRaw,IPPROTO_IP,IP_HDRINCL,&ion,
sizeof(ion));
bwrote = sendto(sockRaw,ip_data,datasize,0,(struct sockaddr*)&dest,
sizeof(dest));
... ... ...
我是用了IP_HDRINCL,但程序却无反应,如果把ip_data改成icmp_data
则用抓包工具看到的结果是IP报头仍然是原来的,
所以我不明白为什么我用了原始socket和IP_HDRINCL,并且是在Win2000下运行,为什么还是不能改IP包头呢?
一些资料上的实例都是同时改TCP(或UDP),IP的报头,对于这些程序我没运行过,所以怀疑是否能够很好的运行。
... ... ...
sockRaw = WSASocket (AF_INET,
SOCK_RAW,
IPPROTO_ICMP,
NULL,0,0);
... ... ...
bread = setsockopt(sockRaw,IPPROTO_IP,IP_HDRINCL,&ion,
sizeof(ion));
bwrote = sendto(sockRaw,ip_data,datasize,0,(struct sockaddr*)&dest,
sizeof(dest));
... ... ...
我是用了IP_HDRINCL,但程序却无反应,如果把ip_data改成icmp_data
则用抓包工具看到的结果是IP报头仍然是原来的,
所以我不明白为什么我用了原始socket和IP_HDRINCL,并且是在Win2000下运行,为什么还是不能改IP包头呢?
一些资料上的实例都是同时改TCP(或UDP),IP的报头,对于这些程序我没运行过,所以怀疑是否能够很好的运行。
#define MAX_MESSAGE 4068
#define MAX_PACKET 4096
//
// Setup some default values
//
#define DEFAULT_PORT 5000
#define DEFAULT_IP "192.168.0.100"
#define DEFAULT_COUNT 5
#define DEFAULT_MESSAGE "This is a test"//
// Define the IP header. Make the version and length field one
// character since we can't declare two 4 bit fields without
// the compiler aligning them on at least a 1 byte boundary.
//
typedef struct ip_hdr
{
unsigned char ip_verlen; // IP version & length
unsigned char ip_tos; // IP type of service
unsigned short ip_totallength; // Total length
unsigned short ip_id; // Unique identifier
unsigned short ip_offset; // Fragment offset field
unsigned char ip_ttl; // Time to live
unsigned char ip_protocol; // Protocol(TCP,UDP etc)
unsigned short ip_checksum; // IP checksum
unsigned int ip_srcaddr; // Source address
unsigned int ip_destaddr; // Destination address
} IP_HDR, *PIP_HDR, FAR* LPIP_HDR;
//
// Define the UDP header
//
typedef struct udp_hdr
{
unsigned short src_portno; // Source port number
unsigned short dst_portno; // Destination port number
unsigned short udp_length; // UDP packet length
unsigned short udp_checksum; // UDP checksum (optional)
} UDP_HDR, *PUDP_HDR;//
// Global variables
//
unsigned long dwToIP, // IP to send to
dwFromIP; // IP to send from (spoof)
unsigned short iToPort, // Port to send to
iFromPort; // Port to send from (spoof)
DWORD dwCount; // Number of times to send char
// Creating a raw socket //
s = WSASocket(AF_INET, SOCK_RAW, IPPROTO_UDP, NULL, 0,0);
if (s == INVALID_SOCKET)
{
printf("WSASocket() failed: %d\n", WSAGetLastError());
return -1;
} // Enable the IP header include option
//
bOpt = TRUE;
ret = setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&bOpt, sizeof(bOpt));
if (ret == SOCKET_ERROR)
{
printf("setsockopt(IP_HDRINCL) failed: %d\n", WSAGetLastError());
return -1;
}
// Initalize the IP header
//
iTotalSize = sizeof(ipHdr) + sizeof(udpHdr) + strlen(strMessage); iIPVersion = 4;
iIPSize = sizeof(ipHdr) / sizeof(unsigned long);
//
// IP version goes in the high order 4 bits of ip_verlen. The
// IP header length (in 32-bit words) goes in the lower 4 bits.
//
ipHdr.ip_verlen = (iIPVersion << 4) | iIPSize;
ipHdr.ip_tos = 0; // IP type of service
ipHdr.ip_totallength = htons(iTotalSize); // Total packet len
ipHdr.ip_id = 0; // Unique identifier: set to 0
ipHdr.ip_offset = 0; // Fragment offset field
ipHdr.ip_ttl = 128; // Time to live
ipHdr.ip_protocol = 0x11; // Protocol(UDP)
ipHdr.ip_checksum = 0 ; // IP checksum
ipHdr.ip_srcaddr = dwFromIP; // Source address
ipHdr.ip_destaddr = dwToIP; // Destination address
//
// Initalize the UDP header
//
iUdpSize = sizeof(udpHdr) + strlen(strMessage); udpHdr.src_portno = htons(iFromPort) ;
udpHdr.dst_portno = htons(iToPort) ;
udpHdr.udp_length = htons(iUdpSize) ;
udpHdr.udp_checksum = 0 ;
//
// Build the UDP pseudo-header for calculating the UDP checksum.
// The pseudo-header consists of the 32-bit source IP address,
// the 32-bit destination IP address, a zero byte, the 8-bit
// IP protocol field, the 16-bit UDP length, and the UDP
// header itself along with its data (padded with a 0 if
// the data is odd length).
//
iUdpChecksumSize = 0;
ptr = buf;
ZeroMemory(buf, MAX_PACKET); memcpy(ptr, &ipHdr.ip_srcaddr, sizeof(ipHdr.ip_srcaddr));
ptr += sizeof(ipHdr.ip_srcaddr);
iUdpChecksumSize += sizeof(ipHdr.ip_srcaddr); memcpy(ptr, &ipHdr.ip_destaddr, sizeof(ipHdr.ip_destaddr));
ptr += sizeof(ipHdr.ip_destaddr);
iUdpChecksumSize += sizeof(ipHdr.ip_destaddr); ptr++;
iUdpChecksumSize += 1; memcpy(ptr, &ipHdr.ip_protocol, sizeof(ipHdr.ip_protocol));
ptr += sizeof(ipHdr.ip_protocol);
iUdpChecksumSize += sizeof(ipHdr.ip_protocol); memcpy(ptr, &udpHdr.udp_length, sizeof(udpHdr.udp_length));
ptr += sizeof(udpHdr.udp_length);
iUdpChecksumSize += sizeof(udpHdr.udp_length);
memcpy(ptr, &udpHdr, sizeof(udpHdr));
ptr += sizeof(udpHdr);
iUdpChecksumSize += sizeof(udpHdr); for(i = 0; i < strlen(strMessage); i++, ptr++)
*ptr = strMessage[i];
iUdpChecksumSize += strlen(strMessage); cksum = checksum((USHORT *)buf, iUdpChecksumSize);
udpHdr.udp_checksum = cksum;
//
// Now assemble the IP and UDP headers along with the data
// so we can send it
//
ZeroMemory(buf, MAX_PACKET);
ptr = buf; memcpy(ptr, &ipHdr, sizeof(ipHdr)); ptr += sizeof(ipHdr);
memcpy(ptr, &udpHdr, sizeof(udpHdr)); ptr += sizeof(udpHdr);
memcpy(ptr, strMessage, strlen(strMessage)); // Apparently, this SOCKADDR_IN structure makes no difference.
// Whatever we put as the destination IP addr in the IP header
// is what goes. Specifying a different destination in remote
// will be ignored.
//
remote.sin_family = AF_INET;
remote.sin_port = htons(iToPort);
remote.sin_addr.s_addr = dwToIP;
for(i = 0; i < dwCount; i++)
{
ret = sendto(s, buf, iTotalSize, 0, (SOCKADDR *)&remote,
sizeof(remote));
if (ret == SOCKET_ERROR)
{
printf("sendto() failed: %d\n", WSAGetLastError());
break;
}
else
printf("sent %d bytes\n", ret);
}
closesocket(s) ;
WSACleanup() ;
#define MAX_MESSAGE 4068
#define MAX_PACKET 4096
//
// Setup some default values
//
#define DEFAULT_PORT 5000
#define DEFAULT_IP "192.168.0.100"
#define DEFAULT_COUNT 5
#define DEFAULT_MESSAGE "This is a test"//
// Define the IP header. Make the version and length field one
// character since we can't declare two 4 bit fields without
// the compiler aligning them on at least a 1 byte boundary.
//
typedef struct ip_hdr
{
unsigned char ip_verlen; // IP version & length
unsigned char ip_tos; // IP type of service
unsigned short ip_totallength; // Total length
unsigned short ip_id; // Unique identifier
unsigned short ip_offset; // Fragment offset field
unsigned char ip_ttl; // Time to live
unsigned char ip_protocol; // Protocol(TCP,UDP etc)
unsigned short ip_checksum; // IP checksum
unsigned int ip_srcaddr; // Source address
unsigned int ip_destaddr; // Destination address
} IP_HDR, *PIP_HDR, FAR* LPIP_HDR;
//
// Define the UDP header
//
typedef struct udp_hdr
{
unsigned short src_portno; // Source port number
unsigned short dst_portno; // Destination port number
unsigned short udp_length; // UDP packet length
unsigned short udp_checksum; // UDP checksum (optional)
} UDP_HDR, *PUDP_HDR;//
// Global variables
//
unsigned long dwToIP, // IP to send to
dwFromIP; // IP to send from (spoof)
unsigned short iToPort, // Port to send to
iFromPort; // Port to send from (spoof)
DWORD dwCount; // Number of times to send char
// Creating a raw socket //
s = WSASocket(AF_INET, SOCK_RAW, IPPROTO_UDP, NULL, 0,0);
if (s == INVALID_SOCKET)
{
printf("WSASocket() failed: %d\n", WSAGetLastError());
return -1;
} // Enable the IP header include option
//
bOpt = TRUE;
ret = setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&bOpt, sizeof(bOpt));
if (ret == SOCKET_ERROR)
{
printf("setsockopt(IP_HDRINCL) failed: %d\n", WSAGetLastError());
return -1;
}
// Initalize the IP header
//
iTotalSize = sizeof(ipHdr) + sizeof(udpHdr) + strlen(strMessage); iIPVersion = 4;
iIPSize = sizeof(ipHdr) / sizeof(unsigned long);
//
// IP version goes in the high order 4 bits of ip_verlen. The
// IP header length (in 32-bit words) goes in the lower 4 bits.
//
ipHdr.ip_verlen = (iIPVersion << 4) | iIPSize;
ipHdr.ip_tos = 0; // IP type of service
ipHdr.ip_totallength = htons(iTotalSize); // Total packet len
ipHdr.ip_id = 0; // Unique identifier: set to 0
ipHdr.ip_offset = 0; // Fragment offset field
ipHdr.ip_ttl = 128; // Time to live
ipHdr.ip_protocol = 0x11; // Protocol(UDP)
ipHdr.ip_checksum = 0 ; // IP checksum
ipHdr.ip_srcaddr = dwFromIP; // Source address
ipHdr.ip_destaddr = dwToIP; // Destination address
//
// Initalize the UDP header
//
iUdpSize = sizeof(udpHdr) + strlen(strMessage); udpHdr.src_portno = htons(iFromPort) ;
udpHdr.dst_portno = htons(iToPort) ;
udpHdr.udp_length = htons(iUdpSize) ;
udpHdr.udp_checksum = 0 ;
//
// Build the UDP pseudo-header for calculating the UDP checksum.
// The pseudo-header consists of the 32-bit source IP address,
// the 32-bit destination IP address, a zero byte, the 8-bit
// IP protocol field, the 16-bit UDP length, and the UDP
// header itself along with its data (padded with a 0 if
// the data is odd length).
//
iUdpChecksumSize = 0;
ptr = buf;
ZeroMemory(buf, MAX_PACKET); memcpy(ptr, &ipHdr.ip_srcaddr, sizeof(ipHdr.ip_srcaddr));
ptr += sizeof(ipHdr.ip_srcaddr);
iUdpChecksumSize += sizeof(ipHdr.ip_srcaddr); memcpy(ptr, &ipHdr.ip_destaddr, sizeof(ipHdr.ip_destaddr));
ptr += sizeof(ipHdr.ip_destaddr);
iUdpChecksumSize += sizeof(ipHdr.ip_destaddr); ptr++;
iUdpChecksumSize += 1; memcpy(ptr, &ipHdr.ip_protocol, sizeof(ipHdr.ip_protocol));
ptr += sizeof(ipHdr.ip_protocol);
iUdpChecksumSize += sizeof(ipHdr.ip_protocol); memcpy(ptr, &udpHdr.udp_length, sizeof(udpHdr.udp_length));
ptr += sizeof(udpHdr.udp_length);
iUdpChecksumSize += sizeof(udpHdr.udp_length);
memcpy(ptr, &udpHdr, sizeof(udpHdr));
ptr += sizeof(udpHdr);
iUdpChecksumSize += sizeof(udpHdr); for(i = 0; i < strlen(strMessage); i++, ptr++)
*ptr = strMessage[i];
iUdpChecksumSize += strlen(strMessage); cksum = checksum((USHORT *)buf, iUdpChecksumSize);
udpHdr.udp_checksum = cksum;
//
// Now assemble the IP and UDP headers along with the data
// so we can send it
//
ZeroMemory(buf, MAX_PACKET);
ptr = buf; memcpy(ptr, &ipHdr, sizeof(ipHdr)); ptr += sizeof(ipHdr);
memcpy(ptr, &udpHdr, sizeof(udpHdr)); ptr += sizeof(udpHdr);
memcpy(ptr, strMessage, strlen(strMessage)); // Apparently, this SOCKADDR_IN structure makes no difference.
// Whatever we put as the destination IP addr in the IP header
// is what goes. Specifying a different destination in remote
// will be ignored.
//
remote.sin_family = AF_INET;
remote.sin_port = htons(iToPort);
remote.sin_addr.s_addr = dwToIP;
for(i = 0; i < dwCount; i++)
{
ret = sendto(s, buf, iTotalSize, 0, (SOCKADDR *)&remote,
sizeof(remote));
if (ret == SOCKET_ERROR)
{
printf("sendto() failed: %d\n", WSAGetLastError());
break;
}
else
printf("sent %d bytes\n", ret);
}
closesocket(s) ;
WSACleanup() ;
一起使用,也不是把IP和TCP一起使用,而是把IP和ICMP一起使用,于是就行不通了