PXELINUX: handle OACK packets with extra NULs, cleaner TFTP error
[people/sha0/syslinux.git] / core / pxelinux.asm
index 9d9d5b4..de1b10c 100644 (file)
@@ -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