1 //==========================================================================
5 // Stand-alone IP networking support for RedBoot
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
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.
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
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.
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.
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.
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####
45 // Contributors: gthomas
50 // This code is part of RedBoot (tm).
52 //####DESCRIPTIONEND####
54 //==========================================================================
58 #ifndef CYGDAT_REDBOOT_DEFAULT_IP_ADDR
59 # define CYGDAT_REDBOOT_DEFAULT_IP_ADDR 0, 0, 0, 0
61 #ifndef CYGDAT_REDBOOT_DEFAULT_IP_ADDR_MASK
62 # define CYGDAT_REDBOOT_DEFAULT_IP_ADDR_MASK 255, 255, 255, 0
64 #ifndef CYGDAT_REDBOOT_DEFAULT_GATEWAY_IP_ADDR
65 # define CYGDAT_REDBOOT_DEFAULT_GATEWAY_IP_ADDR 0, 0, 0, 0
68 ip_addr_t __local_ip_addr = { CYGDAT_REDBOOT_DEFAULT_IP_ADDR };
69 #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
70 ip_addr_t __local_ip_mask = { CYGDAT_REDBOOT_DEFAULT_IP_ADDR_MASK };
71 ip_addr_t __local_ip_gate = { CYGDAT_REDBOOT_DEFAULT_GATEWAY_IP_ADDR };
76 #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
78 * See if an address is on the local network
81 __ip_addr_local(ip_addr_t *addr)
84 ((__local_ip_addr[0] ^ (*addr)[0]) & __local_ip_mask[0]) |
85 ((__local_ip_addr[1] ^ (*addr)[1]) & __local_ip_mask[1]) |
86 ((__local_ip_addr[2] ^ (*addr)[2]) & __local_ip_mask[2]) |
87 ((__local_ip_addr[3] ^ (*addr)[3]) & __local_ip_mask[3]));
92 * Match given IP address to our address.
93 * Check for broadcast matches as well.
96 ip_addr_match(ip_addr_t addr)
98 if (addr[0] == 255 && addr[1] == 255 && addr[2] == 255 && addr[3] == 255)
101 if (!memcmp(addr, __local_ip_addr, sizeof(ip_addr_t)))
105 * Consider it an address match if we haven't gotten our IP address yet.
106 * Some DHCP servers will address IP packets to the assigned address
107 * instead of a IP broadcast address.
109 if (__local_ip_addr[0] == 0 && __local_ip_addr[1] == 0 &&
110 __local_ip_addr[2] == 0 && __local_ip_addr[3] == 0)
117 extern void __tcp_handler(pktbuf_t *, ip_route_t *);
120 * Handle IP packets coming from the polled ethernet interface.
123 __ip_handler(pktbuf_t *pkt, enet_addr_t *src_enet_addr)
125 ip_header_t *ip = pkt->ip_hdr;
129 /* first make sure its ours and has a good checksum. */
130 if (!ip_addr_match(ip->destination) ||
131 __sum((word *)ip, ip->hdr_len << 2, 0) != 0) {
136 memcpy(r.ip_addr, ip->source, sizeof(ip_addr_t));
137 memcpy(r.enet_addr, src_enet_addr, sizeof(enet_addr_t));
139 hdr_bytes = ip->hdr_len << 2;
140 pkt->pkt_bytes = ntohs(ip->length) - hdr_bytes;
142 switch (ip->protocol) {
146 pkt->icmp_hdr = (icmp_header_t *)(((char *)ip) + hdr_bytes);
147 __icmp_handler(pkt, &r);
153 pkt->tcp_hdr = (tcp_header_t *)(((char *)ip) + hdr_bytes);
154 __tcp_handler(pkt, &r);
160 pkt->udp_hdr = (udp_header_t *)(((char *)ip) + hdr_bytes);
161 __udp_handler(pkt, &r);
175 * The IP data field should contain pkt->pkt_bytes of data.
176 * pkt->[udp|tcp|icmp]_hdr points to the IP data field. Any
177 * IP options are assumed to be already in place in the IP
181 __ip_send(pktbuf_t *pkt, int protocol, ip_route_t *dest)
183 ip_header_t *ip = pkt->ip_hdr;
185 unsigned short cksum;
188 * Figure out header length. The use udp_hdr is
189 * somewhat arbitrary, but works because it is
190 * a union with other IP protocol headers.
192 hdr_bytes = (((char *)pkt->udp_hdr) - ((char *)ip));
194 pkt->pkt_bytes += hdr_bytes;
197 ip->hdr_len = hdr_bytes >> 2;
199 ip->length = htons(pkt->pkt_bytes);
200 ip->ident = htons(ip_ident);
205 ip->protocol = protocol;
207 memcpy(ip->source, __local_ip_addr, sizeof(ip_addr_t));
208 memcpy(ip->destination, dest->ip_addr, sizeof(ip_addr_t));
209 cksum = __sum((word *)ip, hdr_bytes, 0);
210 ip->checksum = htons(cksum);
212 __enet_send(pkt, &dest->enet_addr, ETH_TYPE_IP);