⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dhcp.c

📁 ATmega103、ATmega128做的开发板web server源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************
* dhcp.c: Dynamic Host Configuration Protocol
* 
* Copyright (c) 2001 Atmel Corporation.
* All Rights Reserved.
*
* You are autorized to use, copy and distribute this software only at 
* a single site (the term "site" meaning a single company location). 
* This copyright notice must be included in any copy, modification 
* or portion of this software merged into another program.
* 
* This software is licenced solely for use with Atmel AVR micro 
* controller family. The software may not be modified to execute on 
* any other microcontroller architectures
*
* This software is provided "as is"; Without warranties either express
* or implied, including any warranty regarding merchantability, 
* fitness for a particular purpose or noninfringement. 
*
* In no event shall Atmel or its suppliers be liable for any special, 
* indirect,incidential or concequential damages resulting from the 
* use or inability to use this software.
*
* Revision history:
* January 17, 2001:   Version 1.0   Created by JB
* July 13, 2001		  Version 1.2     JB
* 					- Changed to IAR compiler V2.25
*					- Renamed flash file functions to avoid conflict with 
*					  standard file I/O names	
*					- Bug fixes in HTTP
*					- Speed optimization in TCP 
*
*******************************************************************/
#define ENABLE_BIT_DEFINITIONS

#include "dhcp.h"
#include "udp.h"
#include "ethernet.h"
#include "main.h"
#include "dataflash.h"
#include <iom103.h>
#include <ina90.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#define SwapEndian(in)		(in >> 24) | \
							((in & 0x00FF0000) >> 8) |\
							((in & 0x0000FF00) << 8) |\
							(in << 24)
/*macros*/
#define TO_UINT(x) ((x) / 2)                          
#define TO_ULONG(x) ((x) / 4)
#define LO(x) ((unsigned char) ((x)&0x00ff))          //returns the lower end byte of an integer
#define HI(x) ((unsigned char) (((x)>>8)&0x00ff))     //returns the higher end byte of an integer   
#define TOINT(x,y) (((x<<8)&0xff00) | (y&0x00ff) )   //combines two bytes into an integer

/*dhcp states*/
#define INITREBOOT              0
#define REBOOTING               1
#define INIT                    2
#define SELECTING               3
#define REQUESTING              4
#define BOUND                   5
#define RENEWING                6
#define REBINDING               7             

/*when dhcpConf is set the IP-layer will forward all UDP datagrams and ignores the dest. IP-address field*/
extern unsigned char dhcpConf;                  
extern config_type ID;

unsigned char dhcpState = INITREBOOT;             //initial state INITREBOOT
UDPB dhcpBuffer;                                //buffer for receiving/sending packets


struct {                                        //varouis status varaiables required by dhcp
  unsigned char XID0,XID1,XID2,XID3;            
  int ip0,ip1;
  int sId0,sId1;
  unsigned int nextEvent;                       
  unsigned int cnt;
  unsigned int min; 
  unsigned int arpWait;
  unsigned char minEvent;                       //is set when min is incremented
}dhcpStatus;                                    

// char msg[100];                                  //for debuging

void DHCP(void)
{
  unsigned char retranMax;                      //max number of retransmitions, used in states REBOOTING and REQUESTING
  unsigned char * pdata = &dhcpBuffer.data[DHCP_FIELD_OPTIONS+findOption(DHCP_OPTION_SERVERID)+2];
  unsigned char msg_data  = dhcpBuffer.data[DHCP_FIELD_OPTIONS+findOption(DHCP_OPTION_MSGTYPE)+2];

  for (;;)
  {
    retranMax=DHCP_RETRAN;
    switch (dhcpState)
    {
      case INITREBOOT:
      
        dhcpConf=1;                               //set dhcp configuration flag, this will make the IP-layer
                                                  //forward all UDP datagrams and ignores the dest. IP-address field
        dhcpStatus.ip0=EEgetInt(DHCP_EEADDRESS);  //read the last obtained IP-address from EEPROM
        dhcpStatus.ip1=EEgetInt(DHCP_EEADDRESS+2);
        if ( dhcpStatus.ip0==0xffff && dhcpStatus.ip1==0xffff ) //check if there was an IP-address stored in EEPROM
        {
          dhcpState=INIT;                          //if no IP-address was found, go to state INIT
        }
        else
        {
          sendDHCPREQUEST();               
          dhcpState=REBOOTING;
        }
        break;

      case REBOOTING:
      
        if (wait((DHCP_RETRAN+1)-retranMax))        //wait longer for each retransmition, as defined in rfc2131
        {
          if (msg_data == DHCPACK) //if ack is received
          {
            
            /* read server identifier option */
            dhcpStatus.sId0 = TOINT(pdata[2],pdata[3]);
            dhcpStatus.sId1 = TOINT(pdata[4],pdata[5]);                       
            
            /*configure the EWS with the obtained IP*/
            ID.IP0 = TOINT(pdata[2],pdata[3]);                     
            ID.IP1 = TOINT(pdata[4],pdata[5]);
            
            dhcpMAC(dhcpStatus.sId0,dhcpStatus.sId1); //dhcpserver (ip,mac) is stored permanently in ARP-table
            calcT1();                               //calculate when to enter state RENEWING
            dhcpStatus.min=0;
            dhcpConf=0;
            dhcpState=BOUND;
          }
          else if (msg_data == DHCPNAK)
          {
            dhcpState=INIT;
          }
        }
        else if (retranMax == 0)                     //if maximum retransmitions is reached go to state INIT
        {
          dhcpState=INIT;
        }
        else
        {                                            
          retranMax--;                                
          sendDHCPREQUEST();                          
        }
        break;

     case INIT:
     
        dhcpConf=1;                                 //set dhcp configuration flag, this will make the IP-layer
                                                    //forward all UDP datagrams and ignores the dest. IP-address field
        ID.IP0=0;                                   //clear the current IP-address
        ID.IP1=0;
        dhcpState=SELECTING;
        break;
     
     case SELECTING:
     
        sendDHCPDISCOVER(); 
        if (wait(2))                                 //wait for timeout or received UDP datagram on port 68
        {
          if (msg_data == DHCPOFFER)
          {
            if (checkXID())                          //check if XID is correct
            {
              /* read server identifier option */
         		dhcpStatus.sId0 = TOINT(pdata[2],pdata[3]);
            	dhcpStatus.sId1 = TOINT(pdata[4],pdata[5]); 
              /* read offered ip adress from yiaddr */
              dhcpStatus.ip0 = TOINT(dhcpBuffer.data[DHCP_FIELD_YIADDR],dhcpBuffer.data[DHCP_FIELD_YIADDR+1]);
              dhcpStatus.ip1 = TOINT(dhcpBuffer.data[DHCP_FIELD_YIADDR+2],dhcpBuffer.data[DHCP_FIELD_YIADDR+3]);                   
              
              sendDHCPREQUEST();
              dhcpState=REQUESTING;
            }
          }                        
        }
        break;
        
      case REQUESTING:
      
        if (wait((DHCP_RETRAN+1)-retranMax))         //wait longer for each retranMaxsmition, as defined in rfc2131
        {
          if ( msg_data == DHCPACK && checkXID())
          {                      
            /*start using ip address assigned by dhcpserver*/
            ID.IP0=TOINT(dhcpBuffer.data[DHCP_FIELD_YIADDR],dhcpBuffer.data[DHCP_FIELD_YIADDR+1]);
            ID.IP1=TOINT(dhcpBuffer.data[DHCP_FIELD_YIADDR+2],dhcpBuffer.data[DHCP_FIELD_YIADDR+3]);
            /*write leased ip address to EEPROM */
            EEputInt(DHCP_EEADDRESS,ID.IP0);
            EEputInt(DHCP_EEADDRESS+2,ID.IP1);
            dhcpMAC(dhcpStatus.sId0,dhcpStatus.sId1); //dhcpserver (ip,mac) is stored permanently in ARP-table
            calcT1();                                 //calculate when to enter state RENEWING
            dhcpStatus.min=0;
            dhcpConf=0;                               //dhcp configuration is done
            dhcpState=BOUND;
          }
			else if ( msg_data == DHCPNAK)
          {
            dhcpState=INIT;
          }
        }
        else if (retranMax ==0)                        //if all retransmissions fails, enter state INIT
        {
          dhcpState=INIT;
        }
        else
        {
          retranMax--;
          sendDHCPREQUEST();
        }
        break;    
    
      case RENEWING:
          
        if (dhcpStatus.minEvent)                       //only run if min has changed
        {
          sendDHCPREQUEST();
          dhcpStatus.minEvent=0; 
        }
        if (readUDP(68,&dhcpBuffer))                   //if new data
        {
          if (msg_data == DHCPACK && checkXID())
          {                                          
            calcT1();                                 
            dhcpStatus.min=0;
            //dhcpConf=0;
            dhcpState=BOUND;
          }
          else if (msg_data == DHCPNAK && checkXID())
          {
            dhcpState=INIT;
            break;
          }  
        }
        
        if (dhcpStatus.min>=dhcpStatus.nextEvent)        //T2 has occured enter state REBINING
        {
          dhcpStatus.nextEvent=(unsigned int) dhcpStatus.nextEvent*DHCP_TIMEOUT;
          dhcpStatus.min=0;
          dhcpState=REBINDING;
        }
        break; 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -