UdpOutDevice is a pseudo interface that allows communcation with the real world through the UdpOutScheduler. More...
#include <UdpOutDevice.h>
Protected Member Functions | |
virtual char * | encapsulate (cPacket *msg, unsigned int *length, sockaddr **addr, socklen_t *addrlen) |
Converts an IP datagram to a data block for sending it to the (realworld) network. | |
virtual cPacket * | decapsulate (char *buf, uint32_t length, sockaddr *addr, socklen_t addrlen) |
Parses data received from the (realworld) network and converts it into a cMessage. |
UdpOutDevice is a pseudo interface that allows communcation with the real world through the UdpOutScheduler.
WARNING: This does ONLY work with the combination IPv4|UDP|OverlayMessage
Definition at line 36 of file UdpOutDevice.h.
cPacket * UdpOutDevice::decapsulate | ( | char * | buf, | |
uint32_t | length, | |||
sockaddr * | addr, | |||
socklen_t | addrlen | |||
) | [protected, virtual] |
Parses data received from the (realworld) network and converts it into a cMessage.
buf | A pointer to the data to be parsed | |
length | The lenght of the buffer in bytes | |
addr | The destination address | |
addrlen | The length of the address |
Implements RealworldConnector.
Definition at line 109 of file UdpOutDevice.cc.
{ if (!addr) { opp_error("UdpOutDevice::decapsulate called without providing " "sockaddr (addr = NULL)"); } if (addrlen != sizeof(sockaddr_in) ) { opp_error("UdpOutDevice::decapsulate called with wrong sockaddr length. " "Only IPv4 is supported at the moment!"); } sockaddr_in* addrbuf = (sockaddr_in*) addr; IPDatagram* IP = new IPDatagram; UDPPacket* UDP = new UDPPacket; cPacket* payload = 0; // Parse Payload payload = parser->decapsulatePayload(buf, length); if (!payload) { EV << "[UdpOutDevice::decapsulate()]\n" << " Parsing of payload failed, dropping packet" << endl; goto parse_error; } // Create IP + UDP header IP->setSrcAddress(IPAddress(ntohl(addrbuf->sin_addr.s_addr))); IP->setDestAddress(IPAddressResolver().addressOf(getParentModule()).get4()); IP->setTransportProtocol(IPPROTO_UDP); IP->setTimeToLive(42); // Does not matter, packet ends here IP->setIdentification(42); // Faked: There is no way to get the real ID IP->setMoreFragments(false); IP->setDontFragment(false); IP->setFragmentOffset(0); IP->setDiffServCodePoint(0); // Faked... IP->setBitLength(160); UDP->setSourcePort(ntohs(addrbuf->sin_port)); UDP->setDestinationPort(getParentModule()->getSubmodule("overlay", 0)-> gate("appIn")->getNextGate()->getOwnerModule()-> par("localPort").longValue()); UDP->setByteLength(8); // Done... UDP->encapsulate(payload); IP->encapsulate(UDP); delete[] buf; delete addr; return IP; parse_error: delete IP; delete UDP; delete[] buf; delete addr; delete payload; return NULL; }
char * UdpOutDevice::encapsulate | ( | cPacket * | msg, | |
unsigned int * | length, | |||
sockaddr ** | addr, | |||
socklen_t * | addrlen | |||
) | [protected, virtual] |
Converts an IP datagram to a data block for sending it to the (realworld) network.
msg | A pointer to the message to be converted | |
length | A pointer to an int that will hold the length of the converted data | |
addr | The destination address | |
addrlen | The length of the address |
Implements RealworldConnector.
Definition at line 36 of file UdpOutDevice.cc.
{ cPacket* payloadMsg = NULL; char* payload = NULL; sockaddr_in* addrbuf = NULL; unsigned int payloadLen; IPDatagram* IP = check_and_cast<IPDatagram*>(msg); // FIXME: Cast ICMP-Messages UDPPacket* UDP = dynamic_cast<UDPPacket*>(IP->decapsulate()); if (!UDP) { EV << "[UdpOutDevice::encapsulate()]\n" << " Can't parse non-UDP packets (e.g. ICMP) (yet)" << endl; goto parse_error; } // TODO(?) Handle fragmented packets if( IP->getMoreFragments() ) { EV << "[UdpOutDevice::encapsulate()]\n" << " Can't parse fragmented packets" << endl; goto parse_error; } payloadMsg = UDP->decapsulate(); // parse payload payload = parser->encapsulatePayload(payloadMsg, &payloadLen); if (!payload) { EV << "[UdpOutDevice::encapsulate()]\n" << " Can't parse packet payload, dropping packet" << endl; goto parse_error; } if (payloadLen > mtu) { EV << "[UdpOutDevice::encapsulate()]\n" << " Encapsulating packet failed: packet too long" << endl; goto parse_error; } *length = payloadLen; // create sockaddr addrbuf = new sockaddr_in; addrbuf->sin_family = AF_INET; addrbuf->sin_port = htons(UDP->getDestinationPort()); addrbuf->sin_addr.s_addr = htonl(IP->getDestAddress().getInt()); *addrlen = sizeof(sockaddr_in); *addr = (sockaddr*) addrbuf; delete IP; delete UDP; delete payloadMsg; return payload; parse_error: delete IP; delete UDP; delete payloadMsg; delete payload; return NULL; }