UdpOutDevice.cc

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2006 Institut fuer Telematik, Universitaet Karlsruhe (TH)
00003 //
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU General Public License
00006 // as published by the Free Software Foundation; either version 2
00007 // of the License, or (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017 //
00018 
00024 #define WANT_WINSOCK2
00025 #include <platdep/sockets.h>
00026 
00027 #include "IPDatagram_m.h"
00028 #include "UDPPacket.h"
00029 #include "IPAddressResolver.h"
00030 
00031 #include "UdpOutDevice.h"
00032 
00033 
00034 Define_Module(UdpOutDevice);
00035 
00036 char* UdpOutDevice::encapsulate(cPacket *msg,
00037                                 unsigned int* length,
00038                                 sockaddr** addr,
00039                                 socklen_t* addrlen)
00040 {
00041     cPacket* payloadMsg = NULL;
00042     char* payload = NULL;
00043     sockaddr_in* addrbuf = NULL;
00044 
00045     unsigned int payloadLen;
00046 
00047     IPDatagram* IP = check_and_cast<IPDatagram*>(msg);
00048     // FIXME: Cast ICMP-Messages
00049     UDPPacket* UDP = dynamic_cast<UDPPacket*>(IP->decapsulate());
00050 
00051     if (!UDP) {
00052         EV << "[UdpOutDevice::encapsulate()]\n"
00053            << "    Can't parse non-UDP packets (e.g. ICMP) (yet)"
00054            << endl;
00055 
00056         goto parse_error;
00057     }
00058 
00059     // TODO(?) Handle fragmented packets
00060     if( IP->getMoreFragments() ) {
00061         EV << "[UdpOutDevice::encapsulate()]\n"
00062             << "    Can't parse fragmented packets"
00063             << endl;
00064         goto parse_error;
00065     }
00066 
00067     payloadMsg = UDP->decapsulate();
00068 
00069     // parse payload
00070     payload = parser->encapsulatePayload(payloadMsg, &payloadLen);
00071     if (!payload) {
00072         EV << "[UdpOutDevice::encapsulate()]\n"
00073            << "    Can't parse packet payload, dropping packet"
00074            << endl;
00075         goto parse_error;
00076     }
00077 
00078     if (payloadLen > mtu) {
00079         EV << "[UdpOutDevice::encapsulate()]\n"
00080            << "    Encapsulating packet failed: packet too long"
00081            << endl;
00082         goto parse_error;
00083     }
00084 
00085     *length = payloadLen;
00086 
00087     // create sockaddr
00088     addrbuf = new sockaddr_in;
00089     addrbuf->sin_family = AF_INET;
00090     addrbuf->sin_port = htons(UDP->getDestinationPort());
00091     addrbuf->sin_addr.s_addr = htonl(IP->getDestAddress().getInt());
00092     *addrlen = sizeof(sockaddr_in);
00093     *addr = (sockaddr*) addrbuf;
00094 
00095     delete IP;
00096     delete UDP;
00097     delete payloadMsg;
00098     return payload;
00099 
00100 parse_error:
00101     delete IP;
00102     delete UDP;
00103     delete payloadMsg;
00104     delete payload;
00105     return NULL;
00106 
00107 }
00108 
00109 cPacket* UdpOutDevice::decapsulate(char* buf,
00110                                     uint32_t length,
00111                                     sockaddr* addr,
00112                                     socklen_t addrlen)
00113 {
00114     if (!addr) {
00115         opp_error("UdpOutDevice::decapsulate called without providing "
00116                   "sockaddr (addr = NULL)");
00117     }
00118 
00119     if (addrlen != sizeof(sockaddr_in) ) {
00120         opp_error("UdpOutDevice::decapsulate called with wrong sockaddr length. "
00121                   "Only IPv4 is supported at the moment!");
00122     }
00123     sockaddr_in* addrbuf = (sockaddr_in*) addr;
00124 
00125     IPDatagram* IP = new IPDatagram;
00126     UDPPacket* UDP = new UDPPacket;
00127     cPacket* payload = 0;
00128 
00129     // Parse Payload
00130     payload = parser->decapsulatePayload(buf, length);
00131 
00132     if (!payload) {
00133         EV << "[UdpOutDevice::decapsulate()]\n"
00134            << "    Parsing of payload failed, dropping packet"
00135            << endl;
00136         goto parse_error;
00137     }
00138 
00139     // Create IP + UDP header
00140     IP->setSrcAddress(IPAddress(ntohl(addrbuf->sin_addr.s_addr)));
00141     IP->setDestAddress(IPAddressResolver().addressOf(getParentModule()).get4());
00142     IP->setTransportProtocol(IPPROTO_UDP);
00143     IP->setTimeToLive(42); // Does not matter, packet ends here
00144     IP->setIdentification(42); // Faked: There is no way to get the real ID
00145     IP->setMoreFragments(false);
00146     IP->setDontFragment(false);
00147     IP->setFragmentOffset(0);
00148     IP->setDiffServCodePoint(0); // Faked...
00149     IP->setBitLength(160);
00150 
00151     UDP->setSourcePort(ntohs(addrbuf->sin_port));
00152     UDP->setDestinationPort(getParentModule()->getSubmodule("overlay", 0)->
00153                             gate("appIn")->getNextGate()->getOwnerModule()->
00154                             par("localPort").longValue());
00155 
00156     UDP->setByteLength(8);
00157 
00158     // Done...
00159     UDP->encapsulate(payload);
00160     IP->encapsulate(UDP);
00161     delete[] buf;
00162     delete addr;
00163     return IP;
00164 
00165 parse_error:
00166     delete IP;
00167     delete UDP;
00168     delete[] buf;
00169     delete addr;
00170     delete payload;
00171     return NULL;
00172 }
00173 
Generated on Wed May 26 16:21:15 2010 for OverSim by  doxygen 1.6.3