OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [ecos-2.0/] [packages/] [redboot/] [v2_0/] [src/] [net/] [bootp.c] - Blame information for rev 1773

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1254 phoenix
//==========================================================================
2
//
3
//      net/bootp.c
4
//
5
//      Stand-alone minimal BOOTP 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 <redboot.h>
57
#include <net/net.h>
58
#include <net/bootp.h>
59
 
60
extern int net_debug;
61
 
62
#define SHOULD_BE_RANDOM  0x12345555
63
 
64
/* How many milliseconds to wait before retrying the request */
65
#define RETRY_TIME  1000
66
#define MAX_RETRIES   30
67
 
68
static bootp_header_t *bp_info;
69
 
70
#ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
71
static const unsigned char dhcpCookie[] = {99,130,83,99};
72
static const unsigned char dhcpEndOption[] = {255};
73
static const unsigned char dhcpRequestOption[] = {52,1,3};
74
#endif
75
 
76
static void
77
bootp_handler(udp_socket_t *skt, char *buf, int len,
78
              ip_route_t *src_route, word src_port)
79
{
80
    bootp_header_t *b;
81
#ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
82
    unsigned char *p,*end;
83
    int optlen;
84
#endif
85
 
86
    b = (bootp_header_t *)buf;
87
    if (bp_info) {
88
        memset(bp_info,0,sizeof *bp_info);
89
        if (len > sizeof *bp_info)
90
            len = sizeof *bp_info;
91
        memcpy(bp_info, b, len);
92
    }
93
 
94
    // Only accept pure REPLY responses
95
    if (b->bp_op != BOOTREPLY)
96
      return;
97
 
98
    // Must be sent to me, as well!
99
    if (memcmp(b->bp_chaddr, __local_enet_addr, 6))
100
      return;
101
 
102
    memcpy(__local_ip_addr, &b->bp_yiaddr, 4);
103
#ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
104
    memcpy(__local_ip_gate, &b->bp_giaddr, 4);
105
 
106
    if (memcmp(b->bp_vend, dhcpCookie, sizeof(dhcpCookie)))
107
      return;
108
 
109
    optlen = len - (b->bp_vend - ((unsigned char*)b));
110
 
111
    p = b->bp_vend+4;
112
    end = ((unsigned char*)b) + len;
113
 
114
    while (p < end) {
115
        unsigned char tag = *p;
116
        if (tag == TAG_END)
117
          break;
118
        if (tag == TAG_PAD)
119
          optlen = 1;
120
        else {
121
            optlen = p[1];
122
            p += 2;
123
            switch (tag) {
124
             case TAG_SUBNET_MASK:  // subnet mask
125
                memcpy(__local_ip_mask,p,4);
126
                break;
127
             case TAG_GATEWAY:  // router
128
                memcpy(__local_ip_gate,p,4);
129
                break;
130
             default:
131
                break;
132
            }
133
        }
134
        p += optlen;
135
    }
136
#endif
137
}
138
 
139
#define AddOption(p,d) do {memcpy(p,d,sizeof d); p += sizeof d;} while (0)
140
 
141
/*
142
 * Find our IP address and copy to __local_ip_addr.
143
 * Return zero if successful, -1 if not.
144
 */
145
int
146
__bootp_find_local_ip(bootp_header_t *info)
147
{
148
    udp_socket_t udp_skt;
149
    bootp_header_t b;
150
    ip_route_t     r;
151
    int            retry;
152
    unsigned long  start;
153
    ip_addr_t saved_ip_addr;
154
#ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
155
    unsigned char *p;
156
#endif
157
    int txSize;
158
 
159
    bp_info = info;
160
 
161
    memset(&b, 0, sizeof(b));
162
 
163
    b.bp_op = BOOTREQUEST;
164
    b.bp_htype = HTYPE_ETHERNET;
165
    b.bp_hlen = 6;
166
    b.bp_xid = SHOULD_BE_RANDOM;
167
 
168
#ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
169
    p = b.bp_vend;
170
 
171
    AddOption(p,dhcpCookie);
172
    AddOption(p,dhcpRequestOption);
173
    AddOption(p,dhcpEndOption);
174
 
175
    // Some servers insist on a minimum amount of "vendor" data
176
    if (p < &b.bp_vend[BP_MIN_VEND_SIZE]) p = &b.bp_vend[BP_MIN_VEND_SIZE];
177
    txSize = p - (unsigned char*)&b;
178
#else
179
    txSize = sizeof(b);
180
#endif
181
 
182
    memcpy( saved_ip_addr, __local_ip_addr, sizeof(__local_ip_addr) );
183
    memset( __local_ip_addr, 0, sizeof(__local_ip_addr) );
184
 
185
    memcpy(b.bp_chaddr, __local_enet_addr, 6);
186
 
187
    /* fill out route for a broadcast */
188
    r.ip_addr[0] = 255;
189
    r.ip_addr[1] = 255;
190
    r.ip_addr[2] = 255;
191
    r.ip_addr[3] = 255;
192
    r.enet_addr[0] = 255;
193
    r.enet_addr[1] = 255;
194
    r.enet_addr[2] = 255;
195
    r.enet_addr[3] = 255;
196
    r.enet_addr[4] = 255;
197
    r.enet_addr[5] = 255;
198
 
199
    /* setup a socket listener for bootp replies */
200
    __udp_install_listener(&udp_skt, IPPORT_BOOTPC, bootp_handler);
201
 
202
    retry = MAX_RETRIES;
203
    while (retry-- > 0) {
204
        start = MS_TICKS();
205
 
206
        __udp_send((char *)&b, txSize, &r, IPPORT_BOOTPS, IPPORT_BOOTPC);
207
 
208
        do {
209
            __enet_poll();
210
            if (__local_ip_addr[0] || __local_ip_addr[1] ||
211
                __local_ip_addr[2] || __local_ip_addr[3]) {
212
                /* success */
213
                __udp_remove_listener(IPPORT_BOOTPC);
214
                return 0;
215
            }
216
        } while ((MS_TICKS_DELAY() - start) < RETRY_TIME);
217
    }
218
 
219
    /* timed out */
220
    __udp_remove_listener(IPPORT_BOOTPC);
221
    net_debug = 0;
222
    memcpy( __local_ip_addr, saved_ip_addr, sizeof(__local_ip_addr));
223
    return -1;
224
}
225
 
226
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.