Go Down

Topic: Trying to build DHCP for arduino0019 and more (Read 3266 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
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy