diff --git a/libraries/Ethernet/examples/DhcpHostname/DhcpHostname.ino b/libraries/Ethernet/examples/DhcpHostname/DhcpHostname.ino new file mode 100644 index 00000000000..cea9ce88e0c --- /dev/null +++ b/libraries/Ethernet/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/libraries/Ethernet/src/Dhcp.cpp b/libraries/Ethernet/src/Dhcp.cpp index 3702d73b64d..6d06f9ddb28 100644 --- a/libraries/Ethernet/src/Dhcp.cpp +++ b/libraries/Ethernet/src/Dhcp.cpp @@ -10,6 +10,11 @@ #include "utility/util.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; @@ -21,6 +26,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(); @@ -204,12 +223,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); @@ -459,6 +474,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]; buf[0]='0'; diff --git a/libraries/Ethernet/src/Dhcp.h b/libraries/Ethernet/src/Dhcp.h index 22900eade35..9fd42b70c44 100644 --- a/libraries/Ethernet/src/Dhcp.h +++ b/libraries/Ethernet/src/Dhcp.h @@ -44,7 +44,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) @@ -155,6 +156,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(); @@ -169,8 +171,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(); }; diff --git a/libraries/Ethernet/src/Ethernet.cpp b/libraries/Ethernet/src/Ethernet.cpp index 54cf8d64cb0..f44e0f2fb14 100644 --- a/libraries/Ethernet/src/Ethernet.cpp +++ b/libraries/Ethernet/src/Ethernet.cpp @@ -9,6 +9,11 @@ uint16_t EthernetClass::_server_port[MAX_SOCK_NUM] = { 0, 0, 0, 0 }; int EthernetClass::begin(uint8_t *mac_address, unsigned long timeout, unsigned long responseTimeout) +{ + return begin(mac_address, NULL, timeout, responseTimeout); +} + +int EthernetClass::begin(uint8_t *mac_address, const char *hostname, unsigned long timeout, unsigned long responseTimeout) { static DhcpClass s_dhcp; _dhcp = &s_dhcp; @@ -22,7 +27,7 @@ int EthernetClass::begin(uint8_t *mac_address, unsigned long timeout, unsigned l SPI.endTransaction(); // Now try to get our config info from a DHCP server - int ret = _dhcp->beginWithDHCP(mac_address, timeout, responseTimeout); + int ret = _dhcp->beginWithDHCP(mac_address, hostname, timeout, responseTimeout); if(ret == 1) { // We've successfully found a DHCP server and got our configuration info, so set things @@ -133,4 +138,9 @@ IPAddress EthernetClass::dnsServerIP() return _dnsServerAddress; } +const char* EthernetClass::hostname() const +{ + return _dhcp ? _dhcp->getHostname() : ""; +} + EthernetClass Ethernet; diff --git a/libraries/Ethernet/src/Ethernet.h b/libraries/Ethernet/src/Ethernet.h index 083df4427b0..3e61b4b9434 100644 --- a/libraries/Ethernet/src/Ethernet.h +++ b/libraries/Ethernet/src/Ethernet.h @@ -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, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); + int begin(uint8_t *mac_address, const char *hostname, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); 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); @@ -31,6 +32,7 @@ class EthernetClass { IPAddress subnetMask(); IPAddress gatewayIP(); IPAddress dnsServerIP(); + const char* hostname() const; friend class EthernetClient; friend class EthernetServer;