Skip to content

Feature: implement DHCP options provider and parser #1244

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
39 changes: 30 additions & 9 deletions libraries/Ethernet/Dhcp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,10 +242,16 @@ void DhcpClass::send_DHCP_MESSAGE(uint8_t messageType, uint16_t secondsElapsed)
buffer[5] = domainName;
buffer[6] = dhcpT1value;
buffer[7] = dhcpT2value;
buffer[8] = endOption;


//put data in W5100 transmit buffer
_dhcpUdpSocket.write(buffer, 9);
_dhcpUdpSocket.write(buffer, 8);

if (_optionProvider != NULL) {
// If we have a custom option provider - pass the socket to it.
(*_optionProvider)(messageType, &_dhcpUdpSocket);
}

_dhcpUdpSocket.write(endOption);

_dhcpUdpSocket.endPacket();
}
Expand All @@ -254,6 +260,7 @@ uint8_t DhcpClass::parseDHCPResponse(unsigned long responseTimeout, uint32_t& tr
{
uint8_t type = 0;
uint8_t opt_len = 0;
uint8_t optionType = 0;

unsigned long startTime = millis();

Expand Down Expand Up @@ -291,7 +298,8 @@ uint8_t DhcpClass::parseDHCPResponse(unsigned long responseTimeout, uint32_t& tr

while (_dhcpUdpSocket.available() > 0)
{
switch (_dhcpUdpSocket.read())
optionType = _dhcpUdpSocket.read();
switch (optionType)
{
case endOption :
break;
Expand Down Expand Up @@ -364,11 +372,16 @@ uint8_t DhcpClass::parseDHCPResponse(unsigned long responseTimeout, uint32_t& tr
break;

default :
opt_len = _dhcpUdpSocket.read();
// Skip over the rest of this option
while (opt_len--)
{
_dhcpUdpSocket.read();
if (_optionParser != NULL) {
// If we have a custom option parser - pass the value to it.
(*_optionParser)(optionType, &_dhcpUdpSocket);
} else {
opt_len = _dhcpUdpSocket.read();
// Skip over the rest of this option
while (opt_len--)
{
_dhcpUdpSocket.read();
}
}
break;
}
Expand Down Expand Up @@ -478,3 +491,11 @@ void DhcpClass::printByte(char * buf, uint8_t n ) {
*str-- = c < 10 ? c + '0' : c + 'A' - 10;
} while(n);
}

void DhcpClass::setOptionParser(DhcpOptionParser* parser) {
_optionParser = parser;
}

void DhcpClass::setOptionProvider(DhcpOptionProvider* provider) {
_optionProvider = provider;
}
12 changes: 11 additions & 1 deletion libraries/Ethernet/Dhcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ enum
dhcpMaxMsgSize = 57,*/
dhcpT1value = 58,
dhcpT2value = 59,
/*dhcpClassIdentifier = 60,*/
dhcpClassIdentifier = 60,
dhcpClientIdentifier = 61,
endOption = 255
};
Expand All @@ -136,6 +136,9 @@ typedef struct _RIP_MSG_FIXED
uint8_t chaddr[6];
}RIP_MSG_FIXED;

typedef void (DhcpOptionParser)(uint8_t optionType, EthernetUDP *client);
typedef void (DhcpOptionProvider)(uint8_t messageType, EthernetUDP *client);

class DhcpClass {
private:
uint32_t _dhcpInitialTransactionId;
Expand All @@ -156,6 +159,8 @@ class DhcpClass {
unsigned long _secTimeout;
uint8_t _dhcp_state;
EthernetUDP _dhcpUdpSocket;
DhcpOptionProvider* _optionProvider;
DhcpOptionParser* _optionParser;

int request_DHCP_lease();
void reset_DHCP_lease();
Expand All @@ -165,6 +170,8 @@ class DhcpClass {

uint8_t parseDHCPResponse(unsigned long responseTimeout, uint32_t& transactionId);
public:
DhcpClass() : _optionParser(NULL), _optionProvider(NULL) {};

IPAddress getLocalIp();
IPAddress getSubnetMask();
IPAddress getGatewayIp();
Expand All @@ -173,6 +180,9 @@ class DhcpClass {

int beginWithDHCP(uint8_t *, unsigned long timeout = 60000, unsigned long responseTimeout = 4000);
int checkLease();

void setOptionParser(DhcpOptionParser* optionParser);
void setOptionProvider(DhcpOptionProvider* optionProvider);
};

#endif
9 changes: 7 additions & 2 deletions libraries/Ethernet/Ethernet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ uint8_t EthernetClass::_state[MAX_SOCK_NUM] = {
uint16_t EthernetClass::_server_port[MAX_SOCK_NUM] = {
0, 0, 0, 0 };

int EthernetClass::begin(uint8_t *mac_address)
int EthernetClass::begin(uint8_t *mac_address, DhcpOptionParser* optionParser, DhcpOptionProvider* optionProvider)
{
static DhcpClass s_dhcp;
_dhcp = &s_dhcp;

_dhcp->setOptionParser(optionParser);
_dhcp->setOptionProvider(optionProvider);

// Initialise the basic info
W5100.init();
Expand All @@ -34,6 +35,10 @@ int EthernetClass::begin(uint8_t *mac_address)
return ret;
}

int EthernetClass::begin(uint8_t *mac_address) {
return begin(mac_address, NULL, NULL);
}

void EthernetClass::begin(uint8_t *mac_address, IPAddress local_ip)
{
// Assume the DNS server will be the machine on the same network as the local IP
Expand Down
1 change: 1 addition & 0 deletions libraries/Ethernet/Ethernet.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class EthernetClass {
// configuration through DHCP.
// Returns 0 if the DHCP configuration failed, and 1 if it succeeded
int begin(uint8_t *mac_address);
int begin(uint8_t *mac_address, DhcpOptionParser* parser, DhcpOptionProvider* provider);
void begin(uint8_t *mac_address, IPAddress local_ip);
void begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server);
void begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server, IPAddress gateway);
Expand Down