/[H8]/trunk/docs/Microchip TCP_IP stack/TCPIP Stack/IP.c
ViewVC logotype

Annotation of /trunk/docs/Microchip TCP_IP stack/TCPIP Stack/IP.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 15 - (hide annotations) (download)
Thu Apr 19 09:01:15 2007 UTC (17 years, 2 months ago) by hedin
File MIME type: text/plain
File size: 10337 byte(s)
added the TCP/IP stack, source code.
1 hedin 15 /*********************************************************************
2     *
3     * Internet Protocol (IP) Version 4 Communications Layer
4     * Module for Microchip TCP/IP Stack
5     * -Provides a transport for TCP, UDP, and ICMP messages
6     * -Reference: RFC 791
7     *
8     *********************************************************************
9     * FileName: IP.C
10     * Dependencies: string.h
11     * StackTsk.h
12     * Helpers.h
13     * IP.h
14     * Processor: PIC18, PIC24F, PIC24H, dsPIC30F, dsPIC33F
15     * Complier: Microchip C18 v3.02 or higher
16     * Microchip C30 v2.01 or higher
17     * Company: Microchip Technology, Inc.
18     *
19     * Software License Agreement
20     *
21     * Copyright © 2002-2007 Microchip Technology Inc. All rights
22     * reserved.
23     *
24     * Microchip licenses to you the right to use, modify, copy, and
25     * distribute:
26     * (i) the Software when embedded on a Microchip microcontroller or
27     * digital signal controller product (“Device”) which is
28     * integrated into Licensee’s product; or
29     * (ii) ONLY the Software driver source files ENC28J60.c and
30     * ENC28J60.h ported to a non-Microchip device used in
31     * conjunction with a Microchip ethernet controller for the
32     * sole purpose of interfacing with the ethernet controller.
33     *
34     * You should refer to the license agreement accompanying this
35     * Software for additional information regarding your rights and
36     * obligations.
37     *
38     * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” WITHOUT
39     * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
40     * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
41     * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
42     * MICROCHIP BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR
43     * CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
44     * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
45     * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
46     * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
47     * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
48     * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
49     *
50     *
51     * Author Date Comment
52     *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
53     * Nilesh Rajbharti 4/27/01 Original (Rev 1.0)
54     * Nilesh Rajbharti 2/9/02 Cleanup
55     * Nilesh Rajbharti 5/22/02 Rev 2.0 (See version.log for detail)
56     * Howard Schlunder 8/31/04 Beta Rev 0.9 (See version.log for detail)
57     * Howard Schlunder 1/5/06 Improved DMA checksum efficiency
58     * Darren Rook 9/21/06 Corrected IPHeaderLen not being
59     * initialized when NON_MCHP_MAC defined.
60     ********************************************************************/
61     #define __IP_C
62    
63     #include "TCPIP Stack/TCPIP.h"
64    
65     // This is left shifted by 4. Actual value is 0x04.
66     #define IPv4 (0x40u)
67     #define IP_VERSION IPv4
68    
69     // IHL (Internet Header Length) is # of DWORDs in a header.
70     // Since, we do not support options, our IP header length will be
71     // minimum i.e. 20 bytes : IHL = 20 / 4 = 5.
72     #define IP_IHL (0x05)
73    
74     #define IP_SERVICE_NW_CTRL (0x07)
75     #define IP_SERVICE_IN_CTRL (0x06)
76     #define IP_SERVICE_ECP (0x05)
77     #define IP_SERVICE_OVR (0x04)
78     #define IP_SERVICE_FLASH (0x03)
79     #define IP_SERVICE_IMM (0x02)
80     #define IP_SERVICE_PRIOR (0x01)
81     #define IP_SERVICE_ROUTINE (0x00)
82    
83     #define IP_SERVICE_N_DELAY (0x00)
84     #define IP_SERCICE_L_DELAY (0x08)
85     #define IP_SERVICE_N_THRPT (0x00)
86     #define IP_SERVICE_H_THRPT (0x10)
87     #define IP_SERVICE_N_RELIB (0x00)
88     #define IP_SERVICE_H_RELIB (0x20)
89    
90     #define IP_SERVICE (IP_SERVICE_ROUTINE | IP_SERVICE_N_DELAY)
91    
92     #define MY_IP_TTL (100) // Time-To-Live in hops
93    
94    
95    
96    
97     static WORD _Identifier = 0;
98     static BYTE IPHeaderLen;
99    
100    
101     static void SwapIPHeader(IP_HEADER* h);
102    
103    
104    
105    
106     /*********************************************************************
107     * Function: BOOL IPGetHeader( IP_ADDR *localIP,
108     * NODE_INFO *remote,
109     * BYTE *Protocol,
110     * WORD *len)
111     *
112     * PreCondition: MACGetHeader() == TRUE
113     *
114     * Input: localIP - Local node IP Address as received
115     * in current IP header.
116     * If this information is not required
117     * caller may pass NULL value.
118     * remote - Remote node info
119     * Protocol - Current packet protocol
120     * len - Current packet data length
121     *
122     * Output: TRUE, if valid packet was received
123     * FALSE otherwise
124     *
125     * Side Effects: None
126     *
127     * Note: Only one IP message can be received.
128     * Caller may not transmit and receive a message
129     * at the same time.
130     *
131     ********************************************************************/
132     BOOL IPGetHeader(IP_ADDR *localIP,
133     NODE_INFO *remote,
134     BYTE *protocol,
135     WORD *len)
136     {
137     WORD_VAL CalcChecksum;
138     IP_HEADER header;
139    
140     #if defined(NON_MCHP_MAC)
141     WORD_VAL ReceivedChecksum;
142     WORD checksums[2];
143     BYTE optionsLen;
144     #define MAX_OPTIONS_LEN (40) // As per RFC 791.
145     BYTE options[MAX_OPTIONS_LEN];
146     #endif
147    
148     // Read IP header.
149     MACGetArray((BYTE*)&header, sizeof(header));
150    
151     // Make sure that this is an IPv4 packet.
152     if ( (header.VersionIHL & 0xf0) != IP_VERSION )
153     return FALSE;
154    
155     IPHeaderLen = (header.VersionIHL & 0x0f) << 2;
156    
157     #if !defined(NON_MCHP_MAC)
158     // Validate the IP header. If it is correct, the checksum
159     // will come out to 0x0000 (because the header contains a
160     // precomputed checksum). A corrupt header will have a
161     // nonzero checksum.
162     CalcChecksum.Val = MACCalcRxChecksum(0, IPHeaderLen);
163    
164     // Seek to the end of the IP header
165     MACSetReadPtrInRx(IPHeaderLen);
166    
167     if(CalcChecksum.Val)
168     #else
169     // Calculate options length in this header, if there is any.
170     // IHL is in terms of numbers of 32-bit DWORDs; i.e. actual
171     // length is 4 times IHL.
172     optionsLen = IPHeaderLen - sizeof(header);
173    
174     // If there is any option(s), read it so that we can include them
175     // in checksum calculation.
176     if ( optionsLen > MAX_OPTIONS_LEN )
177     return FALSE;
178    
179     if ( optionsLen > 0 )
180     MACGetArray(options, optionsLen);
181    
182     // Save header checksum; clear it and recalculate it ourselves.
183     ReceivedChecksum.Val = header.HeaderChecksum;
184     header.HeaderChecksum = 0;
185    
186     // Calculate checksum of header including options bytes.
187     checksums[0] = ~CalcIPChecksum((BYTE*)&header, sizeof(header));
188    
189     // Calculate Options checksum too, if they are present.
190     if ( optionsLen > 0 )
191     checksums[1] = ~CalcIPChecksum((BYTE*)options, optionsLen);
192     else
193     checksums[1] = 0;
194    
195     CalcChecksum.Val = CalcIPChecksum((BYTE*)checksums,
196     2 * sizeof(WORD));
197    
198     // Make sure that checksum is correct
199     if ( ReceivedChecksum.Val != CalcChecksum.Val )
200     #endif
201     {
202     // Bad packet. The function caller will be notified by means of the FALSE
203     // return value and it should discard the packet.
204     return FALSE;
205     }
206    
207     // Network to host conversion.
208     SwapIPHeader(&header);
209    
210     // If caller is intrested, return destination IP address
211     // as seen in this IP header.
212     if ( localIP )
213     localIP->Val = header.DestAddress.Val;
214    
215     remote->IPAddr.Val = header.SourceAddress.Val;
216     *protocol = header.Protocol;
217     *len = header.TotalLength - IPHeaderLen;
218    
219     return TRUE;
220     }
221    
222    
223    
224    
225     /*********************************************************************
226     * Function: WORD IPPutHeader(NODE_INFO *remote,
227     * BYTE protocol,
228     * WORD len)
229     *
230     * PreCondition: IPIsTxReady() == TRUE
231     *
232     * Input: *remote - Destination node address
233     * protocol - Current packet protocol
234     * len - Current packet data length
235     *
236     * Output: (WORD)0
237     *
238     * Side Effects: None
239     *
240     * Note: Only one IP message can be transmitted at any
241     * time.
242     ********************************************************************/
243     WORD IPPutHeader(NODE_INFO *remote,
244     BYTE protocol,
245     WORD len)
246     {
247     IP_HEADER header;
248    
249     IPHeaderLen = sizeof(IP_HEADER);
250    
251     header.VersionIHL = IP_VERSION | IP_IHL;
252     header.TypeOfService = IP_SERVICE;
253     header.TotalLength = sizeof(header) + len;
254     header.Identification = ++_Identifier;
255     header.FragmentInfo = 0;
256     header.TimeToLive = MY_IP_TTL;
257     header.Protocol = protocol;
258     header.HeaderChecksum = 0;
259     header.SourceAddress = AppConfig.MyIPAddr;
260    
261     header.DestAddress.Val = remote->IPAddr.Val;
262    
263     SwapIPHeader(&header);
264    
265     header.HeaderChecksum = CalcIPChecksum((BYTE*)&header, sizeof(header));
266    
267     MACPutHeader(&remote->MACAddr, MAC_IP, (sizeof(header)+len));
268     MACPutArray((BYTE*)&header, sizeof(header));
269    
270     return 0x0000;
271    
272     }
273    
274     /*********************************************************************
275     * Function: IPSetRxBuffer(WORD Offset)
276     *
277     * PreCondition: IPHeaderLen must have been intialized by
278     * IPGetHeader() or IPPutHeader()
279     *
280     * Input: Offset from beginning of IP data field
281     *
282     * Output: Next Read/Write access to receive buffer is
283     * set to Offset
284     *
285     * Side Effects: None
286     *
287     * Note: None
288     *
289     ********************************************************************/
290     void IPSetRxBuffer(WORD Offset)
291     {
292     MACSetReadPtrInRx(Offset+IPHeaderLen);
293     }
294    
295    
296    
297     static void SwapIPHeader(IP_HEADER* h)
298     {
299     h->TotalLength = swaps(h->TotalLength);
300     h->Identification = swaps(h->Identification);
301     h->HeaderChecksum = swaps(h->HeaderChecksum);
302     }

  ViewVC Help
Powered by ViewVC 1.1.20