From 0f48f5ba07eec363c5010415e40e2a2ff9089880 Mon Sep 17 00:00:00 2001 From: Stijn Hoop Date: Wed, 21 Nov 2018 10:16:33 +0100 Subject: [PATCH 1/2] Add DHCP hostname option --- examples/DhcpHostname/DhcpHostname.ino | 46 ++++++++++++++++++++++++++ src/Dhcp.cpp | 32 ++++++++++++++---- src/Dhcp.h | 3 +- src/Ethernet.cpp | 12 +++++-- src/Ethernet.h | 6 ++++ 5 files changed, 90 insertions(+), 9 deletions(-) create mode 100644 examples/DhcpHostname/DhcpHostname.ino diff --git a/examples/DhcpHostname/DhcpHostname.ino b/examples/DhcpHostname/DhcpHostname.ino new file mode 100644 index 00000000..cea9ce88 --- /dev/null +++ b/examples/DhcpHostname/DhcpHostname.ino @@ -0,0 +1,46 @@ +/* + DHCP-based hostname printer + + Circuit: + Ethernet shield attached to pins 10, 11, 12, 13 + + created 10 Dec 2016 + by mykh +*/ + +#include + +// MAC address +byte mac[] = { + 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 +}; +// Hostname +const char* hostname = "myarduino"; + +// Initialize the Ethernet client library +EthernetClient client; + +void setup() { + // Open serial communications and wait for port to open: + Serial.begin(9600); + // this check is only needed on the Leonardo: + while (!Serial) { + ; + } + + // start the Ethernet connection: + Serial.println("Setup..."); + while (Ethernet.begin(mac, hostname) == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + delay(10000); + Serial.println("Reconnecting..."); + } + + // print your hostname: + Serial.print("My Hostname: "); + Serial.println(Ethernet.hostname()); +} + +void loop() { + Ethernet.maintain(); +} diff --git a/src/Dhcp.cpp b/src/Dhcp.cpp index 2bfd584b..e909963f 100644 --- a/src/Dhcp.cpp +++ b/src/Dhcp.cpp @@ -7,6 +7,11 @@ #include "utility/w5100.h" int DhcpClass::beginWithDHCP(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout) +{ + return beginWithDHCP(mac, NULL, timeout, responseTimeout); +} + +int DhcpClass::beginWithDHCP(uint8_t *mac, const char *hostname, unsigned long timeout, unsigned long responseTimeout) { _dhcpLeaseTime=0; _dhcpT1=0; @@ -18,6 +23,20 @@ int DhcpClass::beginWithDHCP(uint8_t *mac, unsigned long timeout, unsigned long memset(_dhcpMacAddr, 0, 6); reset_DHCP_lease(); + if (NULL == hostname) + { + strcpy(_dhcpHostname, HOST_NAME); + int offset = strlen(HOST_NAME); + printByte((char*)&(_dhcpHostname[offset + 0]), mac[3]); + printByte((char*)&(_dhcpHostname[offset + 2]), mac[4]); + printByte((char*)&(_dhcpHostname[offset + 4]), mac[5]); + _dhcpHostname[offset + 6] = 0; + } + else + { + strlcpy(_dhcpHostname, hostname, MAX_HOST_NAME_LENGTH + 1); + } + memcpy((void*)_dhcpMacAddr, (void*)mac, 6); _dhcp_state = STATE_DHCP_START; return request_DHCP_lease(); @@ -188,12 +207,8 @@ void DhcpClass::send_DHCP_MESSAGE(uint8_t messageType, uint16_t secondsElapsed) // OPT - host name buffer[16] = hostName; - buffer[17] = strlen(HOST_NAME) + 6; // length of hostname + last 3 bytes of mac address - strcpy((char*)&(buffer[18]), HOST_NAME); - - printByte((char*)&(buffer[24]), _dhcpMacAddr[3]); - printByte((char*)&(buffer[26]), _dhcpMacAddr[4]); - printByte((char*)&(buffer[28]), _dhcpMacAddr[5]); + buffer[17] = strlen(_dhcpHostname); // length of hostname + strcpy((char*)&(buffer[18]), _dhcpHostname); //put data in W5100 transmit buffer _dhcpUdpSocket.write(buffer, 30); @@ -420,6 +435,11 @@ IPAddress DhcpClass::getDnsServerIp() return IPAddress(_dhcpDnsServerIp); } +const char* DhcpClass::getHostname() const +{ + return _dhcpHostname; +} + void DhcpClass::printByte(char * buf, uint8_t n ) { char *str = &buf[1]; diff --git a/src/Dhcp.h b/src/Dhcp.h index 43ec4f85..37199f15 100644 --- a/src/Dhcp.h +++ b/src/Dhcp.h @@ -42,7 +42,8 @@ #define MAGIC_COOKIE 0x63825363 #define MAX_DHCP_OPT 16 -#define HOST_NAME "WIZnet" +#define HOST_NAME "WIZnet" //default host name +#define MAX_HOST_NAME_LENGTH 12 #define DEFAULT_LEASE (900) //default lease time in seconds #define DHCP_CHECK_NONE (0) diff --git a/src/Ethernet.cpp b/src/Ethernet.cpp index 658bd642..4ae4d7c0 100644 --- a/src/Ethernet.cpp +++ b/src/Ethernet.cpp @@ -27,6 +27,11 @@ IPAddress EthernetClass::_dnsServerAddress; DhcpClass* EthernetClass::_dhcp = NULL; int EthernetClass::begin(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout) +{ + begin(mac, NULL, timeout, responseTimeout); +} + +int EthernetClass::begin(uint8_t *mac, const char* hostname, unsigned long timeout, unsigned long responseTimeout) { static DhcpClass s_dhcp; _dhcp = &s_dhcp; @@ -39,7 +44,7 @@ int EthernetClass::begin(uint8_t *mac, unsigned long timeout, unsigned long resp SPI.endTransaction(); // Now try to get our config info from a DHCP server - int ret = _dhcp->beginWithDHCP(mac, timeout, responseTimeout); + int ret = _dhcp->beginWithDHCP(mac, hostname, timeout, responseTimeout); if (ret == 1) { // We've successfully found a DHCP server and got our configuration // info, so set things accordingly @@ -230,7 +235,10 @@ void EthernetClass::setRetransmissionCount(uint8_t num) SPI.endTransaction(); } - +const char* EthernetClass::hostname() const +{ + return _dhcp ? _dhcp->getHostname() : ""; +} diff --git a/src/Ethernet.h b/src/Ethernet.h index 376e6c59..2e4f5f63 100644 --- a/src/Ethernet.h +++ b/src/Ethernet.h @@ -50,6 +50,7 @@ #include #include "Client.h" +#include "Dhcp.h" #include "Server.h" #include "Udp.h" @@ -80,6 +81,7 @@ class EthernetClass { // gain the rest of the configuration through DHCP. // Returns 0 if the DHCP configuration failed, and 1 if it succeeded static int begin(uint8_t *mac, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); + static int begin(uint8_t *mac, const char *hostname, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); static int maintain(); static EthernetLinkStatus linkStatus(); static EthernetHardwareStatus hardwareStatus(); @@ -96,6 +98,7 @@ class EthernetClass { static IPAddress subnetMask(); static IPAddress gatewayIP(); static IPAddress dnsServerIP() { return _dnsServerAddress; } + const char* hostname() const; void setMACAddress(const uint8_t *mac_address); void setLocalIP(const IPAddress local_ip); @@ -296,6 +299,7 @@ class DhcpClass { unsigned long _lastCheckLeaseMillis; uint8_t _dhcp_state; EthernetUDP _dhcpUdpSocket; + char _dhcpHostname[MAX_HOST_NAME_LENGTH + 1]; int request_DHCP_lease(); void reset_DHCP_lease(); @@ -310,8 +314,10 @@ class DhcpClass { IPAddress getGatewayIp(); IPAddress getDhcpServerIp(); IPAddress getDnsServerIp(); + const char* getHostname() const; int beginWithDHCP(uint8_t *, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); + int beginWithDHCP(uint8_t *, const char *, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); int checkLease(); }; From adbe3fcc25b61d678373e4fb5e9904636669fea5 Mon Sep 17 00:00:00 2001 From: Stijn Hoop Date: Wed, 1 Jul 2020 22:05:36 +0200 Subject: [PATCH 2/2] Fixes after review --- examples/DhcpHostname/DhcpHostname.ino | 5 +++-- src/Dhcp.cpp | 14 +++++--------- src/Ethernet.cpp | 7 +------ src/Ethernet.h | 6 ++---- 4 files changed, 11 insertions(+), 21 deletions(-) diff --git a/examples/DhcpHostname/DhcpHostname.ino b/examples/DhcpHostname/DhcpHostname.ino index cea9ce88..723d9873 100644 --- a/examples/DhcpHostname/DhcpHostname.ino +++ b/examples/DhcpHostname/DhcpHostname.ino @@ -12,9 +12,10 @@ // MAC address byte mac[] = { - 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 + 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; -// Hostname + +// Hostname, max length 12 characters, ASCII only const char* hostname = "myarduino"; // Initialize the Ethernet client library diff --git a/src/Dhcp.cpp b/src/Dhcp.cpp index e909963f..930aacee 100644 --- a/src/Dhcp.cpp +++ b/src/Dhcp.cpp @@ -6,11 +6,6 @@ #include "Dhcp.h" #include "utility/w5100.h" -int DhcpClass::beginWithDHCP(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout) -{ - return beginWithDHCP(mac, NULL, timeout, responseTimeout); -} - int DhcpClass::beginWithDHCP(uint8_t *mac, const char *hostname, unsigned long timeout, unsigned long responseTimeout) { _dhcpLeaseTime=0; @@ -25,12 +20,13 @@ int DhcpClass::beginWithDHCP(uint8_t *mac, const char *hostname, unsigned long t if (NULL == hostname) { - strcpy(_dhcpHostname, HOST_NAME); - int offset = strlen(HOST_NAME); + strlcpy(_dhcpHostname, HOST_NAME, MAX_HOST_NAME_LENGTH - 5); + _dhcpHostname[MAX_HOST_NAME_LENGTH - 4] = '\0'; + int offset = strlen(_dhcpHostname); printByte((char*)&(_dhcpHostname[offset + 0]), mac[3]); printByte((char*)&(_dhcpHostname[offset + 2]), mac[4]); printByte((char*)&(_dhcpHostname[offset + 4]), mac[5]); - _dhcpHostname[offset + 6] = 0; + _dhcpHostname[offset + 6] = '\0'; } else { @@ -208,7 +204,7 @@ void DhcpClass::send_DHCP_MESSAGE(uint8_t messageType, uint16_t secondsElapsed) // OPT - host name buffer[16] = hostName; buffer[17] = strlen(_dhcpHostname); // length of hostname - strcpy((char*)&(buffer[18]), _dhcpHostname); + strlcpy((char*)&(buffer[18]), _dhcpHostname, MAX_HOST_NAME_LENGTH + 1); //put data in W5100 transmit buffer _dhcpUdpSocket.write(buffer, 30); diff --git a/src/Ethernet.cpp b/src/Ethernet.cpp index 4ae4d7c0..f19977ea 100644 --- a/src/Ethernet.cpp +++ b/src/Ethernet.cpp @@ -26,12 +26,7 @@ IPAddress EthernetClass::_dnsServerAddress; DhcpClass* EthernetClass::_dhcp = NULL; -int EthernetClass::begin(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout) -{ - begin(mac, NULL, timeout, responseTimeout); -} - -int EthernetClass::begin(uint8_t *mac, const char* hostname, unsigned long timeout, unsigned long responseTimeout) +int EthernetClass::begin(uint8_t *mac, const char *hostname, unsigned long timeout, unsigned long responseTimeout) { static DhcpClass s_dhcp; _dhcp = &s_dhcp; diff --git a/src/Ethernet.h b/src/Ethernet.h index 2e4f5f63..1f804ee7 100644 --- a/src/Ethernet.h +++ b/src/Ethernet.h @@ -80,8 +80,7 @@ class EthernetClass { // Initialise the Ethernet shield to use the provided MAC address and // gain the rest of the configuration through DHCP. // Returns 0 if the DHCP configuration failed, and 1 if it succeeded - static int begin(uint8_t *mac, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); - static int begin(uint8_t *mac, const char *hostname, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); + static int begin(uint8_t *mac, const char *hostname = nullptr, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); static int maintain(); static EthernetLinkStatus linkStatus(); static EthernetHardwareStatus hardwareStatus(); @@ -316,8 +315,7 @@ class DhcpClass { IPAddress getDnsServerIp(); const char* getHostname() const; - int beginWithDHCP(uint8_t *, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); - int beginWithDHCP(uint8_t *, const char *, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); + int beginWithDHCP(uint8_t *, const char * = nullptr, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); int checkLease(); };