#include <TunOutDevice.h>
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. |
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.
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) |
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.
buf | A pointer to the data to be parsed | |
length | The lenght of the buffer in bytes | |
addr | Ignored (deleted) | |
addrlen | Ignored |
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 | , | |||
0 | ||||
) |