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)
 Converts an IP datagram to a data block for sending it to the tun device.
virtual cMessage * decapsulate (char *buf, uint32_t length)
 Parses data received from the tun device and converts it into a cMessage.


Member Function Documentation

cMessage * TunOutDevice::decapsulate ( char *  buf,
uint32_t  length 
) [protected, virtual]

Parses data received from the tun device and converts it into a cMessage.

Parameters:
buf A pointer to the data to be parsed
length The lenght of the buffer in bytes
Returns:
The parsed message

Implements RealworldConnector.

00111 {
00112     // Message starts with IP header
00113     iphdr* ip_buf = (iphdr*) buf;
00114     udphdr* udp_buf;
00115     IPDatagram* IP = new IPDatagram;
00116     UDPPacket* UDP = new UDPPacket;
00117     cMessage* payload = 0;
00118     unsigned int payloadLen, datagramlen;
00119     unsigned int packetlen = ntohs(ip_buf->tot_len);
00120 
00121     // Parsing of IP header, sanity checks
00122     if (  packetlen != length ) {
00123         ev << "TunOutDevice: Dropping bogus packet, header says: length = " << packetlen << " but actual length = " << length <<".\n";
00124         goto parse_error;
00125     }
00126     if (  packetlen > mtu ) {
00127         ev << "TunOutDevice: Dropping bogus packet, length = " << packetlen << " but mtu = " << mtu <<".\n";
00128         goto parse_error;
00129     }
00130     if ( ip_buf->version != 4 ) {
00131         ev << "TunOutDevice: Dropping Packet: Packet is not IPv4.\n";
00132         goto parse_error;
00133     }
00134     if ( ntohs(ip_buf->frag_off) & 0xBFFF ) { // mask DF bit
00135         ev << "TunOutDevice: Dropping Packet: Can't handle fragmented packets.\n";
00136         goto parse_error;
00137     }
00138     if ( ip_buf->protocol != IPPROTO_UDP ) { // FIXME: allow ICMP packets
00139         ev << "TunOutDevice: Dropping Packet: Packet is not UDP.\n";
00140         goto parse_error;
00141     }
00142     IP->setSrcAddress( IPAddress( ntohl(ip_buf->saddr) ));
00143     IP->setDestAddress( IPAddress( ntohl(ip_buf->daddr) ));
00144     IP->setTransportProtocol( ip_buf->protocol );
00145     IP->setTimeToLive( ip_buf->ttl );
00146     IP->setIdentification( ntohs(ip_buf->id) );
00147     IP->setMoreFragments( false );
00148     IP->setDontFragment( true );
00149     IP->setFragmentOffset( 0 );
00150     IP->setDiffServCodePoint( ip_buf->tos );
00151     IP->setLength( ip_buf->ihl*32 );
00152     // FIXME: check IP and UDP checksum...
00153 
00154     // Parse UDP header, sanity checks
00155     udp_buf = (udphdr*)( ((uint32_t *)ip_buf) + ip_buf->ihl );
00156     datagramlen = ntohs(udp_buf->len);
00157     if ( (datagramlen != packetlen - ip_buf->ihl*4) ) {
00158         ev << "TunOutDevice: Dropping Packet: Bogus UDP datagram length: len = " << datagramlen << " packetlen = " << packetlen << " ihl*4 " << ip_buf->ihl*4 << ".\n";
00159         goto parse_error;
00160     }
00161     UDP->setSourcePort( ntohs( udp_buf->source ));
00162     UDP->setDestinationPort( ntohs( udp_buf->dest ));
00163     UDP->setByteLength( sizeof( struct udphdr ) );
00164 
00165     // parse payload
00166     payloadLen = datagramlen - sizeof( struct udphdr );
00167     payload = parser->decapsulatePayload( ((char*) udp_buf) + sizeof( struct udphdr ), payloadLen );
00168     if (!payload) {
00169         ev << "TunOutDevice: Parsing of Payload failed, dropping packet.\n";
00170         goto parse_error;
00171     }
00172     // encapsulate messages
00173     UDP->encapsulate( payload );
00174     IP->encapsulate( UDP );
00175 
00176     delete buf;
00177     return IP;
00178 
00179     // In case the parsing of the packet failed, free allocated memory
00180 parse_error:
00181     delete buf;
00182     delete IP;
00183     delete UDP;
00184     return NULL;
00185 }

char * TunOutDevice::encapsulate ( cMessage *  msg,
unsigned int *  length 
) [protected, virtual]

Converts an IP datagram to a data block for sending it to the tun device.

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
Returns:
A pointer to the converted data

Implements RealworldConnector.

00012 {
00013     struct udppseudohdr {
00014         uint32_t saddr;
00015         uint32_t daddr;
00016         uint8_t zero;
00017         uint8_t protocol;
00018         uint16_t lenght;
00019     }
00020     * pseudohdr;
00021 
00022     unsigned int payloadlen;
00023     static unsigned int iplen = 20; // we don't generate IP options
00024     static unsigned int udplen = 8;
00025     cMessage* payloadMsg = NULL;
00026     char* buf = NULL, *payload = NULL;
00027     uint32_t saddr, daddr; 
00028     iphdr* ip_buf;
00029     udphdr* udp_buf;
00030 
00031     IPDatagram* IP = check_and_cast<IPDatagram*>(msg);
00032     // FIXME: Cast ICMP-Messages
00033     UDPPacket* UDP = dynamic_cast<UDPPacket*>(IP->decapsulate());
00034     if (!UDP) {
00035         EV << "Can't parse non-UDP packets (e.g. ICMP) (yet)...\n";
00036         goto parse_error;
00037     }
00038     payloadMsg = UDP->decapsulate();
00039 
00040     // parse payload
00041     payload = parser->encapsulatePayload(payloadMsg, &payloadlen);
00042     if (!payload )
00043         goto parse_error;
00044 
00045     *length = payloadlen + iplen + udplen;
00046     if( *length > mtu ) {
00047         EV << "TunOutDevice::encapsulate: Error: Packet too big! Size = " << *length << " MTU = " << mtu << "\n";
00048         goto parse_error;
00049     }
00050 
00051     buf = new char[*length];
00052 
00053     // We use the buffer to build an ip packet.
00054     // To minimise unnecessary copying, we start with the payload
00055     // and write it to the end of the buffer
00056     memcpy( (buf + iplen + udplen), payload, payloadlen);
00057 
00058     // write udp header in front of the payload
00059     udp_buf = (udphdr*) (buf + iplen);
00060     udp_buf->source = htons(UDP->sourcePort());
00061     udp_buf->dest = htons(UDP->destinationPort());
00062     udp_buf->len = htons(udplen + payloadlen);
00063     udp_buf->check = 0;
00064 
00065     // Write udp pseudoheader in from of udp header
00066     // this will be overwritten by ip header
00067     pseudohdr = (udppseudohdr*) (buf + iplen - sizeof(struct udppseudohdr));
00068     saddr = htonl(IP->srcAddress().getInt());
00069     daddr = htonl(IP->destAddress().getInt());
00070     pseudohdr->saddr = saddr;
00071     pseudohdr->daddr = daddr;
00072     pseudohdr->zero = 0;
00073     pseudohdr->protocol = IPPROTO_UDP;
00074     pseudohdr->lenght = udp_buf->len;
00075 
00076     // compute UDP checksum
00077     udp_buf->check = cksum((uint16_t*) pseudohdr, sizeof(struct udppseudohdr) + udplen + payloadlen);
00078 
00079     // write ip header to begin of buffer
00080     ip_buf = (iphdr*) buf;
00081     ip_buf->version = 4; // IPv4
00082     ip_buf->ihl = iplen / 4;
00083     ip_buf->tos = IP->diffServCodePoint();
00084     ip_buf->tot_len = htons(*length);
00085     ip_buf->id = htons(IP->identification());
00086     ip_buf->frag_off = htons(IP_DF); // DF, no fragments
00087     ip_buf->ttl = IP->timeToLive();
00088     ip_buf->protocol = IPPROTO_UDP;
00089     ip_buf->saddr = saddr;
00090     ip_buf->daddr = daddr;
00091     ip_buf->check = 0;
00092     ip_buf->check = cksum((uint16_t*) ip_buf, iplen);
00093 
00094     delete IP;
00095     delete UDP;
00096     delete payloadMsg;
00097     delete payload;
00098 
00099     return buf;
00100 
00101 parse_error:
00102     delete IP;
00103     delete UDP;
00104     delete payloadMsg;
00105     delete payload;
00106     return NULL;
00107 
00108 }

TunOutDevice::Module_Class_Members ( TunOutDevice  ,
RealworldDevice  ,
 
)


The documentation for this class was generated from the following files:
Generated on Fri May 11 14:52:41 2007 for ITM OverSim by  doxygen 1.4.7