This is the first hook called by the network protocol before it routes a datagram that was received from the lower layer.
The nextHopAddress is ignored when the outputNetworkInterface is nullptr.
149 const auto& dgram = removeNetworkProtocolHeader<Ipv4Header>(datagram);
150 const auto& networkHeader = staticPtrCast<Ipv4Header>(dgram->dupShared());
156 if (dgram->isFragment()) {
164 auto& sctpMsg = datagram->removeAtFront<SctpHeader>();
165 Ptr<SctpHeader> sctp = staticPtrCast<SctpHeader>(sctpMsg->dupShared());
166 unsigned int numberOfChunks = sctpMsg->getSctpChunksArraySize();
167 if (numberOfChunks == 1)
168 chunk = sctpMsg->peekFirstChunk();
170 chunk = sctpMsg->peekLastChunk();
172 entry =
natTable->getEntry(dgram->getSourceAddress(), sctpMsg->getSrcPort(), dgram->getDestinationAddress(), sctpMsg->getDestPort(), sctpMsg->getVTag());
173 EV_INFO <<
"getEntry for " << dgram->getSourceAddress() <<
":" << sctpMsg->getSrcPort() <<
" to " << dgram->getDestinationAddress() <<
":" << sctpMsg->getDestPort() <<
" peerVTag=" << sctpMsg->getVTag() <<
"\n";
174 uint32_t numberOfChunks = sctpMsg->getSctpChunksArraySize();
175 if (entry ==
nullptr) {
176 EV_INFO <<
"no entry found\n";
177 if (numberOfChunks == 1)
178 chunk = sctpMsg->peekFirstChunk();
180 chunk = sctpMsg->peekLastChunk();
181 if (chunk->getSctpChunkType() ==
INIT || chunk->getSctpChunkType() ==
ASCONF) {
182 EV_INFO <<
"could be an Init collision\n";
183 entry =
natTable->getSpecialEntry(dgram->getSourceAddress(), sctpMsg->getSrcPort(), dgram->getDestinationAddress(), sctpMsg->getDestPort());
184 if (entry !=
nullptr) {
185 if (chunk->getSctpChunkType() ==
INIT) {
186 SctpInitChunk *initChunk = check_and_cast<SctpInitChunk *>(chunk);
187 entry->setLocalVTag(initChunk->getInitTag());
188 EV_INFO <<
"InitTag=" << initChunk->getInitTag() <<
"\n";
190 else if (chunk->getSctpChunkType() ==
ASCONF) {
191 SctpAsconfChunk *asconfChunk = check_and_cast<SctpAsconfChunk *>(chunk);
192 entry->setLocalVTag(asconfChunk->getPeerVTag());
194 networkHeader->setDestinationAddress(entry->getLocalAddress().toIpv4());
195 sctp->setDestPort(entry->getLocalPort());
196 EV_INFO <<
"destAddress set to " << dgram->getDestinationAddress() <<
", destPort set to " << sctp->getDestPort() <<
"\n";
222 networkHeader->setDestinationAddress(entry->getLocalAddress().toIpv4());
223 sctp->setDestPort(entry->getLocalPort());
224 if (entry->getGlobalVTag() == 0 && chunk->getSctpChunkType() ==
INIT_ACK) {
225 SctpInitAckChunk *initAckChunk = check_and_cast<SctpInitAckChunk *>(chunk);
226 entry->setGlobalVTag(initAckChunk->getInitTag());
228 EV <<
"destAddress set to " << dgram->getDestinationAddress() <<
", destPort set to " << sctpMsg->getDestPort() <<
"\n";
232 if (chunk->getSctpChunkType() ==
INIT) {
233 EV <<
"getLocALEntry for " << dgram->getSourceAddress() <<
":" << sctpMsg->getSrcPort() <<
" to " << dgram->getDestinationAddress() <<
":" << sctpMsg->getDestPort() <<
" peerVTag=" << sctpMsg->getVTag() <<
"\n";
234 entry =
natTable->getLocalInitEntry(dgram->getDestinationAddress(), sctpMsg->getSrcPort(), sctpMsg->getDestPort());
235 if (entry ==
nullptr) {
236 entry =
new SctpNatEntry();
237 entry->setLocalAddress(dgram->getSourceAddress());
238 entry->setLocalPort(sctpMsg->getSrcPort());
239 entry->setGlobalAddress(dgram->getDestinationAddress());
240 entry->setGlobalPort(sctpMsg->getDestPort());
241 entry->setNattedPort(sctpMsg->getSrcPort());
242 entry->setNattedAddress(dgram->getDestinationAddress());
243 SctpInitChunk *initChunk = check_and_cast<SctpInitChunk *>(chunk);
244 entry->setGlobalVTag(initChunk->getInitTag());
245 natTable->natEntries.push_back(entry);
246 EV <<
"added entry for local deliver\n";
253 SctpNatEntry *entry2 =
new SctpNatEntry();
254 entry2->setLocalAddress(dgram->getSourceAddress());
255 entry2->setLocalPort(sctpMsg->getSrcPort());
256 entry2->setGlobalAddress(entry->getGlobalAddress());
257 entry2->setGlobalPort(sctpMsg->getDestPort());
258 entry2->setNattedPort(sctpMsg->getSrcPort());
259 entry2->setNattedAddress(entry->getGlobalAddress());
260 SctpInitChunk *initChunk = check_and_cast<SctpInitChunk *>(chunk);
261 entry2->setGlobalVTag(initChunk->getInitTag());
262 natTable->natEntries.push_back(entry2);
263 networkHeader->setDestinationAddress(entry->getLocalAddress().toIpv4());
264 sctp->setDestPort(entry->getLocalPort());
265 networkHeader->setSourceAddress(entry->getGlobalAddress().toIpv4());
266 sctp->setSrcPort(entry->getGlobalPort());
267 EV <<
"added additional entry for local deliver\n";
269 EV <<
"destAddress set to " << dgram->getDestinationAddress() <<
", destPort set to " << sctpMsg->getDestPort() <<
"\n";
273 EV <<
"no INIT: destAddr=" << dgram->getDestinationAddress() <<
" destPort=" << sctpMsg->getDestPort() <<
" srcPort=" << sctpMsg->getSrcPort() <<
" vTag=" << sctpMsg->getVTag() <<
"\n";
274 entry =
natTable->getLocalEntry(dgram->getDestinationAddress(), sctpMsg->getSrcPort(), sctpMsg->getDestPort(), sctpMsg->getVTag());
275 if (entry !=
nullptr) {
276 networkHeader->setDestinationAddress(entry->getLocalAddress().toIpv4());
277 sctp->setDestPort(entry->getLocalPort());
278 networkHeader->setSourceAddress(entry->getGlobalAddress().toIpv4());
279 sctp->setSrcPort(entry->getGlobalPort());
282 EV <<
"no entry found\n";