?? ip.lst
字號:
C51 COMPILER V7.50 IP 07/04/2000 11:33:15 PAGE 1
C51 COMPILER V7.50, COMPILATION OF MODULE IP
OBJECT MODULE PLACED IN IP.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE IP.C OPTIMIZE(9,SPEED) BROWSE DEBUG OBJECTEXTEND
line 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 "C8051f.h"
8 #include "net.h"
9 #include "cksum.h"
10 #include "arp.h"
11 #include "eth.h"
12 #include "icmp.h"
13 #include "udp.h"
14 #include "serial.h"
15 #include "tcp.h"
16 #include "ip.h"
17
18 extern UCHAR idata debug;
19 extern ULONG code my_ipaddr;
20 WAIT xdata wait;
21
22
23 //------------------------------------------------------------------------
24 // This handles outgoing IP datagrams. It adds the 20 byte IP header
25 // and checksum then forwards the IP datagram to the Ethernet layer
26 // for sending. See "TCP/IP Illustrated, Volume 1" Sect 3.2
27 //------------------------------------------------------------------------
28 void ip_send(UCHAR xdata * outbuf, ULONG ipaddr, UCHAR proto_id, UINT len)
29 {
30 1 IP_HEADER xdata * ip;
31 1 UCHAR xdata * hwaddr;
32 1 static UINT ip_ident = 0;
33 1
34 1 ip = (IP_HEADER xdata *)(outbuf + 14);
35 1 ip->ver_len = 0x45; // IPv4 with 20 byte header
36 1 ip->type_of_service = 0;
37 1 ip->total_length = 20 + len;
38 1 ip->identifier = ip_ident++; // sequential identifier
39 1 ip->fragment_info = 0; // not fragmented
40 1 ip->time_to_live = 32; // max hops
41 1 ip->protocol_id = proto_id; // type of payload
42 1 ip->header_cksum = 0;
43 1 ip->source_ipaddr = my_ipaddr;
44 1
45 1 // Outgoing IP address
46 1 ip->dest_ipaddr = ipaddr;
47 1
48 1 // Compute and insert complement of checksum of ip header
49 1 // Outgoing ip header length is always 20 bytes
50 1 ip->header_cksum = ~cksum(outbuf + 14, 20);
51 1
52 1 // Use ARP to get hardware address to send this to
53 1 hwaddr = arp_resolve(ip->dest_ipaddr);
54 1
55 1 // Null means that the ARP resolver did not find the IP address
C51 COMPILER V7.50 IP 07/04/2000 11:33:15 PAGE 2
56 1 // in its cache so had to send an ARP request
57 1 if (hwaddr == NULL)
58 1 {
59 2 // Fill in the destination information so ehrn the ARP response
60 2 // arrives we can identify it and know what to do when we get it
61 2 wait.buf = outbuf;
62 2 wait.ipaddr = ip->dest_ipaddr;
63 2 wait.proto_id = proto_id;
64 2 wait.len = len;
65 2 wait.timer = ARP_TIMEOUT;
66 2 return;
67 2 }
68 1
69 1 eth_send(outbuf, hwaddr, IP_PACKET, 20 + len);
70 1 }
71
72
73
74 //------------------------------------------------------------------------
75 // This handles incoming IP datagrams from the Ethernet layer
76 // See "TCP/IP Illustrated, Volume 1" Sect 3.2
77 //------------------------------------------------------------------------
78 void ip_rcve(UCHAR xdata * inbuf)
79 {
80 1 IP_HEADER xdata * ip;
81 1 UINT idata header_len, payload_len;
82 1
83 1 ip = (IP_HEADER xdata *)(inbuf + 14);
84 1
85 1 // Make sure it is addressed to my IP address
86 1 if (ip->dest_ipaddr != my_ipaddr) return;
87 1
88 1 // Validate checksum of ip header
89 1 header_len = 4 * (0x0F & ip->ver_len);
90 1 payload_len = ip->total_length - header_len;
91 1 if (cksum(inbuf + 14, header_len) != 0xFFFF)
92 1 {
93 2 if (debug) serial_send("IP: Error, cksum bad\r");
94 2 return;
95 2 }
96 1
97 1 // Make sure incoming message is IP version 4
98 1 if ((ip->ver_len >> 4) != 0x04)
99 1 {
100 2 if (debug) serial_send("IP: Error, not IPv4\r");
101 2 return;
102 2 }
103 1
104 1 // Make sure incoming message is not fragmented because
105 1 // we cannot handle fragmented messages
106 1 if ((ip->fragment_info & 0x3FFF) != 0)
107 1 {
108 2 if (debug) serial_send("IP: Error, fragmented msg rcvd\r");
109 2 return;
110 2 }
111 1
112 1 // At this point we have received a valid IP datagram addressed
113 1 // to me. We do not use header options, and do not forward
114 1 // messages, so in the unlikely event there are header options,
115 1 // delete them and shift the data down. The advantage is that
116 1 // layers such as UDP and TCP know where their data starts
117 1 if (header_len > 20)
C51 COMPILER V7.50 IP 07/04/2000 11:33:15 PAGE 3
118 1 {
119 2 if (debug) serial_send("IP: Rcvd header > 20 bytes\r");
120 2
121 2 // Use memmove because of overlap
122 2 memmove(inbuf + 34, inbuf + 14 + header_len, payload_len);
123 2
124 2 // Adjust info to reflect the move
125 2 header_len = 20;
126 2 ip->ver_len = 0x45;
127 2 ip->total_length = 20 + payload_len;
128 2 }
129 1
130 1
131 1 // Look at protocol ID byte and call the appropriate
132 1 // function to handle the received message. See
133 1 // "TCP/IP Illustrated, Volume 1" Sect 1.7 and RFC 791
134 1 // for values for various protocols
135 1 switch (ip->protocol_id)
136 1 {
137 2 case ICMP_TYPE:
138 2 if (debug) serial_send("IP: ICMP pkt rcvd\r");
139 2 icmp_rcve(inbuf, payload_len);
140 2 break;
141 2
142 2 case IGMP_TYPE:
143 2 // We cannot handle IGMP messages
144 2 if (debug) serial_send("IP: Error, IGMP pkt rcvd\r");
145 2 break;
146 2
147 2 case UDP_TYPE:
148 2 if (debug) serial_send("IP: UDP pkt rcvd\r");
149 2 udp_rcve(inbuf, payload_len);
150 2 break;
151 2
152 2 case TCP_TYPE:
153 2 if (debug) serial_send("IP: TCP pkt rcvd\r");
154 2 tcp_rcve(inbuf, payload_len);
155 2 break;
156 2
157 2 default:
158 2 if (debug) serial_send("IP: Unknown IP proto id rcvd\r");
159 2 break;
160 2 }
161 1 }
162
163
164
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 702 ----
CONSTANT SIZE = 222 ----
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 + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -