Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated RouterAlertHandling branch #11

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/applications/generic/IPvXTrafGen.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include "IPvXAddressResolver.h"
#include "IPv4ControlInfo.h"
#include "IPv6ControlInfo.h"
#include "IPv6ExtensionHeaders.h"
#include "IPv4Datagram.h"


Define_Module(IPvXTrafGen);
Expand Down Expand Up @@ -187,6 +189,11 @@ void IPvXTrafGen::sendPacket()
IPv4ControlInfo *controlInfo = new IPv4ControlInfo();
controlInfo->setDestAddr(destAddr.get4());
controlInfo->setProtocol(protocol);
if (par("routerAlert").boolValue() == true)
{
controlInfo->setOptions(IPOPTION_ROUTER_ALERT);
}
controlInfo->setOptions(148);
payload->setControlInfo(controlInfo);
gate = "ipOut";
}
Expand All @@ -196,6 +203,14 @@ void IPvXTrafGen::sendPacket()
IPv6ControlInfo *controlInfo = new IPv6ControlInfo();
controlInfo->setDestAddr(destAddr.get6());
controlInfo->setProtocol(protocol);
if (par("routerAlert").boolValue() == true)
{
// TODO how do we do this extension header handling elegantly?
IPv6HopByHopOptionsHeader *hdr = new IPv6HopByHopOptionsHeader();
hdr->setOptionsArraySize(1);
hdr->setOptions(0, new IPv6OptionRouterAlert());
controlInfo->addExtensionHeader(hdr);
}
payload->setControlInfo(controlInfo);
gate = "ipv6Out";
}
Expand Down
1 change: 1 addition & 0 deletions src/applications/generic/IPvXTrafGen.ned
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ simple IPvXTrafGen like IIPvXTrafficGenerator
int protocol; // value for ~IPv4ControlInfo / ~IPv6ControlInfo protocol field
volatile int packetLength @unit("B"); // packet length in bytes
string destAddresses = default(""); // list of destination addresses, separated by spaces
bool routerAlert = default(false); // set the router alert header option
@display("i=block/source");
@signal[sentPk](type=cPacket);
@signal[rcvdPk](type=cPacket);
Expand Down
29 changes: 29 additions & 0 deletions src/networklayer/common/IRouterAlertHandler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// Copyright (C) 2013 Markus Brueckner
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see http://www.gnu.org/licenses/.
//

#ifndef IROUTERALERTHANDLER_H_
#define IROUTERALERTHANDLER_H_

/**
* Base class for all router alert handlers. See the NED file for more
* information.
*/
class IRouterAlertHandler : public cSimpleModule
{
};

#endif /* IROUTERALERTHANDLER_H_ */
35 changes: 35 additions & 0 deletions src/networklayer/common/IRouterAlertHandler.ned
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// Copyright (C) 2013 Markus Brueckner
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see http://www.gnu.org/licenses/.
//

package inet.networklayer.common;

// generic router alert handler interface
// This interface can be sub-classed by modules interested in intercepting
// IPv4 and IPv6 packets with the Router Alert option set. The interface
// offers two gates: one for receiving packets from the network layer (routerAlertIn)
// and one for re-injecting packets into the network layer (routerAlertReturn).
// Packets arriving at routerAlertIn are handed over to the module completely.
// If the packets are to be sent onwards along the normal routing path, they
// have to be re-injected via the routerAlertReturn gate.
moduleinterface IRouterAlertHandler
{
parameters:
@display("i=block/control_s");
gates:
input routerAlertIn @labels(IPv4Datagram,IPv6Datagram);
output routerAlertReturn @labels(IPv4Datagram,IPv6Datagram);
}
1 change: 1 addition & 0 deletions src/networklayer/contract/IPv4ControlInfo.msg
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ class IPv4ControlInfo
abstract int explicitCongestionNotification; // maps to bits 6-7 of trafficClass
short timeToLive; // maximum hop count
bool dontFragment; // "don't fragment" bit
int options; // The "options" header field

// The following fields are used in the DSR protocol; TODO revise
IPv4Address nextHopAddr; // next hop address (DSR)
Expand Down
20 changes: 19 additions & 1 deletion src/networklayer/ipv4/IPv4.cc
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,22 @@ void IPv4::handlePacketFromNetwork(IPv4Datagram *datagram, InterfaceEntry *fromI

EV << "Received datagram `" << datagram->getName() << "' with dest=" << destAddr << "\n";

// handle router alert option field -> This ist handled only on intermediate routers and not on the endpoints
// also the packet is not handled again if it returns from the router alert handler
if ((!datagram->getArrivalGate()->isName("routerAlertReturn")) && !(rt->isLocalAddress(destAddr)) && datagram->getOptionCode() == IPOPTION_ROUTER_ALERT) // FIXME If the option code handling is changed to support multiple options, we have to change this here too
{
// send the datagram to the router alert gate
cGate *rout = gate("routerAlertOut");
if (rout != 0 && rout->isConnected()) {
send(datagram, rout);
// bail out of the handling. The packet has to be re-injected by the Option handler, when needed
return; // FIXME maybe implement without return?
}
else {
EV << "Router alert option set, but no handler connected. Ignoring.\n";
}
}

if (fromIE->isLoopback())
{
reassembleAndDeliver(datagram);
Expand Down Expand Up @@ -805,7 +821,9 @@ IPv4Datagram *IPv4::encapsulate(cPacket *transportPacket, IPv4ControlInfo *contr
datagram->setTimeToLive(ttl);
datagram->setTransportProtocol(controlInfo->getProtocol());

// setting IPv4 options is currently not supported
if (controlInfo->getOptions() != 0) {
datagram->setOptionCode(controlInfo->getOptions()); // FIXME will only work so long as only one option header is supported
}

return datagram;
}
Expand Down
12 changes: 11 additions & 1 deletion src/networklayer/ipv4/IPv4.ned
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,15 @@ package inet.networklayer.ipv4;
// method which determines processing time for a packet, or (2) use a
// different base class.
//
// @see ~RoutingTable, ~IPv4ControlInfo, ~IPv4RoutingDecision, ~ARP
// <b>Packet interception</p>
//
// Implementers interested in intercepting packets that pass through the IP layer
// can hook a ~IRouterAlertHandler-like module to the routerAlertOut gate. The
// IP module will then hand over all packets carrying the router alert option field
// to this module for detailled processing. In order to carry on with normal routing,
// packets must be returned using the routerAlertReturn gate.
//
// @see ~RoutingTable, ~IPv4ControlInfo, ~IPv4RoutingDecision, ~ARP, ~IRouterAlertHandler
//
// @author Andras Varga
//
Expand All @@ -96,4 +104,6 @@ simple IPv4
output transportOut[] @labels(IPv4ControlInfo/up,TCPSegment,UDPPacket);
input queueIn[] @labels(IPv4Datagram);
output queueOut @labels(IPv4Datagram);
output routerAlertOut @labels(IPv4Datagram);
input routerAlertReturn @labels(IPv4Datagram);
}
26 changes: 26 additions & 0 deletions src/networklayer/ipv6/IPv6.cc
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,32 @@ void IPv6::endService(cPacket *msg)
// 2. The Ethernet or PPP frame is dropped by the link-layer if there is a transmission error.
ASSERT(!datagram->hasBitError());

if (!rt->isLocalAddress(datagram->getDestAddress()))
{
// handle router alert options, if set
cGate *rout = gate("routerAlertOut");
// only check if we have a handler and this datagram wasn't returned from it already
if (rout && rout->isConnected() && !(datagram->arrivedOn("routerAlertReturn")))
{
for (int i = datagram->getExtensionHeaderArraySize() - 1; i >= 0; --i)
{
// check whether the router alert extension header is set
IPv6ExtensionHeaderPtr extHdr = datagram->getExtensionHeader(i);
if (extHdr->getExtensionType() == IP_PROT_IPv6EXT_HOP) {
// check whether the router alert option is set
IPv6HopByHopOptionsHeader *optHdr = check_and_cast<IPv6HopByHopOptionsHeader *>(extHdr);
for (int hi = optHdr->getOptionsArraySize() - 1 ; hi >= 0; --hi) {
if (optHdr->getOptions(hi)->getOptionType() == 5) { // FIXME implement symbolic constant
// we have router alert set -> hand it over to the router alert handler
send(datagram, rout);
return; // TODO break out here without using return?
}
}
}
}
}
}

// remove control info
delete datagram->removeControlInfo();

Expand Down
14 changes: 13 additions & 1 deletion src/networklayer/ipv6/IPv6.ned
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,16 @@ package inet.networklayer.ipv6;
// datagrams are processed in order. The processing time is determined by the
// procDelay module parameter.
//
// @see ~RoutingTable6, ~IPv6ControlInfo, ~IPv6NeighbourDiscovery, ~ICMPv6
// <b>Packet interception</p>
//
// Implementers interested in intercepting packets that pass through the IP layer
// can hook a ~IRouterAlertHandler-like module to the routerAlertOut gate. The
// IP module will then hand over all packets carrying the router alert option field
// in the HopByHopExtensionHeader to this module for detailled processing.
// In order to carry on with normal routing, packets must be returned using
// the routerAlertReturn gate.
//
// @see ~RoutingTable6, ~IPv6ControlInfo, ~IPv6NeighbourDiscovery, ~ICMPv6, ~IRouterAlertHandler
//
// @author Andras Varga
//
Expand All @@ -97,5 +106,8 @@ simple IPv6
//the following gates are added by Zarrar Yousaf on 19.06.07
input xMIPv6In;
output xMIPv6Out;
// gates for handling IPv6 Router Alert options
input routerAlertReturn @labels(IPv6Datagram);
output routerAlertOut @labels(IPv6Datagram);
}

39 changes: 39 additions & 0 deletions src/networklayer/ipv6/IPv6ExtensionHeaders.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,42 @@ void IPv6RoutingHeader::setAddressArraySize(unsigned int size)
IPv6RoutingHeader_Base::setAddressArraySize(size);
byteLength_var = 8 + 16 * size;
}

void IPv6HopByHopOptionsHeader::clean()
{
// clean away the options
for (int i = getOptionsArraySize()-1; i >= 0; --i)
{
delete getOptions(i);
}
}

void IPv6HopByHopOptionsHeader::copy(const IPv6HopByHopOptionsHeader& other)
{
if (getOptionsArraySize() > 0)
{
clean();
}
setOptionsArraySize(other.getOptionsArraySize());
for (int i = other.getOptionsArraySize()-1; i >= 0; --i)
{
setOptions(i, other.getOptions(i)->dup());
}
}

IPv6HopByHopOptionsHeader::~IPv6HopByHopOptionsHeader()
{
clean();
}

IPv6HopByHopOptionsHeader::IPv6HopByHopOptionsHeader(const IPv6HopByHopOptionsHeader &other)
{
setOptionsArraySize(0);
copy(other);
}

IPv6HopByHopOptionsHeader& IPv6HopByHopOptionsHeader::operator=(const IPv6HopByHopOptionsHeader& other)
{
copy(other);
return *this;
}
13 changes: 13 additions & 0 deletions src/networklayer/ipv6/IPv6ExtensionHeaders.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,17 @@ class IPv6RoutingHeader : public IPv6RoutingHeader_Base
virtual void setAddressArraySize(unsigned int size);
};

class IPv6HopByHopOptionsHeader : public IPv6HopByHopOptionsHeader_Base
{
private:
void clean();
void copy(const IPv6HopByHopOptionsHeader& other);
public:
IPv6HopByHopOptionsHeader() : IPv6HopByHopOptionsHeader_Base() {}
~IPv6HopByHopOptionsHeader();
IPv6HopByHopOptionsHeader(const IPv6HopByHopOptionsHeader& other);
IPv6HopByHopOptionsHeader& operator=(const IPv6HopByHopOptionsHeader& other);
virtual IPv6HopByHopOptionsHeader *dup() const {return new IPv6HopByHopOptionsHeader(*this);}
// ADD CODE HERE to redefine and implement pure virtual functions from IPv6HopByHopOptionsHeader_Base
};
#endif // __INET_IPV6EXTENSIONHEADERS_H_
18 changes: 18 additions & 0 deletions src/networklayer/ipv6/IPv6ExtensionHeaders.msg
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,40 @@ cplusplus {{
#include "IPProtocolId_m.h"

#define IPv6_FRAGMENT_HEADER_LENGTH 8
class IPv6Option;
typedef IPv6Option *IPv6OptionPtr;
}}


class noncobject IPv6Address;

class noncobject IPv6ExtensionHeader;

class noncobject IPv6OptionPtr;

class IPv6Option
{
unsigned char optionType;
unsigned char optionLength;
}

class IPv6OptionRouterAlert extends IPv6Option
{
optionType = 5; // FIXME use symbolic constant
optionLength = 2;
}

//
// Hop-by-Hop Options Header.
// RFC 2460 Section 4.3
// Next Header Value: 0
//
class IPv6HopByHopOptionsHeader extends IPv6ExtensionHeader
{
@customize(true);
extensionType = IP_PROT_IPv6EXT_HOP;
byteLength = 8; // FIXME verify
IPv6OptionPtr options[];
}

//
Expand Down
15 changes: 14 additions & 1 deletion src/nodes/inet/NetworkLayer.ned
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package inet.nodes.inet;

import inet.networklayer.arp.ARP;
import inet.networklayer.common.IRouterAlertHandler;
import inet.networklayer.autorouting.ipv4.IPv4NodeConfigurator;
import inet.networklayer.ipv4.ErrorHandling;
import inet.networklayer.ipv4.ICMP;
Expand All @@ -37,6 +38,10 @@ module NetworkLayer
@display("i=block/fork");
bool proxyARP = default(true);
string igmpType = default("IGMPv2");
// router alert handler type. Put here a string naming the type of router alert handler
// module that you want to use (if any). The network layer will then instantiate and
// connect the respective module automatically.
string routerAlertHandlerType = default("");
gates:
input ifIn[] @labels(IPv4Datagram);
input tcpIn @labels(TCPSegment,IPv4ControlInfo/down);
Expand All @@ -57,6 +62,7 @@ module NetworkLayer
output manetOut;
output igmpOut;


submodules:
configurator: IPv4NodeConfigurator {
@display("p=39,158");
Expand Down Expand Up @@ -89,7 +95,9 @@ module NetworkLayer
parameters:
@display("p=239,63");
}

routerAlertHandler: <routerAlertHandlerType> like IRouterAlertHandler if routerAlertHandlerType != "" {
@display("p=294,103");
}
connections allowunconnected:
// transport Layer
ip.transportOut[0] --> { @display("m=n"); } --> tcpOut;
Expand Down Expand Up @@ -136,5 +144,10 @@ module NetworkLayer
for i=0..sizeof(ifOut)-1 {
arp.nicOut[i] --> { @display("m=s"); } --> ifOut[i];
}

if routerAlertHandlerType != "" {
ip.routerAlertOut --> routerAlertHandler.routerAlertIn;
routerAlertHandler.routerAlertReturn --> ip.routerAlertReturn;
}
}

Loading