program SendRawTCPPacket;
{$mode objfpc}{$H+}
uses
SysUtils, Sockets, ctypes; //BaseUnix; // J: Commenting out Linux stuff
type
TIpHeader = packed record
ver_len: Byte; // Version and header length
tos: Byte; // Type of service
total_len: Word; // Total length
id: Word; // Identification
frag_offset: Word; // Fragment offset and flags
ttl: Byte; // Time to live
proto: Byte; // Protocol (TCP = 6)
checksum: Word; // Header checksum
src_addr: LongWord; // Source IP address
dest_addr: LongWord; // Destination IP address
end;
TTcpHeader = packed record
src_port: Word; // Source port
dest_port: Word; // Destination port
seq_num: LongWord; // Sequence number
ack_num: LongWord; // Acknowledgment number
offset_res: Byte; // Data offset and reserved bits
flags: Byte; // Flags
window: Word; // Window size
checksum: Word; // Checksum
urgent_ptr: Word; // Urgent pointer
end;
var
sock: cint;
destAddr: sockaddr_in;
packet: array[0..39] of Byte;
ipHeader: TIpHeader;
tcpHeader: TTcpHeader;
destIp: string;
destPort: Word;
function CalculateChecksum(buffer: PWord; size: Integer): Word;
var
sum: LongWord;
i: Integer;
begin
sum := 0;
for i := 0 to (size div 2) - 1 do
Inc(sum, buffer[i]);
// Add carry bits
while (sum shr 16) > 0 do
sum := (sum and $FFFF) + (sum shr 16);
Result := not Word(sum);
end;
begin
// Set destination IP and port
destIp := '192.168.1.1'; // Replace with the target IP
destPort := 80; // Replace with the target port (HTTP)
// Create a raw socket
sock := fpSocket(AF_INET, SOCK_RAW, IPPROTO_TCP);
if sock < 0 then
begin
writeln('Failed to create raw socket. Root privileges are required.');
halt(1);
end;
// Set up destination address
FillChar(destAddr, SizeOf(destAddr), 0);
destAddr.sin_family := AF_INET;
destAddr.sin_port := htons(destPort);
destAddr.sin_addr.s_addr := StrToHostAddr(destIp).s_addr;
// Create IP header
FillChar(ipHeader, SizeOf(ipHeader), 0);
ipHeader.ver_len := (4 shl 4) or (SizeOf(ipHeader) div 4); // IPv4 and header length
ipHeader.ttl := 64;
ipHeader.proto := IPPROTO_TCP;
ipHeader.src_addr := StrToHostAddr('192.168.1.100').s_addr; // Replace with your IP
ipHeader.dest_addr := destAddr.sin_addr.s_addr;
ipHeader.total_len := htons(SizeOf(ipHeader) + SizeOf(tcpHeader));
ipHeader.checksum := CalculateChecksum(@ipHeader, SizeOf(ipHeader));
// Create TCP header
FillChar(tcpHeader, SizeOf(tcpHeader), 0);
tcpHeader.src_port := htons(12345); // Arbitrary source port
tcpHeader.dest_port := htons(destPort);
tcpHeader.seq_num := htonl(1);
tcpHeader.ack_num := 0;
tcpHeader.offset_res := (SizeOf(tcpHeader) div 4) shl 4;
tcpHeader.flags := $02; // SYN flag
tcpHeader.window := htons(1024);
tcpHeader.checksum := CalculateChecksum(@tcpHeader, SizeOf(tcpHeader));
// Combine headers into packet
Move(ipHeader, packet, SizeOf(ipHeader));
Move(tcpHeader, packet[SizeOf(ipHeader)], SizeOf(tcpHeader));
// Send packet
if fpSendTo(sock, @packet, SizeOf(packet), 0, @destAddr, SizeOf(destAddr)) < 0 then
writeln('Failed to send packet.')
else
writeln('Packet sent successfully.');
// Close socket
//fpClose(sock); // J: Not available in Sockets under Windows
CloseSocket(sock)
end.