mirror of
https://git.checksum.fail/alec/erythros
synced 2025-12-08 03:59:54 +02:00
src/net: Add tcp_rst_packet()
This commit is contained in:
@@ -722,6 +722,75 @@ class TCPIP {
|
||||
.tx_queue.push(packet)
|
||||
|
||||
}
|
||||
fn tcp_rst_packet(mut this, anon mut session: TcpSession) throws {
|
||||
mut packet: [u8] = []
|
||||
|
||||
let header_length: u16 = 32
|
||||
let flags: u16 = 0x8004 // RST
|
||||
|
||||
let maximum_payload_size_to_transmit: i64 = 1024
|
||||
mut payload_size: i64 = maximum_payload_size_to_transmit
|
||||
let payload_offset: i64 = session.tx_chunk_counter * maximum_payload_size_to_transmit
|
||||
if session.pending_data_to_transmit.size() as! i64 - payload_offset < maximum_payload_size_to_transmit {
|
||||
payload_size = session.pending_data_to_transmit.size() as! i64 - payload_offset
|
||||
}
|
||||
|
||||
mut ipv4_total_length: u16 = 0
|
||||
ipv4_total_length += 20; // IPv4
|
||||
ipv4_total_length += header_length + payload_size as! u16 // TCP
|
||||
|
||||
.push_ethernet_header(packet, destination_mac: session.remote_mac, source_mac: session.local_mac, ethertype: 0x0800)
|
||||
.push_ipv4_header(packet, total_length: ipv4_total_length, flags: 0x40, protocol: 0x06, source_address: session.local_address, destination_address: session.remote_address)
|
||||
|
||||
|
||||
// FIXME: put this into .push_tcp_header
|
||||
|
||||
Util::push_u16_to_u8_array(packet, session.local_port)
|
||||
Util::push_u16_to_u8_array(packet, session.remote_port)
|
||||
Util::push_u32_to_u8_array(packet, session.local_sequence_number)
|
||||
Util::push_u32_to_u8_array(packet, session.acknowledgement_number)
|
||||
Util::push_u16_to_u8_array(packet, flags)
|
||||
Util::push_u16_to_u8_array(packet, session.last_window_size)
|
||||
Util::push_u16_to_u8_array(packet, 0 as! u16) // Checksum placeholder
|
||||
Util::push_u16_to_u8_array(packet, 0 as! u16) // Urgent pointer
|
||||
|
||||
mut tcp_options: [u8] = [0x01, 0x01, 0x08, 0x0a]
|
||||
packet.push_values(&tcp_options)
|
||||
|
||||
let timestamp: u32 = (session.timestamp_origin + (Time::jiffies() - session.timestamp_origin)) as! u32
|
||||
Util::push_u32_to_u8_array(packet, timestamp)
|
||||
Util::push_u32_to_u8_array(packet, session.timestamp_last_echo_reply)
|
||||
|
||||
for i in payload_offset..(payload_offset + payload_size) {
|
||||
packet.push(session.pending_data_to_transmit[i])
|
||||
}
|
||||
|
||||
// Calculate TCP checksum
|
||||
|
||||
mut checksum_packet: [u8] = []
|
||||
// Source and destination IP
|
||||
for i in 26..34 {
|
||||
checksum_packet.push(packet[i])
|
||||
}
|
||||
// Protocol
|
||||
checksum_packet.push(0x00u8)
|
||||
checksum_packet.push(0x06u8)
|
||||
// TCP Packet length
|
||||
let tcp_packet_length: u16 = header_length + payload_size as! u16
|
||||
Util::push_u16_to_u8_array(checksum_packet, tcp_packet_length)
|
||||
|
||||
for i in 34..packet.size() {
|
||||
checksum_packet.push(packet[i])
|
||||
}
|
||||
|
||||
mut checksum = .calculate_header_checksum(checksum_packet, offset: 0, count: checksum_packet.size() as! i64)
|
||||
packet[50] = (checksum >> 8) as! u8
|
||||
packet[51] = (checksum & 0xff) as! u8
|
||||
|
||||
.tx_queue.push(packet)
|
||||
|
||||
}
|
||||
|
||||
public fn tcp_transmit_pending_data_for_existing_sessions(mut this) throws {
|
||||
for i in 0..this.tcp_sessions.size() {
|
||||
if .tcp_sessions[i].pending_data_to_transmit.size() > 0 {
|
||||
@@ -1013,15 +1082,22 @@ class TCPIP {
|
||||
let socket = session.socket
|
||||
mut length = session.received_data.size()
|
||||
mut max_length: usize = 0
|
||||
mut close_connection: bool = false
|
||||
// s[4] = 0; // receive_buffer_size
|
||||
if (socket > 0) {
|
||||
unsafe {
|
||||
cpp {
|
||||
"u64 *s = (u64*)socket;
|
||||
max_length = s[4];"
|
||||
max_length = s[4];
|
||||
close_connection = s[11];
|
||||
if (close_connection) { s[11] = 0; };"
|
||||
}
|
||||
}
|
||||
}
|
||||
if close_connection {
|
||||
.tcp_rst_packet(session)
|
||||
.tcp_sessions[i].state = TcpSessionState::Closed
|
||||
}
|
||||
// FIXME: Should the client be responsible for malloc()ing the receive buffer?
|
||||
if length > 65536 {
|
||||
length = 65536
|
||||
@@ -1130,6 +1206,10 @@ class TCPIP {
|
||||
mut echo_reply: u32 = 0
|
||||
mut tcp_options_offset = 54
|
||||
|
||||
if (.tcp_sessions[i].state as! i64 == TcpSessionState::Closed as! i64) {
|
||||
return
|
||||
}
|
||||
|
||||
while tcp_options_offset < frame.size() as! i64 {
|
||||
match frame[tcp_options_offset] {
|
||||
0u8 => { tcp_options_offset++ }
|
||||
|
||||
Reference in New Issue
Block a user