#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <netinet/in.h> #include <netinet/ip.h> #include <netinet/tcp.h> #include <sys/socket.h> #include <arpa/inet.h> #define DESTINATION_IP "172.27.0.1" // 目标IP地址 #define DESTINATION_PORT 80 // 目标端口号 struct pseudo_header { unsigned long source_address; unsigned long dest_address; unsigned short placeholder; uint8_t protocol; unsigned short tcp_length; struct tcphdr tcp; }; // 计算校验和的函数 unsigned short checksum(unsigned short *ptr, int nbytes) { unsigned long sum; unsigned short oddbyte; unsigned short answer; sum = 0; while (nbytes > 1) { sum += *ptr++; nbytes -= 2; } if (nbytes == 1) { oddbyte = 0; *((unsigned char *)&oddbyte) = *(unsigned char *)ptr; sum += oddbyte; } sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); answer = (unsigned short)~sum; return answer; } int main() { // 创建原始套接字 int sockfd; sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); if (sockfd < 0) { perror("Socket creation failed"); exit(EXIT_FAILURE); } // 设置IP头部的目标地址 struct sockaddr_in dest_addr; dest_addr.sin_family = AF_INET; dest_addr.sin_port = htons(DESTINATION_PORT); dest_addr.sin_addr.s_addr = inet_addr(DESTINATION_IP); // 构造TCP头部 char packet[4096]; // 足够大以容纳TCP报文 struct iphdr *iph = (struct iphdr *)packet; struct tcphdr *tcph = (struct tcphdr *)(packet + sizeof(struct iphdr)); memset(packet, 0, sizeof(packet)); // 清空数据包 // 设置IP头部信息 iph->ihl = 5; iph->version = 4; iph->tos = 0; iph->tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr); iph->id = htonl(54321); iph->frag_off = 0; iph->ttl = 255; iph->protocol = IPPROTO_TCP; iph->check = 0; iph->saddr = inet_addr("8.8.8.8"); // 源IP地址 iph->daddr = dest_addr.sin_addr.s_addr; // 设置TCP头部信息 tcph->source = htons(12345); // 伪造源端口 tcph->dest = htons(DESTINATION_PORT); tcph->seq = 0; tcph->ack_seq = 0; tcph->doff = 5; tcph->syn = 0; // 不设置SYN标志位 tcph->window = htons(65535); tcph->check = 0; tcph->urg_ptr = 0; // 计算TCP校验和 struct pseudo_header psh; psh.source_address = iph->saddr; psh.dest_address = iph->daddr; psh.placeholder = 0; psh.protocol = IPPROTO_TCP; psh.tcp_length = htons(sizeof(struct tcphdr)); int psize = sizeof(struct pseudo_header) + sizeof(struct tcphdr); char *pseudogram = malloc(psize); memcpy(pseudogram, (char *)&psh, sizeof(struct pseudo_header)); memcpy(pseudogram + sizeof(struct pseudo_header), tcph, sizeof(struct tcphdr)); tcph->check = checksum((unsigned short *)pseudogram, psize); // 发送数据包 if (sendto(sockfd, packet, iph->tot_len, 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr)) < 0) { perror("Sendto failed"); exit(EXIT_FAILURE); } // 关闭套接字 close(sockfd); return 0; } // build // gcc send_tcp_packet.c -o send_tcp_packet