#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