diff --git a/examples/DhcpHostname/DhcpHostname.ino b/examples/DhcpHostname/DhcpHostname.ino new file mode 100644 index 00000000..723d9873 --- /dev/null +++ b/examples/DhcpHostname/DhcpHostname.ino @@ -0,0 +1,47 @@ +/* + 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[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED +}; + +// Hostname, max length 12 characters, ASCII only +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..930aacee 100644 --- a/src/Dhcp.cpp +++ b/src/Dhcp.cpp @@ -6,7 +6,7 @@ #include "Dhcp.h" #include "utility/w5100.h" -int DhcpClass::beginWithDHCP(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout) +int DhcpClass::beginWithDHCP(uint8_t *mac, const char *hostname, unsigned long timeout, unsigned long responseTimeout) { _dhcpLeaseTime=0; _dhcpT1=0; @@ -18,6 +18,21 @@ int DhcpClass::beginWithDHCP(uint8_t *mac, unsigned long timeout, unsigned long memset(_dhcpMacAddr, 0, 6); reset_DHCP_lease(); + if (NULL == hostname) + { + 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'; + } + 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 +203,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 + strlcpy((char*)&(buffer[18]), _dhcpHostname, MAX_HOST_NAME_LENGTH + 1); //put data in W5100 transmit buffer _dhcpUdpSocket.write(buffer, 30); @@ -420,6 +431,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..f19977ea 100644 --- a/src/Ethernet.cpp +++ b/src/Ethernet.cpp @@ -26,7 +26,7 @@ IPAddress EthernetClass::_dnsServerAddress; DhcpClass* EthernetClass::_dhcp = NULL; -int EthernetClass::begin(uint8_t *mac, 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; @@ -39,7 +39,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 +230,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..1f804ee7 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" @@ -79,7 +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 = nullptr, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); static int maintain(); static EthernetLinkStatus linkStatus(); static EthernetHardwareStatus hardwareStatus(); @@ -96,6 +97,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 +298,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 +313,9 @@ 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 * = nullptr, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); int checkLease(); };