|
@@ -43,23 +43,20 @@
|
43
|
43
|
* pxenv_udp_read(). (If s_PXENV_UDP_OPEN::src_ip is 0.0.0.0, the
|
44
|
44
|
* local station's IP address will remain unchanged.)
|
45
|
45
|
*
|
46
|
|
- * You can have multiple UDP connections open simultaneously (and
|
47
|
|
- * even open concurrently with TFTP connections), provided that
|
|
46
|
+ * You can only have one open UDP connection at a time. You cannot
|
|
47
|
+ * have a UDP connection open at the same time as a TFTP connection.
|
|
48
|
+ * (This is not strictly true for Etherboot; see the relevant @ref
|
|
49
|
+ * pxe_note_udp "implementation note" for more details.)
|
48
|
50
|
*
|
49
|
|
- * - they all have the same local IP address, and
|
|
51
|
+ * On x86, you must set the s_PXE::StatusCallout field to a nonzero
|
|
52
|
+ * value before calling this function in protected mode. You cannot
|
|
53
|
+ * call this function with a 32-bit stack segment. (See the relevant
|
|
54
|
+ * @ref pxe_x86_pmode16 "implementation note" for more details.)
|
50
|
55
|
*
|
51
|
|
- * - you take the multiple connections into account when calling
|
52
|
|
- * pxenv_udp_read().
|
53
|
|
- *
|
54
|
|
- * On x86, you can call pxenv_udp_open() in real mode, 16-bit
|
55
|
|
- * protected mode with a 16-bit stack segment, 16-bit protected mode
|
56
|
|
- * with a 32-bit stack segment, or V86 mode. The pxe::StatusCallout
|
57
|
|
- * field may be zero even in protected mode.
|
58
|
|
- *
|
59
|
|
- * @note The PXE specification states that you have only one UDP
|
60
|
|
- * connection open at a time, and that you cannot have a UDP
|
61
|
|
- * connection open simultaneously with a TFTP connection. Etherboot
|
62
|
|
- * does not enforce this unnecessary restriction.
|
|
56
|
+ * @note The PXE specification does not make it clear whether the IP
|
|
57
|
+ * address supplied in s_PXENV_UDP_OPEN::src_ip should be used only
|
|
58
|
+ * for this UDP connection, or retained for all future communication.
|
|
59
|
+ * The latter seems more consistent with typical PXE stack behaviour.
|
63
|
60
|
*
|
64
|
61
|
*/
|
65
|
62
|
PXENV_EXIT_t pxenv_udp_open ( struct s_PXENV_UDP_OPEN *udp_open ) {
|
|
@@ -85,21 +82,19 @@ PXENV_EXIT_t pxenv_udp_open ( struct s_PXENV_UDP_OPEN *udp_open ) {
|
85
|
82
|
* @ret s_PXENV_UDP_CLOSE::Status PXE status code
|
86
|
83
|
* @err None -
|
87
|
84
|
*
|
88
|
|
- * Closes a UDP "connection" opened with pxenv_udp_open(). Since UDP
|
89
|
|
- * is a connectionless protocol, this is a no-op.
|
90
|
|
- *
|
91
|
|
- * You can call pxenv_udp_close() even if there is another active UDP
|
92
|
|
- * or TFTP connection, since it has no effect on anything.
|
|
85
|
+ * Closes a UDP "connection" opened with pxenv_udp_open().
|
93
|
86
|
*
|
94
|
|
- * You can call pxenv_udp_close() in real mode, 16-bit protected mode
|
95
|
|
- * with a 16-bit stack segment, 16-bit protected mode with a 32-bit
|
96
|
|
- * stack segment, or V86 mode. The pxe::StatusCallout field may be
|
97
|
|
- * zero even in protected mode.
|
|
87
|
+ * You can only have one open UDP connection at a time. You cannot
|
|
88
|
+ * have a UDP connection open at the same time as a TFTP connection.
|
|
89
|
+ * You cannot use pxenv_udp_close() to close a TFTP connection; use
|
|
90
|
+ * pxenv_tftp_close() instead. (This is not strictly true for
|
|
91
|
+ * Etherboot; see the relevant @ref pxe_note_udp "implementation note"
|
|
92
|
+ * for more details.)
|
98
|
93
|
*
|
99
|
|
- * @note The PXE specification states that you have only one UDP
|
100
|
|
- * connection open at a time, and that you cannot have a UDP
|
101
|
|
- * connection open simultaneously with a TFTP connection. Etherboot
|
102
|
|
- * does not enforce this unnecessary restriction.
|
|
94
|
+ * On x86, you must set the s_PXE::StatusCallout field to a nonzero
|
|
95
|
+ * value before calling this function in protected mode. You cannot
|
|
96
|
+ * call this function with a 32-bit stack segment. (See the relevant
|
|
97
|
+ * @ref pxe_x86_pmode16 "implementation note" for more details.)
|
103
|
98
|
*
|
104
|
99
|
*/
|
105
|
100
|
PXENV_EXIT_t pxenv_udp_close ( struct s_PXENV_UDP_CLOSE *udp_close __unused ) {
|
|
@@ -119,7 +114,7 @@ PXENV_EXIT_t pxenv_udp_close ( struct s_PXENV_UDP_CLOSE *udp_close __unused ) {
|
119
|
114
|
* @v s_PXENV_UDP_WRITE::buffer_size Length of the UDP payload
|
120
|
115
|
* @v s_PXENV_UDP_WRITE::buffer Address of the UDP payload
|
121
|
116
|
* @ret #PXENV_EXIT_SUCCESS Packet was transmitted successfully
|
122
|
|
- * @ret #PXENV_EXIT_FAILURE Packet could not be transmitter
|
|
117
|
+ * @ret #PXENV_EXIT_FAILURE Packet could not be transmitted
|
123
|
118
|
* @ret s_PXENV_UDP_WRITE::Status PXE status code
|
124
|
119
|
* @err #PXENV_STATUS_UNDI_INVALID_STATE NIC could not be initialised
|
125
|
120
|
* @err #PXENV_STATUS_OUT_OF_RESOURCES Packet was too large to transmit
|
|
@@ -138,20 +133,15 @@ PXENV_EXIT_t pxenv_udp_close ( struct s_PXENV_UDP_CLOSE *udp_close __unused ) {
|
138
|
133
|
*
|
139
|
134
|
* If s_PXENV_UDP_WRITE::src_port is 0, port 2069 will be used.
|
140
|
135
|
*
|
141
|
|
- * It is not necessary to call pxenv_udp_open() before using
|
142
|
|
- * pxenv_udp_write(), unless you want to change the local station's IP
|
143
|
|
- * address. pxenv_udp_write() can be called even if there is another
|
144
|
|
- * active UDP or TFTP connection,.
|
145
|
|
- *
|
146
|
|
- * You can call pxenv_udp_write() in real mode, 16-bit protected mode
|
147
|
|
- * with a 16-bit stack segment, 16-bit protected mode with a 32-bit
|
148
|
|
- * stack segment, or V86 mode. The pxe::StatusCallout field may be
|
149
|
|
- * zero even in protected mode.
|
|
136
|
+ * You must have opened a UDP connection with pxenv_udp_open() before
|
|
137
|
+ * calling pxenv_udp_write(). (This is not strictly true for
|
|
138
|
+ * Etherboot; see the relevant @ref pxe_note_udp "implementation note"
|
|
139
|
+ * for more details.)
|
150
|
140
|
*
|
151
|
|
- * @note The PXE specification states that you have only one UDP
|
152
|
|
- * connection open at a time, and that you cannot have a UDP
|
153
|
|
- * connection open simultaneously with a TFTP connection. Etherboot
|
154
|
|
- * does not enforce this unnecessary restriction.
|
|
141
|
+ * On x86, you must set the s_PXE::StatusCallout field to a nonzero
|
|
142
|
+ * value before calling this function in protected mode. You cannot
|
|
143
|
+ * call this function with a 32-bit stack segment. (See the relevant
|
|
144
|
+ * @ref pxe_x86_pmode16 "implementation note" for more details.)
|
155
|
145
|
*
|
156
|
146
|
* @bug s_PXENV_UDP_WRITE::gw is ignored; the default routing table is
|
157
|
147
|
* always used.
|
|
@@ -278,26 +268,20 @@ static int await_pxe_udp ( int ival __unused, void *ptr,
|
278
|
268
|
* s_PXENV_UDP_READ::Status==PXENV_STATUS_FAILURE.
|
279
|
269
|
*
|
280
|
270
|
* If s_PXENV_UDP_READ::dest_ip is 0.0.0.0, UDP packets addressed to
|
281
|
|
- * any IP address will be accepted and may be returned.
|
|
271
|
+ * any IP address will be accepted and may be returned to the caller.
|
282
|
272
|
*
|
283
|
273
|
* If s_PXENV_UDP_READ::d_port is 0, UDP packets addressed to any UDP
|
284
|
|
- * port will be accepted and may be returned.
|
|
274
|
+ * port will be accepted and may be returned to the caller.
|
285
|
275
|
*
|
286
|
|
- * It is not necessary to call pxenv_udp_open() before using
|
287
|
|
- * pxenv_udp_read(). pxenv_udp_read() can be called even if there is
|
288
|
|
- * another active UDP or TFTP connection, but be aware that you might
|
289
|
|
- * then receive (or cause to be lost) a packet belonging to another
|
290
|
|
- * connection.
|
|
276
|
+ * You must have opened a UDP connection with pxenv_udp_open() before
|
|
277
|
+ * calling pxenv_udp_read(). (This is not strictly true for
|
|
278
|
+ * Etherboot; see the relevant @ref pxe_note_udp "implementation note"
|
|
279
|
+ * for more details.)
|
291
|
280
|
*
|
292
|
|
- * You can call pxenv_udp_read() in real mode, 16-bit protected mode
|
293
|
|
- * with a 16-bit stack segment, 16-bit protected mode with a 32-bit
|
294
|
|
- * stack segment, or V86 mode. The pxe::StatusCallout field may be
|
295
|
|
- * zero even in protected mode.
|
296
|
|
- *
|
297
|
|
- * @note The PXE specification states that you have only one UDP
|
298
|
|
- * connection open at a time, and that you cannot have a UDP
|
299
|
|
- * connection open simultaneously with a TFTP connection. Etherboot
|
300
|
|
- * does not enforce this unnecessary restriction.
|
|
281
|
+ * On x86, you must set the s_PXE::StatusCallout field to a nonzero
|
|
282
|
+ * value before calling this function in protected mode. You cannot
|
|
283
|
+ * call this function with a 32-bit stack segment. (See the relevant
|
|
284
|
+ * @ref pxe_x86_pmode16 "implementation note" for more details.)
|
301
|
285
|
*
|
302
|
286
|
* @note The PXE specification (version 2.1) does not state that we
|
303
|
287
|
* should fill in s_PXENV_UDP_READ::dest_ip and
|
|
@@ -319,3 +303,31 @@ PXENV_EXIT_t pxenv_udp_read ( struct s_PXENV_UDP_READ *udp_read ) {
|
319
|
303
|
udp_read->Status = PXENV_STATUS_SUCCESS;
|
320
|
304
|
return PXENV_EXIT_SUCCESS;
|
321
|
305
|
}
|
|
306
|
+
|
|
307
|
+/** @page pxe_notes PXE implementation notes
|
|
308
|
+
|
|
309
|
+@section pxe_note_udp The connectionless nature of UDP
|
|
310
|
+
|
|
311
|
+The PXE specification states that it is possible to have only one open
|
|
312
|
+UDP or TFTP connection at any one time. Etherboot does not
|
|
313
|
+rigourously enforce this restriction, on the UNIX principle that the
|
|
314
|
+code should not prevent the user from doing stupid things, because
|
|
315
|
+that would also prevent the user from doing clever things. Since UDP
|
|
316
|
+is a connectionless protocol, it is perfectly possible to have
|
|
317
|
+multiple concurrent UDP "connections" open, provided that you take the
|
|
318
|
+multiplicity of connections into account when calling
|
|
319
|
+pxenv_udp_read(). Similarly, there is no technical reason that
|
|
320
|
+prevents you from calling pxenv_udp_write() in the middle of a TFTP
|
|
321
|
+download.
|
|
322
|
+
|
|
323
|
+Etherboot will therefore never return error codes indicating "a
|
|
324
|
+connection is already open", such as #PXENV_STATUS_UDP_OPEN. If you
|
|
325
|
+want to have multiple concurrent connections, go for it (but don't
|
|
326
|
+expect your perfectly sensible code to work with any other PXE stack).
|
|
327
|
+
|
|
328
|
+Since Etherboot treats UDP as the connectionless protocol that it
|
|
329
|
+really is, pxenv_udp_close() is actually a no-op, and there is no need
|
|
330
|
+to call pxenv_udp_open() before using pxenv_udp_write() or
|
|
331
|
+pxenv_udp_read().
|
|
332
|
+
|
|
333
|
+*/
|