#include "dev/etherint.hh"
#include "dev/etherpkt.hh"
#include "dev/ethertap.hh"
-#include "sim/builder.hh"
using namespace std;
virtual void process(int revent) { tap->process(revent); }
};
-EtherTap::EtherTap(const string &name, EtherDump *d, int port, int bufsz)
- : EtherInt(name), event(NULL), socket(-1), buflen(bufsz), dump(d),
- txEvent(this)
+EtherTap::EtherTap(const Params *p)
+ : EtherObject(p), event(NULL), socket(-1), buflen(p->bufsz), dump(p->dump),
+ interface(NULL), txEvent(this)
{
+ if (ListenSocket::allDisabled())
+ fatal("All listeners are disabled! EtherTap can't work!");
+
buffer = new char[buflen];
- listener = new TapListener(this, port);
+ listener = new TapListener(this, p->port);
listener->listen();
+ interface = new EtherTapInt(name() + ".interface", this);
}
EtherTap::~EtherTap()
DPRINTF(Ethernet, "EtherTap output len=%d\n", packet->length);
DDUMP(EthernetData, packet->data, packet->length);
uint32_t len = htonl(packet->length);
- write(socket, &len, sizeof(len));
- write(socket, packet->data, packet->length);
+ ssize_t ret = write(socket, &len, sizeof(len));
+ if (ret != sizeof(len))
+ return false;
+ ret = write(socket, packet->data, packet->length);
+ if (ret != packet->length)
+ return false;
- recvDone();
+ interface->recvDone();
return true;
}
DPRINTF(Ethernet, "EtherTap input len=%d\n", packet->length);
DDUMP(EthernetData, packet->data, packet->length);
- if (!sendPacket(packet)) {
+ if (!interface->sendPacket(packet)) {
DPRINTF(Ethernet, "bus busy...buffer for retransmission\n");
packetBuffer.push(packet);
if (!txEvent.scheduled())
- txEvent.schedule(curTick + retryTime);
+ schedule(txEvent, curTick + retryTime);
} else if (dump) {
dump->dump(packet);
}
return;
EthPacketPtr packet = packetBuffer.front();
- if (sendPacket(packet)) {
+ if (interface->sendPacket(packet)) {
if (dump)
dump->dump(packet);
DPRINTF(Ethernet, "EtherTap retransmit\n");
}
if (!packetBuffer.empty() && !txEvent.scheduled())
- txEvent.schedule(curTick + retryTime);
+ schedule(txEvent, curTick + retryTime);
+}
+
+EtherInt*
+EtherTap::getEthPort(const std::string &if_name, int idx)
+{
+ if (if_name == "tap") {
+ if (interface->getPeer())
+ panic("Interface already connected to\n");
+ return interface;
+ }
+ return NULL;
}
+
//=====================================================================
void
//=====================================================================
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherTap)
-
- SimObjectParam<EtherInt *> peer;
- SimObjectParam<EtherDump *> dump;
- Param<unsigned> port;
- Param<unsigned> bufsz;
-
-END_DECLARE_SIM_OBJECT_PARAMS(EtherTap)
-
-BEGIN_INIT_SIM_OBJECT_PARAMS(EtherTap)
-
- INIT_PARAM_DFLT(peer, "peer interface", NULL),
- INIT_PARAM_DFLT(dump, "object to dump network packets to", NULL),
- INIT_PARAM_DFLT(port, "tap port", 3500),
- INIT_PARAM_DFLT(bufsz, "tap buffer size", 10000)
-
-END_INIT_SIM_OBJECT_PARAMS(EtherTap)
-
-
-CREATE_SIM_OBJECT(EtherTap)
+EtherTap *
+EtherTapParams::create()
{
- EtherTap *tap = new EtherTap(getInstanceName(), dump, port, bufsz);
-
- if (peer) {
- tap->setPeer(peer);
- peer->setPeer(tap);
- }
-
- return tap;
+ return new EtherTap(this);
}
-
-REGISTER_SIM_OBJECT("EtherTap", EtherTap)