diff options
authorH. Peter Anvin <hpa@zytor.com>2009-06-08 22:19:41 -0700
committerH. Peter Anvin <hpa@zytor.com>2009-06-08 22:19:41 -0700
commit6e969f3b4359125780868d9747bc59bbeee86a9e (patch)
parent9147554cd1ab47d51fd4f50a001f05fa665ecfd0 (diff)
PXELINUX: handle OACK packets with extra NULs, cleaner TFTP error
There are apparently TFTP servers in the field which will send OACK packets with extra NUL bytes appended at the end. If we find an OACK packet where the only thing left at some point during processing is NULs, then just consider the packet processed. We have reported all TFTP protocol errors as "tsize required", which is definitely not true anymore. Change error code to 0 (undefined) and the error string to "TFTP error". When this code gets converted to C we'll do better. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
2 files changed, 23 insertions, 11 deletions
diff --git a/NEWS b/NEWS
index bdc46cbc..5a18525b 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,8 @@ Changes in 3.82:
interrupts disabled.
* Do not invoke the idle handler during large file loads.
* Simple menu: make ONTIMEOUT work with MENU HIDDEN.
+ * PXELINUX: handle TFTP servers which have extra NULs at the
+ end of an OACK packet.
Changes in 3.81:
* Shuffler: fix bug in real-mode entry. This affected a
diff --git a/core/pxelinux.asm b/core/pxelinux.asm
index 9d9d5b4d..de1b10c3 100644
--- a/core/pxelinux.asm
+++ b/core/pxelinux.asm
@@ -1106,6 +1106,15 @@ searchdir:
jcxz .done_pkt ; No options acked
+ ; Some TFTP servers have junk NUL bytes at the end of the packet.
+ ; If all that is left is NUL, then consider the packet processed.
+ mov di,si
+ push cx
+ xor ax,ax
+ repz scasb
+ pop cx
+ jz .done_pkt
mov di,si
mov bx,si
.opt_name_loop: lodsb
@@ -1115,10 +1124,10 @@ searchdir:
loop .opt_name_loop
; We ran out, and no final null
- jmp .err_reply
+ jmp .done_pkt ; Ignore runt option
.got_opt_name: ; si -> option value
dec cx ; bytes left in pkt
- jz .err_reply ; Option w/o value
+ jz .done_pkt ; Option w/o value, ignore
; Parse option pointed to by bx; guaranteed to be
; null-terminated.
@@ -1141,7 +1150,8 @@ searchdir:
pop si
pop cx
- jmp .err_reply ; Non-negotiated option returned
+ ; Non-negotiated option returned, no idea what it means...
+ jmp .err_reply
.get_value: pop si ; si -> option value
pop cx ; cx -> bytes left in pkt
@@ -1221,13 +1231,13 @@ searchdir:
pop es
jmp .done_pkt
-.err_reply: ; Option negotiation error. Send ERROR reply.
+.err_reply: ; TFTP protocol error. Send ERROR reply.
; ServerIP and gateway are already programmed in
mov si,[bp-6]
mov ax,[si+tftp_remoteport]
mov word [pxe_udp_write_pkt.rport],ax
- mov word [pxe_udp_write_pkt.buffer],tftp_opt_err
- mov word [pxe_udp_write_pkt.buffersize],tftp_opt_err_len
+ mov word [pxe_udp_write_pkt.buffer],tftp_proto_err
+ mov word [pxe_udp_write_pkt.buffersize],tftp_proto_err_len
mov di,pxe_udp_write_pkt
call pxenv
@@ -2725,12 +2735,12 @@ tftp_opt_table:
tftp_opts equ ($-tftp_opt_table)/6
-; Error packet to return on options negotiation error
+; Error packet to return on TFTP protocol error
-tftp_opt_err dw TFTP_ERROR ; ERROR packet
- dw TFTP_EOPTNEG ; ERROR 8: bad options
- db 'tsize option required', 0 ; Error message
-tftp_opt_err_len equ ($-tftp_opt_err)
+tftp_proto_err dw TFTP_ERROR ; ERROR packet
+ dw TFTP_EUNDEF ; ERROR 0: undefined
+ db 'TFTP protocol error', 0 ; Error message
+tftp_proto_err_len equ ($-tftp_proto_err)
alignz 4
ack_packet_buf: dw TFTP_ACK, 0 ; TFTP ACK packet