OverSim
UdpOutDevice.cc
Go to the documentation of this file.
1 //
2 // Copyright (C) 2006 Institut fuer Telematik, Universitaet Karlsruhe (TH)
3 //
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 //
18 
24 #define WANT_WINSOCK2
25 #include <platdep/sockets.h>
26 
27 #include "IPDatagram_m.h"
28 #include "UDPPacket.h"
29 #include "IPAddressResolver.h"
30 
31 #include "UdpOutDevice.h"
32 
33 
35 
36 char* UdpOutDevice::encapsulate(cPacket *msg,
37  unsigned int* length,
38  sockaddr** addr,
39  socklen_t* addrlen)
40 {
41  cPacket* payloadMsg = NULL;
42  char* payload = NULL;
43  sockaddr_in* addrbuf = NULL;
44 
45  unsigned int payloadLen;
46 
47  IPDatagram* IP = check_and_cast<IPDatagram*>(msg);
48  // FIXME: Cast ICMP-Messages
49  UDPPacket* UDP = dynamic_cast<UDPPacket*>(IP->decapsulate());
50 
51  if (!UDP) {
52  EV << "[UdpOutDevice::encapsulate()]\n"
53  << " Can't parse non-UDP packets (e.g. ICMP) (yet)"
54  << endl;
55 
56  goto parse_error;
57  }
58 
59  // TODO(?) Handle fragmented packets
60  if( IP->getMoreFragments() ) {
61  EV << "[UdpOutDevice::encapsulate()]\n"
62  << " Can't parse fragmented packets"
63  << endl;
64  goto parse_error;
65  }
66 
67  payloadMsg = UDP->decapsulate();
68 
69  // parse payload
70  payload = parser->encapsulatePayload(payloadMsg, &payloadLen);
71  if (!payload) {
72  EV << "[UdpOutDevice::encapsulate()]\n"
73  << " Can't parse packet payload, dropping packet"
74  << endl;
75  goto parse_error;
76  }
77 
78  if (payloadLen > mtu) {
79  EV << "[UdpOutDevice::encapsulate()]\n"
80  << " Encapsulating packet failed: packet too long"
81  << endl;
82  goto parse_error;
83  }
84 
85  *length = payloadLen;
86 
87  // create sockaddr
88  addrbuf = new sockaddr_in;
89  addrbuf->sin_family = AF_INET;
90  addrbuf->sin_port = htons(UDP->getDestinationPort());
91  addrbuf->sin_addr.s_addr = htonl(IP->getDestAddress().getInt());
92  *addrlen = sizeof(sockaddr_in);
93  *addr = (sockaddr*) addrbuf;
94 
95  delete IP;
96  delete UDP;
97  delete payloadMsg;
98  return payload;
99 
100 parse_error:
101  delete IP;
102  delete UDP;
103  delete payloadMsg;
104  delete payload;
105  return NULL;
106 
107 }
108 
109 cPacket* UdpOutDevice::decapsulate(char* buf,
110  uint32_t length,
111  sockaddr* addr,
112  socklen_t addrlen)
113 {
114  if (!addr) {
115  opp_error("UdpOutDevice::decapsulate called without providing "
116  "sockaddr (addr = NULL)");
117  }
118 
119  if (addrlen != sizeof(sockaddr_in) ) {
120  opp_error("UdpOutDevice::decapsulate called with wrong sockaddr length. "
121  "Only IPv4 is supported at the moment!");
122  }
123  sockaddr_in* addrbuf = (sockaddr_in*) addr;
124 
125  IPDatagram* IP = new IPDatagram;
126  UDPPacket* UDP = new UDPPacket;
127  cPacket* payload = 0;
128 
129  // Parse Payload
130  payload = parser->decapsulatePayload(buf, length);
131 
132  if (!payload) {
133  EV << "[UdpOutDevice::decapsulate()]\n"
134  << " Parsing of payload failed, dropping packet"
135  << endl;
136  goto parse_error;
137  }
138 
139  // Create IP + UDP header
140  IP->setSrcAddress(IPAddress(ntohl(addrbuf->sin_addr.s_addr)));
141  IP->setDestAddress(IPAddressResolver().addressOf(getParentModule()).get4());
142  IP->setTransportProtocol(IPPROTO_UDP);
143  IP->setTimeToLive(42); // Does not matter, packet ends here
144  IP->setIdentification(42); // Faked: There is no way to get the real ID
145  IP->setMoreFragments(false);
146  IP->setDontFragment(false);
147  IP->setFragmentOffset(0);
148  IP->setDiffServCodePoint(0); // Faked...
149  IP->setBitLength(160);
150 
151  UDP->setSourcePort(ntohs(addrbuf->sin_port));
152  UDP->setDestinationPort(getParentModule()->getSubmodule("overlay", 0)->
153  gate("appIn")->getNextGate()->getOwnerModule()->
154  par("localPort").longValue());
155 
156  UDP->setByteLength(8);
157 
158  // Done...
159  UDP->encapsulate(payload);
160  IP->encapsulate(UDP);
161  delete[] buf;
162  delete addr;
163  return IP;
164 
165 parse_error:
166  delete IP;
167  delete UDP;
168  delete[] buf;
169  delete addr;
170  delete payload;
171  return NULL;
172 }
173