Go Down

Topic: Trying to build DHCP for arduino0019 and more (Read 3118 times) previous topic - next topic

gerasimone

Hi everyone,
i'm an italian software developer (objective-c, java, php), just started playing with arduino a week ago.
I want to build a DHCP library for the new arduino release, at this moment i was able to send the DHCPDISCOVER packet well composed, and the dhcp server reply with a packet, but i can't receive that packet with the UDP library in arduino.
Probably i miss something, are here someone able with udp and dhcp and want to collaborate in this library?
thanks
;)


robtillaart

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

gerasimone

yes i see other libraries, but they're based on old version of ethernet library.

I do some progress, but don't understand why, when serial monitor is opened, program does not receive the udp, as i close the serial monitor popup the led light up.
see the sketch attached, any help is approached (it's a study sketch, so don't take care by comments  :-[ )

Code: [Select]

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

#define DEBUG

/* DHCP state machine. */
#define STATE_DHCP_START        0
#define      STATE_DHCP_DISCOVER      1
#define      STATE_DHCP_REQUEST      2
#define      STATE_DHCP_LEASED      3
#define      STATE_DHCP_REREQUEST      4
#define      STATE_DHCP_RELEASE      5

#define DHCP_FLAGSBROADCAST      0x8000

/* UDP port numbers for DHCP */
#define      DHCP_SERVER_PORT      67
#define DHCP_CLIENT_PORT      68

/* DHCP message OP code */
#define DHCP_BOOTREQUEST      1
#define DHCP_BOOTREPLY            2

/* DHCP message type */
#define      DHCP_DISCOVER            1
#define DHCP_OFFER            2
#define      DHCP_REQUEST            3
#define      DHCP_DECLINE            4
#define      DHCP_ACK            5
#define DHCP_NAK            6
#define      DHCP_RELEASE            7
#define DHCP_INFORM            8

#define DHCP_HTYPE10MB            1
#define DHCP_HTYPE100MB            2

#define DHCP_HLENETHERNET      6
#define DHCP_HOPS            0
#define DHCP_SECS            0

#define dhcpSIZE                240

#define zap(x) if(x){free(x); x=0;}

/**
* @brief            for the DHCP message
*/
typedef struct RIP_MSG{
     byte              op;
     byte              htype;
     byte              hlen;
     byte              hops;
     unsigned long      xid;
     unsigned int      secs;
     unsigned int      flags;
     byte              ciaddr[4];
     byte              yiaddr[4];
     byte          siaddr[4];
     byte              giaddr[4];
     byte          chaddr[16];
     byte          sname[64];
     byte          file[128];
       byte            magic[4];
     byte          OPT[];
};

/**
* @brief      DHCP option and value (cf. RFC1533)
*/
enum{
  DhcpOptionPadding            = 0,
  DhcpOptionSubnetMask         = 1,
  DhcpOptionRoutersOnSubnet    = 3,
  DhcpOptionDNS                = 6,
  DhcpOptionHostName           = 12,
  DhcpOptionDomainName         = 15,
  DhcpOptionRequestedIPaddr      = 50,
  DhcpOptionIPAddrLeaseTime      = 51,
  DhcpOptionOptionOverload      = 52,
  DhcpOptionMessageType      = 53,
  DhcpOptionServerIdentifier      = 54,
  DhcpOptionParamRequest      = 55,
  DhcpOptionMsg            = 56,
  DhcpOptionMaxMsgSize       = 57,
  DhcpOptionT1value                  = 58,
  DhcpOptionT2value            = 59,
  DhcpOptionClassIdentifier      = 60,
  DhcpOptionClientIdentifier      = 61,
  DhcpOptionEnd                 = 255
};

byte mac[] = { 0xDE, 0xAF, 0xAE, 0xDF, 0xFE, 0xED };
byte ip[] = { 0,0,0,0 };

unsigned int dhcp_state;
unsigned long startTime;
unsigned long lastTime;
unsigned long _dhcpTransactionId = 123456; /* todo */

byte broadcastIp[] = { 255,255,255,255 };
byte dhcpServerIp[4];

// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,


void setup() {
 Serial.begin(9600);
 // start the Ethernet and UDP:
 Ethernet.begin(mac,ip);
 Udp.begin(DHCP_CLIENT_PORT);
 startTime = millis();
 lastTime = startTime;

 dhcp_state = STATE_DHCP_START;
 
 pinMode(9, OUTPUT);
 digitalWrite(9, LOW);
}

void loop() {
 if(dhcp_state == STATE_DHCP_START) {
   #ifdef DEBUG
   Serial.println("STATE_DHCP_START");
   #endif
   
   RIP_MSG *packet = (RIP_MSG *)malloc(dhcpSIZE +4 * sizeof(byte *));
   packet->op = DHCP_BOOTREQUEST;
   packet->htype = DHCP_HTYPE10MB;
   packet->hlen = DHCP_HLENETHERNET;
   packet->hops = DHCP_HOPS;
   packet->xid = dhcp_swapl(_dhcpTransactionId);
   packet->secs = 0;
   packet->flags = dhcp_swaps(DHCP_FLAGSBROADCAST);
   memset(packet->ciaddr, 0, 4);
   memset(packet->yiaddr, 0, 4);
   memset(packet->siaddr, 0, 4);
   memset(packet->giaddr, 0, 4);
   memset(packet->sname, 0, 64);
   memset(packet->file, 0, 128);
   memcpy(packet->chaddr, mac, sizeof(mac));
   packet->magic[0] = 99;
   packet->magic[1] = 130;
   packet->magic[2] = 83;
   packet->magic[3] = 99;
   
   unsigned int ptr = 0;
   // OPTION: message type
   packet->OPT[ptr] = DhcpOptionMessageType;
   ptr += 1;
   packet->OPT[ptr] = 1;
   ptr += 1;
   packet->OPT[ptr] = 1; //DhcpMessageDiscover
   ptr += 1;
   packet->OPT[ptr] = DhcpOptionEnd;
   ptr += 1;
   
   Udp.sendPacket((byte *)packet,dhcpSIZE +4,broadcastIp,DHCP_SERVER_PORT);
   #ifdef DEBUG
   Serial.println("STATE_DHCP_DISCOVER");
   Serial.print("send pack size: ");
   Serial.println(sizeof(*packet));
   #endif
   dhcp_state = STATE_DHCP_DISCOVER;
   zap(packet);
 }
 
 if(Udp.available()) {
   
   // Get packet size and allocate memory
   int packetSize = Udp.available()-8;
   RIP_MSG *packet = (RIP_MSG *)malloc(packetSize * sizeof(byte *));
   Udp.readPacket((byte *)packet,packetSize);
 
 // Find real size and make copy of incoming options
 // Attempt to handle missing 'DhcpOptionEnd' - corrupted line?
   int optLoc = 0;
   while(packet->OPT[optLoc] != DhcpOptionEnd && optLoc < packetSize-dhcpSIZE){
     optLoc = 2+optLoc+packet->OPT[optLoc+1];
   }
   int optSize = optLoc;
   byte *options = (byte *)malloc(optSize * sizeof(byte *));
   memcpy( options , packet->OPT , optSize);
   digitalWrite(9, HIGH);
 
   #ifdef DEBUG
   Serial.print("Packet size ");
   Serial.println(packetSize, DEC);
   Serial.print("Options size ");
   Serial.println(optSize, DEC);
   Serial.println("Fetched");
   for(int i = 0;i < (optSize);i++){
     Serial.print(options[i], DEC);
     Serial.print(" ");
   }
   Serial.println();
   #endif

 }
 
 
 #ifdef DEBUG
 /*
 if( millis()-lastTime > 1000 ){
   Serial.print(".");
   lastTime = millis();
 }
 */
 #endif
}


uint16_t dhcp_swaps(uint16_t i) {
     uint16_t ret=0;
     ret = (i & 0xFF) << 8;
     ret |= ((i >> 8)& 0xFF);
     return ret;      
}

uint32_t dhcp_swapl(uint32_t l) {
     uint32_t ret=0;
     ret = (l & 0xFF) << 24;
     ret |= ((l >> 8) & 0xFF) << 16;
     ret |= ((l >> 16) & 0xFF) << 8;
     ret |= ((l >> 24) & 0xFF);
     return ret;
}

Folderol

This might give you some ideas:

http://www.musically.me.uk/DHCP_Web_Server_12.pde

it's the most recent version of my attempt to get a DHCP server.

More details here:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1273689407

Check the last few entries :)

Go Up