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

📄 dhcpd.c

📁 這是一個實時嵌入式作業系統 實作了MCS51 ARM等MCU
💻 C
📖 第 1 页 / 共 3 页
字号:
/**************************************************************************** * netutils/dhcpd/dhcpd.c * *   Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. *   Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * 3. Neither the name NuttX nor the names of its contributors may be *    used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************//**************************************************************************** * Included Files ****************************************************************************/#ifdef CONFIG_NETUTILS_DHCPD_HOST# include <stdio.h>typedef unsigned char uint8;typedef unsigned short uint16;typedef unsigned int  uint32;typedef unsigned char boolean;# define HTONS(a) htons(a)# define HTONL(a) htonl(a)# define dbg(...) printf(__VA_ARGS__)# define vdbg(...) printf(__VA_ARGS__)# define TRUE  (1)# define FALSE (0)# define ERROR (-1)# define OK    (0)#else# include <nuttx/config.h># include <debug.h># include <net/uip/dhcpd.h>#endif#include <sys/types.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <string.h>#include <unistd.h>#include <time.h>#include <errno.h>#include <net/if.h>#include <netinet/in.h>#include <arpa/inet.h>/**************************************************************************** * Private Data ****************************************************************************/#define DHCP_SERVER_PORT         67#define DHCP_CLIENT_PORT         68/* Option codes understood in this file                                     *//*                              Code    Data   Description                  *//*                                      Length                              */#define DHCP_OPTION_PAD           1  /*  1     Pad                          */#define DHCP_OPTION_REQ_IPADDR   50  /*  4     Requested IP Address         */#define DHCP_OPTION_LEASE_TIME   51  /*  4     IP address lease time        */#define DHCP_OPTION_OVERLOAD     52  /*  1     Option overload              */#define DHCP_OPTION_MSG_TYPE     53  /*  1     DHCP message type            */#define DHCP_OPTION_SERVER_ID    54  /*  4     Server identifier            */#define DHCP_OPTION_END         255  /*  0     End                          *//* Values for the dhcp msg 'op' field */#define DHCP_REQUEST              1#define DHCP_REPLY                2/* DHCP message types understood in this file */#define DHCPDISCOVER              1  /* Received from client only */#define DHCPOFFER                 2  /* Sent from server only */#define DHCPREQUEST               3  /* Received from client only */#define DHCPDECLINE               4  /* Received from client only */#define DHCPACK                   5  /* Sent from server only */#define DHCPNAK                   6  /* Sent from server only */#define DHCPRELEASE               7  /* Received from client only */#define DHCPINFORM                8  /* Not used *//* The form of an option is: *   code   - 1 byte *   length - 1 byte *   data   - variable number of bytes */#define DHCPD_OPTION_CODE         0#define DHCPD_OPTION_LENGTH       1#define DHCPD_OPTION_DATA         2/* Size of options in DHCP message */#define DHCPD_OPTIONS_SIZE        312/* Values for htype and hlen field */#define DHCP_HTYPE_ETHERNET       1#define DHCP_HLEN_ETHERNET        6/* Values for flags field */#define BOOTP_BROADCAST           0x8000/* Legal values for this option are: * *   1     the 'file' field is used to hold options *   2     the 'sname' field is used to hold options *   3     both fields are used to hold options */#define DHCPD_OPTION_FIELD        0#define DHCPD_FILE_FIELD          1#define DHCPD_SNAME_FIELD         2#ifndef CONFIG_NETUTILS_DHCPD_LEASETIME# define CONFIG_NETUTILS_DHCPD_LEASETIME (60*60*24*10) /* 10 days */# undef CONFIG_NETUTILS_DHCPD_MINLEASETIME# undef CONFIG_NETUTILS_DHCPD_MAXLEASETIME#endif#ifndef CONFIG_NETUTILS_DHCPD_MINLEASETIME# define CONFIG_NETUTILS_DHCPD_MINLEASETIME (60*60*24*1) /* 1 days */#endif#ifndef CONFIG_NETUTILS_DHCPD_MAXLEASETIME# define CONFIG_NETUTILS_DHCPD_MAXLEASETIME (60*60*24*30) /* 30 days */#endif#ifndef CONFIG_NETUTILS_DHCPD_INTERFACE# define CONFIG_NETUTILS_DHCPD_INTERFACE "eth0"#endif#ifndef CONFIG_NETUTILS_DHCPD_MAXLEASES# define CONFIG_NETUTILS_DHCPD_MAXLEASES 16#endif#ifndef CONFIG_NETUTILS_DHCPD_STARTIP# define CONFIG_NETUTILS_DHCPD_STARTIP (10<<24|0<<16|0<<16|2)#endif#undef CONFIG_NETUTILS_DHCP_OPTION_ENDIP#define CONFIG_NETUTILS_DHCP_OPTION_ENDIP \  (CONFIG_NETUTILS_DHCPD_STARTIP + CONFIG_NETUTILS_DHCPD_MAXLEASES - 1)#ifndef CONFIG_NETUTILS_DHCPD_OFFERTIME# define CONFIG_NETUTILS_DHCPD_OFFERTIME (60*60) /* 1 hour */#endif#ifndef CONFIG_NETUTILS_DHCPD_DECLINETIME# define CONFIG_NETUTILS_DHCPD_DECLINETIME (60*60) /* 1 hour */#endif#undef HAVE_LEASE_TIME#if defined(CONFIG_NETUTILS_DHCPD_HOST) || !defined(CONFIG_DISABLE_POSIX_TIMERS)# define HAVE_LEASE_TIME 1#endif/**************************************************************************** * Private Types ****************************************************************************//* This structure describes one element in the lease table.  There is one slot * in the lease table for each assign-able IP address (hence, the IP address * itself does not have to be in the table. */struct lease_s{  uint8    mac[DHCP_HLEN_ETHERNET]; /* MAC address (network order) -- could be larger! */  boolean  allocated;               /* true: IP address is allocated */#ifdef HAVE_LEASE_TIME  time_t   expiry;                  /* Lease expiration time (seconds past Epoch) */#endif};struct dhcpmsg_s{  uint8  op;  uint8  htype;  uint8  hlen;  uint8  hops;  uint8  xid[4];  uint16 secs;  uint16 flags;  uint8  ciaddr[4];  uint8  yiaddr[4];  uint8  siaddr[4];  uint8  giaddr[4];  uint8  chaddr[16];#ifndef CONFIG_NET_DHCP_LIGHT  uint8  sname[64];  uint8  file[128];#endif  uint8  options[312];};struct dhcpd_state_s{  /* Server configuration */  in_addr_t        ds_serverip;   /* The server IP address */  /* Message buffers */  struct dhcpmsg_s ds_inpacket;   /* Holds the incoming DHCP client message */  struct dhcpmsg_s ds_outpacket;  /* Holds the outgoing DHCP server message */  /* Parsed options from the incoming DHCP client message */  uint8            ds_optmsgtype;   /* Incoming DHCP message type */  in_addr_t        ds_optreqip;     /* Requested IP address (host order) */  in_addr_t        ds_optserverip;  /* Serverip IP address (host order) */  time_t           ds_optleasetime; /* Requested lease time (host order) */  /* End option pointer for outgoing DHCP server message */  uint8           *ds_optend;  /* Leases */  struct lease_s   ds_leases[CONFIG_NETUTILS_DHCPD_MAXLEASES];};/**************************************************************************** * Private Data ****************************************************************************/static const uint8          g_magiccookie[4] = {99, 130, 83, 99};static const uint8          g_anyipaddr[4] = {0, 0, 0, 0};static struct dhcpd_state_s g_state;/**************************************************************************** * Private Functions ****************************************************************************//**************************************************************************** * Name: dhcpd_time ****************************************************************************/#ifdef CONFIG_NETUTILS_DHCPD_HOST# define dhcpd_time() time(0)#elif defined(HAVE_LEASE_TIME)static time_t dhcpd_time(void){  struct timespec time;  time_t ret = 0;  if (clock_gettime(CLOCK_REALTIME, &time) == OK)    {      ret = time.tv_sec;    }  return ret;}#else# define dhcpd_time() (0)#endif/**************************************************************************** * Name: dhcpd_leaseexpired ****************************************************************************/#ifdef HAVE_LEASE_TIMEstatic inline boolean dhcpd_leaseexpired(struct lease_s *lease){  if (lease->expiry < dhcpd_time())    {      return FALSE;    }  else    {      memset(lease, 0, sizeof(struct lease_s));      return TRUE;    }}#else# define dhcpd_leaseexpired(lease) (FALSE)#endif/**************************************************************************** * Name: dhcpd_setlease ****************************************************************************/struct lease_s *dhcpd_setlease(const uint8 *mac, in_addr_t ipaddr, time_t expiry){  int ndx = ntohl(ipaddr) - CONFIG_NETUTILS_DHCPD_STARTIP;  struct lease_s *ret = NULL;  if (ndx >= 0 && ndx < CONFIG_NETUTILS_DHCPD_MAXLEASES)    {        ret = &g_state.ds_leases[ndx];        memcpy(ret->mac, mac, DHCP_HLEN_ETHERNET);        ret->allocated = TRUE;#ifdef HAVE_LEASE_TIME        ret->expiry = dhcpd_time() + expiry;#endif    }  return ret;}/**************************************************************************** * Name: dhcp_leaseipaddr ****************************************************************************/static inline in_addr_t dhcp_leaseipaddr( struct lease_s *lease){  return htonl((g_state.ds_leases - lease)/sizeof(struct lease_s) + CONFIG_NETUTILS_DHCPD_STARTIP);}/**************************************************************************** * Name: dhcpd_findbymac ****************************************************************************/static struct lease_s *dhcpd_findbymac(const uint8 *mac){  int i;  for (i = 0; i < CONFIG_NETUTILS_DHCPD_MAXLEASES; i++)    {      if (memcmp(g_state.ds_leases[i].mac, mac, DHCP_HLEN_ETHERNET) == 0)        {          return &(g_state.ds_leases[i]);        }    }  return NULL;}/**************************************************************************** * Name: dhcpd_findbyipaddr ****************************************************************************/static struct lease_s *dhcpd_findbyipaddr(in_addr_t ipaddr){  if (ipaddr >= CONFIG_NETUTILS_DHCPD_STARTIP &&      ipaddr <= CONFIG_NETUTILS_DHCP_OPTION_ENDIP)    {      struct lease_s *lease = &g_state.ds_leases[ipaddr - CONFIG_NETUTILS_DHCPD_STARTIP];      if (lease->allocated > 0)        {          return lease;        }    }  return NULL;}/**************************************************************************** * Name: dhcpd_allocipaddr ****************************************************************************/in_addr_t dhcpd_allocipaddr(void){  struct lease_s *lease = NULL;  in_addr_t ipaddr;  ipaddr = CONFIG_NETUTILS_DHCPD_STARTIP;  for (; ipaddr <= CONFIG_NETUTILS_DHCP_OPTION_ENDIP; ipaddr++)    {      if ((ipaddr & 0xff) == 0 || (ipaddr & 0xff) == 0xff)        {          continue;        }      lease = dhcpd_findbyipaddr(ipaddr);      if ((!lease || dhcpd_leaseexpired(lease)))        {#warning "FIXME: Should check if anything responds to an ARP request or ping"#warning "       to verify that there is no other user of this IP address"          memset(g_state.ds_leases[ipaddr - CONFIG_NETUTILS_DHCPD_STARTIP].mac, 0, DHCP_HLEN_ETHERNET);          g_state.ds_leases[ipaddr - CONFIG_NETUTILS_DHCPD_STARTIP].allocated = TRUE;#ifdef HAVE_LEASE_TIME          g_state.ds_leases[ipaddr - CONFIG_NETUTILS_DHCPD_STARTIP].expiry = dhcpd_time() + CONFIG_NETUTILS_DHCPD_OFFERTIME;#endif          return ntohl(ipaddr);        }    }  return 0;}/**************************************************************************** * Name: dhcpd_parseoptions ****************************************************************************/static inline boolean dhcpd_parseoptions(void){  uint32 tmp;  uint8 *ptr;  uint8 overloaded;  uint8 currfield;  int optlen;  int remaining;  /* Verify that the option field starts with a valid magic number */  ptr = g_state.ds_inpacket.options;  if (memcmp(ptr, g_magiccookie, 4) != 0)    {      /* Bad magic number... skip g_state.ds_outpacket */      dbg("Bad magic: %d,%d,%d,%d\n", ptr[0], ptr[1], ptr[2], ptr[3]);      return FALSE;    }  /* Set up to parse the options */  ptr        += 4;  remaining  = DHCPD_OPTIONS_SIZE - 4;  overloaded = DHCPD_OPTION_FIELD;  currfield  = DHCPD_OPTION_FIELD;  /* Set all options to the default value */  g_state.ds_optmsgtype   = 0;    /* Incoming DHCP message type */  g_state.ds_optreqip     = 0;    /* Requested IP address (host order) */  g_state.ds_optserverip  = 0;    /* Serverip IP address (host order) */

⌨️ 快捷键说明

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