Skip to content

Commit

Permalink
Skip packets with invalid protocol states (#21)
Browse files Browse the repository at this point in the history
Such as middlebox as an endpoint resetting or reconnecting to devices
  • Loading branch information
kyechou committed Oct 31, 2022
1 parent 1e5f2d4 commit e23ba3a
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 99 deletions.
168 changes: 84 additions & 84 deletions src/emulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,90 @@ void Emulation::teardown() {
stop_listener = false;
}

void Emulation::reset_offsets() {
this->seq_offsets.clear();
this->port_offsets.clear();
}

void Emulation::apply_offsets(Packet &pkt) const {
// Skip any non-TCP packets
if (!PS_IS_TCP(pkt.get_proto_state())) {
return;
}

// Skip if this middlebox is not an endpoint
if (!this->emulated_mb->has_ip(pkt.get_dst_ip())) {
return;
}

EmuPktKey key(pkt.get_src_ip(), pkt.get_src_port());

// Apply seq offset to the ack number
uint32_t seq_offset = 0;
auto i = this->seq_offsets.find(key);
if (i != this->seq_offsets.end()) {
seq_offset = i->second;
}
pkt.set_ack(pkt.get_ack() + seq_offset);

// Apply port offset to the dst port number
uint16_t port_offset = 0;
auto j = this->port_offsets.find(key);
if (j != this->port_offsets.end()) {
port_offset = j->second;
}
pkt.set_dst_port(pkt.get_dst_port() + port_offset);
}

void Emulation::update_offsets(std::list<Packet> &pkts) {
for (auto &pkt : pkts) {
this->update_offsets(pkt);
}
}

void Emulation::update_offsets(Packet &pkt) {
// Skip any non-TCP packets
if (!PS_IS_TCP(pkt.get_proto_state())) {
return;
}

// Skip if this middlebox is not an endpoint
if (!this->emulated_mb->has_ip(pkt.get_src_ip())) {
return;
}

EmuPktKey key(pkt.get_dst_ip(), pkt.get_dst_port());
uint16_t flags = pkt.get_proto_state() & (~0x800U);

// Update seq offset
if (flags == TH_SYN || flags == (TH_SYN | TH_ACK)) {
this->seq_offsets[key] = pkt.get_seq();
pkt.set_seq(0);
} else {
uint32_t offset = 0;
auto i = this->seq_offsets.find(key);
if (i != this->seq_offsets.end()) {
offset = i->second;
}
pkt.set_seq(pkt.get_seq() - offset);
}

// Update (src) port offset
if (flags == TH_SYN) {
if (pkt.get_src_port() >= 1024) {
this->port_offsets[key] = pkt.get_src_port() - DYNAMIC_PORT;
pkt.set_src_port(DYNAMIC_PORT);
}
} else {
uint16_t offset = 0;
auto i = this->port_offsets.find(key);
if (i != this->port_offsets.end()) {
offset = i->second;
}
pkt.set_src_port(pkt.get_src_port() - offset);
}
}

Middlebox *Emulation::get_mb() const {
return emulated_mb;
}
Expand Down Expand Up @@ -228,87 +312,3 @@ std::list<Packet> Emulation::send_pkt(const Packet &pkt) {
this->update_offsets(pkts);
return pkts;
}

void Emulation::reset_offsets() {
this->seq_offsets.clear();
this->port_offsets.clear();
}

void Emulation::apply_offsets(Packet &pkt) const {
// Skip any non-TCP packets
if (!PS_IS_TCP(pkt.get_proto_state())) {
return;
}

// Skip if this middlebox is not an endpoint
if (!this->emulated_mb->has_ip(pkt.get_dst_ip())) {
return;
}

EmuPktKey key(pkt.get_src_ip(), pkt.get_src_port());

// Apply seq offset to the ack number
uint32_t seq_offset = 0;
auto i = this->seq_offsets.find(key);
if (i != this->seq_offsets.end()) {
seq_offset = i->second;
}
pkt.set_ack(pkt.get_ack() + seq_offset);

// Apply port offset to the dst port number
uint16_t port_offset = 0;
auto j = this->port_offsets.find(key);
if (j != this->port_offsets.end()) {
port_offset = j->second;
}
pkt.set_dst_port(pkt.get_dst_port() + port_offset);
}

void Emulation::update_offsets(std::list<Packet> &pkts) {
for (auto &pkt : pkts) {
this->update_offsets(pkt);
}
}

void Emulation::update_offsets(Packet &pkt) {
// Skip any non-TCP packets
if (!PS_IS_TCP(pkt.get_proto_state())) {
return;
}

// Skip if this middlebox is not an endpoint
if (!this->emulated_mb->has_ip(pkt.get_src_ip())) {
return;
}

EmuPktKey key(pkt.get_dst_ip(), pkt.get_dst_port());
uint16_t flags = pkt.get_proto_state() & (~0x800U);

// Update seq offset
if (flags == TH_SYN || flags == (TH_SYN | TH_ACK)) {
this->seq_offsets[key] = pkt.get_seq();
pkt.set_seq(0);
} else {
uint32_t offset = 0;
auto i = this->seq_offsets.find(key);
if (i != this->seq_offsets.end()) {
offset = i->second;
}
pkt.set_seq(pkt.get_seq() - offset);
}

// Update (src) port offset
if (flags == TH_SYN) {
if (pkt.get_src_port() >= 1024) {
this->port_offsets[key] = pkt.get_src_port() - DYNAMIC_PORT;
pkt.set_src_port(DYNAMIC_PORT);
}
} else {
uint16_t offset = 0;
auto i = this->port_offsets.find(key);
if (i != this->port_offsets.end()) {
offset = i->second;
}
pkt.set_src_port(pkt.get_src_port() - offset);
}
}
3 changes: 2 additions & 1 deletion src/lib/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,8 @@ void Net::process_proto_state(Packet &pkt) const {
} else if (pkt.get_proto_state() > old_proto_state) {
pkt.set_next_phase(true);
} else {
Logger::error("Invalid protocol state");
Logger::warn("Invalid protocol state");
pkt.set_proto_state(PS_INVALID);
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/process/forwarding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,9 @@ void ForwardingProcess::update_model_from_pkts(

Net::get().identify_conn(recv_pkt);
Net::get().process_proto_state(recv_pkt);
if (recv_pkt.get_proto_state() == PS_INVALID) {
continue;
}
Net::get().check_seq_ack(recv_pkt);
Logger::info("Received packet " + recv_pkt.to_string());

Expand Down
30 changes: 16 additions & 14 deletions src/protocols.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,24 @@ static inline std::string proto_str(int n) {
/*
* Protocol state
*/
// TODO: Make this an enum class
// Note that for TCP four-way termination handshake, we assume that the second
// (ACK) and third (FIN) steps are always set within the same packet.
#define PS_TCP_INIT_1 0 // TCP 3-way handshake SYN
#define PS_TCP_INIT_2 1 // TCP 3-way handshake SYN/ACK
#define PS_TCP_INIT_3 2 // TCP 3-way handshake ACK
#define PS_TCP_L7_REQ 3 // TCP L7 request
#define PS_TCP_L7_REQ_A 4 // TCP L7 request ACK
#define PS_TCP_L7_REP 5 // TCP L7 reply
#define PS_TCP_L7_REP_A 6 // TCP L7 reply ACK
#define PS_TCP_TERM_1 7 // TCP termination FIN/ACK
#define PS_TCP_TERM_2 8 // TCP termination FIN/ACK
#define PS_TCP_TERM_3 9 // TCP termination ACK
#define PS_UDP_REQ 10 // UDP request
#define PS_UDP_REP 11 // UDP reply
#define PS_ICMP_ECHO_REQ 12 // ICMP echo request
#define PS_ICMP_ECHO_REP 13 // ICMP echo reply
#define PS_INVALID 0
#define PS_TCP_INIT_1 1 // TCP 3-way handshake SYN
#define PS_TCP_INIT_2 2 // TCP 3-way handshake SYN/ACK
#define PS_TCP_INIT_3 3 // TCP 3-way handshake ACK
#define PS_TCP_L7_REQ 4 // TCP L7 request
#define PS_TCP_L7_REQ_A 5 // TCP L7 request ACK
#define PS_TCP_L7_REP 6 // TCP L7 reply
#define PS_TCP_L7_REP_A 7 // TCP L7 reply ACK
#define PS_TCP_TERM_1 8 // TCP termination FIN/ACK
#define PS_TCP_TERM_2 9 // TCP termination FIN/ACK
#define PS_TCP_TERM_3 10 // TCP termination ACK
#define PS_UDP_REQ 11 // UDP request
#define PS_UDP_REP 12 // UDP reply
#define PS_ICMP_ECHO_REQ 13 // ICMP echo request
#define PS_ICMP_ECHO_REP 14 // ICMP echo reply

#define PS_IS_REQUEST_DIR(x) \
((x) == PS_TCP_INIT_1 || (x) == PS_TCP_INIT_3 || (x) == PS_TCP_L7_REQ || \
Expand Down

0 comments on commit e23ba3a

Please sign in to comment.