25 #include "IPDatagram_m.h"
26 #include "UDPPacket.h"
30 #if not defined _WIN32 && not defined __APPLE__
32 #include <netinet/ip.h>
33 #include <netinet/udp.h>
51 unsigned int payloadlen;
52 static unsigned int iplen = 20;
53 static unsigned int udplen = 8;
54 cPacket* payloadMsg = NULL;
55 char* buf = NULL, *payload = NULL;
56 uint32_t saddr, daddr;
57 volatile iphdr* ip_buf;
58 volatile udphdr* udp_buf;
60 IPDatagram* IP = check_and_cast<IPDatagram*>(msg);
63 UDPPacket* UDP =
dynamic_cast<UDPPacket*
>(IP->decapsulate());
65 EV <<
"[TunOutDevice::encapsulate()]\n"
66 <<
" Can't parse non-UDP packets (e.g. ICMP) (yet)"
72 if( IP->getMoreFragments() ) {
73 EV <<
"[TunOutDevice::encapsulate()]\n"
74 <<
" Can't parse fragmented packets"
78 payloadMsg = UDP->decapsulate();
83 EV <<
"[TunOutDevice::encapsulate()]\n"
84 <<
" Can't parse packet payload, dropping packet"
89 *length = payloadlen + iplen + udplen;
91 EV <<
"[TunOutDevice::encapsulate()]\n"
92 <<
" Error: Packet too big! Size = " << *length <<
" MTU = " <<
mtu
97 buf =
new char[*length];
102 memcpy( (buf + iplen + udplen), payload, payloadlen);
105 udp_buf = (udphdr*) (buf + iplen);
106 udp_buf->source = htons(UDP->getSourcePort());
107 udp_buf->dest = htons(UDP->getDestinationPort());
108 udp_buf->len = htons(udplen + payloadlen);
113 pseudohdr = (udppseudohdr*) (buf + iplen -
sizeof(
struct udppseudohdr));
114 saddr = htonl(IP->getSrcAddress().getInt());
115 daddr = htonl(IP->getDestAddress().getInt());
116 pseudohdr->saddr = saddr;
117 pseudohdr->daddr = daddr;
119 pseudohdr->protocol = IPPROTO_UDP;
120 pseudohdr->lenght = udp_buf->len;
123 udp_buf->check =
cksum((uint16_t*) pseudohdr,
sizeof(
struct udppseudohdr) + udplen + payloadlen);
126 ip_buf = (iphdr*) buf;
128 ip_buf->ihl = iplen / 4;
129 ip_buf->tos = IP->getDiffServCodePoint();
130 ip_buf->tot_len = htons(*length);
131 ip_buf->id = htons(IP->getIdentification());
132 ip_buf->frag_off = htons(IP_DF);
133 ip_buf->ttl = IP->getTimeToLive();
134 ip_buf->protocol = IPPROTO_UDP;
135 ip_buf->saddr = saddr;
136 ip_buf->daddr = daddr;
138 ip_buf->check =
cksum((uint16_t*) ip_buf, iplen);
162 iphdr* ip_buf = (iphdr*) buf;
164 IPDatagram* IP =
new IPDatagram;
165 UDPPacket* UDP =
new UDPPacket;
166 cPacket* payload = 0;
167 unsigned int payloadLen, datagramlen;
168 unsigned int packetlen = ntohs(ip_buf->tot_len);
171 if ( packetlen != length ) {
172 EV <<
"[TunOutDevice::decapsulate()]\n"
173 <<
" Dropping bogus packet, header says: length = " << packetlen <<
"\n"
174 <<
" but actual length = " << length
178 if ( packetlen >
mtu ) {
179 EV <<
"[TunOutDevice::decapsulate()]\n"
180 <<
" Dropping bogus packet, length = " << packetlen <<
"\n"
181 <<
" but mtu = " <<
mtu
185 if ( ip_buf->version != 4 ) {
186 EV <<
"[TunOutDevice::decapsulate()]\n"
187 <<
" Dropping Packet: Packet is not IPv4"
191 if ( ntohs(ip_buf->frag_off) & 0xBFFF ) {
192 EV <<
"[TunOutDevice::decapsulate()]\n"
193 <<
" Dropping Packet: Can't handle fragmented packets"
197 if ( ip_buf->protocol != IPPROTO_UDP ) {
198 EV <<
"[TunOutDevice::decapsulate()]\n"
199 <<
" Dropping Packet: Packet is not UDP"
203 IP->setSrcAddress( IPAddress( ntohl(ip_buf->saddr) ));
204 IP->setDestAddress( IPAddress( ntohl(ip_buf->daddr) ));
205 IP->setTransportProtocol( ip_buf->protocol );
206 IP->setTimeToLive( ip_buf->ttl );
207 IP->setIdentification( ntohs(ip_buf->id) );
208 IP->setMoreFragments(
false );
209 IP->setDontFragment(
true );
210 IP->setFragmentOffset( 0 );
211 IP->setDiffServCodePoint( ip_buf->tos );
212 IP->setBitLength( ip_buf->ihl*32 );
216 udp_buf = (udphdr*)( ((uint32_t *)ip_buf) + ip_buf->ihl );
217 datagramlen = ntohs(udp_buf->len);
218 if ( (datagramlen != packetlen - ip_buf->ihl*4) ) {
219 EV <<
"[TunOutDevice::decapsulate()]\n"
220 <<
" Dropping Packet: Bogus UDP datagram length: len = " << datagramlen <<
"\n"
221 <<
" packetlen = " << packetlen <<
" ihl*4 " << ip_buf->ihl*4
225 UDP->setSourcePort( ntohs( udp_buf->source ));
226 UDP->setDestinationPort( ntohs( udp_buf->dest ));
227 UDP->setByteLength(
sizeof(
struct udphdr ) );
230 payloadLen = datagramlen -
sizeof(
struct udphdr );
233 EV <<
"[TunOutDevice::decapsulate()]\n"
234 <<
" Parsing of Payload failed, dropping packet"
239 UDP->encapsulate( payload );
240 IP->encapsulate( UDP );
262 throw cRuntimeError(
"TunOutDevice::decapsulate(): Not supported on Windows/Mac OS yet");
266 unsigned int* length,
270 throw cRuntimeError(
"TunOutDevice::encapsulate(): Not supported on Windows/Mac OS yet");