📄 dhcp.lst
字号:
C51 COMPILER V7.06 DHCP 09/26/2008 13:36:22 PAGE 1
C51 COMPILER V7.06, COMPILATION OF MODULE DHCP
OBJECT MODULE PLACED IN ..\OUT\Dhcp.obj
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE ..\Source\Dhcp.c BROWSE DEBUG OBJECTEXTEND PRINT(..\OUT\Dhcp.lst) OBJECT(..
-\OUT\Dhcp.obj)
stmt level source
1 /*
2 *****************************************************************************************************
3 *
4 * File name: dhcp.c
5 *****************************************************************************************************
6 */
7 #include "..\head\includes.h"
8
9
10 void DHCP_Pack(unsigned char PACK_TYPE) ;
11 /*
12 *****************************************************************************************************
13 *FUNC: DHCP解析
14 *NOTE:
15 *****************************************************************************************************
16 */
17 //******* DHCP 的6种状态 *******
18 #define DHCP_INIT 0
19 #define DHCP_SELECT 1
20 #define DHCP_REQUEST 2
21 #define DHCP_BOUND 3
22 #define DHCP_RENEW 4
23 #define DHCP_REBIND 5
24
25
26 //******* DHCP 的几种报文类型状态 *******
27 #define OP_DHCPDISCOVER 1
28 #define OP_DHCPOFFER 2
29 #define OP_DHCPREQUEST 3
30 #define OP_DHCPDELINE 4
31 #define OP_DHCPACK 5
32 #define OP_DHCPNACK 6
33 #define OP_DHCPRELEASE 7
34 #define OP_DHCPINFORM 8
35
36
37
38 _DHCP_REG_ xdata DHCPReg;
39 bit bBound = FALSE;
40
41 /*
42 *****************************************************************************************************
43 *FUNC: 绑定与释放回调函数
44 *NOTE:
45 *****************************************************************************************************
46 */
47 void On_Bound(void) reentrant
48 {
49 1 //申请到的IP可写入FLASH,下次开机时优先申请该IP.可选做
50 1 DHCPReg.timer100.dwords = 60; //2分钟 FOR DEBUG
51 1 if ((DHCPReg.timer100.dwords == 0) || (DHCPReg.timer100.dwords > 7200)){
52 2 DHCPReg.timer100.dwords = 7200; //如果DHCP没指配时间或大于2小时,默认为2小时
53 2 }
54 1 my_ip_address.dwords = DHCPReg.myip.dwords; //使用分配得到的IP
C51 COMPILER V7.06 DHCP 09/26/2008 13:36:22 PAGE 2
55 1 gateway_ip_address.dwords = DHCPReg.gatewayip.dwords; //使用分配得到的网关IP
56 1 mask_ip_address.dwords = DHCPReg.maskip.dwords; //使用分配得到的子网掩码
57 1 if (gateway_ip_address.dwords == 0) { //网关IP=0
58 2 if (DHCPReg.severip.dwords != 0) { //DHCP服务器IP不等于0
59 3 gateway_ip_address.dwords = DHCPReg.severip.dwords;//把DHCP服务器IP当作网关IP
60 3 }
61 2 }
62 1
63 1 DHCPReg.timer50.dwords = (DHCPReg.timer100.dwords) / 2; //50%定时器
64 1 DHCPReg.timer87.dwords = DHCPReg.timer100.dwords * 875 /1000; //87.5%定时器
65 1 bBound = TRUE;
66 1 }
67
68
69 void On_Release(void)reentrant
70 {
71 1 DHCP_Pack(OP_DHCPRELEASE);
72 1 bBound = FALSE;
73 1 DHCPReg.state = DHCP_INIT;
74 1
75 1 if (bConnect) { //如果已连上,关闭链路
76 2 tcp_send(&TCPSend,FLG_RST, 20, IndexOfClient); //这里一定要加RST
77 2 InerClose(IndexOfClient); //关闭该套接字,重连
78 2 }
79 1 }
80
81 /*
82 *****************************************************************************************************
83 *FUNC: DHCP 初始化
84 *NOTE:
85 *****************************************************************************************************
86 */
87 void DHCPValueInit(void)
88 {
89 1 bBound = FALSE;
90 1 DHCPReg.state = DHCP_INIT;
91 1 DHCPReg.myip.dwords = 0;
92 1 DHCPReg.gatewayip.dwords = 0;
93 1 DHCPReg.maskip.dwords = 0;
94 1 DHCPReg.dns_m.dwords = 0;
95 1 DHCPReg.dns_s.dwords = 0;
96 1 DHCPReg.severip.dwords = 0;
97 1 DHCPReg.timer100.dwords = 0;
98 1 DHCPReg.timer50.dwords = 0;
99 1 DHCPReg.timer87.dwords = 0;
100 1 }
101 void DHCPInit(void)
102 {
103 1 DHCPValueInit();
104 1 DHCPReg.on_bound = (void*)On_Bound;
105 1 DHCPReg.on_release = (void*)On_Release;
106 1 }
107
108
109 /*
110 *****************************************************************************************************
111 *FUNC: 打包 DHCP Discover
112 *NOTE: 1: DHCP 是基于UDP协议的
113 2: 果没回应隔9,13,16秒后再发,如果还是没响应,隔5分钟分钟再发起DISCOVER
114 3: UDP CRC包括UDP头及UDP数据 长度len
115
116 全部广播在家里路由器试可以续租可以得到响应
C51 COMPILER V7.06 DHCP 09/26/2008 13:36:22 PAGE 3
117 //my_ip_address.dwords = 0;//自己的IP还是未知发0.0.0.0
118 //DHCP_Pack_Send(pTxdnet, dest_ip, UDP_TYPE, len);
119 *****************************************************************************************************
120 */
121 void DHCP_Pack(unsigned char PACK_TYPE)
122 {
123 1 unsigned int len,i;
124 1 unsigned char model_id_len=0,j;
125 1 union netcard xdata *pTxdnet;
126 1 union IP_address xdata dest_ip;
127 1 union IP_address xdata source_ip;
128 1
129 1 pTxdnet = &UDPSend;
130 1
131 1 source_ip.dwords = 0; //源IP未知,发送0.0.0.0
132 1 dest_ip.dwords = 0xffffffff; //目的IP未知,采用广播
133 1
134 1 pTxdnet->udpframe.sourceport = 68; //DHCP源端口为68
135 1 pTxdnet->udpframe.destport = 67; //DHCP目的端口为67
136 1 //pTxdnet->udpframe.length = len; //长度未定
137 1 pTxdnet->udpframe.crc = 0; //UDP头部8字节
138 1
139 1
140 1 pTxdnet->ipframe.sourceip[0] = source_ip.words[0]; //参于计算检验和,不算在UDP长度里
141 1 pTxdnet->ipframe.sourceip[1] = source_ip.words[1]; //源IP未知,发送0.0.0.0
142 1 pTxdnet->ipframe.destip[0] = dest_ip.words[0];
143 1 pTxdnet->ipframe.destip[1] = dest_ip.words[1]; // ffffffff
144 1
145 1 pTxdnet->dhcpframe.op = 1; //DHCP 请求
146 1 pTxdnet->dhcpframe.hardwaretype = 1; //以太网
147 1 pTxdnet->dhcpframe.hardwarelen = 6;
148 1 pTxdnet->dhcpframe.hops = 0; //跳数置0
149 1 pTxdnet->dhcpframe.transactionid = DHCPReg.transactionid; //类似SEQ
150 1 pTxdnet->dhcpframe.seconds = 500; //?
151 1 pTxdnet->dhcpframe.flags = 0x8000; //最高位为1:广播请求,0:单播 抓包=0
152 1
153 1 for (i=0; i<4; i++) {
154 2 if ((PACK_TYPE == OP_DHCPREQUEST) && bBound){ //续租的时候这里要填之前申请到的本地IP
155 3 pTxdnet->dhcpframe.clientip[i] = DHCPReg.myip.bytes[i];
156 3 } else {
157 3 pTxdnet->dhcpframe.clientip[i] = 0; //参照抓包也是=0
158 3 }
159 2 pTxdnet->dhcpframe.yourip[i] = 0; //DHCP服务器分配给客户端的
160 2 pTxdnet->dhcpframe.severip[i] = 0; //如果须要转发才填
161 2 pTxdnet->dhcpframe.gatewayip[i] = 0; //如果须要转发才填
162 2 }
163 1
164 1 for (i=0; i<16; i++) { //16字节前6字节填客户硬件地址,余补0
165 2 if (i < 6) {
166 3 pTxdnet->dhcpframe.clientmac[i] = my_ethernet_address.bytes[i];
167 3 } else {
168 3 pTxdnet->dhcpframe.clientmac[i] = 0;
169 3 }
170 2 }
171 1 for (i=0; i<64; i++) { //服务器主机名Server之名称字串,以0x00结尾
172 2 pTxdnet->dhcpframe.severhostname[i] = 0;
173 2 }
174 1 for (i=0; i<128; i++) { //启动文件名若client需要透过网路开机
175 2 pTxdnet->dhcpframe.bootfilename[i] = 0;
176 2 }
177 1
178 1 pTxdnet->dhcpframe.magic[0]=0x63; //抓包这里有四字节内容如右:(OK)
C51 COMPILER V7.06 DHCP 09/26/2008 13:36:22 PAGE 4
179 1 pTxdnet->dhcpframe.magic[1]=0x82;
180 1 pTxdnet->dhcpframe.magic[2]=0x53;
181 1 pTxdnet->dhcpframe.magic[3]=0x63;
182 1 //len = 8+28+16+64+128+4;
183 1 len = 248; //长度很重要
184 1
185 1 //---------- 以下为OPTIONS --------------------
186 1 i=0; //长度可变
187 1
188 1 //----- 包类型 -----------
189 1 pTxdnet->dhcpframe.options[i++]=53; //选项代码
190 1 pTxdnet->dhcpframe.options[i++]=1; //选项长度
191 1 pTxdnet->dhcpframe.options[i++]=PACK_TYPE; //DHCP包类型
192 1
193 1 //----- 请求自动分配 ------
194 1 if (PACK_TYPE == OP_DHCPDISCOVER) { //发现包时请求自动分配
195 2 pTxdnet->dhcpframe.options[i++]=0x74;
196 2 pTxdnet->dhcpframe.options[i++]=1;
197 2 pTxdnet->dhcpframe.options[i++]=1;
198 2 }
199 1
200 1 //----- 请求使用该本地IP ------
201 1 if ((PACK_TYPE == OP_DHCPREQUEST) && (bBound==FALSE)){ //DHCP offer后有分配给一个本地IP
202 2 pTxdnet->dhcpframe.options[i++]=50; //请求本地IP填在选项里
203 2 pTxdnet->dhcpframe.options[i++]=4;
204 2 pTxdnet->dhcpframe.options[i++]=DHCPReg.myip.bytes[0];
205 2 pTxdnet->dhcpframe.options[i++]=DHCPReg.myip.bytes[1];
206 2 pTxdnet->dhcpframe.options[i++]=DHCPReg.myip.bytes[2];
207 2 pTxdnet->dhcpframe.options[i++]=DHCPReg.myip.bytes[3];
208 2
209 2 //DHCP SEVER IP填在选项里
210 2 pTxdnet->dhcpframe.options[i++]=54;
211 2 pTxdnet->dhcpframe.options[i++]=4;
212 2 pTxdnet->dhcpframe.options[i++]=DHCPReg.severip.bytes[0];
213 2 pTxdnet->dhcpframe.options[i++]=DHCPReg.severip.bytes[1];
214 2 pTxdnet->dhcpframe.options[i++]=DHCPReg.severip.bytes[2];
215 2 pTxdnet->dhcpframe.options[i++]=DHCPReg.severip.bytes[3];
216 2 }
217 1
218 1 //----- 主动释放时如果有本地IP,选填 ------
219 1 if ((PACK_TYPE == OP_DHCPRELEASE) && (bBound == TRUE)) {
220 2 pTxdnet->dhcpframe.options[i++]=50; //请求本地IP填在选项里
221 2 pTxdnet->dhcpframe.options[i++]=4;
222 2 pTxdnet->dhcpframe.options[i++]=DHCPReg.myip.bytes[0];
223 2 pTxdnet->dhcpframe.options[i++]=DHCPReg.myip.bytes[1];
224 2 pTxdnet->dhcpframe.options[i++]=DHCPReg.myip.bytes[2];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -