|
INET Framework for OMNeT++/OMNEST
|
Implements a DHCP server.
More...
#include <DhcpServer.h>
|
| virtual int | numInitStages () const override |
| |
| virtual void | initialize (int stage) override |
| |
| virtual void | handleMessageWhenUp (cMessage *msg) override |
| |
| virtual void | openSocket () |
| |
| virtual DhcpLease * | getLeaseByMac (MacAddress mac) |
| |
| virtual DhcpLease * | getAvailableLease (Ipv4Address requestedAddress, const MacAddress &clientMAC) |
| |
| virtual void | processDhcpMessage (Packet *packet) |
| |
| virtual void | sendOffer (DhcpLease *lease, const Ptr< const DhcpMessage > &dhcpMsg) |
| |
| virtual void | sendAck (DhcpLease *lease, const Ptr< const DhcpMessage > &dhcpMsg) |
| |
| virtual void | sendNak (const Ptr< const DhcpMessage > &dhcpMsg) |
| |
| virtual void | handleSelfMessages (cMessage *msg) |
| |
| virtual NetworkInterface * | chooseInterface () |
| |
| virtual void | sendToUDP (Packet *msg, int srcPort, const L3Address &destAddr, int destPort) |
| |
| virtual void | socketDataArrived (UdpSocket *socket, Packet *packet) override |
| | Notifies about data arrival, packet ownership is transferred to the callee. More...
|
| |
| virtual void | socketErrorArrived (UdpSocket *socket, Indication *indication) override |
| | Notifies about error indication arrival, indication ownership is transferred to the callee. More...
|
| |
| virtual void | socketClosed (UdpSocket *socket) override |
| | Notifies about socket closed, indication ownership is transferred to the callee. More...
|
| |
| virtual void | receiveSignal (cComponent *source, simsignal_t signalID, cObject *obj, cObject *details) override |
| |
| virtual void | handleStartOperation (LifecycleOperation *operation) override |
| |
| virtual void | handleStopOperation (LifecycleOperation *operation) override |
| |
| virtual void | handleCrashOperation (LifecycleOperation *operation) override |
| |
| virtual bool | isInitializeStage (int stage) const override |
| |
| virtual bool | isModuleStartStage (int stage) const override |
| |
| virtual bool | isModuleStopStage (int stage) const override |
| |
| virtual int | numInitStages () const override |
| |
| virtual void | refreshDisplay () const override |
| |
| virtual void | handleMessage (cMessage *msg) override |
| |
| virtual void | handleMessageWhenDown (cMessage *msg) |
| |
| virtual bool | handleOperationStage (LifecycleOperation *operation, IDoneCallback *doneCallback) override |
| | Perform one stage of a lifecycle operation. More...
|
| |
| virtual State | getInitialOperationalState () const |
| | Returns initial operational state: OPERATING or NOT_OPERATING. More...
|
| |
| virtual void | handleActiveOperationTimeout (cMessage *message) |
| |
| virtual bool | isUp () const |
| | utility functions More...
|
| |
| virtual bool | isDown () const |
| |
| virtual void | setOperationalState (State newState) |
| |
| virtual void | scheduleOperationTimeout (simtime_t timeout) |
| |
| virtual void | setupActiveOperation (LifecycleOperation *operation, IDoneCallback *doneCallback, State) |
| |
| virtual void | delayActiveOperationFinish (simtime_t timeout) |
| |
| virtual void | startActiveOperationExtraTime (simtime_t delay=SIMTIME_ZERO) |
| |
| virtual void | startActiveOperationExtraTimeOrFinish (simtime_t extraTime) |
| |
| virtual void | finishActiveOperation () |
| |
Implements a DHCP server.
See NED file for more details.
◆ DhcpLeased
◆ TimerType
◆ DhcpServer()
| inet::DhcpServer::DhcpServer |
( |
| ) |
|
◆ ~DhcpServer()
| inet::DhcpServer::~DhcpServer |
( |
| ) |
|
|
virtual |
◆ chooseInterface()
87 IInterfaceTable *ift = getModuleFromPar<IInterfaceTable>(par(
"interfaceTableModule"),
this);
88 const char *interfaceName = par(
"interface");
89 NetworkInterface *
ie =
nullptr;
91 if (strlen(interfaceName) > 0) {
92 ie = ift->findInterfaceByName(interfaceName);
94 throw cRuntimeError(
"Interface \"%s\" does not exist", interfaceName);
98 for (
int i = 0; i < ift->getNumInterfaces(); i++) {
99 NetworkInterface *current = ift->getInterface(i);
100 if (!current->isLoopback()) {
102 throw cRuntimeError(
"Multiple non-loopback interfaces found, please select explicitly which one you want to serve DHCP requests on");
107 throw cRuntimeError(
"No non-loopback interface found to be configured via DHCP");
Referenced by handleStartOperation().
◆ getAvailableLease()
502 if (!requestedAddress.isUnspecified()) {
504 return &
leased[requestedAddress];
507 leased[requestedAddress] = DhcpLease();
508 leased[requestedAddress].ip = requestedAddress;
512 return &
leased[requestedAddress];
517 Ipv4Address ip(beginAddr + i);
Referenced by processDhcpMessage().
◆ getLeaseByMac()
484 for (
auto& elem :
leased) {
486 if (elem.second.mac == mac) {
487 EV_DETAIL <<
"Found lease for MAC " << mac <<
"." << endl;
488 return &(elem.second);
491 EV_DETAIL <<
"Lease not found for MAC " << mac <<
"." << endl;
Referenced by processDhcpMessage().
◆ handleCrashOperation()
◆ handleMessageWhenUp()
| void inet::DhcpServer::handleMessageWhenUp |
( |
cMessage * |
msg | ) |
|
|
overrideprotectedvirtual |
Implements inet::OperationalMixin< cSimpleModule >.
115 if (msg->isSelfMessage()) {
118 else if (msg->arrivedOn(
"socketIn")) {
122 throw cRuntimeError(
"Unknown incoming gate: '%s'", msg->getArrivalGate()->getFullName());
◆ handleSelfMessages()
| void inet::DhcpServer::handleSelfMessages |
( |
cMessage * |
msg | ) |
|
|
protectedvirtual |
◆ handleStartOperation()
Implements inet::OperationalMixin< cSimpleModule >.
552 const char *gatewayStr = par(
"gateway");
555 long numReservedAddresses = par(
"numReservedAddresses");
556 uint32_t networkStartAddress = ipv4data->getIPAddress().getInt() & ipv4data->getNetmask().getInt();
557 ipAddressStart = Ipv4Address(networkStartAddress + numReservedAddresses);
559 throw cRuntimeError(
"The numReservedAddresses parameter larger than address range");
561 throw cRuntimeError(
"Not enough IP addresses in subnet for %d clients",
maxNumOfClients);
◆ handleStopOperation()
◆ initialize()
| void inet::DhcpServer::initialize |
( |
int |
stage | ) |
|
|
overrideprotectedvirtual |
◆ numInitStages()
| virtual int inet::DhcpServer::numInitStages |
( |
| ) |
const |
|
inlineoverrideprotectedvirtual |
◆ openSocket()
| void inet::DhcpServer::openSocket |
( |
| ) |
|
|
protectedvirtual |
64 throw cRuntimeError(
"Interface to listen does not exist. aborting");
67 EV_INFO <<
"DHCP server bound to port " <<
serverPort << endl;
Referenced by handleSelfMessages().
◆ processDhcpMessage()
| void inet::DhcpServer::processDhcpMessage |
( |
Packet * |
packet | ) |
|
|
protectedvirtual |
154 ASSERT(
isUp() &&
ie !=
nullptr);
156 const auto& dhcpMsg = packet->peekAtFront<DhcpMessage>();
159 int inputInterfaceId = packet->getTag<InterfaceInd>()->getInterfaceId();
161 EV_WARN <<
"DHCP message arrived on a different interface, dropping\n";
168 int messageType = dhcpMsg->getOptions().getMessageType();
171 EV_INFO <<
"DHCPDISCOVER arrived. Handling it." << endl;
176 lease =
getAvailableLease(dhcpMsg->getOptions().getRequestedIp(), dhcpMsg->getChaddr());
177 if (lease !=
nullptr) {
179 lease->mac = dhcpMsg->getChaddr();
180 lease->xid = dhcpMsg->getXid();
182 lease->leased =
true;
186 EV_ERROR <<
"No lease available. Ignoring discover." << endl;
190 lease->xid = dhcpMsg->getXid();
196 EV_INFO <<
"DHCPREQUEST arrived. Handling it." << endl;
199 if (dhcpMsg->getOptions().getServerIdentifier() ==
ie->
getProtocolData<Ipv4InterfaceData>()->getIPAddress()) {
204 if (lease !=
nullptr) {
205 if (lease->ip != dhcpMsg->getOptions().getRequestedIp()) {
206 EV_ERROR <<
"The 'requested IP address' must be filled in with the 'yiaddr' value from the chosen DHCPOFFER." << endl;
210 EV_INFO <<
"From now " << lease->ip <<
" is leased to " << lease->mac <<
"." << endl;
211 lease->xid = dhcpMsg->getXid();
213 lease->leased =
true;
222 EV_ERROR <<
"There is no available lease for " << dhcpMsg->getChaddr() <<
". Probably, the client missed to send DHCPDISCOVER before DHCPREQUEST." << endl;
227 if (dhcpMsg->getCiaddr().isUnspecified()) {
229 Ipv4Address requestedAddress = dhcpMsg->getOptions().getRequestedIp();
230 auto it =
leased.find(requestedAddress);
234 EV_WARN <<
"DHCP server has no record of IP " << requestedAddress <<
"." << endl;
237 DhcpLease *lease = &it->second;
238 EV_INFO <<
"Initialization with known IP address (INIT-REBOOT) " << lease->ip <<
" on " << lease->mac <<
" was successful." << endl;
239 lease->xid = dhcpMsg->getXid();
241 lease->leased =
true;
247 EV_ERROR <<
"The requested IP address is incorrect, or is on the wrong network." << endl;
252 auto it =
leased.find(dhcpMsg->getCiaddr());
254 DhcpLease *lease = &it->second;
255 EV_INFO <<
"Request for renewal/rebinding IP " << lease->ip <<
" to " << lease->mac <<
"." << endl;
256 lease->xid = dhcpMsg->getXid();
258 lease->leased =
true;
264 EV_ERROR <<
"Renewal/rebinding process failed: requested IP address " << dhcpMsg->getCiaddr() <<
" not found in the server's database!" << endl;
271 EV_WARN <<
"BOOTREQUEST arrived, but DHCP message type is unknown. Dropping it." << endl;
274 EV_WARN <<
"Message opcode is unknown. This DHCP server only handles BOOTREQUEST messages. Dropping it." << endl;
277 EV_DEBUG <<
"Deleting " << packet <<
"." << endl;
Referenced by socketDataArrived().
◆ receiveSignal()
| void inet::DhcpServer::receiveSignal |
( |
cComponent * |
source, |
|
|
simsignal_t |
signalID, |
|
|
cObject * |
obj, |
|
|
cObject * |
details |
|
) |
| |
|
overrideprotectedvirtual |
76 NetworkInterface *nie = check_and_cast<NetworkInterface *>(obj);
78 throw cRuntimeError(
"Reacting to interface deletions is not implemented in this module");
82 throw cRuntimeError(
"Unexpected signal: %s", getSignalName(signalID));
◆ sendAck()
322 EV_INFO <<
"Sending the ACK to " << lease->mac <<
"." << endl;
324 Packet *pk =
new Packet(
"DHCPACK");
325 const auto& ack = makeShared<DhcpMessage>();
327 uint16_t length = 236;
331 ack->setXid(lease->xid);
333 ack->setBroadcast(
false);
334 ack->setCiaddr(lease->ip);
335 ack->setYiaddr(lease->ip);
337 ack->setChaddr(lease->mac);
340 ack->getOptionsForUpdate().setMessageType(
DHCPACK);
344 ack->getOptionsForUpdate().setSubnetMask(lease->subnetMask);
346 ack->getOptionsForUpdate().setRenewalTime(SimTime(
leaseTime * 0.5).trunc(SIMTIME_S));
348 ack->getOptionsForUpdate().setRebindingTime(SimTime(
leaseTime * 0.875).trunc(SIMTIME_S));
350 ack->getOptionsForUpdate().setLeaseTime(SimTime(
leaseTime).trunc(SIMTIME_S));
352 ack->getOptionsForUpdate().setRouterArraySize(1);
353 ack->getOptionsForUpdate().setRouter(0, lease->gateway);
354 length += (2 + 1 *
sizeof(uint32_t));
355 ack->getOptionsForUpdate().setDnsArraySize(1);
356 ack->getOptionsForUpdate().setDns(0, lease->dns);
357 length += (2 + 1 *
sizeof(uint32_t));
360 ack->getOptionsForUpdate().setServerIdentifier(
ie->
getProtocolData<Ipv4InterfaceData>()->getIPAddress());
366 ack->setChunkLength(
B(length));
368 pk->insertAtBack(ack);
371 lease->leaseTime = simTime();
385 Ipv4Address destAddr;
386 if (!packet->getGiaddr().isUnspecified())
387 destAddr = packet->getGiaddr();
388 else if (!packet->getCiaddr().isUnspecified())
389 destAddr = packet->getCiaddr();
390 else if (packet->getBroadcast())
Referenced by processDhcpMessage().
◆ sendNak()
| void inet::DhcpServer::sendNak |
( |
const Ptr< const DhcpMessage > & |
dhcpMsg | ) |
|
|
protectedvirtual |
286 Packet *pk =
new Packet(
"DHCPNAK");
287 const auto& nak = makeShared<DhcpMessage>();
289 uint16_t length = 236;
293 nak->setXid(msg->getXid());
295 nak->setBroadcast(msg->getBroadcast());
296 nak->setGiaddr(msg->getGiaddr());
297 nak->setChaddr(msg->getChaddr());
298 nak->getOptionsForUpdate().setServerIdentifier(
ie->
getProtocolData<Ipv4InterfaceData>()->getIPAddress());
300 nak->getOptionsForUpdate().setMessageType(
DHCPNAK);
306 nak->setChunkLength(
B(length));
308 pk->insertAtBack(nak);
315 if (!msg->getGiaddr().isUnspecified())
316 destAddr = msg->getGiaddr();
Referenced by processDhcpMessage().
◆ sendOffer()
403 EV_INFO <<
"Offering " << *lease << endl;
405 Packet *pk =
new Packet(
"DHCPOFFER");
406 const auto& offer = makeShared<DhcpMessage>();
408 uint16_t length = 236;
412 offer->setXid(lease->xid);
414 offer->setBroadcast(
false);
416 offer->setYiaddr(lease->ip);
417 offer->setGiaddr(lease->gateway);
419 offer->setChaddr(lease->mac);
422 offer->getOptionsForUpdate().setMessageType(
DHCPOFFER);
426 offer->getOptionsForUpdate().setSubnetMask(lease->subnetMask);
428 offer->getOptionsForUpdate().setRenewalTime(SimTime(
leaseTime * 0.5).trunc(SIMTIME_S));
430 offer->getOptionsForUpdate().setRebindingTime(SimTime(
leaseTime * 0.875).trunc(SIMTIME_S));
432 offer->getOptionsForUpdate().setLeaseTime(SimTime(
leaseTime).trunc(SIMTIME_S));
434 offer->getOptionsForUpdate().setRouterArraySize(1);
435 offer->getOptionsForUpdate().setRouter(0, lease->gateway);
436 length += (2 + 1 *
sizeof(uint32_t));
437 offer->getOptionsForUpdate().setDnsArraySize(1);
438 offer->getOptionsForUpdate().setDns(0, lease->dns);
439 length += (2 + 1 *
sizeof(uint32_t));
442 offer->getOptionsForUpdate().setServerIdentifier(
ie->
getProtocolData<Ipv4InterfaceData>()->getIPAddress());
448 offer->setChunkLength(
B(length));
451 lease->leaseTime = simTime();
452 pk->insertAtBack(offer);
466 Ipv4Address destAddr;
467 if (!packet->getGiaddr().isUnspecified())
468 destAddr = packet->getGiaddr();
469 else if (!packet->getCiaddr().isUnspecified())
470 destAddr = packet->getCiaddr();
471 else if (packet->getBroadcast())
Referenced by processDhcpMessage().
◆ sendToUDP()
| void inet::DhcpServer::sendToUDP |
( |
Packet * |
msg, |
|
|
int |
srcPort, |
|
|
const L3Address & |
destAddr, |
|
|
int |
destPort |
|
) |
| |
|
protectedvirtual |
◆ socketClosed()
| void inet::DhcpServer::socketClosed |
( |
UdpSocket * |
socket | ) |
|
|
overrideprotectedvirtual |
◆ socketDataArrived()
| void inet::DhcpServer::socketDataArrived |
( |
UdpSocket * |
socket, |
|
|
Packet * |
packet |
|
) |
| |
|
overrideprotectedvirtual |
◆ socketErrorArrived()
Notifies about error indication arrival, indication ownership is transferred to the callee.
Implements inet::UdpSocket::ICallback.
133 EV_WARN <<
"Unknown message '" << indication->getName() <<
"', kind = " << indication->getKind() <<
", discarding it." << endl;
◆ clientPort
| int inet::DhcpServer::clientPort = -1 |
|
protected |
◆ gateway
◆ ie
Referenced by chooseInterface(), DhcpServer(), handleCrashOperation(), handleStartOperation(), handleStopOperation(), openSocket(), processDhcpMessage(), receiveSignal(), sendAck(), sendNak(), sendOffer(), and sendToUDP().
◆ ipAddressStart
◆ leased
◆ leaseTime
| unsigned int inet::DhcpServer::leaseTime = 0 |
|
protected |
◆ maxNumOfClients
| unsigned int inet::DhcpServer::maxNumOfClients = 0 |
|
protected |
◆ numReceived
| int inet::DhcpServer::numReceived = 0 |
|
protected |
◆ numSent
| int inet::DhcpServer::numSent = 0 |
|
protected |
◆ serverPort
| int inet::DhcpServer::serverPort = -1 |
|
protected |
◆ socket
◆ startTime
| simtime_t inet::DhcpServer::startTime |
|
protected |
◆ startTimer
| cMessage* inet::DhcpServer::startTimer = nullptr |
|
protected |
◆ subnetMask
The documentation for this class was generated from the following files:
void setOutputGate(cGate *toUdp)
Sets the gate on which to send to UDP.
Definition: UdpSocket.h:117
virtual void sendToUDP(Packet *msg, int srcPort, const L3Address &destAddr, int destPort)
Definition: DhcpServer.cc:536
uint32_t getInt() const
Returns the address as an uint32_t in host byte order (e.g.
Definition: Ipv4Address.h:186
State operationalState
Definition: OperationalMixin.h:23
virtual bool isUp() const
utility functions
Definition: OperationalMixin.h:66
@ START_DHCP
Definition: DhcpServer.h:31
void bind(int localPort)
Bind the socket to a local port number.
Definition: UdpSocket.cc:34
void sendTo(Packet *msg, L3Address destAddr, int destPort)
Sends a data packet to the given address and port.
Definition: UdpSocket.cc:69
@ DHCPACK
Definition: DhcpMessage_m.h:88
virtual void sendAck(DhcpLease *lease, const Ptr< const DhcpMessage > &dhcpMsg)
Definition: DhcpServer.cc:320
virtual void sendOffer(DhcpLease *lease, const Ptr< const DhcpMessage > &dhcpMsg)
Definition: DhcpServer.cc:401
cModule * getContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:40
virtual void initialize(int stage) override
Definition: OperationalMixinImpl.h:26
unsigned int maxNumOfClients
Definition: DhcpServer.h:41
removed InterfaceReq
Definition: IUdp-gates.txt:11
virtual void destroy() override
Notify the protocol that the owner of ISocket has destroyed the socket.
Definition: UdpSocket.cc:98
const InterfaceProtocolData * getProtocolData(int index) const
Returns the protocol data at the given index.
Definition: NetworkInterface.h:287
@ DHCPDISCOVER
Definition: DhcpMessage_m.h:84
simtime_t startTime
Definition: DhcpServer.h:49
int serverPort
Definition: DhcpServer.h:37
void setCallback(ICallback *cb)
Sets a callback object, to be used with processMessage().
Definition: UdpSocket.cc:338
@ DHCPOFFER
Definition: DhcpMessage_m.h:85
virtual DhcpLease * getLeaseByMac(MacAddress mac)
Definition: DhcpServer.cc:482
static const Ipv4Address ALLONES_ADDRESS
255.255.255.255
Definition: Ipv4Address.h:94
simsignal_t interfaceDeletedSignal
Definition: Simsignals.cc:31
intscale< b, 1, 8 > B
Definition: Units.h:1168
int getInterfaceId() const
Definition: NetworkInterface.h:232
int numSent
Definition: DhcpServer.h:35
virtual void processMessage(cMessage *msg) override
Examines the message, takes ownership, and updates socket state.
Definition: UdpSocket.cc:343
static bool maskedAddrAreEqual(const Ipv4Address &addr1, const Ipv4Address &addr2, const Ipv4Address &netmask)
Test if the masked addresses (ie the mask is applied to addr1 and addr2) are equal.
Definition: Ipv4Address.cc:249
Ipv4Address ipAddressStart
Definition: DhcpServer.h:45
NetworkInterface * ie
Definition: DhcpServer.h:47
@ DHCPNAK
Definition: DhcpMessage_m.h:89
INET_API InitStage INITSTAGE_LOCAL
Initialization of local state that don't use or affect other modules includes:
virtual void close() override
Unbinds the socket.
Definition: UdpSocket.cc:87
#define NUM_INIT_STAGES
Definition: InitStageRegistry.h:73
virtual DhcpLease * getAvailableLease(Ipv4Address requestedAddress, const MacAddress &clientMAC)
Definition: DhcpServer.cc:497
double max(const double a, const double b)
Returns the maximum of a and b.
Definition: SctpAssociation.h:266
UdpSocket socket
Definition: DhcpServer.h:48
DhcpLeased leased
Definition: DhcpServer.h:33
virtual bool isOpen() const override
Definition: UdpSocket.h:293
void setBroadcast(bool broadcast)
Set the Broadcast option on the UDP socket.
Definition: UdpSocket.cc:139
Ipv4Address gateway
Definition: DhcpServer.h:44
INET_API InitStage INITSTAGE_APPLICATION_LAYER
Initialization of applications.
virtual void delayActiveOperationFinish(simtime_t timeout)
Definition: OperationalMixinImpl.h:161
Ipv4Address subnetMask
Definition: DhcpServer.h:43
virtual void openSocket()
Definition: DhcpServer.cc:61
virtual void startActiveOperationExtraTimeOrFinish(simtime_t extraTime)
Definition: OperationalMixinImpl.h:179
virtual NetworkInterface * chooseInterface()
Definition: DhcpServer.cc:85
#define Enter_Method(...)
Definition: SelfDoc.h:71
@ DHCPREQUEST
Definition: DhcpMessage_m.h:86
virtual void sendNak(const Ptr< const DhcpMessage > &dhcpMsg)
Definition: DhcpServer.cc:283
@ BOOTREQUEST
Definition: DhcpMessage_m.h:60
int numReceived
Definition: DhcpServer.h:36
@ ADDR_IPv4
Definition: L3AddressResolver.h:70
@ BOOTREPLY
Definition: DhcpMessage_m.h:61
virtual void processDhcpMessage(Packet *packet)
Definition: DhcpServer.cc:152
bool containsKey(const std::map< K, V, _C > &m, const Tk &a)
Definition: stlutils.h:80
cMessage * startTimer
Definition: DhcpServer.h:50
unsigned int leaseTime
Definition: DhcpServer.h:42
virtual void handleSelfMessages(cMessage *msg)
Definition: DhcpServer.cc:143
int clientPort
Definition: DhcpServer.h:38