数据包未发送

时间:2019-12-20 23:08:39

标签: c windows sockets tcp raw-sockets

我是原始套接字的新手,我试图了解该过程的每个步骤,但似乎不起作用,设置IPPROTO_TCP时会导致错误 10022 ,而在它设置为IPPROTO_RAW,我看不到问题,可能不止一个,对那些可以指导我并向我展示我的错误的人感到高兴。

参考: https://www.binarytides.com/tcp-syn-portscan-in-c-with-linux-sockets/ https://www.binarytides.com/raw-sockets-using-winsock/

#pragma comment(lib, "Ws2_32.lib")

#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>
#include <ws2tcpip.h>
#include <Windows.h>

#pragma pack(push, 1)
typedef struct 
{
  unsigned char ip_header_len : 4; // 4-bit header length (in 32-bit words) normally=5 (Means 20 Bytes may be 24 also)
  unsigned char version : 4; // 4-bit IPv4 version
  unsigned char tos; // IP type of service
  unsigned short total_length; // Total length
  unsigned short id; // Unique identifier

  unsigned char frag_offset : 5; // Fragment offset field

  unsigned char more_fragment : 1;
  unsigned char dont_fragment : 1;
  unsigned char reserved_zero : 1;

  unsigned char frag_offset1; //fragment offset

  unsigned char ttl; // Time to live
  unsigned char protocol; // Protocol(TCP,UDP etc)
  unsigned short checksum; // IP checksum
  unsigned int srcaddr; // Source address
  unsigned int destaddr; // Source address
} iphdr;

typedef struct
{
  unsigned short source_port; // source port
  unsigned short dest_port; // destination port
  unsigned int sequence; // sequence number - 32 bits
  unsigned int acknowledge; // acknowledgement number - 32 bits

  unsigned char ns : 1; //Nonce Sum Flag Added in RFC 3540.
  unsigned char reserved_part1 : 3; //according to rfc
  unsigned char data_offset : 4; /*The number of 32-bit words in the TCP header.
  This indicates where the data begins.
  The length of the TCP header is always a multiple
  of 32 bits.*/

  unsigned char fin : 1; //Finish Flag
  unsigned char syn : 1; //Synchronise Flag
  unsigned char rst : 1; //Reset Flag
  unsigned char psh : 1; //Push Flag
  unsigned char ack : 1; //Acknowledgement Flag
  unsigned char urg : 1; //Urgent Flag

  unsigned char ecn : 1; //ECN-Echo Flag
  unsigned char cwr : 1; //Congestion Window Reduced Flag

  ////////////////////////////////

  unsigned short window; // window
  unsigned short checksum; // checksum
  unsigned short urgent_pointer; // urgent pointer
} tcphdr;
#pragma pack(pop)

unsigned short csum(unsigned short* ptr, int nbytes)
{
  register long sum;
  unsigned short oddbyte;
  register short answer;

  sum = 0;
  while (nbytes > 1)
  {
    sum += *ptr++;
    nbytes -= 2;
  }

  if (nbytes == 1)
  {
    oddbyte = 0;
    *((u_char*) & oddbyte) = *(u_char*)ptr;
    sum += oddbyte;
  }

  sum = (sum >> 16) + (sum & 0xffff);
  sum = sum + (sum >> 16);
  answer = (short)~sum;

  return (answer);
}

char* getLocalIP(char* buffer)
{
  int sock = socket(AF_INET, SOCK_DGRAM, 0);

  const char* kGoogleDnsIp = "8.8.8.8";
  int dns_port = 53;

  struct sockaddr_in serv;

  memset(&serv, 0, sizeof(serv));
  serv.sin_family = AF_INET;
  serv.sin_addr.s_addr = inet_addr(kGoogleDnsIp);
  serv.sin_port = htons(dns_port);

  int err = connect(sock, (const struct sockaddr*) &serv, sizeof(serv));

  struct sockaddr_in name;
  socklen_t namelen = sizeof(name);
  err = getsockname(sock, (struct sockaddr*) &name, &namelen);

  const char* p = inet_ntop(AF_INET, &name.sin_addr, buffer, 100);

  closesocket(sock);

  return buffer;
}

typedef struct
{
  iphdr iph;
  tcphdr tcph;
} DATAGRAM;

int main(int argc, char* argv[])
{
  int one = 1;
  DATAGRAM dg;
  WSADATA data;
  sockaddr_in dest;

  WSAStartup(MAKEWORD(2, 2), &data);

  char* ip = "1.2.3.4";
  long port = 1234;

  int source_port = 1111;
  char source_ip[20];

  getLocalIP(source_ip);

  dest.sin_addr.s_addr = inet_addr(ip);
  dest.sin_port = htons(port);
  dest.sin_family = AF_INET;

  ZeroMemory(&dg, sizeof(dg));

  //Fill in the IP Header
  dg.iph.ip_header_len = 5;
  dg.iph.version = 4;
  dg.iph.total_length = htons(sizeof(dg));
  dg.iph.id = htons(13133);
  dg.iph.dont_fragment = 1;
  dg.iph.ttl = 49;
  dg.iph.protocol = IPPROTO_TCP;
  dg.iph.srcaddr = inet_addr(source_ip);
  dg.iph.destaddr = dest.sin_addr.s_addr;
  dg.iph.checksum = htons(csum((unsigned short*)&dg, sizeof(dg)));

  //TCP Header
  dg.tcph.source_port = htons(source_port);
  dg.tcph.dest_port = dest.sin_port;
  dg.tcph.sequence = htonl(1);
  dg.tcph.acknowledge = htonl(1);
  dg.tcph.syn = 1;
  dg.tcph.window = htons(65535);

  auto sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);

  if (sock == SOCKET_ERROR)
  {
    printf("WSAError socket(): %d \n", WSAGetLastError());
    system("pause");
    return 0;
  }

  if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&one, sizeof(one)) == SOCKET_ERROR)
  {
    printf("Error setting IP_HDRINCL.Error number : %d.Error message : %s \n", errno, strerror(errno));
    printf("WSAError setsockopt(): %d \n", WSAGetLastError());
    system("pause");
    return 0;
  }

  if (sendto(sock, (char*)&dg, sizeof(dg), 0, (sockaddr*)&dest, sizeof(dest)) == SOCKET_ERROR)
  {
    printf("WSAError sendto(): %d \n", WSAGetLastError());
    system("pause");
    return 0;
  }

  closesocket(sock);

  system("pause");

  return 0;
}

0 个答案:

没有答案