发送raw tcp包 发表于 2024-06-18 | 分类于 tutorial 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129struct iphdr { uint8_t ihl :4, version:4; uint8_t tos; uint16_t tot_len; uint16_t id; uint16_t frag_off; uint8_t ttl; uint8_t protocol; uint16_t check; int32_t saddr; int32_t daddr; }; struct tcphdr { uint16_t source; uint16_t dest; uint32_t seq; uint32_t ack_seq; uint16_t res1:4, doff:4, fin:1, syn:1, rst:1, psh:1, ack:1, urg:1, ece:1, cwr:1; uint16_t window; uint16_t check; uint16_t urg_ptr; }; struct pseudo_header { u_int32_t source_address; u_int32_t dest_address; u_int8_t placeholder; u_int8_t protocol; u_int16_t tcp_length; }; static uint16_t checksum(uint8_t* buf, size_t size) { int res = 0; uint16_t* ptr = (uint16_t*)buf; for (int i = 0; i < size / 2; i++) { res += ptr[i]; } if (size & 1) { res += buf[size - 1]; } res = (res >> 16) + (res & 0xFFFF); res += (res >> 16); return ~res; } static int send_rst(std::string ip, uint16_t port) { int fd; uint8_t buf[128]; uint8_t psb[128]; struct pseudo_header psh; struct iphdr* iph = (struct iphdr*)buf; struct tcphdr* tcph = (struct tcphdr*)(buf + sizeof(struct iphdr)); struct sockaddr_in dest; int val; fd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); if (fd < 0) { printf("socket open failed\n"); return -1; } val = 1; setsockopt(fd, IPPROTO_IP, IP_HDRINCL, &val, sizeof(val)); memset(buf, 0, sizeof(buf)); iph->ihl = sizeof(struct iphdr) >> 2; iph->version = 4; iph->tos = 0; iph->tot_len = htons(sizeof(struct iphdr) + sizeof(struct tcphdr)); iph->id = htonl(54321); iph->frag_off = 0; iph->ttl = 255; iph->protocol = IPPROTO_TCP; iph->saddr = inet_addr("192.168.1.1"); iph->daddr = inet_addr(ip.c_str()); iph->check = 0; iph->check = checksum((uint8_t*)iph, sizeof(struct iphdr)); tcph->source = htons(7000); tcph->dest = htons(port); tcph->seq = 123456789; tcph->ack_seq = 0; tcph->doff = sizeof(struct tcphdr) >> 2; tcph->rst = 1; tcph->window = htons(5840); tcph->check = 0; tcph->urg_ptr = 0; psh.source_address = iph->saddr; psh.dest_address = iph->daddr; psh.placeholder = 0; psh.protocol = IPPROTO_TCP; psh.tcp_length = htons(sizeof(struct tcphdr)); memcpy(psb, &psh, sizeof(struct pseudo_header)); memcpy(psb + sizeof(struct pseudo_header), tcph, sizeof(struct tcphdr)); tcph->check = checksum(psb, sizeof(struct pseudo_header) + sizeof(struct tcphdr)); dest.sin_family = AF_INET; dest.sin_port = tcph->dest; dest.sin_addr.s_addr = iph->daddr; if (sendto(fd, buf, sizeof(struct iphdr) + sizeof(struct tcphdr), 0, (struct sockaddr*)&dest, sizeof(dest)) < 0) { printf("send failed: %s\n", strerror(errno)); } close(fd); return 0; }