From: H. Peter Anvin Date: Tue, 9 Jun 2009 05:19:41 +0000 (-0700) Subject: PXELINUX: handle OACK packets with extra NULs, cleaner TFTP error X-Git-Tag: syslinux-3.82-pre5^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6e969f3b4359125780868d9747bc59bbeee86a9e;p=platform%2Fupstream%2Fsyslinux.git 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 --- diff --git a/NEWS b/NEWS index bdc46cb..5a18525 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 9d9d5b4..de1b10c 100644 --- a/core/pxelinux.asm +++ b/core/pxelinux.asm @@ -1106,6 +1106,15 @@ searchdir: .parse_oack: jcxz .done_pkt ; No options acked .get_opt_name: + ; 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: stosb 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 mov bx,PXENV_UDP_WRITE 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