📄 dhcp.c
字号:
/***********************************************************************//* *//* Module: dhcp.c *//* Release: 2001.3 *//* Version: 2001.2 *//* Purpose: DHCP Client Implementation *//* *//*---------------------------------------------------------------------*//* *//* Copyright 2000, Blunk Microsystems *//* ALL RIGHTS RESERVED *//* *//* Licensees have the non-exclusive right to use, modify, or extract *//* this computer program for software development at a single site. *//* This program may be resold or disseminated in executable format *//* only. The source code may not be redistributed or resold. *//* *//* *//***********************************************************************/#include "tcp_ipp.h"#include "ip/ip.h"#include <string.h>#include <stdlib.h>/***********************************************************************//* Symbol Definitions *//***********************************************************************/#define DHCP_SERV 67#define DHCP_CLNT 68#define BOOTREQUEST 1#define BOOTREPLY 2#define TRANSITION 0#define MSG_TIMEOUT 222#define LEASE_TIMEOUT 223#define K64_SECONDS (TICKS_PER_SEC * 64)#define K10_SECONDS (TICKS_PER_SEC * 10)#define K9_SECONDS (TICKS_PER_SEC * 9)#define K4_SECONDS (TICKS_PER_SEC * 4)#define K2_SECONDS (TICKS_PER_SEC * 2)#define K1_SECOND (TICKS_PER_SEC * 1)/*** Option Types*/#define PADDING 0#define SUBNET_MASK 1#define ROUTER_IP 3#define DNS_SERVER 6#define MAX_SIZE 22#define REQ_ADDRESS 50#define LEASE_TIME 51#define OVERLOAD 52#define USE_FILE_FIELD 1#define USE_SNAME_FIELD 2#define MSG_TYPE 53#define SERVER_ID 54#define PARAM_REQ_LIST 55#define RENEWAL_T1 58#define REBINDING_T2 59#define OPTION_END 255/*** DHCP States*/enum DhcpStates{ DHCP_FREE = 0, DHCP_INIT, DHCP_SELECT, DHCP_REQUEST, DHCP_ARP, DHCP_BOUND, DHCP_RENEW, DHCP_REBIND};/*** DHCP Message Types*/enum DhcpTypes{ DHCPDISCOVER = 1, DHCPOFFER, DHCPREQUEST, DHCPDECLINE, DHCPACK, DHCPNAK, DHCPRELEASE, DHCPINFORM};/***********************************************************************//* Type Definitions *//***********************************************************************//*** Format of DHCP message*/typedef struct{ ui8 op; /* BOOTREQUEST or BOOTREPLY */ ui8 htype; /* hardware type */ ui8 hlen; /* hw address length: ETH_ALEN for Ethernet */ ui8 hops; /* clients set to zero */ ui32 xid; /* transaction identifier */ ui16 secs; /* seconds since IA access or renewal began */ ui16 flags; /* broadcast request */ ui32 ciaddr; /* client IA: used in bound, renewal, rebinding */ ui32 yiaddr; /* your IP address, filled in by server */ ui32 siaddr; /* IP address of next server to use */ ui32 giaddr; /* relay agent IP address */ ui8 chaddr[16]; /* client hardware address */ ui8 sname[64]; /* optional server host name */ ui8 file[128]; /* boot file name */ ui8 options[64];} DhcpMsg;/***********************************************************************//* Function Prototypes *//***********************************************************************/static void dhcp_free(int event);static void dhcp_init(int event);static void dhcp_select(int event);static void dhcp_request(int event);static void dhcp_arp(int event);static void dhcp_bound(int event);static void dhcp_renew(int event);static void dhcp_rebind(int event);/***********************************************************************//* Global Variable Definitions *//***********************************************************************//*** Global DHCP Information*/static int DnsS;static ui32 TransactionId;static void (*DhcpSwitch[])(int event) ={ dhcp_free, /* DHCP_FREE */ dhcp_init, /* DHCP_INIT */ dhcp_select, /* DHCP_SELECT */ dhcp_request, /* DHCP_REQUEST */ dhcp_arp, /* DHCP_ARP */ dhcp_bound, /* DHCP_BOUND */ dhcp_renew, /* DHCP_RENEW */ dhcp_rebind, /* DHCP_BIND */};/*** Per NI Information*/static struct{ int state; ui32 req_time; ui32 rebindT2; ui32 leaseTime; ui32 router; ui32 serverID; ui32 subnetMask; Ni *ni; TcpTmr msgTimer; TcpTmr leaseTimer; ui32 reqAddr; uint retransDelay; ui32 renewT1;} dhcp;/***********************************************************************//* Local Function Definitions *//***********************************************************************//***********************************************************************//* send_msg: Send DHCP message *//* *//* Inputs: ni = pointer to network interface structure *//* ip_addr = requested address or 0, according to type *//* type = DHCP message type *//* *//***********************************************************************/static void send_msg(Ni *ni, ui32 ip_addr, int type){ DhcpMsg *msg; NetBuf *buf; Route route; SockAddr dest; SOCKET sock = &Socks[DnsS - 1]; ui8 *opts; /*-------------------------------------------------------------------*/ /* Allocate buffer for DHCP request. */ /*-------------------------------------------------------------------*/ buf = tcpGetBuf(sizeof(DhcpMsg)); if (buf == NULL) { NetError(NULL, ENOBUFS); return; } msg = (DhcpMsg *)((char *)buf->ip_data + UDP_HLEN); /*-------------------------------------------------------------------*/ /* Initialize DHCP client message structure. */ /*-------------------------------------------------------------------*/ msg->op = BOOTREQUEST; msg->htype = ni->hw_type; msg->hops = 0; msg->xid = htonl(TransactionId); if ((type == DHCPDECLINE) || (type == DHCPRELEASE)) { msg->secs = 0; } else { ui16 secs = (ui16)(dhcp.req_time / TICKS_PER_SEC); msg->secs = htons(secs); } msg->flags = 0x0000; msg->ciaddr = ip_addr; msg->yiaddr = 0; msg->siaddr = 0; msg->giaddr = 0; if ((ni->flags & NIF_P2P) == FALSE) { memcpy(msg->chaddr, ni->hw_addr, ni->ha_len); msg->hlen = ni->ha_len; } else msg->hlen = 0; memset(msg->sname, 0, 64); memset(msg->file, 0, 128); /*-------------------------------------------------------------------*/ /* Assign "magic cookie" to first four bytes of options field. */ /*-------------------------------------------------------------------*/ msg->options[0] = 99; msg->options[1] = 130; msg->options[2] = 83; msg->options[3] = 99; /*-------------------------------------------------------------------*/ /* Set message type option. */ /*-------------------------------------------------------------------*/ msg->options[4] = MSG_TYPE; msg->options[5] = 1; /* option length */ msg->options[6] = (ui8)type; /*-------------------------------------------------------------------*/ /* Prepare to add additional options. */ /*-------------------------------------------------------------------*/ opts = &msg->options[7]; /*-------------------------------------------------------------------*/ /* If conditions are right, add server ID option. */ /*-------------------------------------------------------------------*/ if ((dhcp.state == DHCP_REQUEST) || (type == DHCPDECLINE) || (type == DHCPRELEASE)) { *opts++ = SERVER_ID; *opts++ = 4; /* option length */ memcpy(opts, &dhcp.serverID, 4); opts += 4; } /*-------------------------------------------------------------------*/ /* If conditions are right, add parameter list option. */ /*-------------------------------------------------------------------*/ if ((type == DHCPDISCOVER) || (type == DHCPREQUEST) || (type == DHCPINFORM)) { *opts++ = PARAM_REQ_LIST; *opts++ = 3; /* option length */ *opts++ = ROUTER_IP; *opts++ = SUBNET_MASK; *opts++ = DNS_SERVER; } /*-------------------------------------------------------------------*/ /* If conditions are right, add requested address option. */ /*-------------------------------------------------------------------*/ if (dhcp.reqAddr && !ip_addr) { *opts++ = REQ_ADDRESS; *opts++ = 4; /* option length */ memcpy(opts, &dhcp.reqAddr, 4); opts += 4; } /*-------------------------------------------------------------------*/ /* Finish with the "end" option. */ /*-------------------------------------------------------------------*/ *opts++ = OPTION_END; /*-------------------------------------------------------------------*/ /* Adding padding to extend BOOTP message size to 300 bytes. */ /*-------------------------------------------------------------------*/ while ((opts - &msg->op) < 300) *opts++ = PADDING; /*-------------------------------------------------------------------*/ /* Steer through the remainder of UDP/IP stack so that the packet is */ /* transmitted from this network interface. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -