Skip to content

Instantly share code, notes, and snippets.

@gjyoung1974
Created November 19, 2024 19:45
Show Gist options
  • Save gjyoung1974/fd631ae22320d9de786c50c57855af01 to your computer and use it in GitHub Desktop.
Save gjyoung1974/fd631ae22320d9de786c50c57855af01 to your computer and use it in GitHub Desktop.
// 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