我是原始套接字的新手,我试图了解该过程的每个步骤,但似乎不起作用,设置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;
}