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
Have you searched for UDP and DHCP libraries allready (just to see how others did it?) e.g.
http://bitbucket.org/bjoern/arduino_osc/src/tip/libraries/Ethernet/
http://blog.jordanterrell.com/post/Arduino-DHCP-Library-Version-04.aspx
(google Arduino DHCP libraries)
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 :-[ )
#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;
}
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