root/ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/ip.c

Revision 12368, 6.1 kB (checked in by BrainSlayer, 5 months ago)

tftp server added, supports wiligear, ubiquiti and dd-wrt webflash format

Line 
1 //==========================================================================
2 //
3 //      net/ip.c
4 //
5 //      Stand-alone IP networking support for RedBoot
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 // Copyright (C) 2002 Gary Thomas
13 //
14 // eCos is free software; you can redistribute it and/or modify it under
15 // the terms of the GNU General Public License as published by the Free
16 // Software Foundation; either version 2 or (at your option) any later version.
17 //
18 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
21 // for more details.
22 //
23 // You should have received a copy of the GNU General Public License along
24 // with eCos; if not, write to the Free Software Foundation, Inc.,
25 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 //
27 // As a special exception, if other files instantiate templates or use macros
28 // or inline functions from this file, or you compile this file and link it
29 // with other works to produce a work based on this file, this file does not
30 // by itself cause the resulting work to be covered by the GNU General Public
31 // License. However the source code for this file must still be made available
32 // in accordance with section (3) of the GNU General Public License.
33 //
34 // This exception does not invalidate any other reasons why a work based on
35 // this file might be covered by the GNU General Public License.
36 //
37 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
38 // at http://sources.redhat.com/ecos/ecos-license/
39 // -------------------------------------------
40 //####ECOSGPLCOPYRIGHTEND####
41 //==========================================================================
42 //#####DESCRIPTIONBEGIN####
43 //
44 // Author(s):    gthomas
45 // Contributors: gthomas
46 // Date:         2000-07-14
47 // Purpose:     
48 // Description: 
49 //             
50 // This code is part of RedBoot (tm).
51 //
52 //####DESCRIPTIONEND####
53 //
54 //==========================================================================
55
56 #include <net/net.h>
57
58 #ifndef CYGDAT_REDBOOT_DEFAULT_IP_ADDR
59 # define CYGDAT_REDBOOT_DEFAULT_IP_ADDR 0, 0, 0, 0
60 #endif
61 #ifndef CYGDAT_REDBOOT_DEFAULT_IP_ADDR_MASK
62 # define CYGDAT_REDBOOT_DEFAULT_IP_ADDR_MASK 255, 255, 255, 0
63 #endif
64 #ifndef CYGDAT_REDBOOT_DEFAULT_GATEWAY_IP_ADDR
65 # define CYGDAT_REDBOOT_DEFAULT_GATEWAY_IP_ADDR 0, 0, 0, 0
66 #endif
67
68 ip_addr_t __local_ip_addr = { CYGDAT_REDBOOT_DEFAULT_IP_ADDR };
69
70 #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
71 ip_addr_t __local_ip_mask = { CYGDAT_REDBOOT_DEFAULT_IP_ADDR_MASK };
72 ip_addr_t __local_ip_gate = { CYGDAT_REDBOOT_DEFAULT_GATEWAY_IP_ADDR };
73 #endif
74
75 static word ip_ident;
76
77 #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
78 /*
79  * See if an address is on the local network
80  */
81 int __ip_addr_local(ip_addr_t * addr)
82 {
83         return !(((__local_ip_addr[0] ^ (*addr)[0]) & __local_ip_mask[0]) |
84                  ((__local_ip_addr[1] ^ (*addr)[1]) & __local_ip_mask[1]) |
85                  ((__local_ip_addr[2] ^ (*addr)[2]) & __local_ip_mask[2]) |
86                  ((__local_ip_addr[3] ^ (*addr)[3]) & __local_ip_mask[3]));
87 }
88 #endif
89
90 /*
91  * Match given IP address to our address.
92  * Check for broadcast matches as well.
93  */
94 static int ip_addr_match(ip_addr_t addr)
95 {
96         if (addr[0] == 255 && addr[1] == 255 && addr[2] == 255
97             && addr[3] == 255)
98                 return 1;
99
100         if (!memcmp(addr, __local_ip_addr, sizeof(ip_addr_t)))
101                 return 1;
102
103         /*
104          * Consider it an address match if we haven't gotten our IP address yet.
105          * Some DHCP servers will address IP packets to the assigned address
106          * instead of a IP broadcast address.
107          */
108         if (__local_ip_addr[0] == 0 && __local_ip_addr[1] == 0 &&
109             __local_ip_addr[2] == 0 && __local_ip_addr[3] == 0)
110                 return 1;
111
112         return 0;
113 }
114
115 extern void __tcp_handler(pktbuf_t *, ip_route_t *);
116
117 /*
118  * Handle IP packets coming from the polled ethernet interface.
119  */
120 void __ip_handler(pktbuf_t * pkt, enet_addr_t * src_enet_addr)
121 {
122         ip_header_t *ip = pkt->ip_hdr;
123         ip_route_t r;
124         int hdr_bytes;
125
126         /* first make sure its ours and has a good checksum. */
127         if (!ip_addr_match(ip->destination) ||
128             __sum((word *) ip, ip->hdr_len << 2, 0) != 0) {
129                 __pktbuf_free(pkt);
130                 return;
131         }
132
133         memcpy(r.ip_addr, ip->source, sizeof(ip_addr_t));
134         memcpy(r.enet_addr, src_enet_addr, sizeof(enet_addr_t));
135
136         hdr_bytes = ip->hdr_len << 2;
137         pkt->pkt_bytes = ntohs(ip->length) - hdr_bytes;
138
139         switch (ip->protocol) {
140
141 #if NET_SUPPORT_ICMP
142         case IP_PROTO_ICMP:
143                 pkt->icmp_hdr = (icmp_header_t *) (((char *)ip) + hdr_bytes);
144                 __icmp_handler(pkt, &r);
145                 break;
146 #endif
147
148 #if NET_SUPPORT_TCP
149         case IP_PROTO_TCP:
150                 pkt->tcp_hdr = (tcp_header_t *) (((char *)ip) + hdr_bytes);
151                 __tcp_handler(pkt, &r);
152                 break;
153 #endif
154
155 #if NET_SUPPORT_UDP
156         case IP_PROTO_UDP:
157                 pkt->udp_hdr = (udp_header_t *) (((char *)ip) + hdr_bytes);
158                 __udp_handler(pkt, &r);
159                 break;
160 #endif
161
162         default:
163                 __pktbuf_free(pkt);
164                 break;
165         }
166 }
167
168 /*
169  * Send an IP packet.
170  *
171  * The IP data field should contain pkt->pkt_bytes of data.
172  * pkt->[udp|tcp|icmp]_hdr points to the IP data field. Any
173  * IP options are assumed to be already in place in the IP
174  * options field.
175  */
176 int __ip_send(pktbuf_t * pkt, int protocol, ip_route_t * dest)
177 {
178         ip_header_t *ip = pkt->ip_hdr;
179         int hdr_bytes;
180         unsigned short cksum;
181
182         /*
183          * Figure out header length. The use udp_hdr is
184          * somewhat arbitrary, but works because it is
185          * a union with other IP protocol headers.
186          */
187         hdr_bytes = (((char *)pkt->udp_hdr) - ((char *)ip));
188
189         pkt->pkt_bytes += hdr_bytes;
190
191         ip->version = 4;
192         ip->hdr_len = hdr_bytes >> 2;
193         ip->tos = 0;
194         ip->length = htons(pkt->pkt_bytes);
195         ip->ident = htons(ip_ident);
196         ip_ident++;
197         ip->fragment = 0;
198         ip->ttl = 255;
199         ip->ttl = 64;
200         ip->protocol = protocol;
201         ip->checksum = 0;
202         memcpy(ip->source, __local_ip_addr, sizeof(ip_addr_t));
203         memcpy(ip->destination, dest->ip_addr, sizeof(ip_addr_t));
204         cksum = __sum((word *) ip, hdr_bytes, 0);
205         ip->checksum = htons(cksum);
206
207         __enet_send(pkt, &dest->enet_addr, ETH_TYPE_IP);
208         return 0;
209 }
Note: See TracBrowser for help on using the browser.