]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/net/common/v2_0/tests/dhcp_test2.c
unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / packages / net / common / v2_0 / tests / dhcp_test2.c
1 //==========================================================================
2 //
3 //      tests/dhcp_test2.c
4 //
5 //      Test of repeatedly releasing and reacquiring DHCP leases
6 //
7 //==========================================================================
8 //####BSDCOPYRIGHTBEGIN####
9 //
10 // -------------------------------------------
11 //
12 // Portions of this software may have been derived from OpenBSD or other sources,
13 // and are covered by the appropriate copyright disclaimers included herein.
14 //
15 // -------------------------------------------
16 //
17 //####BSDCOPYRIGHTEND####
18 //==========================================================================
19 //#####DESCRIPTIONBEGIN####
20 //
21 // Author(s):    hmt, tomislav.sostaric@ascom.ch
22 // Contributors: 
23 // Date:         2002-03-11
24 // Purpose:      Test repeated up-down cycles of interfaces with DHCP.
25 // Description:  
26 //              
27 //
28 //####DESCRIPTIONEND####
29 //
30 //==========================================================================
31
32 /* 
33  * A test program for bringing out the DHCP memory leak bug
34  * This file is in the public domain and may be used for any purpose
35  */
36
37 /* INCLUDES */
38
39 #include <network.h>
40
41 #include <pkgconf/system.h>
42 #include <pkgconf/net.h>
43
44 #include <cyg/infra/testcase.h>
45
46 #ifdef CYGPKG_NET_DHCP
47
48 #ifdef CYGBLD_DEVS_ETH_DEVICE_H    // Get the device config if it exists
49 #include CYGBLD_DEVS_ETH_DEVICE_H  // May provide CYGTST_DEVS_ETH_TEST_NET_REALTIME
50 #endif
51
52
53 #include <stdio.h>                      /* printf */
54 #include <string.h>                     /* strlen */
55 #include <cyg/kernel/kapi.h>            /* All the kernel specific stuff */
56 #include <cyg/io/io.h>                  /* I/O functions */
57 #include <cyg/hal/hal_arch.h>           /* CYGNUM_HAL_STACK_SIZE_TYPICAL */
58 #include <network.h>
59 #include <dhcp.h>
60
61 // ------------------------------------------------------------------------
62
63 #define FALSE 0
64 #define TRUE 1
65 #define TICKS_PER_SEC 100
66
67 #define nLOOPS 1000000
68 #define LOOPS 10
69
70 // ------------------------------------------------------------------------
71
72 #define NINTERFACES (2)
73
74 struct bootp bootp_data[ NINTERFACES ];
75 cyg_uint8 state[ NINTERFACES ];
76 struct dhcp_lease lease[ NINTERFACES ];
77 int up[ NINTERFACES ], oldup[ NINTERFACES ];
78
79 char *eth[ NINTERFACES ] = { "eth0", "eth1" };
80
81 int counter = 0;
82
83 void
84 tdhcp_init( int which )
85 {
86     printf("%s: Initializing device to use DHCP.\n", eth[which] );
87     bzero( &bootp_data[which], sizeof( *bootp_data ) );
88     state[which] = 0;
89     bzero( &lease[which], sizeof( *lease ) );
90     up[which] = oldup[which] = FALSE;
91 }
92
93
94 void
95 tdhcp_do_one( int which )
96 {
97     oldup[which] = up[which];
98     up[which] = do_dhcp( eth[which], &bootp_data[which], &state[which], &lease[which] );
99 }
100
101 void
102 tdhcp_updown_one( int which )
103 {
104     /* DHCP wants interface to go up or down, do it. */
105     if (up[which] != oldup[which]) {
106         if (up[which]) {
107             char tbuf[256];
108             int result;
109
110             result = init_net( eth[which], &bootp_data[which]);
111             if (!result) {
112                 printf("%s: Initialization (DHCP) failed.\n", eth[which] );
113                 return;
114             }
115             
116             if (lease[which].expiry == (cyg_tick_count_t)-1) {
117                 strcpy(tbuf, "infinite");
118             } else {
119                 cyg_tick_count_t now;
120                 unsigned int exp;
121                 
122                 now = cyg_current_time();
123                 exp = ((lease[which].expiry > now) ? lease[which].expiry - now : 0) / TICKS_PER_SEC;
124                 sprintf(tbuf, "%ud %uh %um %us", exp / 86400, 
125                         (exp / 3600) % 24, (exp / 60) % 60, exp % 60);
126             }
127             printf("%s: Configured by DHCP, IP address %s, "
128                    "lease expiry: %s.\n", eth[which], 
129                    inet_ntoa(bootp_data[which].bp_yiaddr), tbuf);
130             printf("%s: Interface ready\n", eth[which] );
131         } else {
132             printf("%s: Deconfigured by DHCP.\n", eth[which] );
133             cyg_thread_delay(10);
134             do_dhcp_down_net( eth[which], &bootp_data[which], &state[which], &lease[which]);
135             state[which] = DHCPSTATE_INIT;
136         }
137     }
138 }
139
140 void
141 tdhcp_release_one( int which )
142 {
143     /* If DHCP failed (most probably because there was no DHCP server around),
144      * sleep a bit, then try again. Otherwise, just wait until DHCP needs our
145      * attention.
146      */
147     if (state[which] == DHCPSTATE_FAILED) {
148         printf("%s: DHCP failed, will retry later.\n", eth[which] );
149         cyg_thread_delay(10);
150         printf("%s: Retrying DHCP.\n", eth[which] );
151     }
152     cyg_thread_delay(10);
153     printf("%s: Releasing DHCP lease.\n", eth[which] );
154     do_dhcp_release( eth[which], &bootp_data[which], &state[which], &lease[which]);
155     cyg_thread_delay(10);
156     up[which] = FALSE;
157     state[which] = DHCPSTATE_INIT;
158 }
159
160
161 static void
162 dhcp_if_fn(cyg_addrword_t data)
163 {
164     CYG_TEST_INIT();
165
166 #ifdef CYGHWR_NET_DRIVER_ETH0
167     tdhcp_init( 0 );
168 #endif // CYGHWR_NET_DRIVER_ETH0
169 #ifdef CYGHWR_NET_DRIVER_ETH1
170     tdhcp_init( 1 );
171 #endif // CYGHWR_NET_DRIVER_ETH1
172     
173     while ( ++counter < LOOPS ) {
174         diag_printf( "--------- counter %d ---------\n", counter );
175 #ifdef CYGHWR_NET_DRIVER_ETH0
176         tdhcp_do_one( 0 );
177 #endif // CYGHWR_NET_DRIVER_ETH0
178 #ifdef CYGHWR_NET_DRIVER_ETH1
179         tdhcp_do_one( 1 );
180 #endif // CYGHWR_NET_DRIVER_ETH1
181
182 #ifdef CYGHWR_NET_DRIVER_ETH0
183         tdhcp_updown_one( 0 );
184 #endif // CYGHWR_NET_DRIVER_ETH0
185 #ifdef CYGHWR_NET_DRIVER_ETH1
186         tdhcp_updown_one( 1 );
187 #endif // CYGHWR_NET_DRIVER_ETH1
188
189 #ifdef CYGHWR_NET_DRIVER_ETH0
190         tdhcp_release_one( 0 );
191 #endif // CYGHWR_NET_DRIVER_ETH0
192 #ifdef CYGHWR_NET_DRIVER_ETH1
193         tdhcp_release_one( 1 );
194 #endif // CYGHWR_NET_DRIVER_ETH1
195     }
196     CYG_TEST_PASS_EXIT( "All done" );
197 }
198
199
200 // ------------------------------------------------------------------------
201
202 #define NTHREADS 1
203 #define STACKSIZE ( CYGNUM_HAL_STACK_SIZE_TYPICAL + 4096 )
204
205 static cyg_handle_t thread[NTHREADS];
206 static cyg_thread thread_obj[NTHREADS];
207 static char stack[NTHREADS][STACKSIZE];
208
209 void cyg_user_start(void)
210 {
211     // Use the DHCP thread prio as provided even though we're not using the thread itself;
212     // This priroty should be right (lower than net thread prio) by default.
213     cyg_thread_create(CYGPKG_NET_DHCP_THREAD_PRIORITY, dhcp_if_fn, (cyg_addrword_t) 0, "dhcp",
214                       (void *)stack[0], STACKSIZE, &thread[0], &thread_obj[0]);
215     cyg_thread_resume(thread[0]);
216 }
217
218 // ------------------------------------------------------------------------
219
220 #else // CYGPKG_NET_DHCP
221
222 void cyg_user_start(void)
223 {
224     CYG_TEST_INIT();
225     CYG_TEST_NA( "DHCP is not enabled" );
226     CYG_TEST_EXIT( "DHCP is not enabled" );
227 }
228
229 #endif // CYGPKG_NET_DHCP
230
231 // ------------------------------------------------------------------------
232
233 // EOF dhcp_test2.c