DHCP Client for WIZ820io(W5200)

Dependencies:   EthernetNetIf mbed

DHCPClient.h

Committer:
va009039
Date:
2012-04-10
Revision:
0:db4242c89949

File content as of revision 0:db4242c89949:

// DHCPClient.h 2012/4/10
#ifndef DHCPCLIENT_H
#define DHCPCLIENT_H
#include "UDPSocket.h"

//#define DHCP_VERBOSE

#define DHCP_OFFSET_OP 0
#define DHCP_OFFSET_XID 4
#define DHCP_OFFSET_YIADDR 16
#define DHCP_OFFSET_CHADDR 28
#define DHCP_OFFSET_MAGIC_COOKIE 236
#define DHCP_OFFSET_OPTIONS 240
#define DHCP_MAX_PACKET_SIZE 600

extern void _DHCP_OnEvent(UDPSocketEvent e); // DHCPClient.cpp

class DHCPClient {
    int discover(uint8_t buf[], int size) {
        memset(buf, 0x00, size);
        const uint8_t headers[] = {0x01,0x01,0x06,0x00,
                                   0x12,0x34,0x56,0x78}; // xid
        memcpy(buf, headers, sizeof(headers));
        int t = clock();
        xid[0] = t<<24;
        xid[1] = t<<16;
        xid[2] = t<<8;
        xid[3] = t;
        memcpy(buf+DHCP_OFFSET_XID, xid, 4);
        W5100.getMACAddress(buf+DHCP_OFFSET_CHADDR);
        const uint8_t options[] = {0x63,0x82,0x53,0x63, // magic cookie
                                   0x35,0x01,0x01, // DHCP DISCOVER
                                   0xff};
        memcpy(buf+DHCP_OFFSET_MAGIC_COOKIE, options, sizeof(options));
        //printHex((u8*)buf, 236);
        uint8_t ip[4] = {0,0,0,0};
        W5100.setIPAddress(ip);
        return DHCP_OFFSET_MAGIC_COOKIE + sizeof(options);
    }
    
    int request(uint8_t buf[], int size) {
        memset(buf, 0x00, size);
        const uint8_t headers[] = {0x01,0x01,0x06,0x00,
                                   0x12,0x34,0x56,0x78}; // xid
        memcpy(buf, headers, sizeof(headers));
        memcpy(buf+DHCP_OFFSET_XID, xid, 4);
        memcpy(buf+DHCP_OFFSET_YIADDR, yiaddr, 4);
        W5100.getMACAddress(buf+DHCP_OFFSET_CHADDR);
        const uint8_t options[] = {0x63,0x82,0x53,0x63, // magic cookie
                                   0x35,0x01,0x03, // DHCP REQUEST
                                   0x32,0x04,0x00,0x00,0x00,0x00, // request IP
                                   0xff};
        memcpy(buf+DHCP_OFFSET_MAGIC_COOKIE, options, sizeof(options));
        memcpy(buf+DHCP_OFFSET_MAGIC_COOKIE+9, yiaddr, 4);
        return DHCP_OFFSET_MAGIC_COOKIE + sizeof(options);
    }
    
    int offer_ack(uint8_t buf[], int size);

    bool verify(uint8_t buf[], int len) {
        if (len < DHCP_OFFSET_OPTIONS) {
            return false;
        }
        if (buf[DHCP_OFFSET_OP] != 0x02) {
            return false;
        }
        if (memcmp(buf+DHCP_OFFSET_XID, xid, 4) != 0) {
            return false;
        }
        return true;
    }
public:
    void callback(UDPSocketEvent e);
    int setup(int timeout_ms = 15000);
    DHCPClient();
    uint8_t chaddr[6]; // MAC
    uint8_t yiaddr[4]; // IP
    uint8_t dnsaddr[4]; // DNS
    uint8_t gateway[4];
    uint8_t netmask[4];
private:
    MyUDPSocket* p_udp;
    uint8_t xid[4];
    bool exit_flag;
};
#endif //DHCPCLIENT_H