]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/net/common/v2_0/include/dhcp.h
unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / packages / net / common / v2_0 / include / dhcp.h
1 #ifndef CYGONCE_NET_TCPIP_DHCP_H
2 #define CYGONCE_NET_TCPIP_DHCP_H
3
4 //==========================================================================
5 //
6 //      include/dhcp.h
7 //
8 //      DHCP protocol support
9 //
10 //==========================================================================
11 //####BSDCOPYRIGHTBEGIN####
12 //
13 // -------------------------------------------
14 //
15 // Portions of this software may have been derived from OpenBSD or other sources,
16 // and are covered by the appropriate copyright disclaimers included herein.
17 //
18 // -------------------------------------------
19 //
20 //####BSDCOPYRIGHTEND####
21 //==========================================================================
22 //#####DESCRIPTIONBEGIN####
23 //
24 // Author(s):    hmt
25 // Contributors: gthomas
26 // Date:         2000-07-01
27 // Purpose:      Support DHCP initialization in eCos TCPIP stack
28 // Description:  
29 //              
30 //
31 //####DESCRIPTIONEND####
32 //
33 //==========================================================================
34
35 // 
36 // DHCP.  RFC2131, RFC1533, RFC1534
37 // See also bootp.h
38 // 
39
40 #include <pkgconf/system.h>
41 #include <pkgconf/net.h>
42
43 #ifdef CYGPKG_NET_DHCP
44
45 #include <machine/types.h>
46
47 #include <cyg/kernel/kapi.h>
48
49 #include <bootp.h>
50
51 // DHCP messages; these are sent in the tag TAG_DHCP_MESS_TYPE already
52 // defined in bootp.h
53
54 #define DHCPDISCOVER    1
55 #define DHCPOFFER       2
56 #define DHCPREQUEST     3
57 #define DHCPDECLINE     4
58 #define DHCPACK         5
59 #define DHCPNAK         6
60 #define DHCPRELEASE     7
61
62 // DHCP interface state machine states; these are published so that app
63 // code can know what to do... (see page 35 of RFC2131)
64
65 // These we will use in the normal course of events
66 #define DHCPSTATE_INIT             1
67 #define DHCPSTATE_SELECTING        2 // wait for replies to b/c DISCOVER
68 #define DHCPSTATE_REQUESTING       3
69 #define DHCPSTATE_REQUEST_RECV     4 // wait for replies to b/c REQUEST
70 #define DHCPSTATE_BOUND            5
71 #define DHCPSTATE_RENEWING         6 // wait for replies to u/c REQUEST
72 #define DHCPSTATE_RENEW_RECV       7
73 #define DHCPSTATE_REBINDING        8 // wait for replies to b/c REQUEST
74 #define DHCPSTATE_REBIND_RECV      9
75 #define DHCPSTATE_BOOTP_FALLBACK  10 // fall back to plain bootp
76 #define DHCPSTATE_NOTBOUND        11 // To let app tidy up
77 #define DHCPSTATE_FAILED          12 // Net is down
78 #define DHCPSTATE_DO_RELEASE      13 // Force release of the current lease
79 // These we don't use
80 //#define DHCPSTATE_INITREBOOT
81 //#define DHCPSTATE_REBOOTING
82
83 // These are to let the app inspect the state of the interfaces when
84 // managing them itself, by analogy with eth0_up &c; eth0_bootp_data and so
85 // on will still be used with DHCP.
86 #ifdef CYGHWR_NET_DRIVER_ETH0
87 extern cyg_uint8   eth0_dhcpstate;
88 #endif
89 #ifdef CYGHWR_NET_DRIVER_ETH1
90 extern cyg_uint8   eth1_dhcpstate;
91 #endif
92
93 // This is public so the app can wait on it or poll it when managing DHCP
94 // itself.  It will be zero while the app should wait, and posted when a
95 // call to do_dhcp() is needed.  If, instead, the app wishes to manage DHCP
96 // with a thread per interface somehow, then separate semaphores may be used.
97 // See the dhcp_lease structure definition below.
98 extern cyg_sem_t dhcp_needs_attention;
99
100 // This routine is used at startup time, and after relinquishing leases or
101 // after a lease timeout: it does DHCP or bootp or static setup according
102 // to configuration.
103 extern void init_all_network_interfaces(void);
104
105 // This routine does the work of renewing leases &c.
106 // return value: 1 => everything OK, no change.
107 // 0 => close your connections, then call do_dhcp_halt() to halt the
108 // interface(s) in question (it knows because the state will be NOTBOUND).
109 // After that you can return to the start and use
110 // init_all_network_interfaces() as usual.
111 extern int dhcp_bind( void );
112
113 // Shutdown any interface which is not already shut down - whether
114 // initialized by DHCP or not.  Reason: because of the broadcast-while-not-
115 // -fully-initialized nature of the DHCP conversation, all other interfaces
116 // must be shut down during that.  So one down, all down, is required.
117 extern int dhcp_halt( void );
118
119 // Release (and set state to DHCPSTATE_NOTBOUND) all interfaces - we are
120 // closing down.  (unlikely but useful for testing)
121 // Interfaces are left up; use dhcp_halt() to bring them right down, then
122 // call init_all_network_interfaces() as usual to restart all.
123 extern int dhcp_release( void );
124
125 // The intent with this API is that a simple DHCP client thread, which
126 // maintains the state of the interfaces, can go as follows:
127 // (after init_all_networks is called from elsewhere)
128 //
129 //    while ( 1 ) {
130 //        while ( 1 ) {
131 //            cyg_semaphore_wait( &dhcp_needs_attention );
132 //            if ( ! dhcp_bind() ) // a lease expired
133 //                break; // If we need to re-bind
134 //        }
135 //        dhcp_halt(); // tear everything down
136 //        init_all_network_interfaces(); // re-initialize
137 //    }
138 //
139 // and if the application does not want to suffer the overhead of a
140 // separate thread and its stack for this, this functionality can be placed
141 // in the app's server loop in an obvious fashion.  That is the goal of
142 // breaking out these internal elements.  For example, some server might
143 // be arranged to poll DHCP from time to time like this:
144 //
145 //    while ( 1 ) {
146 //        init_all_network_interfaces();
147 //        open-my-listen-sockets();
148 //        while ( 1 ) {
149 //            serve-one-request();
150 //            // sleeps if no connections, but not forever; so this loop is
151 //            // polled a few times a minute...
152 //            if ( cyg_semaphore_trywait( &dhcp_needs_attention )) {
153 //                if ( ! dhcp_bind() ) {
154 //                    close-my-listen-sockets();
155 //                    dhcp_halt();
156 //                    break;
157 //                }
158 //            }
159 //        }
160 //    }
161 //
162 // ------------------------------------------------------------------------
163
164 // Set hostname to be used with the DHCP TAG_HOST_NAME option.
165 // Call this before calling init_all_network_interfaces() to
166 // set the hostname value.
167 #ifdef CYGOPT_NET_DHCP_OPTION_HOST_NAME
168 extern void dhcp_set_hostname(char *hostname);
169 #else
170 #define dhcp_set_hostname(hostname)        CYG_EMPTY_STATEMENT
171 #endif
172
173 #ifdef CYGOPT_NET_DHCP_DHCP_THREAD
174 // Then we provide such a thread...
175
176 // Provide a separate thread to renew DHCP leases; otherwise the
177 // application MUST periodically examine the semaphore dhcp_needs_attention
178 // and call dhcp_bind() if it is signalled.  If enabled, this thread does
179 // all that for you.  Independent of this option, initialization of the
180 // interfaces still occurs in init_all_network_interfaces() and your
181 // startup code must call that.  It will start the DHCP management thread
182 // if necessary.  If a lease fails to be renewed, the management thread
183 // will shut down all interfaces and attempt to initialize all the
184 // interfaces again from scratch.  This may cause chaos in the app, which
185 // is why managing the DHCP state in an application aware thread is
186 // actually better, just far less convenient for testing.
187
188 extern cyg_handle_t dhcp_mgt_thread_h; // To allow its external manipulation.
189 extern cyg_thread   dhcp_mgt_thread;   // The object itself
190
191 extern void dhcp_start_dhcp_mgt_thread( void );
192
193 #endif
194
195 // The function is provided unconditionally so that the app can put it in a
196 // thread of its own.  If the parameter is true, it loops forever; if
197 // false, the call returns if a lease expires, and the caller must tidy up
198 // or reboot the whole machine.
199 extern cyg_thread_entry_t dhcp_mgt_entry;
200 extern void dhcp_mgt_entry( cyg_addrword_t loop_on_failure ); // the function
201
202 // ---------------------------------------------------------------------------
203 // These are rather more internal routines, internal to the protocol engine
204 // in dhcp_prot.c - those above are in dhcp_support.c
205
206 #define DHCP_LEASE_T1 1
207 #define DHCP_LEASE_T2 2
208 #define DHCP_LEASE_EX 4
209
210 struct dhcp_lease {
211     // Client settable: Semaphore to signal when attention is needed:
212     cyg_sem_t          *needs_attention;
213     // Initialize all the rest to zero:
214     cyg_tick_count_t    t1, t2, expiry;
215     volatile cyg_uint8  next;
216     volatile cyg_uint8  which;
217     cyg_handle_t        alarm;
218     // except this one, which is just some space:
219     cyg_alarm           alarm_obj;
220 };
221
222 // These dhcp_lease objects are initialized to use
223 //         extern cyg_sem_t dhcp_needs_attention;
224 // for the semaphore.
225 #ifdef CYGHWR_NET_DRIVER_ETH0
226 extern struct dhcp_lease eth0_lease;
227 #endif
228 #ifdef CYGHWR_NET_DRIVER_ETH1
229 extern struct dhcp_lease eth1_lease;
230 #endif
231
232 extern int
233 do_dhcp(const char *interface, struct bootp *res,
234         cyg_uint8 *pstate, struct dhcp_lease *lease);
235 // NB *res and *pstate and *lease are all INOUT; *res must point to a valid
236 // record from "last time".
237
238 extern int
239 do_dhcp_down_net(const char *intf, struct bootp *res,
240         cyg_uint8 *pstate, struct dhcp_lease *lease);
241
242 extern int
243 do_dhcp_release(const char *intf, struct bootp *res,
244         cyg_uint8 *pstate, struct dhcp_lease *lease);
245
246 #endif // CYGPKG_NET_DHCP
247
248 #endif // CYGONCE_NET_TCPIP_DHCP_H
249 // EOF dhcp.h