Используя SOCKET_RAW в клиентской программе udp, я пытался подделать IP-адрес клиента при отправке пакета на сервер. Он работает нормально, когда я пытаюсь использовать исходный IP-адрес, но когда я пытаюсь подделать IP-адрес, он не подключается к серверу. Если я изменю номер порта клиента без изменения IP-адреса, он будет работать нормально.
Как подменить или изменить IP-адрес клиента в отправляющем пакете, используя заголовки IP или заголовки UDP.
Клиентская программа UDP на C ++:
#include <iostream>
#include <unistd.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <memory>
using namespace std;
#pragma pack(1)
// The IP header structure
//
typedef struct _iphdr
{
unsigned char h_len:4; // Length
unsigned char ver:4; // IP Version
unsigned char tos; // Type of service
unsigned short totlen; // Total length of the packet
unsigned short id; // Unique identifier
unsigned short offset; // Fragment offset field
unsigned char ttl; // Time to live
unsigned char proto; // Protocol(TCP,UDP,ICMP,IGMP...)
unsigned short checksum; // IP checksum
unsigned int srcIP; // Source IP address
unsigned int destIP; // Destination IP address
}IpHeader, * LPIpHeader;
// The UDP header structure
//
typedef struct _udphdr
{
unsigned short sport; // Source Port
unsigned short dport; // Destination Port
unsigned short Length; // Length
unsigned short Checksum; // Checksum
}UdpHeader, * LPUdpHeader;
typedef struct _PSHeader
{
unsigned long srcaddr;
unsigned long destaddr;
unsigned char zero;
unsigned char protocol;
unsigned short len;
}PSHeader;
#pragma pack()
int initialize();
USHORT checksum(USHORT *buffer, int size);
int main()
{
initialize();
SOCKET sock = socket(AF_INET,SOCK_RAW,IPPROTO_UDP);
SOCKADDR_IN sock_addr;
BOOL on = 1;
int ret = setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char *)&on,sizeof(on));
if (ret == SOCKET_ERROR){
printf("Error setting opt: %d",WSAGetLastError());
return -1;
}
unsigned char sendBuf[2048];
memset(sendBuf,0,2048);
unsigned char chksumBuf[2048];
memset(chksumBuf,0,2048);
int chksumLen = 0;
unsigned char data[20];
memset(data,0,20);
strcpy((char*)data,"Hello");
int data_size = strlen((char*)data) + 1;
IpHeader *iphdr;
UdpHeader *udphdr, udpHdr;
int iUdpSize, error;
PSHeader pseudo_header;
iphdr = (IpHeader *) sendBuf; // the ip header now points to the top of the sendBuf
udphdr=(UdpHeader *) (sendBuf + sizeof(IpHeader)); // the udp header points to the part next to the ip header
memcpy(sendBuf+sizeof(IpHeader)+sizeof(UdpHeader),data, data_size);
sock_addr.sin_family = AF_INET;
sock_addr.sin_port = htons (9090);
sock_addr.sin_addr.s_addr = inet_addr("172.24.127.115");
iphdr->ver = 4;
iphdr->h_len = 5;
iphdr->tos = 0;
iphdr->totlen = sizeof (IpHeader) + sizeof (UdpHeader) + data_size;
iphdr->id = 1;
iphdr->offset = 0;
iphdr->ttl = 255;
iphdr->proto = IPPROTO_UDP; //UDP
iphdr->checksum = 0;
iphdr->srcIP = inet_addr ("172.24.127.115"); // your source id
iphdr->destIP = sock_addr.sin_addr.s_addr;
// Initalize the UDP header
//
iUdpSize = sizeof(UdpHeader) + data_size;
udphdr->sport = htons(9095) ;
udphdr->dport = htons(9090) ;
udphdr->Length = htons(iUdpSize) ;
udphdr->Checksum = 0 ;
//calculate UDP CheckSum
pseudo_header.destaddr = inet_addr("172.24.127.115");
pseudo_header.srcaddr = inet_addr("172.24.127.115");
pseudo_header.zero = 0;
pseudo_header.protocol = IPPROTO_UDP;
pseudo_header.len = udphdr->Length;
memcpy(chksumBuf,(PVOID)&pseudo_header,sizeof(pseudo_header));
chksumLen += sizeof(pseudo_header);
memcpy(chksumBuf+chksumLen,udphdr,sizeof(UdpHeader));
chksumLen += sizeof(UdpHeader);
memcpy(chksumBuf+chksumLen,data,data_size);
chksumLen += data_size;
udphdr->Checksum = checksum((unsigned short*) chksumBuf,chksumLen);
iphdr->checksum = checksum((unsigned short *) iphdr, sizeof(IpHeader));
/*for(int i=0;i<40;i++)
printf("%x",sendBuf[i]);*/
error = sendto(sock,(char*)sendBuf,28+data_size,0,(LPSOCKADDR)&sock_addr,sizeof(SOCKADDR_IN));
if(error == SOCKET_ERROR)
cout << WSAGetLastError() << endl;
else
cout << "sent" << endl;
return 0;
}
int initialize()
{
int t;
/* Before any Winsock function to work, we need to call to wsock.dll to initialize those
functions */
WSADATA wsa_data;
t = WSAStartup(MAKEWORD(2,2), &wsa_data);
if(t != 0)
return -1;
else
return 0;
}
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);
}
Программа сервера UPD на JAVA:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDP_SERVER_FILE {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
DatagramSocket serverSocket = new DatagramSocket(9090);
byte[] receiveData = new byte[8];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
System.out.println(receivePacket.getAddress());
System.out.println(receivePacket.getPort());
System.out.println(receivePacket.getSocketAddress());
String sentence = new String( receivePacket.getData());
System.out.println("RECEIVED: " + sentence);
}
}
Мне нужно подделать IP-адрес клиента. Кто-нибудь поможет мне с источником, где я могу хорошо понять эти понятия.