Created
November 19, 2024 19:45
-
-
Save gjyoung1974/fd631ae22320d9de786c50c57855af01 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Manufacture TCP Packets | |
// Compile with | |
// gcc -o raw_tcp raw_tcp.c | |
// run as su | |
// sudo ./raw_tcp | |
#include <stdio.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <sys/socket.h> | |
#include <arpa/inet.h> | |
#include <netinet/ip.h> // For IP header | |
#include <netinet/tcp.h> // For TCP header | |
// Checksum calculation | |
unsigned short checksum(void *b, int len) { | |
unsigned short *buf = b; | |
unsigned int sum = 0; | |
unsigned short result; | |
for (sum = 0; len > 1; len -= 2) | |
sum += *buf++; | |
if (len == 1) | |
sum += *(unsigned char *)buf; | |
sum = (sum >> 16) + (sum & 0xFFFF); | |
sum += (sum >> 16); | |
result = ~sum; | |
return result; | |
} | |
int main() { | |
int sock; | |
char packet[4096]; // Buffer for packet | |
struct sockaddr_in dest_addr; | |
struct iphdr *ip_header; | |
struct tcphdr *tcp_header; | |
// Create a raw socket | |
sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); | |
if (sock < 0) { | |
perror("Socket creation failed"); | |
exit(1); | |
} | |
// Zero out the packet buffer | |
memset(packet, 0, sizeof(packet)); | |
// Fill in IP Header | |
ip_header = (struct iphdr *)packet; | |
ip_header->ihl = 5; // Header length | |
ip_header->version = 4; // IPv4 | |
ip_header->tos = 0; // Type of service | |
ip_header->tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr); // Total length | |
ip_header->id = htonl(54321); // Random id | |
ip_header->frag_off = 0; // No fragmentation | |
ip_header->ttl = 255; // TTL | |
ip_header->protocol = IPPROTO_TCP; // TCP | |
ip_header->saddr = inet_addr("192.168.1.1"); // Source IP | |
ip_header->daddr = inet_addr("192.168.1.2"); // Destination IP | |
ip_header->check = checksum((unsigned short *)ip_header, sizeof(struct iphdr)); | |
// Fill in TCP Header | |
tcp_header = (struct tcphdr *)(packet + sizeof(struct iphdr)); | |
tcp_header->source = htons(12345); // Source port | |
tcp_header->dest = htons(80); // Destination port | |
tcp_header->seq = htonl(0); // Sequence number | |
tcp_header->ack_seq = 0; // Acknowledgment number | |
tcp_header->doff = 5; // Header size | |
tcp_header->syn = 1; // SYN flag | |
tcp_header->window = htons(5840); // Window size | |
tcp_header->check = 0; // Checksum (calculated later) | |
tcp_header->urg_ptr = 0; // Urgent pointer | |
// Pseudo header for checksum calculation | |
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; | |
struct tcphdr tcp; | |
} pseudo_hdr; | |
pseudo_hdr.source_address = ip_header->saddr; | |
pseudo_hdr.dest_address = ip_header->daddr; | |
pseudo_hdr.placeholder = 0; | |
pseudo_hdr.protocol = IPPROTO_TCP; | |
pseudo_hdr.tcp_length = htons(sizeof(struct tcphdr)); | |
memcpy(&pseudo_hdr.tcp, tcp_header, sizeof(struct tcphdr)); | |
tcp_header->check = checksum((unsigned short *)&pseudo_hdr, sizeof(pseudo_hdr)); | |
// Set destination address | |
dest_addr.sin_family = AF_INET; | |
dest_addr.sin_port = tcp_header->dest; | |
dest_addr.sin_addr.s_addr = ip_header->daddr; | |
// Send the packet | |
if (sendto(sock, packet, ip_header->tot_len, 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr)) < 0) { | |
perror("Send failed"); | |
} else { | |
printf("Packet sent successfully\n"); | |
} | |
close(sock); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment