TunOutDevice Class Reference

#include <TunOutDevice.h>

Inheritance diagram for TunOutDevice:

RealworldDevice RealworldConnector

List of all members.


Detailed Description

TunOutDevice is a pseudo interface that allows communcation with the real world through the TunOutScheduler.

WARNING: This does ONLY work with the combination IPv4|UDP|OverlayMessage

Public Member Functions

 Module_Class_Members (TunOutDevice, RealworldDevice, 0)

Protected Member Functions

virtual char * encapsulate (cMessage *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 cMessage * decapsulate (char *buf, uint32_t length, sockaddr *addr, socklen_t addrlen)
 Parses data received from the (realworld) network and converts it into a cMessage.


Member Function Documentation

char * TunOutDevice::encapsulate ( cMessage *  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.

Parameters:
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 Ignored (set to 0)
addrlen Ignored (set to 0)
Returns:
A pointer to the converted data

Implements RealworldConnector.

00038 {
00039     *addr = 0;
00040     *addrlen = 0;
00041 
00042     struct udppseudohdr {
00043         uint32_t saddr;
00044         uint32_t daddr;
00045         uint8_t zero;
00046         uint8_t protocol;
00047         uint16_t lenght;
00048     }
00049     * pseudohdr;
00050 
00051     unsigned int payloadlen;
00052     static unsigned int iplen = 20; // we don't generate IP options
00053     static unsigned int udplen = 8;
00054     cMessage* payloadMsg = NULL;
00055     char* buf = NULL, *payload = NULL;
00056     uint32_t saddr, daddr;
00057     iphdr* ip_buf;
00058     udphdr* udp_buf;
00059 
00060     IPDatagram* IP = check_and_cast<IPDatagram*>(msg);
00061 
00062     // FIXME: Cast ICMP-Messages
00063     UDPPacket* UDP = dynamic_cast<UDPPacket*>(IP->decapsulate());
00064     if (!UDP) {
00065         EV << "[TunOutDevice::encapsulate()]\n"
00066            << "    Can't parse non-UDP packets (e.g. ICMP) (yet)"
00067            << endl;
00068         goto parse_error;
00069     }
00070 
00071     // TODO(?) Handle fragmented packets
00072     if( IP->moreFragments() ) {
00073         EV << "[TunOutDevice::encapsulate()]\n"
00074             << "    Can't parse fragmented packets"
00075             << endl;
00076         goto parse_error;
00077     }
00078     payloadMsg = UDP->decapsulate();
00079 
00080     // parse payload
00081     payload = parser->encapsulatePayload(payloadMsg, &payloadlen);
00082     if (!payload ) {
00083         EV << "[TunOutDevice::encapsulate()]\n"
00084            << "    Can't parse packet payload, dropping packet"
00085            << endl;
00086         goto parse_error;
00087     }
00088 
00089     *length = payloadlen + iplen + udplen;
00090     if( *length > mtu ) {
00091         EV << "[TunOutDevice::encapsulate()]\n"
00092            << "    Error: Packet too big! Size = " << *length << " MTU = " << mtu
00093            << endl;
00094         goto parse_error;
00095     }
00096 
00097     buf = new char[*length];
00098 
00099     // We use the buffer to build an ip packet.
00100     // To minimise unnecessary copying, we start with the payload
00101     // and write it to the end of the buffer
00102     memcpy( (buf + iplen + udplen), payload, payloadlen);
00103 
00104     // write udp header in front of the payload
00105     udp_buf = (udphdr*) (buf + iplen);
00106     udp_buf->source = htons(UDP->sourcePort());
00107     udp_buf->dest = htons(UDP->destinationPort());
00108     udp_buf->len = htons(udplen + payloadlen);
00109     udp_buf->check = 0;
00110 
00111     // Write udp pseudoheader in from of udp header
00112     // this will be overwritten by ip header
00113     pseudohdr = (udppseudohdr*) (buf + iplen - sizeof(struct udppseudohdr));
00114     saddr = htonl(IP->srcAddress().getInt());
00115     daddr = htonl(IP->destAddress().getInt());
00116     pseudohdr->saddr = saddr;
00117     pseudohdr->daddr = daddr;
00118     pseudohdr->zero = 0;
00119     pseudohdr->protocol = IPPROTO_UDP;
00120     pseudohdr->lenght = udp_buf->len;
00121 
00122     // compute UDP checksum
00123     udp_buf->check = cksum((uint16_t*) pseudohdr, sizeof(struct udppseudohdr) + udplen + payloadlen);
00124 
00125     // write ip header to begin of buffer
00126     ip_buf = (iphdr*) buf;
00127     ip_buf->version = 4; // IPv4
00128     ip_buf->ihl = iplen / 4;
00129     ip_buf->tos = IP->diffServCodePoint();
00130     ip_buf->tot_len = htons(*length);
00131     ip_buf->id = htons(IP->identification());
00132     ip_buf->frag_off = htons(IP_DF); // DF, no fragments
00133     ip_buf->ttl = IP->timeToLive();
00134     ip_buf->protocol = IPPROTO_UDP;
00135     ip_buf->saddr = saddr;
00136     ip_buf->daddr = daddr;
00137     ip_buf->check = 0;
00138     ip_buf->check = cksum((uint16_t*) ip_buf, iplen);
00139 
00140     delete IP;
00141     delete UDP;
00142     delete payloadMsg;
00143     delete payload;
00144 
00145     return buf;
00146 
00147 parse_error:
00148     delete IP;
00149     delete UDP;
00150     delete payloadMsg;
00151     delete payload;
00152     return NULL;
00153 
00154 }

cMessage * TunOutDevice::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.

Parameters:
buf A pointer to the data to be parsed
length The lenght of the buffer in bytes
addr Ignored (deleted)
addrlen Ignored
Returns:
The parsed message

Implements RealworldConnector.

00160 {
00161     // Message starts with IP header
00162     iphdr* ip_buf = (iphdr*) buf;
00163     udphdr* udp_buf;
00164     IPDatagram* IP = new IPDatagram;
00165     UDPPacket* UDP = new UDPPacket;
00166     cMessage* payload = 0;
00167     unsigned int payloadLen, datagramlen;
00168     unsigned int packetlen = ntohs(ip_buf->tot_len);
00169 
00170     // Parsing of IP header, sanity checks
00171     if (  packetlen != length ) {
00172         EV << "[TunOutDevice::decapsulate()]\n"
00173            << "    Dropping bogus packet, header says: length = " << packetlen << "\n"
00174            << "    but actual length = " << length
00175            << endl;
00176         goto parse_error;
00177     }
00178     if (  packetlen > mtu ) {
00179         EV << "[TunOutDevice::decapsulate()]\n"
00180            << "    Dropping bogus packet, length = " << packetlen << "\n"
00181            << "    but mtu = " << mtu
00182            << endl;
00183         goto parse_error;
00184     }
00185     if ( ip_buf->version != 4 ) {
00186         EV << "[TunOutDevice::decapsulate()]\n"
00187            << "    Dropping Packet: Packet is not IPv4"
00188            << endl;
00189         goto parse_error;
00190     }
00191     if ( ntohs(ip_buf->frag_off) & 0xBFFF ) { // mask DF bit
00192         EV << "[TunOutDevice::decapsulate()]\n"
00193            << "    Dropping Packet: Can't handle fragmented packets"
00194            << endl;
00195         goto parse_error;
00196     }
00197     if ( ip_buf->protocol != IPPROTO_UDP ) { // FIXME: allow ICMP packets
00198         EV << "[TunOutDevice::decapsulate()]\n"
00199            << "    Dropping Packet: Packet is not UDP"
00200            << endl;
00201         goto parse_error;
00202     }
00203     IP->setSrcAddress( IPAddress( ntohl(ip_buf->saddr) ));
00204     IP->setDestAddress( IPAddress( ntohl(ip_buf->daddr) ));
00205     IP->setTransportProtocol( ip_buf->protocol );
00206     IP->setTimeToLive( ip_buf->ttl );
00207     IP->setIdentification( ntohs(ip_buf->id) );
00208     IP->setMoreFragments( false );
00209     IP->setDontFragment( true );
00210     IP->setFragmentOffset( 0 );
00211     IP->setDiffServCodePoint( ip_buf->tos );
00212     IP->setLength( ip_buf->ihl*32 );
00213     // FIXME: check IP and UDP checksum...
00214 
00215     // Parse UDP header, sanity checks
00216     udp_buf = (udphdr*)( ((uint32_t *)ip_buf) + ip_buf->ihl );
00217     datagramlen = ntohs(udp_buf->len);
00218     if ( (datagramlen != packetlen - ip_buf->ihl*4) ) {
00219         EV << "[TunOutDevice::decapsulate()]\n"
00220            << "    Dropping Packet: Bogus UDP datagram length: len = " << datagramlen << "\n"
00221            << "    packetlen = " << packetlen << " ihl*4 " << ip_buf->ihl*4
00222            << endl;
00223         goto parse_error;
00224     }
00225     UDP->setSourcePort( ntohs( udp_buf->source ));
00226     UDP->setDestinationPort( ntohs( udp_buf->dest ));
00227     UDP->setByteLength( sizeof( struct udphdr ) );
00228 
00229     // parse payload
00230     payloadLen = datagramlen - sizeof( struct udphdr );
00231     payload = parser->decapsulatePayload( ((char*) udp_buf) + sizeof( struct udphdr ), payloadLen );
00232     if (!payload) {
00233         EV << "[TunOutDevice::decapsulate()]\n"
00234            << "    Parsing of Payload failed, dropping packet"
00235            << endl;
00236         goto parse_error;
00237     }
00238     // encapsulate messages
00239     UDP->encapsulate( payload );
00240     IP->encapsulate( UDP );
00241 
00242     delete[] buf;
00243     delete addr;
00244     return IP;
00245 
00246     // In case the parsing of the packet failed, free allocated memory
00247 parse_error:
00248     delete[] buf;
00249     delete addr;
00250     delete IP;
00251     delete UDP;
00252     return NULL;
00253 }

TunOutDevice::Module_Class_Members ( TunOutDevice  ,
RealworldDevice  ,
 
)


The documentation for this class was generated from the following files:

Generated on Fri Sep 19 13:05:08 2008 for ITM OverSim by  doxygen 1.5.5