📄 ip.lst
字号:
C51 COMPILER V7.06 IP 06/26/2004 13:41:25 PAGE 1
C51 COMPILER V7.06, COMPILATION OF MODULE IP
OBJECT MODULE PLACED IN IP.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE IP.C LARGE BROWSE DEBUG OBJECTEXTEND
stmt level source
1 //-----------------------------------------------------------------------------
2 // Net IP.C
3 // This module is the IP layer
4 // Refer to RFC 791, 1122, and RFC 815 (fragmentation)
5 //-----------------------------------------------------------------------------
6 #include <string.h>
7 #include <reg89C58.h>
8 #include <stdio.h>
9 #include "net.h"
10 #include "cksum.h"
11 #include "arp.h"
12 #include "eth.h"
13 #include "icmp.h"
14 #include "udp.h"
15 //#include "serial.h"
16 #include "tcp.h"
17 #include "ip.h"
18
19 extern UCHAR idata debug;
20 extern ULONG data my_ipaddr;
21 WAIT xdata wait;
22
23 char * itoa(UINT value, char * buf, UCHAR radix)
24 {
25 1 UINT i;
26 1 char * ptr;
27 1 char * temphold;
28 1
29 1 temphold = buf;
30 1 ptr = buf + 12;
31 1 *--ptr = 0; // Insert NULL char
32 1 do
33 1 {
34 2 // First create string in reverse order
35 2 i = (value % radix) + 0x30;
36 2 if(i > 0x39) i += 7;
37 2 *--ptr = i;
38 2 value = value / radix;
39 2 } while(value != 0);
40 1
41 1 // Next, move the string 6 places to the left
42 1 // Include NULL character
43 1 for( ; (*buf++ = *ptr++); );
44 1 return(temphold);
45 1 }
46
47
48 //------------------------------------------------------------------------
49 // This handles outgoing IP datagrams. It adds the 20 byte IP header
50 // and checksum then forwards the IP datagram to the Ethernet layer
51 // for sending. See "TCP/IP Illustrated, Volume 1" Sect 3.2
52 //------------------------------------------------------------------------
53 void ip_send(UCHAR xdata * outbuf, ULONG ipaddr, UCHAR proto_id, UINT len)
54 {
55 1 IP_HEADER xdata * ip;
C51 COMPILER V7.06 IP 06/26/2004 13:41:25 PAGE 2
56 1 UCHAR xdata * hwaddr;
57 1 static UINT ip_ident = 0;
58 1
59 1 ip = (IP_HEADER xdata *)(outbuf + 14);
60 1 ip->ver_len = 0x45; // IPv4 with 20 byte header
61 1 ip->type_of_service = 0;
62 1 ip->total_length = 20 + len;
63 1 ip->identifier = ip_ident++; // sequential identifier
64 1 ip->fragment_info = 0; // not fragmented
65 1 ip->time_to_live = 32; // max hops
66 1 ip->protocol_id = proto_id; // type of payload
67 1 ip->header_cksum = 0;
68 1 ip->source_ipaddr = my_ipaddr;
69 1
70 1 // Outgoing IP address
71 1 ip->dest_ipaddr = ipaddr;
72 1
73 1 // Compute and insert complement of checksum of ip header
74 1 // Outgoing ip header length is always 20 bytes
75 1 ip->header_cksum = ~cksum(outbuf + 14, 20);
76 1
77 1 // Use ARP to get hardware address to send this to
78 1 hwaddr = arp_resolve(ip->dest_ipaddr);
79 1
80 1 // Null means that the ARP resolver did not find the IP address
81 1 // in its cache so had to send an ARP request
82 1 if (hwaddr == NULL)
83 1 {
84 2 // Fill in the destination information so ehrn the ARP response
85 2 // arrives we can identify it and know what to do when we get it
86 2 wait.buf = outbuf;
87 2 wait.ipaddr = ip->dest_ipaddr;
88 2 wait.proto_id = proto_id;
89 2 wait.len = len;
90 2 wait.timer = ARP_TIMEOUT;
91 2 return;
92 2 }
93 1
94 1 eth_send(outbuf, hwaddr, IP_PACKET, 20 + len);
95 1 // printf("IP:send IP packet.\n");
96 1 }
97
98
99
100 //------------------------------------------------------------------------
101 // This handles incoming IP datagrams from the Ethernet layer
102 // See "TCP/IP Illustrated, Volume 1" Sect 3.2
103 //------------------------------------------------------------------------
104 void ip_rcve(UCHAR xdata * inbuf)
105 {
106 1 IP_HEADER xdata * ip;
107 1 UINT idata header_len, payload_len;
108 1
109 1 ip = (IP_HEADER xdata *)(inbuf + 14);
110 1
111 1 // Make sure it is addressed to my IP address
112 1 if (ip->dest_ipaddr != my_ipaddr) return;
113 1
114 1 // Validate checksum of ip header
115 1 header_len = 4 * (0x0F & ip->ver_len);
116 1 payload_len = ip->total_length - header_len;
117 1 if (cksum(inbuf + 14, header_len) != 0xFFFF)
C51 COMPILER V7.06 IP 06/26/2004 13:41:25 PAGE 3
118 1 {
119 2 // if (debug) printf("IP: Error, cksum bad\n");
120 2 return;
121 2 }
122 1
123 1 // Make sure incoming message is IP version 4
124 1 if ((ip->ver_len >> 4) != 0x04)
125 1 {
126 2 // if (debug) printf("IP: Error, not IPv4\n");
127 2 return;
128 2 }
129 1
130 1 // Make sure incoming message is not fragmented because
131 1 // we cannot handle fragmented messages
132 1 if ((ip->fragment_info & 0x3FFF) != 0)
133 1 {
134 2 // if (debug) printf("IP: Error, fragmented msg rcvd\n");
135 2 return;
136 2 }
137 1
138 1 // At this point we have received a valid IP datagram addressed
139 1 // to me. We do not use header options, and do not forward
140 1 // messages, so in the unlikely event there are header options,
141 1 // delete them and shift the data down. The advantage is that
142 1 // layers such as UDP and TCP know where their data starts
143 1 if (header_len > 20)
144 1 {
145 2 // if (debug) printf("IP: Rcvd header > 20 bytes\n");
146 2
147 2 // Use memmove because of overlap
148 2 memmove(inbuf + 34, inbuf + 14 + header_len, payload_len);
149 2
150 2 // Adjust info to reflect the move
151 2 header_len = 20;
152 2 ip->ver_len = 0x45;
153 2 ip->total_length = 20 + payload_len;
154 2 }
155 1
156 1
157 1 // Look at protocol ID byte and call the appropriate
158 1 // function to handle the received message. See
159 1 // "TCP/IP Illustrated, Volume 1" Sect 1.7 and RFC 791
160 1 // for values for various protocols
161 1 switch (ip->protocol_id)
162 1 {
163 2 case ICMP_TYPE:
164 2 // if (debug) printf("IP: ICMP pkt rcvd\n");
165 2 icmp_rcve(inbuf, payload_len);
166 2 break;
167 2
168 2 case IGMP_TYPE:
169 2 // We cannot handle IGMP messages
170 2 // if (debug) printf("IP: Error, IGMP pkt rcvd\n");
171 2 break;
172 2
173 2 case UDP_TYPE:
174 2 // if (debug) printf("IP: UDP pkt rcvd\n");
175 2 udp_rcve(inbuf, payload_len);
176 2 break;
177 2
178 2 case TCP_TYPE:
179 2 // if (debug) printf("IP: TCP pkt rcvd\n");
C51 COMPILER V7.06 IP 06/26/2004 13:41:25 PAGE 4
180 2 tcp_rcve(inbuf, payload_len);
181 2 break;
182 2
183 2 default:
184 2 // if (debug) printf("IP: Unknown IP proto id rcvd\n");
185 2 break;
186 2 }
187 1 }
188
189
190
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 1022 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = 12 29
PDATA SIZE = ---- ----
DATA SIZE = ---- ----
IDATA SIZE = ---- 4
BIT SIZE = ---- ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -