source: SVN/cambria/redboot/packages/redboot/current/src/net/ip.c @ 1

Last change on this file since 1 was 1, checked in by Tim Harvey, 2 years ago

restored latest version of files from server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 6.3 KB
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
68ip_addr_t __local_ip_addr = { CYGDAT_REDBOOT_DEFAULT_IP_ADDR };
69#ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
70ip_addr_t __local_ip_mask = { CYGDAT_REDBOOT_DEFAULT_IP_ADDR_MASK };
71ip_addr_t __local_ip_gate = { CYGDAT_REDBOOT_DEFAULT_GATEWAY_IP_ADDR };
72#endif
73
74static word ip_ident;
75
76#ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
77/*
78 * See if an address is on the local network
79 */
80int 
81__ip_addr_local(ip_addr_t *addr)
82{
83  return !(
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]));
88}
89#endif
90
91/*
92 * Match given IP address to our address.
93 * Check for broadcast matches as well.
94 */
95static int
96ip_addr_match(ip_addr_t addr)
97{
98    if (addr[0] == 255 && addr[1] == 255 && addr[2] == 255 && addr[3] == 255)
99        return 1;
100
101    if (!memcmp(addr, __local_ip_addr, sizeof(ip_addr_t)))
102        return 1;
103
104    /*
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.
108     */
109    if (__local_ip_addr[0] == 0 && __local_ip_addr[1] == 0 &&
110        __local_ip_addr[2] == 0 && __local_ip_addr[3] == 0)
111        return 1;
112
113    return 0;
114}
115
116
117extern void __tcp_handler(pktbuf_t *, ip_route_t *);
118
119/*
120 * Handle IP packets coming from the polled ethernet interface.
121 */
122void
123__ip_handler(pktbuf_t *pkt, enet_addr_t *src_enet_addr)
124{
125    ip_header_t *ip = pkt->ip_hdr;
126    ip_route_t  r;
127    int         hdr_bytes;
128
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) {
132        __pktbuf_free(pkt);
133        return;
134    }
135
136    memcpy(r.ip_addr, ip->source, sizeof(ip_addr_t));
137    memcpy(r.enet_addr, src_enet_addr, sizeof(enet_addr_t));
138
139    hdr_bytes = ip->hdr_len << 2;
140    pkt->pkt_bytes = ntohs(ip->length) - hdr_bytes;
141
142    switch (ip->protocol) {
143
144#if NET_SUPPORT_ICMP
145      case IP_PROTO_ICMP:
146        pkt->icmp_hdr = (icmp_header_t *)(((char *)ip) + hdr_bytes);
147        __icmp_handler(pkt, &r);
148        break;
149#endif
150
151#if NET_SUPPORT_TCP
152      case IP_PROTO_TCP:
153        pkt->tcp_hdr = (tcp_header_t *)(((char *)ip) + hdr_bytes);
154        __tcp_handler(pkt, &r);
155        break;
156#endif
157
158#if NET_SUPPORT_UDP
159      case IP_PROTO_UDP:
160        pkt->udp_hdr = (udp_header_t *)(((char *)ip) + hdr_bytes);
161        __udp_handler(pkt, &r);
162        break;
163#endif
164
165      default:
166        __pktbuf_free(pkt);
167        break;
168    }
169}
170
171
172/*
173 * Send an IP packet.
174 *
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
178 * options field.
179 */
180int
181__ip_send(pktbuf_t *pkt, int protocol, ip_route_t *dest)
182{
183    ip_header_t *ip = pkt->ip_hdr;
184    int         hdr_bytes;
185    unsigned short cksum;
186   
187    /*
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.
191     */
192    hdr_bytes = (((char *)pkt->udp_hdr) - ((char *)ip));
193
194    pkt->pkt_bytes += hdr_bytes;
195
196    ip->version = 4;
197    ip->hdr_len = hdr_bytes >> 2;
198    ip->tos = 0;
199    ip->length = htons(pkt->pkt_bytes);
200    ip->ident = htons(ip_ident);
201    ip_ident++;
202    ip->fragment = 0;
203    ip->ttl = 255;
204    ip->ttl = 64;
205    ip->protocol = protocol;
206    ip->checksum = 0;
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);
211
212    __enet_send(pkt, &dest->enet_addr, ETH_TYPE_IP);   
213    return 0;
214}
215
216
Note: See TracBrowser for help on using the repository browser.