diff --git a/dhcp.cpp b/dhcp.cpp index 36b9fb1..a40060a 100644 --- a/dhcp.cpp +++ b/dhcp.cpp @@ -81,7 +81,7 @@ typedef struct { byte op, htype, hlen, hops; uint32_t xid; uint16_t secs, flags; - byte ciaddr[4], yiaddr[4], siaddr[4], giaddr[4]; + byte ciaddr[IP_LEN], yiaddr[IP_LEN], siaddr[IP_LEN], giaddr[IP_LEN]; byte chaddr[16], sname[64], file[128]; // options } DHCPdata; @@ -120,6 +120,12 @@ static void addBytes (byte len, const byte* data) { addToBuf(*data++); } +static void addOption (byte opt, byte len, const byte* data) { + addToBuf(opt); + addToBuf(len); + addBytes(len, data); +} + // Main DHCP sending function @@ -139,15 +145,20 @@ static void addBytes (byte len, const byte* data) { // ---------------------------------------------------------- // options used (both send/receive) -// 12 Host Name Option -// 50 Requested IP Address -// 51 IP Address Lease Time -// 53 DHCP message type -// 54 Server-identifier -// 55 Parameter request list -// 58 Renewal (T1) Time Value -// 61 Client-identifier -// 255 End +#define DHCP_OPT_SUBNET_MASK 1 +#define DHCP_OPT_ROUTERS 3 +#define DHCP_OPT_DOMAIN_NAME_SERVERS 6 +#define DHCP_OPT_HOSTNAME 12 +#define DHCP_OPT_REQUESTED_ADDRESS 50 +#define DHCP_OPT_LEASE_TIME 51 +#define DHCP_OPT_MESSAGE_TYPE 53 +#define DHCP_OPT_SERVER_IDENTIFIER 54 +#define DHCP_OPT_PARAMETER_REQUEST_LIST 55 +#define DHCP_OPT_RENEWAL_TIME 58 +#define DHCP_OPT_CLIENT_IDENTIFIER 61 +#define DHCP_OPT_END 255 + +#define DHCP_HTYPE_ETHER 1 static void send_dhcp_message(uint8_t *requestip) { @@ -175,48 +186,41 @@ static void send_dhcp_message(uint8_t *requestip) { // options defined as option, length, value bufPtr = gPB + UDP_DATA_P + sizeof( DHCPdata ); - // DHCP magic cookie, followed by message type - static byte cookie[] = { 99, 130, 83, 99, 53, 1 }; + // DHCP magic cookie + static const byte cookie[] PROGMEM = { 0x63,0x82,0x53,0x63 }; addBytes(sizeof cookie, cookie); - // addToBuf(53); // DHCP_STATE_SELECTING, DHCP_STATE_REQUESTING - // addToBuf(1); // Length + addToBuf(DHCP_OPT_MESSAGE_TYPE); // DHCP_STATE_SELECTING, DHCP_STATE_REQUESTING + addToBuf(1); // Length addToBuf(dhcpState == DHCP_STATE_INIT ? DHCP_DISCOVER : DHCP_REQUEST); // Client Identifier Option, this is the client mac address - addToBuf(61); // Client identifier - addToBuf(7); // Length - addToBuf(0x01); // Ethernet - addBytes(6, EtherCard::mymac); + addToBuf(DHCP_OPT_CLIENT_IDENTIFIER); + addToBuf(1 + ETH_LEN); // Length (hardware type + client MAC) + addToBuf(DHCP_HTYPE_ETHER); + addBytes(ETH_LEN, EtherCard::mymac); if (hostname[0]) { - byte hostnamelen = strlen(hostname); - addToBuf(12); // Host name Option - addToBuf(hostnamelen); - addBytes(hostnamelen, (byte*) hostname); + addOption(DHCP_OPT_HOSTNAME, strlen(hostname), (byte*) hostname); } if (requestip != NULL) { - addToBuf(50); // Request IP address - addToBuf(4); - addBytes(4, requestip); - - addToBuf(54); // DHCP Server IP address - addToBuf(4); - addBytes(4, EtherCard::dhcpip); + addOption(DHCP_OPT_REQUESTED_ADDRESS, IP_LEN, requestip); + addOption(DHCP_OPT_SERVER_IDENTIFIER, IP_LEN, EtherCard::dhcpip); } // Additional info in parameter list - minimal list for what we need byte len = 3; if (dhcpCustomOptionNum) len++; - addToBuf(55); // Parameter request list + addToBuf(DHCP_OPT_PARAMETER_REQUEST_LIST); addToBuf(len); // Length - addToBuf(1); // Subnet mask - addToBuf(3); // Route/Gateway - addToBuf(6); // DNS Server + addToBuf(DHCP_OPT_SUBNET_MASK); + addToBuf(DHCP_OPT_ROUTERS); + addToBuf(DHCP_OPT_DOMAIN_NAME_SERVERS); if (dhcpCustomOptionNum) addToBuf(dhcpCustomOptionNum); // Custom option - addToBuf(255); // end option + + addToBuf(DHCP_OPT_END); // packet size will be under 300 bytes EtherCard::udpTransmit((bufPtr - gPB) - UDP_DATA_P); @@ -229,12 +233,12 @@ static void process_dhcp_offer(uint16_t len, uint8_t *offeredip) { // Offered IP address is in yiaddr EtherCard::copyIp(offeredip, dhcpPtr->yiaddr); - // Search for the + // Search for the server IP byte *ptr = (byte*) (dhcpPtr + 1) + 4; do { byte option = *ptr++; byte optionLen = *ptr++; - if (option == 54) { + if (option == DHCP_OPT_SERVER_IDENTIFIER) { EtherCard::copyIp(EtherCard::dhcpip, ptr); break; } @@ -256,25 +260,25 @@ static void process_dhcp_ack(uint16_t len) { byte option = *ptr++; byte optionLen = *ptr++; switch (option) { - case 1: + case DHCP_OPT_SUBNET_MASK: EtherCard::copyIp(EtherCard::netmask, ptr); break; - case 3: + case DHCP_OPT_ROUTERS: EtherCard::copyIp(EtherCard::gwip, ptr); break; - case 6: + case DHCP_OPT_DOMAIN_NAME_SERVERS: EtherCard::copyIp(EtherCard::dnsip, ptr); break; - case 51: - case 58: - leaseTime = 0; // option 58 = Renewal Time, 51 = Lease Time + case DHCP_OPT_LEASE_TIME: + case DHCP_OPT_RENEWAL_TIME: + leaseTime = 0; for (byte i = 0; i<4; i++) leaseTime = (leaseTime << 8) + ptr[i]; if (leaseTime != DHCP_INFINITE_LEASE) { leaseTime *= 1000; // milliseconds } break; - case 255: + case DHCP_OPT_END: done = true; break; default: { @@ -299,8 +303,7 @@ static bool dhcp_received_message_type (uint16_t len, byte msgType) { do { byte option = *ptr++; byte optionLen = *ptr++; - if(option == 53 && *ptr == msgType ) { - // DHCP Message type match found + if(option == DHCP_OPT_MESSAGE_TYPE && *ptr == msgType ) { return true; } ptr += optionLen; @@ -390,7 +393,7 @@ void EtherCard::DhcpStateMachine (uint16_t len) case DHCP_STATE_INIT: currentXid = millis(); - memset(myip,0,4); // force ip 0.0.0.0 + memset(myip,0,IP_LEN); // force ip 0.0.0.0 send_dhcp_message(NULL); enableBroadcast(true); //Temporarily enable broadcasts dhcpState = DHCP_STATE_SELECTING; @@ -399,7 +402,7 @@ void EtherCard::DhcpStateMachine (uint16_t len) case DHCP_STATE_SELECTING: if (dhcp_received_message_type(len, DHCP_OFFER)) { - uint8_t offeredip[4]; + uint8_t offeredip[IP_LEN]; process_dhcp_offer(len, offeredip); send_dhcp_message(offeredip); dhcpState = DHCP_STATE_REQUESTING; diff --git a/net.h b/net.h index a80c5b9..054eba2 100755 --- a/net.h +++ b/net.h @@ -15,6 +15,7 @@ // ******* ETH ******* #define ETH_HEADER_LEN 14 +#define ETH_LEN 6 // values of certain bytes: #define ETHTYPE_ARP_H_V 0x08 #define ETHTYPE_ARP_L_V 0x06 @@ -52,6 +53,7 @@ // ******* IP ******* #define IP_HEADER_LEN 20 +#define IP_LEN 4 // ip.src #define IP_SRC_P 0x1a #define IP_DST_P 0x1e