Поддельный IP-адрес клиента udp не может подключиться к серверу - PullRequest
0 голосов
/ 02 апреля 2019

Используя 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-адрес клиента. Кто-нибудь поможет мне с источником, где я могу хорошо понять эти понятия.

...