diff --git a/ncsid/test/nic_mock.cpp b/ncsid/test/nic_mock.cpp
new file mode 100644
index 0000000..8996125
--- /dev/null
+++ b/ncsid/test/nic_mock.cpp
@@ -0,0 +1,337 @@
+#include "nic_mock.h"
+
+#include "platforms/nemora/portable/ncsi.h"
+
+#include <algorithm>
+#include <cstddef>
+#include <stdexcept>
+
+namespace mock
+{
+
+bool NCSIFrame::parse_ethernet_frame(const ncsi_buf_t& ncsi_buf)
+{
+    std::memcpy(&dst_mac_, ncsi_buf.data, sizeof(dst_mac_));
+    std::memcpy(&src_mac_, ncsi_buf.data + sizeof(dst_mac_), sizeof(src_mac_));
+    // The constant defined in a way that assumes big-endian platform, so we are
+    // just going to calculate it here properly.
+    const uint8_t et_hi = *(ncsi_buf.data + 2 * sizeof(mac_addr_t));
+    const uint8_t et_lo = *(ncsi_buf.data + 2 * sizeof(mac_addr_t) + 1);
+    ethertype_ = (et_hi << 8) + et_lo;
+
+    if (ethertype_ != NCSI_ETHERTYPE)
+    {
+        return false;
+    }
+
+    // This code parses the NC-SI command, according to spec and
+    // as defined in platforms/nemora/portable/ncsi.h
+    // It takes some shortcuts to only retrieve the data we are interested in,
+    // such as using offsetof ot get to a particular field.
+    control_packet_type_ =
+        *(ncsi_buf.data + offsetof(ncsi_header_t, control_packet_type));
+    channel_id_ = *(ncsi_buf.data + offsetof(ncsi_header_t, channel_id));
+
+    size_t payload_offset = sizeof(ncsi_header_t);
+    if (control_packet_type_ & NCSI_RESPONSE)
+    {
+        is_response_ = true;
+        control_packet_type_ &= ~NCSI_RESPONSE;
+        std::memcpy(&response_code_, ncsi_buf.data + payload_offset,
+                    sizeof(response_code_));
+        response_code_ = ntohs(response_code_);
+        std::memcpy(&reason_code_,
+                    ncsi_buf.data + payload_offset + sizeof(reason_code_),
+                    sizeof(reason_code_));
+        reason_code_ = ntohs(reason_code_);
+        payload_offset += sizeof(reason_code_) + sizeof(response_code_);
+    }
+
+    if (control_packet_type_ == NCSI_OEM_COMMAND)
+    {
+        std::memcpy(&manufacturer_id_, ncsi_buf.data + payload_offset,
+                    sizeof(manufacturer_id_));
+        manufacturer_id_ = ntohl(manufacturer_id_);
+        // Number of reserved bytes after manufacturer_id_ = 3
+        oem_command_ =
+            *(ncsi_buf.data + payload_offset + sizeof(manufacturer_id_) + 3);
+        payload_offset += sizeof(ncsi_oem_extension_header_t);
+    }
+
+    packet_raw_ =
+        std::vector<uint8_t>(ncsi_buf.data, ncsi_buf.data + ncsi_buf.len);
+    // TODO: Verify payload length.
+
+    return true;
+}
+
+uint32_t NIC::handle_request(const ncsi_buf_t& request_buf,
+                             ncsi_buf_t* response_buf)
+{
+    const ncsi_header_t* ncsi_header =
+        reinterpret_cast<const ncsi_header_t*>(request_buf.data);
+
+    NCSIFrame request_frame;
+    request_frame.parse_ethernet_frame(request_buf);
+    save_frame_to_log(request_frame);
+
+    uint32_t response_size;
+    if (is_loopback_)
+    {
+        std::memcpy(response_buf, &request_buf, sizeof(request_buf));
+        response_size = request_buf.len;
+    }
+    else if (std::find(simple_commands_.begin(), simple_commands_.end(),
+                       ncsi_header->control_packet_type) !=
+             simple_commands_.end())
+    {
+        // Simple Response
+        response_size =
+            ncsi_build_simple_ack(request_buf.data, response_buf->data);
+    }
+    else
+    {
+        // Not-so-Simple Response
+        switch (ncsi_header->control_packet_type)
+        {
+            case NCSI_GET_VERSION_ID:
+                response_size = ncsi_build_version_id_ack(
+                    request_buf.data, response_buf->data, &version_);
+                break;
+            case NCSI_GET_CAPABILITIES:
+                response_size = sizeof(ncsi_capabilities_response_t);
+                {
+                    ncsi_capabilities_response_t response;
+                    ncsi_build_response_header(
+                        request_buf.data, reinterpret_cast<uint8_t*>(&response),
+                        0, 0, response_size - sizeof(ncsi_header_t));
+                    response.channel_count = channel_count_;
+                    std::memcpy(response_buf->data, &response,
+                                sizeof(response));
+                }
+                break;
+            case NCSI_GET_PASSTHROUGH_STATISTICS:
+                if (is_legacy_)
+                {
+                    response_size = ncsi_build_pt_stats_legacy_ack(
+                        request_buf.data, response_buf->data, &stats_legacy_);
+                }
+                else
+                {
+                    response_size = ncsi_build_pt_stats_ack(
+                        request_buf.data, response_buf->data, &stats_);
+                }
+                break;
+            case NCSI_GET_LINK_STATUS:
+                response_size = ncsi_build_link_status_ack(
+                    request_buf.data, response_buf->data, &link_status_);
+                break;
+            case NCSI_OEM_COMMAND:
+                response_size = handle_oem_request(request_buf, response_buf);
+                break;
+            default:
+                response_size = ncsi_build_simple_nack(
+                    request_buf.data, response_buf->data, 1, 1);
+                break;
+        }
+    }
+
+    response_buf->len = response_size;
+
+    return response_size;
+}
+
+uint32_t NIC::handle_oem_request(const ncsi_buf_t& request_buf,
+                                 ncsi_buf_t* response_buf)
+{
+    const ncsi_oem_simple_cmd_t* oem_cmd =
+        reinterpret_cast<const ncsi_oem_simple_cmd_t*>(request_buf.data);
+    uint32_t response_size;
+    switch (oem_cmd->oem_header.oem_cmd)
+    {
+        case NCSI_OEM_COMMAND_GET_HOST_MAC:
+            response_size = ncsi_build_oem_get_mac_ack(
+                request_buf.data, response_buf->data, &mac_);
+            break;
+        case NCSI_OEM_COMMAND_SET_FILTER:
+        {
+            const ncsi_oem_set_filter_cmd_t* cmd =
+                reinterpret_cast<const ncsi_oem_set_filter_cmd_t*>(
+                    request_buf.data);
+            if (set_filter(cmd->hdr.channel_id, cmd->filter))
+            {
+                response_size = ncsi_build_oem_simple_ack(request_buf.data,
+                                                          response_buf->data);
+            }
+            else
+            {
+                response_size = ncsi_build_simple_nack(
+                    request_buf.data, response_buf->data, 3, 4);
+            }
+        }
+        break;
+        case NCSI_OEM_COMMAND_ECHO:
+            response_size =
+                ncsi_build_oem_echo_ack(request_buf.data, response_buf->data);
+            break;
+        case NCSI_OEM_COMMAND_GET_FILTER:
+        {
+            const ncsi_simple_command_t* cmd =
+                reinterpret_cast<const ncsi_simple_command_t*>(
+                    request_buf.data);
+            if (cmd->hdr.channel_id == 0)
+            {
+                response_size = ncsi_build_oem_get_filter_ack(
+                    request_buf.data, response_buf->data, &ch0_filter_);
+            }
+            else if (cmd->hdr.channel_id == 1)
+            {
+                response_size = ncsi_build_oem_get_filter_ack(
+                    request_buf.data, response_buf->data, &ch1_filter_);
+            }
+            else
+            {
+                response_size = ncsi_build_simple_nack(
+                    request_buf.data, response_buf->data, 3, 4);
+            }
+        }
+        break;
+        default:
+            response_size = ncsi_build_simple_nack(request_buf.data,
+                                                   response_buf->data, 1, 2);
+            break;
+    }
+
+    return response_size;
+}
+
+bool NIC::is_filter_configured(uint8_t channel) const
+{
+    if (channel == 0)
+    {
+        return is_ch0_filter_configured_;
+    }
+    else if (channel == 1)
+    {
+        return is_ch1_filter_configured_;
+    }
+
+    throw std::invalid_argument("Unsupported channel");
+}
+
+bool NIC::set_filter(uint8_t channel, const ncsi_oem_filter_t& filter)
+{
+    ncsi_oem_filter_t* nic_filter;
+    if (channel == 0)
+    {
+        nic_filter = &ch0_filter_;
+        is_ch0_filter_configured_ = true;
+    }
+    else if (channel == 1)
+    {
+        nic_filter = &ch1_filter_;
+        is_ch1_filter_configured_ = true;
+    }
+    else
+    {
+        throw std::invalid_argument("Unsupported channel");
+    }
+
+    std::memcpy(nic_filter->mac, filter.mac, MAC_ADDR_SIZE);
+    nic_filter->ip = 0;
+    nic_filter->port = filter.port;
+    return true;
+}
+
+const ncsi_oem_filter_t& NIC::get_filter(uint8_t channel) const
+{
+    if (channel == 0)
+    {
+        return ch0_filter_;
+    }
+    else if (channel == 1)
+    {
+        return ch1_filter_;
+    }
+
+    throw std::invalid_argument("Unsupported channel");
+}
+
+void NIC::set_hostless(bool is_hostless)
+{
+    auto set_flag_op = [](uint8_t lhs, uint8_t rhs) -> auto
+    {
+        return lhs | rhs;
+    };
+
+    auto clear_flag_op = [](uint8_t lhs, uint8_t rhs) -> auto
+    {
+        return lhs & ~rhs;
+    };
+
+    auto flag_op = is_hostless ? set_flag_op : clear_flag_op;
+
+    if (channel_count_ > 0)
+    {
+        ch0_filter_.flags =
+            flag_op(ch0_filter_.flags, NCSI_OEM_FILTER_FLAGS_HOSTLESS);
+    }
+
+    if (channel_count_ > 1)
+    {
+        ch1_filter_.flags =
+            flag_op(ch1_filter_.flags, NCSI_OEM_FILTER_FLAGS_HOSTLESS);
+    }
+}
+
+void NIC::toggle_hostless()
+{
+    if (channel_count_ > 0)
+    {
+        ch0_filter_.flags ^= NCSI_OEM_FILTER_FLAGS_HOSTLESS;
+    }
+
+    if (channel_count_ > 1)
+    {
+        ch1_filter_.flags ^= NCSI_OEM_FILTER_FLAGS_HOSTLESS;
+    }
+}
+
+bool NIC::is_hostless()
+{
+    return ch0_filter_.flags & NCSI_OEM_FILTER_FLAGS_HOSTLESS;
+}
+
+void NIC::save_frame_to_log(const NCSIFrame& frame)
+{
+    if (cmd_log_.size() >= max_log_size_)
+    {
+        cmd_log_.erase(cmd_log_.begin());
+    }
+
+    cmd_log_.push_back(frame);
+}
+
+const std::vector<uint8_t> NIC::simple_commands_ = {
+    NCSI_CLEAR_INITIAL_STATE,
+    NCSI_SELECT_PACKAGE,
+    NCSI_DESELECT_PACKAGE,
+    NCSI_ENABLE_CHANNEL,
+    NCSI_DISABLE_CHANNEL,
+    NCSI_RESET_CHANNEL,
+    NCSI_ENABLE_CHANNEL_NETWORK_TX,
+    NCSI_DISABLE_CHANNEL_NETWORK_TX,
+    NCSI_AEN_ENABLE,
+    NCSI_SET_LINK,
+    NCSI_SET_VLAN_FILTER,
+    NCSI_ENABLE_VLAN,
+    NCSI_DISABLE_VLAN,
+    NCSI_SET_MAC_ADDRESS,
+    NCSI_ENABLE_BROADCAST_FILTER,
+    NCSI_DISABLE_BROADCAST_FILTER,
+    NCSI_ENABLE_GLOBAL_MULTICAST_FILTER,
+    NCSI_DISABLE_GLOBAL_MULTICAST_FILTER,
+    NCSI_SET_NCSI_FLOW_CONTROL,
+};
+
+} // namespace mock
