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.
00113 { 00114 if (!addr) { 00115 opp_error("UdpOutDevice::decapsulate called without providing " 00116 "sockaddr (addr = NULL)"); 00117 } 00118 00119 if (addrlen != sizeof(sockaddr_in) ) { 00120 opp_error("UdpOutDevice::decapsulate called with wrong sockaddr length. " 00121 "Only IPv4 is supported at the moment!"); 00122 } 00123 sockaddr_in* addrbuf = (sockaddr_in*) addr; 00124 00125 IPDatagram* IP = new IPDatagram; 00126 UDPPacket* UDP = new UDPPacket; 00127 cPacket* payload = 0; 00128 00129 // Parse Payload 00130 payload = parser->decapsulatePayload(buf, length); 00131 00132 if (!payload) { 00133 EV << "[UdpOutDevice::decapsulate()]\n" 00134 << " Parsing of payload failed, dropping packet" 00135 << endl; 00136 goto parse_error; 00137 } 00138 00139 // Create IP + UDP header 00140 IP->setSrcAddress(IPAddress(ntohl(addrbuf->sin_addr.s_addr))); 00141 IP->setDestAddress(IPAddressResolver().addressOf(getParentModule()).get4()); 00142 IP->setTransportProtocol(IPPROTO_UDP); 00143 IP->setTimeToLive(42); // Does not matter, packet ends here 00144 IP->setIdentification(42); // Faked: There is no way to get the real ID 00145 IP->setMoreFragments(false); 00146 IP->setDontFragment(false); 00147 IP->setFragmentOffset(0); 00148 IP->setDiffServCodePoint(0); // Faked... 00149 IP->setBitLength(160); 00150 00151 UDP->setSourcePort(ntohs(addrbuf->sin_port)); 00152 UDP->setDestinationPort(getParentModule()->getSubmodule("overlay", 0)-> 00153 gate("appIn")->getNextGate()->getOwnerModule()-> 00154 par("localPort").longValue()); 00155 00156 UDP->setByteLength(8); 00157 00158 // Done... 00159 UDP->encapsulate(payload); 00160 IP->encapsulate(UDP); 00161 delete[] buf; 00162 delete addr; 00163 return IP; 00164 00165 parse_error: 00166 delete IP; 00167 delete UDP; 00168 delete[] buf; 00169 delete addr; 00170 delete payload; 00171 return NULL; 00172 }
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.
00040 { 00041 cPacket* payloadMsg = NULL; 00042 char* payload = NULL; 00043 sockaddr_in* addrbuf = NULL; 00044 00045 unsigned int payloadLen; 00046 00047 IPDatagram* IP = check_and_cast<IPDatagram*>(msg); 00048 // FIXME: Cast ICMP-Messages 00049 UDPPacket* UDP = dynamic_cast<UDPPacket*>(IP->decapsulate()); 00050 00051 if (!UDP) { 00052 EV << "[UdpOutDevice::encapsulate()]\n" 00053 << " Can't parse non-UDP packets (e.g. ICMP) (yet)" 00054 << endl; 00055 00056 goto parse_error; 00057 } 00058 00059 // TODO(?) Handle fragmented packets 00060 if( IP->getMoreFragments() ) { 00061 EV << "[UdpOutDevice::encapsulate()]\n" 00062 << " Can't parse fragmented packets" 00063 << endl; 00064 goto parse_error; 00065 } 00066 00067 payloadMsg = UDP->decapsulate(); 00068 00069 // parse payload 00070 payload = parser->encapsulatePayload(payloadMsg, &payloadLen); 00071 if (!payload) { 00072 EV << "[UdpOutDevice::encapsulate()]\n" 00073 << " Can't parse packet payload, dropping packet" 00074 << endl; 00075 goto parse_error; 00076 } 00077 00078 if (payloadLen > mtu) { 00079 EV << "[UdpOutDevice::encapsulate()]\n" 00080 << " Encapsulating packet failed: packet too long" 00081 << endl; 00082 goto parse_error; 00083 } 00084 00085 *length = payloadLen; 00086 00087 // create sockaddr 00088 addrbuf = new sockaddr_in; 00089 addrbuf->sin_family = AF_INET; 00090 addrbuf->sin_port = htons(UDP->getDestinationPort()); 00091 addrbuf->sin_addr.s_addr = htonl(IP->getDestAddress().getInt()); 00092 *addrlen = sizeof(sockaddr_in); 00093 *addr = (sockaddr*) addrbuf; 00094 00095 delete IP; 00096 delete UDP; 00097 delete payloadMsg; 00098 return payload; 00099 00100 parse_error: 00101 delete IP; 00102 delete UDP; 00103 delete payloadMsg; 00104 delete payload; 00105 return NULL; 00106 00107 }