mirror of
https://github.com/scylladb/scylladb.git
synced 2026-04-22 17:40:34 +00:00
82 lines
2.0 KiB
C++
82 lines
2.0 KiB
C++
/*
|
|
* Copyright (C) 2014 Cloudius Systems, Ltd.
|
|
*
|
|
*/
|
|
|
|
#include "virtio.hh"
|
|
#include "reactor.hh"
|
|
#include "ip.hh"
|
|
#include <iostream>
|
|
#include <utility>
|
|
#include <algorithm>
|
|
|
|
using namespace net;
|
|
|
|
void dump_packet(const packet& p) {
|
|
std::cout << "rx:";
|
|
auto& f = p.fragments[0];
|
|
for (unsigned i = 0; i < std::min(f.size, size_t(30)); ++i) {
|
|
char x[4];
|
|
std::sprintf(x, " %02x", uint8_t(f.base[i]));
|
|
std::cout << x;
|
|
}
|
|
std::cout << "\n";
|
|
}
|
|
|
|
future<> echo_packet(net::device& netif, packet p) {
|
|
auto& f = p.fragments[0];
|
|
if (f.size < sizeof(eth_hdr)) {
|
|
return make_ready_future<>();
|
|
}
|
|
auto pos = 0;
|
|
auto eh = reinterpret_cast<eth_hdr*>(f.base + pos);
|
|
pos += sizeof(*eh);
|
|
ntoh(*eh);
|
|
if (eh->eth_proto != 0x0800) {
|
|
return make_ready_future<>();
|
|
}
|
|
auto iph = reinterpret_cast<ip_hdr*>(f.base + pos);
|
|
ntoh(*iph);
|
|
pos += iph->ihl * 4;
|
|
if (iph->ver != 4 || iph->ihl < 5 || iph->ip_proto != 1) {
|
|
return make_ready_future<>();
|
|
}
|
|
auto ip_len = iph->len;
|
|
auto icmph = reinterpret_cast<icmp_hdr*>(f.base + pos);
|
|
if (icmph->type != 8) {
|
|
return make_ready_future<>();
|
|
}
|
|
auto icmp_len = ip_len - iph->ihl * 4;
|
|
std::swap(eh->src_mac, eh->dst_mac);
|
|
eh->src_mac = { 0x12, 0x23, 0x45, 0x56, 0x67, 0x68 };
|
|
auto x = iph->src_ip;
|
|
iph->src_ip = ipv4_address(0xc0a87a02); // 192.168.122.2
|
|
iph->dst_ip = x;
|
|
icmph->type = 0;
|
|
icmph->csum = 0;
|
|
hton(*iph);
|
|
hton(*eh);
|
|
icmph->csum = ip_checksum(icmph, icmp_len);
|
|
iph->csum = 0;
|
|
iph->csum = ip_checksum(iph, iph->ihl * 4);
|
|
return netif.send(std::move(p));
|
|
}
|
|
|
|
void echo_packets(net::device& netif) {
|
|
netif.receive().then([&netif] (packet p) {
|
|
dump_packet(p);
|
|
return echo_packet(netif, std::move(p));
|
|
}).then([&netif] () {
|
|
echo_packets(netif);
|
|
});
|
|
}
|
|
|
|
int main(int ac, char** av) {
|
|
auto vnet = create_virtio_net_device("tap0");
|
|
echo_packets(*vnet);
|
|
the_reactor.run();
|
|
return 0;
|
|
}
|
|
|
|
|