#include <TunOutDevice.h>
Inheritance diagram for TunOutDevice:
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. |
cMessage * TunOutDevice::decapsulate | ( | char * | buf, | |
uint32_t | length | |||
) | [protected, virtual] |
Parses data received from the tun device and converts it into a cMessage.
buf | A pointer to the data to be parsed | |
length | The lenght of the buffer in bytes |
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.
msg | A pointer to the message to be converted | |
length | A pointer to an int that will hold the length of 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 | , | |||
0 | ||||
) |