ip.lst
来自「单片机控制RTL8019AS的程序,C语言编写,仿真通过.」· LST 代码 · 共 172 行
LST
172 行
C51 COMPILER V7.06 IP 10/09/2006 21:51:55 PAGE 1
C51 COMPILER V7.06, COMPILATION OF MODULE IP
OBJECT MODULE PLACED IN ip.OBJ
COMPILER INVOKED BY: D:\Program Files\Keil\C51\BIN\C51.EXE ip.c 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 <general.h>
8
9
10 extern ULONG code my_ipaddr;
11 WAIT xdata wait;
12
13
14 //------------------------------------------------------------------------
15 // This handles outgoing IP datagrams. It adds the 20 byte IP header
16 // and checksum then forwards the IP datagram to the Ethernet layer
17 // for sending. See "TCP/IP Illustrated, Volume 1" Sect 3.2
18 //------------------------------------------------------------------------
19 void ip_send(UCHAR xdata * outbuf, ULONG ipaddr, UCHAR proto_id, UINT len)
20 {
21 1 IP_HEADER xdata * ip;
22 1 UCHAR xdata * hwaddr;
23 1 static UINT ip_ident = 0;
24 1
25 1 ip = (IP_HEADER xdata *)(outbuf + 14);
26 1 ip->ver_len = 0x45; // IPv4 with 20 byte header
27 1 ip->type_of_service = 0;
28 1 ip->total_length = 20 + len;
29 1 ip->identifier = ip_ident++; // sequential identifier
30 1 ip->fragment_info = 0; // not fragmented
31 1 ip->time_to_live = 32; // max hops
32 1 ip->protocol_id = proto_id; // type of payload
33 1 ip->header_cksum = 0;
34 1 ip->source_ipaddr = my_ipaddr;
35 1
36 1 // Outgoing IP address
37 1 ip->dest_ipaddr = ipaddr;
38 1
39 1 // Compute and insert complement of checksum of ip header
40 1 // Outgoing ip header length is always 20 bytes
41 1 ip->header_cksum = ~cksum(outbuf + 14, 20);
42 1
43 1 // Use ARP to get hardware address to send this to
44 1 hwaddr = arp_resolve(ip->dest_ipaddr);
45 1
46 1 // Null means that the ARP resolver did not find the IP address
47 1 // in its cache so had to send an ARP request
48 1 if (hwaddr == NULL)
49 1 {
50 2 // Fill in the destination information so ehrn the ARP response
51 2 // arrives we can identify it and know what to do when we get it
52 2 wait.buf = outbuf;
53 2 wait.ipaddr = ip->dest_ipaddr;
54 2 wait.proto_id = proto_id;
55 2 wait.len = len;
C51 COMPILER V7.06 IP 10/09/2006 21:51:55 PAGE 2
56 2 wait.timer = ARP_TIMEOUT;
57 2 return;
58 2 }
59 1
60 1 eth_send(outbuf, hwaddr, IP_PACKET, 20 + len);
61 1 }
62
63
64
65 //------------------------------------------------------------------------
66 // This handles incoming IP datagrams from the Ethernet layer
67 // See "TCP/IP Illustrated, Volume 1" Sect 3.2
68 //------------------------------------------------------------------------
69 void ip_rcve(UCHAR xdata * inbuf)
70 {
71 1 IP_HEADER xdata * ip;
72 1 UINT idata header_len, payload_len;
73 1
74 1 ip = (IP_HEADER xdata *)(inbuf + 14);
75 1
76 1 // Make sure it is addressed to my IP address
77 1 if (ip->dest_ipaddr != my_ipaddr) return;
78 1
79 1 // Validate checksum of ip header
80 1 header_len = 4 * (0x0F & ip->ver_len);
81 1 payload_len = ip->total_length - header_len;
82 1 if (cksum(inbuf + 14, header_len) != 0xFFFF)
83 1 {
84 2 return;
85 2 }
86 1
87 1 // Make sure incoming message is IP version 4
88 1 if ((ip->ver_len >> 4) != 0x04)
89 1 {
90 2 return;
91 2 }
92 1
93 1 // Make sure incoming message is not fragmented because
94 1 // we cannot handle fragmented messages
95 1 if ((ip->fragment_info & 0x3FFF) != 0)
96 1 {
97 2 return;
98 2 }
99 1
100 1 // At this point we have received a valid IP datagram addressed
101 1 // to me. We do not use header options, and do not forward
102 1 // messages, so in the unlikely event there are header options,
103 1 // delete them and shift the data down. The advantage is that
104 1 // layers such as UDP and TCP know where their data starts
105 1 if (header_len > 20)
106 1 {
107 2
108 2 // Use memmove because of overlap
109 2 memmove(inbuf + 34, inbuf + 14 + header_len, payload_len);
110 2
111 2 // Adjust info to reflect the move
112 2 header_len = 20;
113 2 ip->ver_len = 0x45;
114 2 ip->total_length = 20 + payload_len;
115 2 }
116 1
117 1
C51 COMPILER V7.06 IP 10/09/2006 21:51:55 PAGE 3
118 1 // Look at protocol ID byte and call the appropriate
119 1 // function to handle the received message. See
120 1 // "TCP/IP Illustrated, Volume 1" Sect 1.7 and RFC 791
121 1 // for values for various protocols
122 1 switch (ip->protocol_id)
123 1 {
124 2 case ICMP_TYPE:
125 2 icmp_rcve(inbuf, payload_len);
126 2 break;
127 2
128 2 case IGMP_TYPE:
129 2 // We cannot handle IGMP messages
130 2 break;
131 2
132 2 case UDP_TYPE:
133 2 break;
134 2
135 2 case TCP_TYPE:
136 2 tcp_rcve(inbuf, payload_len);
137 2 break;
138 2
139 2 default:
140 2 break;
141 2 }
142 1 }
143
144
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 631 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = 10 ----
PDATA SIZE = ---- ----
DATA SIZE = 2 15
IDATA SIZE = ---- 4
BIT SIZE = ---- ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?