]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/net/common/v2_0/src/dhcp_support.c
unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / packages / net / common / v2_0 / src / dhcp_support.c
1 /*==========================================================================
2 //
3 //      dhcp_support.c
4 //
5 //      Support code == friendly API for DHCP client
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 //
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
42 //
43 // Author(s):   hmt
44 // Contributors: gthomas
45 // Date:        2000-07-01
46 // Purpose:     DHCP support
47 // Description: 
48 //
49 //####DESCRIPTIONEND####
50 //
51 //========================================================================*/
52
53 #include <pkgconf/system.h>
54 #include <pkgconf/net.h>
55
56 #ifdef CYGPKG_NET_DHCP
57
58 #include <network.h>
59 #include <dhcp.h>
60
61 // ---------------------------------------------------------------------------
62 #ifdef CYGHWR_NET_DRIVER_ETH0
63 cyg_uint8   eth0_dhcpstate = 0;
64 #endif
65 #ifdef CYGHWR_NET_DRIVER_ETH1
66 cyg_uint8   eth1_dhcpstate = 0;
67 #endif
68
69 cyg_sem_t dhcp_needs_attention;
70
71 #ifdef CYGHWR_NET_DRIVER_ETH0
72 struct dhcp_lease eth0_lease = { &dhcp_needs_attention, 0,0,0,0,0,0 };
73 #endif
74 #ifdef CYGHWR_NET_DRIVER_ETH1
75 struct dhcp_lease eth1_lease = { &dhcp_needs_attention, 0,0,0,0,0,0 };
76 #endif
77
78 // ---------------------------------------------------------------------------
79 //
80 // The point of this module is to deal with all the horrid written out in
81 // full stuff of having two interfaces; it's ugly but it's also most
82 // flexible.  The dhcp_prot.c module should do all the work... 
83 //
84 // ---------------------------------------------------------------------------
85
86 // return value: 1 => everything OK, no change.
87 // 0 => close your connections, then call do_dhcp_halt() to halt the
88 // interface(s) in question (it knows because the state will be NOTBOUND).
89 // After that you can return to the start and use
90 // init_all_network_interfaces(); as usual, or call do_dhcp_bind() by hand,
91 // or whatever...
92 int dhcp_bind( void )
93 {
94 #ifdef CYGHWR_NET_DRIVER_ETH0
95     cyg_uint8 old_eth0_dhcpstate = eth0_dhcpstate;
96 #endif
97 #ifdef CYGHWR_NET_DRIVER_ETH1
98     cyg_uint8 old_eth1_dhcpstate = eth1_dhcpstate;
99 #endif
100
101     // If there are no interfaces at all, init it every time, doesn't
102     // matter.  In case we are called from elsewhere...
103     if ( 1
104 #ifdef CYGHWR_NET_DRIVER_ETH0
105          && eth0_dhcpstate == 0
106 #endif
107 #ifdef CYGHWR_NET_DRIVER_ETH1
108          && eth1_dhcpstate == 0
109 #endif
110         )
111         cyg_semaphore_init( &dhcp_needs_attention, 0 );
112
113     // Run the state machine...
114 #ifdef CYGHWR_NET_DRIVER_ETH0
115     if (eth0_up
116         && DHCPSTATE_FAILED != eth0_dhcpstate )
117             eth0_up = do_dhcp(eth0_name, &eth0_bootp_data, &eth0_dhcpstate, &eth0_lease);
118 #endif            
119 #ifdef CYGHWR_NET_DRIVER_ETH1
120     if (eth1_up
121         && DHCPSTATE_FAILED != eth1_dhcpstate )
122             eth1_up = do_dhcp(eth1_name, &eth1_bootp_data, &eth1_dhcpstate, &eth1_lease);
123 #endif            
124
125     // If the interface newly came up, initialize it:
126     // (this duplicates the code in init_all_network_interfaces() really).
127 #ifdef CYGHWR_NET_DRIVER_ETH0
128     if ( eth0_up
129          && eth0_dhcpstate == DHCPSTATE_BOUND
130          && old_eth0_dhcpstate != eth0_dhcpstate ) {
131         if (!init_net(eth0_name, &eth0_bootp_data)) {
132             eth0_up = false;
133         }
134     }
135 #endif
136 #ifdef CYGHWR_NET_DRIVER_ETH1
137     if ( eth1_up
138          && eth1_dhcpstate == DHCPSTATE_BOUND
139          && old_eth1_dhcpstate != eth1_dhcpstate ) {
140         if (!init_net(eth1_name, &eth1_bootp_data)) {
141             eth1_up = false;
142         }
143     }
144 #endif
145
146 #ifdef CYGHWR_NET_DRIVER_ETH0
147     if ( old_eth0_dhcpstate == DHCPSTATE_BOUND &&
148          eth0_dhcpstate == DHCPSTATE_NOTBOUND )
149         return 0; // a lease timed out; we became unbound
150 #endif
151 #ifdef CYGHWR_NET_DRIVER_ETH1
152     if ( old_eth1_dhcpstate == DHCPSTATE_BOUND &&
153          eth1_dhcpstate == DHCPSTATE_NOTBOUND )
154         return 0; // a lease timed out; we became unbound
155 #endif
156     return 1; // all is well
157 }
158
159
160 // Shutdown any interface whose state is DHCPSTATE_NOTBOUND.
161 int dhcp_halt( void )
162 {
163 #ifdef CYGHWR_NET_DRIVER_ETH0
164     if ( eth0_up
165          && eth0_dhcpstate != DHCPSTATE_FAILED ) {
166         do_dhcp_down_net(eth0_name, &eth0_bootp_data, &eth0_dhcpstate, &eth0_lease);
167     }
168     eth0_up = false;
169 #endif
170 #ifdef CYGHWR_NET_DRIVER_ETH1
171     if ( eth1_up
172          && eth1_dhcpstate != DHCPSTATE_FAILED ) {
173         do_dhcp_down_net(eth1_name, &eth1_bootp_data, &eth1_dhcpstate, &eth1_lease);
174     }
175     eth1_up = false;
176 #endif
177     return 1;
178 }
179
180
181 // Release (and set state to DHCPSTATE_NOTBOUND) all interfaces - we are
182 // closing down.  (unlikely but maybe useful for testing)
183 int dhcp_release( void )
184 {
185 #ifdef CYGHWR_NET_DRIVER_ETH0
186     if (eth0_up)
187         do_dhcp_release(eth0_name, &eth0_bootp_data, &eth0_dhcpstate, &eth0_lease);
188 #endif
189 #ifdef CYGHWR_NET_DRIVER_ETH1
190     if (eth1_up)
191         do_dhcp_release(eth1_name, &eth1_bootp_data, &eth1_dhcpstate, &eth1_lease);
192 #endif
193     return 1;
194 }
195
196
197 // ------------------------------------------------------------------------
198 // The management thread function
199 //
200 // Note: 2007-01-15
201 //  This single management thread attempts to keep all configured
202 //  interfaces alive via DHCP.  While this may be sufficient for 
203 //  many systems, it falls short of perfect.  There should probably
204 //  be a separate thread for each possible interface, along with
205 //  appropriate CDL to control how each inteface is managed.
206 //
207 void dhcp_mgt_entry( cyg_addrword_t loop_on_failure )
208 {
209     int j;
210     bool any_interfaces_up;
211
212     while ( 1 ) {
213         while ( 1 ) {
214             cyg_semaphore_wait( &dhcp_needs_attention );
215             if ( ! dhcp_bind() ) // a lease expired
216                 break; // If we need to re-bind
217         }
218         dhcp_halt(); // tear everything down
219         if ( !loop_on_failure )
220             return; // exit the thread/return
221         do {
222             init_all_network_interfaces(); // re-initialize
223             // If at least one interface is up, then the DHCP machine will run
224             any_interfaces_up = false;
225 #ifdef CYGHWR_NET_DRIVER_ETH0
226             any_interfaces_up |= eth0_up;
227 #endif
228 #ifdef CYGHWR_NET_DRIVER_ETH1
229             any_interfaces_up |= eth1_up;
230 #endif
231         } while (!any_interfaces_up);
232         for ( j = 0; j < CYGPKG_NET_NLOOP; j++ )
233             init_loopback_interface( j );
234 #ifdef CYGPKG_SNMPAGENT
235         SnmpdShutDown(0); // Cycle the snmpd state
236 #endif
237     }
238 }
239
240 #ifdef CYGOPT_NET_DHCP_DHCP_THREAD
241 // Then we provide such a thread...
242 cyg_handle_t dhcp_mgt_thread_h = 0;
243 cyg_thread   dhcp_mgt_thread;
244
245 static cyg_uint8 dhcp_mgt_stack[ CYGPKG_NET_DHCP_THREAD_STACK_SIZE ];
246
247 void dhcp_start_dhcp_mgt_thread( void )
248 {
249     if ( ! dhcp_mgt_thread_h ) {
250         cyg_semaphore_init( &dhcp_needs_attention, 0 );
251         cyg_thread_create(
252             CYGPKG_NET_DHCP_THREAD_PRIORITY,   /* scheduling info (eg pri) */
253             dhcp_mgt_entry,                    /* entry point function */
254             CYGOPT_NET_DHCP_DHCP_THREAD_PARAM, /* entry data */
255             "DHCP lease mgt",                  /* optional thread name */
256             dhcp_mgt_stack,                    /* stack base, NULL = alloc */
257             CYGPKG_NET_DHCP_THREAD_STACK_SIZE, /* stack size, 0 = default */
258             &dhcp_mgt_thread_h,                /* returned thread handle */
259             &dhcp_mgt_thread                   /* put thread here */
260             );
261
262         cyg_thread_resume(dhcp_mgt_thread_h);
263     }
264 }
265
266
267 #endif // CYGOPT_NET_DHCP_DHCP_THREAD
268
269 #endif // CYGPKG_NET_DHCP
270
271 // EOF dhcp_support.c