diff --git a/Dhcp.cpp b/Dhcp.cpp index c15fe83..09cc045 100644 --- a/Dhcp.cpp +++ b/Dhcp.cpp @@ -8,6 +8,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; @@ -20,6 +25,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(); @@ -202,12 +221,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); @@ -466,6 +481,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/Dhcp.h b/Dhcp.h index cc3cd35..e409957 100644 --- a/Dhcp.h +++ b/Dhcp.h @@ -44,8 +44,9 @@ #define MAGIC_COOKIE 0x63825363 #define MAX_DHCP_OPT 16 -#define HOST_NAME "ENC28J" -#define DEFAULT_LEASE (900) //default lease time in seconds +#define HOST_NAME "ENC28J" //default host name +#define MAX_HOST_NAME_LENGTH 12 +#define DEFAULT_LEASE (900) //default lease time in seconds #define DHCP_CHECK_NONE (0) #define DHCP_CHECK_RENEW_FAIL (1) @@ -156,6 +157,7 @@ class DhcpClass { unsigned long _secTimeout; uint8_t _dhcp_state; UIPUDP _dhcpUdpSocket; + char _dhcpHostname[MAX_HOST_NAME_LENGTH + 1]; int request_DHCP_lease(); void reset_DHCP_lease(); @@ -170,8 +172,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/UIPEthernet.cpp b/UIPEthernet.cpp index 91ec70a..5179594 100644 --- a/UIPEthernet.cpp +++ b/UIPEthernet.cpp @@ -57,6 +57,11 @@ UIPEthernetClass::UIPEthernetClass() #if UIP_UDP int UIPEthernetClass::begin(const uint8_t* mac) +{ + return begin(mac, NULL); +} + +UIPEthernetClass::begin(const uint8_t* mac, const char* hostname) { static DhcpClass s_dhcp; _dhcp = &s_dhcp; @@ -65,7 +70,7 @@ UIPEthernetClass::begin(const uint8_t* mac) init(mac); // Now try to get our config info from a DHCP server - int ret = _dhcp->beginWithDHCP((uint8_t*)mac); + int ret = _dhcp->beginWithDHCP((uint8_t*)mac, hostname); if(ret == 1) { // We've successfully found a DHCP server and got our configuration info, so set things @@ -160,6 +165,11 @@ IPAddress UIPEthernetClass::dnsServerIP() return _dnsServerAddress; } +const char* UIPEthernetClass::hostname() const +{ + return _dhcp ? _dhcp->getHostname() : ""; +} + void UIPEthernetClass::tick() { diff --git a/UIPEthernet.h b/UIPEthernet.h index c68d578..0330fdf 100644 --- a/UIPEthernet.h +++ b/UIPEthernet.h @@ -66,6 +66,7 @@ class UIPEthernetClass UIPEthernetClass(); int begin(const uint8_t* mac); + int begin(const uint8_t* mac, const char* hostname); void begin(const uint8_t* mac, IPAddress ip); void begin(const uint8_t* mac, IPAddress ip, IPAddress dns); void begin(const uint8_t* mac, IPAddress ip, IPAddress dns, IPAddress gateway); @@ -80,6 +81,7 @@ class UIPEthernetClass IPAddress subnetMask(); IPAddress gatewayIP(); IPAddress dnsServerIP(); + const char* hostname() const; private: static memhandle in_packet; diff --git a/examples/DhcpHostname/DhcpHostname.ino b/examples/DhcpHostname/DhcpHostname.ino new file mode 100644 index 0000000..4d4de10 --- /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(); +}