Skip to content
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
95 changes: 95 additions & 0 deletions examples/DhcpCustomHostname/DhcpCustomHostname.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
DHCP with custom hostname

This sketch uses the DHCP extensions to the Ethernet library
to get an IP address via DHCP and print the address obtained.
using an Arduino WIZnet Ethernet shield.

It demonstrates how to set a custom hostname for the DHCP request.

Circuit:
Ethernet shield attached to pins 10, 11, 12, 13

created 14 December 2025
by Dmytro Lahoza
*/

#include <SPI.h>
#include <Ethernet.h>

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};

void setup() {
// You can use Ethernet.init(pin) to configure the CS pin
//Ethernet.init(10); // Most Arduino shields
//Ethernet.init(5); // MKR ETH Shield
//Ethernet.init(0); // Teensy 2.0
//Ethernet.init(20); // Teensy++ 2.0
//Ethernet.init(15); // ESP8266 with Adafruit FeatherWing Ethernet
//Ethernet.init(33); // ESP32 with Adafruit FeatherWing Ethernet

// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}

// Set the hostname for the DHCP request
Ethernet.setHostname("arduino-ethernet");

// start the Ethernet connection:
Serial.println("Initialize Ethernet with DHCP:");
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
} else if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Ethernet cable is not connected.");
}
// no point in carrying on, so do nothing forevermore:
while (true) {
delay(1);
}
}
// print your local IP address:
Serial.print("My IP address: ");
Serial.println(Ethernet.localIP());
}

void loop() {
switch (Ethernet.maintain()) {
case 1:
//renewed fail
Serial.println("Error: renewed fail");
break;

case 2:
//renewed success
Serial.println("Renewed success");
//print your local IP address:
Serial.print("My IP address: ");
Serial.println(Ethernet.localIP());
break;

case 3:
//rebind fail
Serial.println("Error: rebind fail");
break;

case 4:
//rebind success
Serial.println("Rebind success");
//print your local IP address:
Serial.print("My IP address: ");
Serial.println(Ethernet.localIP());
break;

default:
//nothing happened
break;
}
}
27 changes: 17 additions & 10 deletions src/Dhcp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,15 @@ void DhcpClass::presend_DHCP()
{
}

void DhcpClass::setCustomHostname(const char* name)
{
_dhcpHostname = name;
}

void DhcpClass::send_DHCP_MESSAGE(uint8_t messageType, uint16_t secondsElapsed)
{
uint8_t buffer[32];
memset(buffer, 0, 32);
uint8_t buffer[64];
memset(buffer, 0, 64);
IPAddress dest_addr(255, 255, 255, 255); // Broadcast address

if (_dhcpUdpSocket.beginPacket(dest_addr, DHCP_SERVER_PORT) == -1) {
Expand Down Expand Up @@ -153,14 +158,14 @@ void DhcpClass::send_DHCP_MESSAGE(uint8_t messageType, uint16_t secondsElapsed)
//put data in W5100 transmit buffer
_dhcpUdpSocket.write(buffer, 28);

memset(buffer, 0, 32); // clear local buffer
memset(buffer, 0, 64); // clear local buffer

memcpy(buffer, _dhcpMacAddr, 6); // chaddr

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

memset(buffer, 0, 32); // clear local buffer
memset(buffer, 0, 64); // clear local buffer

// leave zeroed out for sname && file
// put in W5100 transmit buffer x 6 (192 bytes)
Expand All @@ -187,16 +192,18 @@ void DhcpClass::send_DHCP_MESSAGE(uint8_t messageType, uint16_t secondsElapsed)
memcpy(buffer + 10, _dhcpMacAddr, 6);

// OPT - host name
const char* hostname = _dhcpHostname ? _dhcpHostname : HOST_NAME;
size_t hostnameLen = strlen(hostname);
buffer[16] = hostName;
buffer[17] = strlen(HOST_NAME) + 6; // length of hostname + last 3 bytes of mac address
strcpy((char*)&(buffer[18]), HOST_NAME);
buffer[17] = hostnameLen + 6; // length of hostname + last 3 bytes of mac address
strcpy((char*)&(buffer[18]), hostname);

printByte((char*)&(buffer[24]), _dhcpMacAddr[3]);
printByte((char*)&(buffer[26]), _dhcpMacAddr[4]);
printByte((char*)&(buffer[28]), _dhcpMacAddr[5]);
printByte((char*)&(buffer[18 + hostnameLen]), _dhcpMacAddr[3]);
printByte((char*)&(buffer[18 + hostnameLen + 2]), _dhcpMacAddr[4]);
printByte((char*)&(buffer[18 + hostnameLen + 4]), _dhcpMacAddr[5]);

//put data in W5100 transmit buffer
_dhcpUdpSocket.write(buffer, 30);
_dhcpUdpSocket.write(buffer, 18 + hostnameLen + 6);

if (messageType == DHCP_REQUEST) {
buffer[0] = dhcpRequestedIPaddr;
Expand Down
14 changes: 14 additions & 0 deletions src/Ethernet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,15 @@

IPAddress EthernetClass::_dnsServerAddress;
DhcpClass* EthernetClass::_dhcp = NULL;
char EthernetClass::_hostname[32] = {0};

int EthernetClass::begin(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout)
{
static DhcpClass s_dhcp;
_dhcp = &s_dhcp;
if (_hostname[0] != 0) {
_dhcp->setCustomHostname(_hostname);
}

// Initialise the basic info
if (W5100.init() == 0) return 0;
Expand Down Expand Up @@ -178,6 +182,16 @@ IPAddress EthernetClass::gatewayIP()
return ret;
}

void EthernetClass::setHostname(const char* hostname)
{
if (strlen(hostname) < 32) {
strcpy(_hostname, hostname);
if (_dhcp) {
_dhcp->setCustomHostname(_hostname);
}
}
}

void EthernetClass::setMACAddress(const uint8_t *mac_address)
{
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
Expand Down
4 changes: 4 additions & 0 deletions src/Ethernet.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class EthernetClass {
private:
static IPAddress _dnsServerAddress;
static DhcpClass* _dhcp;
static char _hostname[32];
public:
// Initialise the Ethernet shield to use the provided MAC address and
// gain the rest of the configuration through DHCP.
Expand All @@ -97,6 +98,7 @@ class EthernetClass {
static IPAddress gatewayIP();
static IPAddress dnsServerIP() { return _dnsServerAddress; }

void setHostname(const char* hostname);
void setMACAddress(const uint8_t *mac_address);
void setLocalIP(const IPAddress local_ip);
void setSubnetMask(const IPAddress subnet);
Expand Down Expand Up @@ -297,6 +299,7 @@ class DhcpClass {
unsigned long _lastCheckLeaseMillis;
uint8_t _dhcp_state;
EthernetUDP _dhcpUdpSocket;
const char *_dhcpHostname = NULL;

int request_DHCP_lease();
void reset_DHCP_lease();
Expand All @@ -311,6 +314,7 @@ class DhcpClass {
IPAddress getGatewayIp();
IPAddress getDhcpServerIp();
IPAddress getDnsServerIp();
void setCustomHostname(const char* name);

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