From 184b03ff8dc0f82af4efdee6fa1e7e85a2080ac7 Mon Sep 17 00:00:00 2001 From: hpa Date: Tue, 14 Sep 1999 04:44:54 +0000 Subject: [PATCH] Checkpoint: parse tsize OACK packet. --- pxelinux.asm | 93 ++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 66 insertions(+), 27 deletions(-) diff --git a/pxelinux.asm b/pxelinux.asm index b51cc1a..e407ad5 100644 --- a/pxelinux.asm +++ b/pxelinux.asm @@ -172,9 +172,9 @@ fat_seg equ 0h ; BOGUS struc tftp_port_t tftp_localport resw 1 ; Local port number (0 = not in use) tftp_remoteport resw 1 ; Remote port number -tftp_localip resd 1 ; Local IP address tftp_remoteip resd 1 ; Remote IP address tftp_filepos resd 1 ; Position within file +tftp_filesize resd 1 ; Total file size endstruc %if (tftp_port_t_size & (tftp_port_t_size-1)) @@ -2189,7 +2189,6 @@ tftp_connect: mov di,packet_buf_size mov [pxe_udp_read_pkt.buffersize],di mov eax,[bootp.yip] ; Our own IP - mov [bx+tftp_localip],eax mov [pxe_udp_read_pkt.dip],eax mov [pxe_udp_read_pkt.lport],bx mov di,pxe_udp_read_pkt @@ -2227,50 +2226,84 @@ tftp_connect: mov [bx+tftp_remoteport],ax movzx eax,word [pxe_udp_read_pkt.buffersize] - sub eax, byte 4 - jb .failure ; Garbled reply + sub eax, byte 2 + jb near .failure ; Garbled reply mov [bx+tftp_filepos], eax cmp word [packet_buf], TFTP_ERROR - je .bailnow ; ERROR reply: don't try again + je near .bailnow ; ERROR reply: don't try again - ; SHOULD REALLY SEND ERROR PACKET HERE! - cmp word [packet_buf], TFTP_DATA - je .no_tsize - - ; SHOULD REALLY SEND ERROR PACKET HERE! cmp word [packet_buf], TFTP_OACK - jne .failure ; Non-OACK reply -> error - - cmp word [packet_buf+2], htons(1) - jne .failure ; Packet # != 1 + jne .err_reply ; Now we need to parse the OACK packet to get the transfer ; size. - ; **** WE SHOULD NOT ACK THIS PACKET YET **** -.ackpacket: mov word [packet_buf], TFTP_ACK - mov [pxe_udp_write_pkt.buffersize], word 4 +.parse_oack: mov cx,[pxe_udp_read_pkt.buffersize] + mov si,packet_buf+2 + sub cx,byte 2 + jz .no_tsize ; No options acked +.get_opt_name: mov di,si + mov bx,si +.opt_name_loop: lodsb + and al,al + jz .got_opt_name + or al,20h ; Convert to lowercase + stosb + loop .opt_name_loop + ; We ran out, and no final null + jmp short .err_reply +.got_opt_name: dec cx + jz .failure ; Option w/o value + push cx + mov si,bx + mov di,tsize_str + mov cx,tsize_len + repe cmpsb + pop cx + jne .err_reply ; Bad option -> error +.get_value: xor eax,eax + xor edx,edx +.value_loop: lodsb + and al,al + jz .got_value + sub al,'0' + cmp al, 9 + ja .err_reply + imul edx,10 + add edx,eax + loop .value_loop + ; Ran out before final null + jmp short .err_reply +.got_value: dec cx + jnz .err_reply ; Not end of packet + ; Move size into DX:AX (old calling convention) + ; but let EAX == DX:AX + mov eax,edx + shr edx,16 + + xor edi,edi - mov al,'A' - call writechr - - mov di,pxe_udp_write_pkt - mov bx,0033h ; PXENV_UDP_WRITE - call far [PXENVEntry] - jc .failure - cmp word [pxe_udp_write_pkt.status],byte 0 - jne .failure - ; Success, done! pop si ; Junk pop si ; We want the packet ptr in SI + + mov [si+tftp_filesize],eax + mov [si+tftp_filepos],edi + pop bp ; Junk pop bp ; Junk (retry counter) and bp,bp ; BP != 0, ZF <- 0 pop bp ret +.err_reply: ; Option negotiation error. Send ERROR reply. + mov word [pxe_udp_write_pkt.buffer],tftp_opt_err + mov word [pxe_udp_write_pkt.buffersize],tftp_opt_err_len + mov di,pxe_udp_write_pkt + mov bx,0033h ; PXENV_UDP_WRITE + call far [PXENVEntry] + .no_tsize: mov si,err_oldtftp call writestr jmp kaboom @@ -3387,6 +3420,12 @@ MySocket dw 32768 ; Local UDP socket counter ; tftp_tail db 'octet', 0, 'tsize' ,0, '0', 0 ; Octet mode, request size tftp_tail_len equ ($-tftp_tail) +tsize_str db 'tsize', 0 +tsize_len equ ($-tsize_str) +tftp_opt_err dw TFTP_ERROR ; ERROR packet + dw htons(8) ; ERROR 8: bad options + db 'tsize option required', 0 ; Error message +tftp_opt_err_len equ ($-tftp_opt_err) ; ; Stuff for the command line; we do some trickery here with equ to avoid -- 2.7.4