INET Framework for OMNeT++/OMNEST
inet::sctp::SCTPNatHook Class Reference

#include <SCTPNatHook.h>

Inheritance diagram for inet::sctp::SCTPNatHook:
inet::INetfilter::IHook

Public Member Functions

 SCTPNatHook ()
 
virtual ~SCTPNatHook ()
 
IHook::Result datagramPreRoutingHook (INetworkDatagram *datagram, const InterfaceEntry *inIE, const InterfaceEntry *&outIE, L3Address &nextHopAddr) override
 This is the first hook called by the network protocol before it routes a datagram that was received from the lower layer. More...
 
IHook::Result datagramForwardHook (INetworkDatagram *datagram, const InterfaceEntry *inIE, const InterfaceEntry *&outIE, L3Address &nextHopAddr) override
 This is the second hook called by the network protocol before it sends a datagram to the lower layer. More...
 
IHook::Result datagramPostRoutingHook (INetworkDatagram *datagram, const InterfaceEntry *inIE, const InterfaceEntry *&outIE, L3Address &nextHopAddr) override
 This is the last hook called by the network protocol before it sends a datagram to the lower layer. More...
 
IHook::Result datagramLocalInHook (INetworkDatagram *datagram, const InterfaceEntry *inIE) override
 This is the last hook called by the network protocol before it sends a datagram to the upper layer. More...
 
IHook::Result datagramLocalOutHook (INetworkDatagram *datagram, const InterfaceEntry *&outIE, L3Address &nextHopAddr) override
 This is the first hook called by the network protocol before it routes a datagram that was received from the upper layer. More...
 

Protected Member Functions

void initialize () override
 
void finish () override
 
void sendBackError (IPv4Datagram *dgram)
 

Protected Attributes

IPv4ipLayer
 
SCTPNatTablenatTable
 
IRoutingTablert
 
IInterfaceTableift
 
uint64 nattedPackets
 

Additional Inherited Members

- Private Types inherited from inet::INetfilter::IHook
enum  Type {
  PREROUTING, LOCALIN, FORWARD, POSTROUTING,
  LOCALOUT
}
 
enum  Result { ACCEPT, DROP, QUEUE, STOLEN }
 
- Private Member Functions inherited from inet::INetfilter::IHook
virtual ~IHook ()
 

Constructor & Destructor Documentation

inet::sctp::SCTPNatHook::SCTPNatHook ( )
16 {
17  ipLayer = nullptr;
18  natTable = nullptr;
19  rt = nullptr;
20  ift = nullptr;
21  nattedPackets = 0;
22 }
uint64 nattedPackets
Definition: SCTPNatHook.h:21
IInterfaceTable * ift
Definition: SCTPNatHook.h:20
SCTPNatTable * natTable
Definition: SCTPNatHook.h:18
IPv4 * ipLayer
Definition: SCTPNatHook.h:17
IRoutingTable * rt
Definition: SCTPNatHook.h:19
inet::sctp::SCTPNatHook::~SCTPNatHook ( )
virtual
25 {
26  ipLayer = check_and_cast_nullable<IPv4 *>(getModuleByPath(par("networkProtocolModule")));
27  if (ipLayer)
28  ipLayer->unregisterHook(0, this);
29 }
virtual void unregisterHook(int priority, IHook *hook) override
unregisters a Hook to be executed during datagram processing
Definition: IPv4.cc:918
IPv4 * ipLayer
Definition: SCTPNatHook.h:17

Member Function Documentation

INetfilter::IHook::Result inet::sctp::SCTPNatHook::datagramForwardHook ( INetworkDatagram datagram,
const InterfaceEntry inputInterfaceEntry,
const InterfaceEntry *&  outputInterfaceEntry,
L3Address nextHopAddress 
)
overridevirtual

This is the second hook called by the network protocol before it sends a datagram to the lower layer.

This is done after the datagramPreRoutingHook or the datagramLocalInHook is called and the datagram is routed.

Implements inet::INetfilter::IHook.

42 {
43  SCTPNatEntry *entry;
44  SCTPChunk *chunk;
45  IPv4Datagram *dgram;
46 
47  dgram = dynamic_cast<IPv4Datagram *>(datagram);
48  if (!dgram) {
50  }
51  if (SCTPAssociation::getAddressLevel(dgram->getSrcAddress()) != 3) {
53  }
55  SCTPMessage *sctpMsg = check_and_cast<SCTPMessage *>(dgram->getEncapsulatedPacket());
56  unsigned int numberOfChunks = sctpMsg->getChunksArraySize();
57  if (numberOfChunks == 1)
58  chunk = (SCTPChunk *)(sctpMsg->peekFirstChunk());
59  else
60  chunk = (SCTPChunk *)(sctpMsg->peekLastChunk());
61  EV << "findEntry for " << dgram->getSrcAddress() << ":" << sctpMsg->getSrcPort() << " to " << dgram->getDestAddress() << ":" << sctpMsg->getDestPort() << " vTag=" << sctpMsg->getTag() << " natAddr=" << outIE->ipv4Data()->getIPAddress() << "\n";
62  if (chunk->getChunkType() == INIT || chunk->getChunkType() == INIT_ACK || chunk->getChunkType() == ASCONF) {
63  entry = new SCTPNatEntry();
64  entry->setLocalAddress(dgram->getSrcAddress());
65  entry->setLocalPort(sctpMsg->getSrcPort());
66  entry->setGlobalAddress(dgram->getDestAddress());
67  entry->setGlobalPort(sctpMsg->getDestPort());
68  entry->setNattedAddress(outIE->ipv4Data()->getIPAddress());
69  entry->setNattedPort(sctpMsg->getSrcPort());
70  entry->setGlobalVTag(sctpMsg->getTag());
71  if (chunk->getChunkType() == INIT) {
72  SCTPInitChunk *initChunk = check_and_cast<SCTPInitChunk *>(chunk);
73  entry->setLocalVTag(initChunk->getInitTag());
74  }
75  else if (chunk->getChunkType() == INIT_ACK) {
76  SCTPInitAckChunk *initAckChunk = check_and_cast<SCTPInitAckChunk *>(chunk);
77  entry->setLocalVTag(initAckChunk->getInitTag());
78  }
79  else if (chunk->getChunkType() == ASCONF) {
80  SCTPAsconfChunk *asconfChunk = check_and_cast<SCTPAsconfChunk *>(chunk);
81  entry->setLocalVTag(asconfChunk->getPeerVTag());
82  }
83  dgram->setSrcAddress(outIE->ipv4Data()->getIPAddress());
84  sctpMsg->setSrcPort(entry->getNattedPort());
85  natTable->natEntries.push_back(entry);
86  }
87  else {
88  EV << "other chunkType: " << (chunk->getChunkType() == COOKIE_ECHO ? "Cookie_Echo" : "other") << ", VTag=" << sctpMsg->getTag() << "\n";
89  entry = natTable->findNatEntry(dgram->getSrcAddress(), sctpMsg->getSrcPort(), dgram->getDestAddress(), sctpMsg->getDestPort(), sctpMsg->getTag());
90  if (entry == nullptr) {
91  EV << "no entry found\n";
92  entry = natTable->findNatEntry(dgram->getSrcAddress(), sctpMsg->getSrcPort(), dgram->getDestAddress(), sctpMsg->getDestPort(), 0);
93  if (entry == nullptr) {
94  EV << "send back error message dgram=" << dgram << "\n";
95  sendBackError(dgram);
96  nextHopAddr = dgram->getDestAddress();
97  const InterfaceEntry *tmpIE = inIE;
98  inIE = outIE;
99  outIE = tmpIE;
101  }
102  else {
103  EV << "VTag doesn't match: old VTag=" << entry->getLocalVTag() << ", new VTag=" << sctpMsg->getTag() << "\n";
104  entry->setLocalVTag(sctpMsg->getTag());
105  dgram->setSrcAddress(outIE->ipv4Data()->getIPAddress());
106  sctpMsg->setSrcPort(entry->getNattedPort());
107  EV << "srcAddress set to " << dgram->getSrcAddress() << ", srcPort set to " << sctpMsg->getSrcPort() << "\n";
108  }
109  }
110  else {
111  dgram->setSrcAddress(outIE->ipv4Data()->getIPAddress());
112  sctpMsg->setSrcPort(entry->getNattedPort());
113  EV << "srcAddress set to " << dgram->getSrcAddress() << ", srcPort set to " << sctpMsg->getSrcPort() << "\n";
114  }
115  }
116  nattedPackets++;
118 }
SCTPNatEntryTable natEntries
Definition: SCTPNatTable.h:74
SCTPNatEntry * findNatEntry(L3Address srcAddr, uint16 srcPrt, L3Address destAddr, uint16 destPrt, uint32 globalVtag)
Definition: SCTPNatTable.cc:49
Definition: SCTPAssociation.h:121
uint64 nattedPackets
Definition: SCTPNatHook.h:21
void printNatTable()
Definition: SCTPNatTable.cc:133
Definition: SCTPAssociation.h:130
allows the datagram to pass to the next hook
Definition: INetfilter.h:50
void sendBackError(IPv4Datagram *dgram)
Definition: SCTPNatHook.cc:267
Definition: SCTPAssociation.h:112
static int getAddressLevel(const L3Address &addr)
Utility: return IPv4 or IPv6 address level.
Definition: SCTPAssociationUtil.cc:2814
SCTPNatTable * natTable
Definition: SCTPNatHook.h:18
Definition: SCTPAssociation.h:113
INetfilter::IHook::Result inet::sctp::SCTPNatHook::datagramLocalInHook ( INetworkDatagram datagram,
const InterfaceEntry inputInterfaceEntry 
)
overridevirtual

This is the last hook called by the network protocol before it sends a datagram to the upper layer.

This is done after the datagramPreRoutingHook is called and the datagram is routed.

Implements inet::INetfilter::IHook.

258 {
260 }
allows the datagram to pass to the next hook
Definition: INetfilter.h:50
INetfilter::IHook::Result inet::sctp::SCTPNatHook::datagramLocalOutHook ( INetworkDatagram datagram,
const InterfaceEntry *&  outputInterfaceEntry,
L3Address nextHopAddress 
)
overridevirtual

This is the first hook called by the network protocol before it routes a datagram that was received from the upper layer.

The nextHopAddress is ignored when the outputInterfaceEntry is a nullptr. After this is done

Implements inet::INetfilter::IHook.

263 {
265 }
allows the datagram to pass to the next hook
Definition: INetfilter.h:50
INetfilter::IHook::Result inet::sctp::SCTPNatHook::datagramPostRoutingHook ( INetworkDatagram datagram,
const InterfaceEntry inputInterfaceEntry,
const InterfaceEntry *&  outputInterfaceEntry,
L3Address nextHopAddress 
)
overridevirtual

This is the last hook called by the network protocol before it sends a datagram to the lower layer.

Implements inet::INetfilter::IHook.

253 {
255 }
allows the datagram to pass to the next hook
Definition: INetfilter.h:50
INetfilter::IHook::Result inet::sctp::SCTPNatHook::datagramPreRoutingHook ( INetworkDatagram datagram,
const InterfaceEntry inputInterfaceEntry,
const InterfaceEntry *&  outputInterfaceEntry,
L3Address nextHopAddress 
)
overridevirtual

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 outputInterfaceEntry is nullptr.

Implements inet::INetfilter::IHook.

121 {
122  SCTPNatEntry *entry;
123  SCTPChunk *chunk;
124  IPv4Datagram *dgram;
125 
126  dgram = check_and_cast<IPv4Datagram *>(datagram);
127  if (SCTPAssociation::getAddressLevel(dgram->getSrcAddress()) == 3) {
129  }
131  bool local = ((rt->isLocalAddress(dgram->getDestAddress())) && (SCTPAssociation::getAddressLevel(dgram->getSrcAddress()) == 3));
132  SCTPMessage *sctpMsg = check_and_cast<SCTPMessage *>(dgram->getEncapsulatedPacket());
133  unsigned int numberOfChunks = sctpMsg->getChunksArraySize();
134  if (numberOfChunks == 1)
135  chunk = (SCTPChunk *)(sctpMsg->peekFirstChunk());
136  else
137  chunk = (SCTPChunk *)(sctpMsg->peekLastChunk());
138  if (!local) {
139  entry = natTable->getEntry(dgram->getSrcAddress(), sctpMsg->getSrcPort(), dgram->getDestAddress(), sctpMsg->getDestPort(), sctpMsg->getTag());
140  EV << "getEntry for " << dgram->getSrcAddress() << ":" << sctpMsg->getSrcPort() << " to " << dgram->getDestAddress() << ":" << sctpMsg->getDestPort() << " peerVTag=" << sctpMsg->getTag() << "\n";
141  uint32 numberOfChunks = sctpMsg->getChunksArraySize();
142  if (entry == nullptr) {
143  EV << "no entry found\n";
144  if (numberOfChunks == 1)
145  chunk = (SCTPChunk *)(sctpMsg->peekFirstChunk());
146  else
147  chunk = (SCTPChunk *)(sctpMsg->peekLastChunk());
148  if (chunk->getChunkType() == INIT || chunk->getChunkType() == ASCONF) {
149  EV << "could be an Init collision\n";
150  entry = natTable->getSpecialEntry(dgram->getSrcAddress(), sctpMsg->getSrcPort(), dgram->getDestAddress(), sctpMsg->getDestPort());
151  if (entry != nullptr) {
152  if (chunk->getChunkType() == INIT) {
153  SCTPInitChunk *initChunk = check_and_cast<SCTPInitChunk *>(chunk);
154  entry->setLocalVTag(initChunk->getInitTag());
155  EV << "InitTag=" << initChunk->getInitTag() << "\n";
156  }
157  else if (chunk->getChunkType() == ASCONF) {
158  SCTPAsconfChunk *asconfChunk = check_and_cast<SCTPAsconfChunk *>(chunk);
159  entry->setLocalVTag(asconfChunk->getPeerVTag());
160  }
161  dgram->setDestAddress(entry->getLocalAddress().toIPv4());
162  sctpMsg->setDestPort(entry->getLocalPort());
163  EV << "destAddress set to " << dgram->getDestAddress() << ", destPort set to " << sctpMsg->getDestPort() << "\n";
164  }
165  else {
167  }
168  }
169  else {
170  SCTPChunk *schunk;
171  if (numberOfChunks > 0) {
172  EV << "number of chunks=" << numberOfChunks << "\n";
173  for (uint32 i = 0; i < numberOfChunks; i++) {
174  schunk = (SCTPChunk *)(sctpMsg->removeChunk());
175  if (schunk->getChunkType() == DATA)
176  delete (SCTPSimpleMessage *)schunk->decapsulate();
177  EV << "delete chunk " << schunk->getName() << "\n";
178  delete schunk;
179  }
180  }
182  }
183  }
184  else {
185  dgram->setDestAddress(entry->getLocalAddress().toIPv4());
186  sctpMsg->setDestPort(entry->getLocalPort());
187  if (entry->getGlobalVTag() == 0 && chunk->getChunkType() == INIT_ACK) {
188  SCTPInitAckChunk *initAckChunk = check_and_cast<SCTPInitAckChunk *>(chunk);
189  entry->setGlobalVTag(initAckChunk->getInitTag());
190  }
191  EV << "destAddress set to " << dgram->getDestAddress() << ", destPort set to " << sctpMsg->getDestPort() << "\n";
192  }
193  }
194  else {
195  if (chunk->getChunkType() == INIT) {
196  EV << "getLocALEntry for " << dgram->getSrcAddress() << ":" << sctpMsg->getSrcPort() << " to " << dgram->getDestAddress() << ":" << sctpMsg->getDestPort() << " peerVTag=" << sctpMsg->getTag() << "\n";
197  entry = natTable->getLocalInitEntry(dgram->getDestAddress(), sctpMsg->getSrcPort(), sctpMsg->getDestPort());
198  if (entry == nullptr) {
199  entry = new SCTPNatEntry();
200  entry->setLocalAddress(dgram->getSrcAddress());
201  entry->setLocalPort(sctpMsg->getSrcPort());
202  entry->setGlobalAddress(dgram->getDestAddress());
203  entry->setGlobalPort(sctpMsg->getDestPort());
204  entry->setNattedPort(sctpMsg->getSrcPort());
205  entry->setNattedAddress(dgram->getDestAddress());
206  SCTPInitChunk *initChunk = check_and_cast<SCTPInitChunk *>(chunk);
207  entry->setGlobalVTag(initChunk->getInitTag());
208  natTable->natEntries.push_back(entry);
209  EV << "added entry for local deliver\n";
212  }
213  else {
214  SCTPNatEntry *entry2 = new SCTPNatEntry();
215  entry2->setLocalAddress(dgram->getSrcAddress());
216  entry2->setLocalPort(sctpMsg->getSrcPort());
217  entry2->setGlobalAddress(entry->getGlobalAddress());
218  entry2->setGlobalPort(sctpMsg->getDestPort());
219  entry2->setNattedPort(sctpMsg->getSrcPort());
220  entry2->setNattedAddress(entry->getGlobalAddress());
221  SCTPInitChunk *initChunk = check_and_cast<SCTPInitChunk *>(chunk);
222  entry2->setGlobalVTag(initChunk->getInitTag());
223  natTable->natEntries.push_back(entry2);
224  dgram->setDestAddress(entry->getLocalAddress().toIPv4());
225  sctpMsg->setDestPort(entry->getLocalPort());
226  dgram->setSrcAddress(entry->getGlobalAddress().toIPv4());
227  sctpMsg->setSrcPort(entry->getGlobalPort());
228  EV << "added additional entry for local deliver\n";
230  EV << "destAddress set to " << dgram->getDestAddress() << ", destPort set to " << sctpMsg->getDestPort() << "\n";
231  }
232  }
233  else {
234  EV << "no INIT: destAddr=" << dgram->getDestAddress() << " destPort=" << sctpMsg->getDestPort() << " srcPort=" << sctpMsg->getSrcPort() << " vTag=" << sctpMsg->getTag() << "\n";
235  entry = natTable->getLocalEntry(dgram->getDestAddress(), sctpMsg->getSrcPort(), sctpMsg->getDestPort(), sctpMsg->getTag());
236  if (entry != nullptr) {
237  dgram->setDestAddress(entry->getLocalAddress().toIPv4());
238  sctpMsg->setDestPort(entry->getLocalPort());
239  dgram->setSrcAddress(entry->getGlobalAddress().toIPv4());
240  sctpMsg->setSrcPort(entry->getGlobalPort());
241  }
242  else {
243  EV << "no entry found\n";
245  }
246  }
247  }
248  nattedPackets++;
250 }
SCTPNatEntryTable natEntries
Definition: SCTPNatTable.h:74
Definition: SCTPAssociation.h:111
doesn&#39;t allow the datagram to pass to the next hook, will be deleted
Definition: INetfilter.h:51
uint64 nattedPackets
Definition: SCTPNatHook.h:21
virtual bool isLocalAddress(const L3Address &dest) const =0
Checks if the address is a local one, i.e.
void printNatTable()
Definition: SCTPNatTable.cc:133
Definition: SCTPAssociation.h:130
SCTPNatEntry * getSpecialEntry(L3Address globalAddr, uint16 globalPrt, L3Address nattedAddr, uint16 nattedPrt)
Definition: SCTPNatTable.cc:77
allows the datagram to pass to the next hook
Definition: INetfilter.h:50
Definition: SCTPAssociation.h:112
uint32_t uint32
Definition: Compat.h:30
static int getAddressLevel(const L3Address &addr)
Utility: return IPv4 or IPv6 address level.
Definition: SCTPAssociationUtil.cc:2814
SCTPNatEntry * getLocalInitEntry(L3Address globalAddr, uint16 localPrt, uint16 globalPrt)
Definition: SCTPNatTable.cc:93
SCTPNatTable * natTable
Definition: SCTPNatHook.h:18
SCTPNatEntry * getLocalEntry(L3Address globalAddr, uint16 localPrt, uint16 globalPrt, uint32 localVtag)
Definition: SCTPNatTable.cc:106
Definition: SCTPAssociation.h:113
IRoutingTable * rt
Definition: SCTPNatHook.h:19
void setLocalVTag(uint32 tag)
Definition: SCTPNatTable.h:55
SCTPNatEntry * getEntry(L3Address globalAddr, uint16 globalPrt, L3Address nattedAddr, uint16 nattedPrt, uint32 localVtag)
Definition: SCTPNatTable.cc:62
void inet::sctp::SCTPNatHook::finish ( )
overrideprotected
301 {
302  if (ipLayer)
303  ipLayer->unregisterHook(0, this);
304  ipLayer = nullptr;
305  EV_INFO<< getFullPath() << ": Natted packets: " << nattedPackets << "\n";
306 }
uint64 nattedPackets
Definition: SCTPNatHook.h:21
virtual void unregisterHook(int priority, IHook *hook) override
unregisters a Hook to be executed during datagram processing
Definition: IPv4.cc:918
IPv4 * ipLayer
Definition: SCTPNatHook.h:17
void inet::sctp::SCTPNatHook::initialize ( )
overrideprotected
32 {
33  rt = getModuleFromPar<IRoutingTable>(par("routingTableModule"), this);
34  ift = getModuleFromPar<IInterfaceTable>(par("interfaceTableModule"), this);
35  ipLayer = getModuleFromPar<IPv4>(par("networkProtocolModule"), this);
36  natTable = getModuleFromPar<SCTPNatTable>(par("natTableModule"), this);
37 
38  ipLayer->registerHook(0, this);
39 }
IInterfaceTable * ift
Definition: SCTPNatHook.h:20
SCTPNatTable * natTable
Definition: SCTPNatHook.h:18
IPv4 * ipLayer
Definition: SCTPNatHook.h:17
IRoutingTable * rt
Definition: SCTPNatHook.h:19
void inet::sctp::SCTPNatHook::sendBackError ( IPv4Datagram dgram)
protected

Referenced by datagramForwardHook().

268 {
269  SCTPMessage *sctpmsg = new SCTPMessage();
270  sctpmsg->setByteLength(SCTP_COMMON_HEADER);
271  SCTPErrorChunk *errorChunk = new SCTPErrorChunk("NatError");
272  errorChunk->setChunkType(ERRORTYPE);
273  errorChunk->setByteLength(4);
274  SCTPSimpleErrorCauseParameter *cause = new SCTPSimpleErrorCauseParameter("Cause");
275  cause->setParameterType(MISSING_NAT_ENTRY);
276  cause->setByteLength(4);
277  cause->encapsulate(dgram->dup());
278  errorChunk->setMBit(true);
279  errorChunk->setTBit(true);
280  errorChunk->addParameters(cause);
281  sctpmsg->addChunk(errorChunk);
282 
283  SCTPMessage *oldmsg = check_and_cast<SCTPMessage *>(dgram->decapsulate());
284  sctpmsg->setSrcPort(oldmsg->getDestPort());
285  sctpmsg->setDestPort(oldmsg->getSrcPort());
286  sctpmsg->setTag(oldmsg->getTag());
287  sctpmsg->setChecksumOk(true);
288  dgram->removeControlInfo();
289  dgram->setName(sctpmsg->getName());
290  dgram->setByteLength(IP_HEADER_BYTES);
291  dgram->encapsulate(sctpmsg);
292  IPv4Address tmpaddr = dgram->getDestAddress();
293  dgram->setDestAddress(dgram->getSrcAddress());
294  if (!tmpaddr.isUnspecified())
295  dgram->setSrcAddress(tmpaddr);
296  dgram->setTransportProtocol(IP_PROT_SCTP);
297  delete oldmsg;
298 }
const int IP_HEADER_BYTES
Definition: IPv4Datagram_m.h:41
Definition: SCTPAssociation.h:192
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
Definition: SCTPAssociation.h:120
Definition: IPProtocolId_m.h:91

Member Data Documentation

IInterfaceTable* inet::sctp::SCTPNatHook::ift
protected

Referenced by initialize(), and SCTPNatHook().

IPv4* inet::sctp::SCTPNatHook::ipLayer
protected
SCTPNatTable* inet::sctp::SCTPNatHook::natTable
protected
uint64 inet::sctp::SCTPNatHook::nattedPackets
protected
IRoutingTable* inet::sctp::SCTPNatHook::rt
protected

The documentation for this class was generated from the following files: