- Handle ARP requests while idle in pxelinux
authorhpa <hpa>
Tue, 25 Nov 2003 04:12:43 +0000 (04:12 +0000)
committerhpa <hpa>
Tue, 25 Nov 2003 04:12:43 +0000 (04:12 +0000)
- Actually reallocate sockets correctly in pxelinux

NEWS
conio.inc
isolinux.asm
ldlinux.asm
pxelinux.asm
ui.inc

diff --git a/NEWS b/NEWS
index c796e80..26d8267 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,11 @@ Changes in 2.08:
          than just pressing Enter.
        * Fix bugs in the COMBOOT/COM32 command-line parsing.  APPEND
          now works with COMBOOT/COM32 images.
+       * PXELINUX: Poll for ARP requests while sitting at the
+         prompt.  This makes some boot servers a lot less unhappy.
+       * PXELINUX: Actually free sockets when we get a failure
+         (including file not found.)  This bug would cause us to run
+         out of sockets and thus "go deaf" after a while.
 
 Changes in 2.07:
        * MEMDISK: Workaround for BIOSes which go into a snit when
index 7dc1572..58c7e3a 100644 (file)
--- a/conio.inc
+++ b/conio.inc
@@ -319,7 +319,9 @@ pollchar:
 ; getchar: Read a character from keyboard or serial port
 ;
 getchar:
-.again:                mov ah,1                ; Poll keyboard
+.again:
+               DO_IDLE
+               mov ah,1                ; Poll keyboard
                int 16h
                jnz .kbd                ; Keyboard input?
                mov bx,[SerialPort]
index 7b92fd4..e8e9806 100644 (file)
@@ -41,6 +41,13 @@ SECTORSIZE_LG2       equ 11                  ; 2048 bytes/sector (El Torito requirement)
 SECTORSIZE     equ (1 << SECTORSIZE_LG2)
 
 ;
+; This is what we need to do when idle
+;
+%macro DO_IDLE 0
+       ; Nothing
+%endmacro
+
+;
 ; The following structure is used for "virtual kernels"; i.e. LILO-style
 ; option labels.  The options we permit here are `kernel' and `append
 ; Since there is no room in the bottom 64K for all of these, we
index b39c905..251b0f1 100644 (file)
@@ -46,6 +46,13 @@ retry_count  equ 6                   ; How patient are we with the disk?
 %assign HIGHMEM_SLOP 0                 ; Avoid this much memory near the top
 
 ;
+; This is what we need to do when idle
+;
+%macro DO_IDLE 0
+       ; Nothing
+%endmacro
+
+;
 ; The following structure is used for "virtual kernels"; i.e. LILO-style
 ; option labels.  The options we permit here are `kernel' and `append
 ; Since there is no room in the bottom 64K for all of these, we
index fd2877a..1a2f488 100644 (file)
@@ -53,6 +53,13 @@ TFTP_BLOCKSIZE       equ (1 << TFTP_BLOCKSIZE_LG2)
 %assign USE_PXE_PROVIDED_STACK 1       ; Use stack provided by PXE?
 
 ;
+; This is what we need to do when idle
+;
+%macro DO_IDLE 0
+       call check_for_arp
+%endmacro
+
+;
 ; TFTP operation codes
 ;
 TFTP_RRQ       equ htons(1)            ; Read request
@@ -1230,8 +1237,7 @@ searchdir:
                mov [pxe_udp_read_pkt.status],byte 0
                mov [pxe_udp_read_pkt.buffer],di
                mov [pxe_udp_read_pkt.buffer+2],ds
-               mov di,packet_buf_size
-               mov [pxe_udp_read_pkt.buffersize],di
+               mov word [pxe_udp_read_pkt.buffersize],packet_buf_size
                mov eax,[MyIP]
                mov [pxe_udp_read_pkt.dip],eax
                mov [pxe_udp_read_pkt.lport],bx
@@ -1369,6 +1375,7 @@ searchdir:
                and eax,eax             ; Set ZF depending on file size
                pop bp                  ; Junk
                pop bp                  ; Junk (retry counter)
+               jz .error_si            ; ZF = 1 need to free the socket
                pop bp
                pop es
                ret
@@ -1390,8 +1397,7 @@ searchdir:
                call writestr
                jmp kaboom
 
-.bailnow:      add sp,byte 8           ; Immediate error - no retry
-               jmp short .error
+.bailnow:      mov word [bp-2],1       ; Immediate error - no retry
 
 .failure:      pop bx                  ; Junk
                pop bx
@@ -1400,7 +1406,9 @@ searchdir:
                dec ax                  ; Retry counter
                jnz .sendreq            ; Try again
 
-.error:                xor si,si               ; ZF <- 1
+.error:                mov si,bx               ; Socket pointer
+.error_si:                             ; Socket pointer already in SI
+               call free_socket        ; ZF <- 1, SI <- 0
                pop bp
                pop es
                ret
@@ -1450,6 +1458,22 @@ allocate_socket:
                ret
 
 ;
+; Free socket: socket in SI; return SI = 0, ZF = 1 for convenience
+;
+free_socket:
+               push es
+               pusha
+               xor ax,ax
+               mov es,ax
+               mov di,si
+               mov cx,tftp_clear_words
+               rep stosw
+               popa
+               pop es
+               xor si,si
+               ret
+
+;
 ; strcpy: Copy DS:SI -> ES:DI up to and including a null byte
 ;
 strcpy:                push ax
@@ -1659,15 +1683,7 @@ getfssec:        push si
 
                ; The socket is closed and the buffer drained
                ; Close socket structure and re-init for next user
-               push es
-               push ds
-               pop es
-               mov di,si
-               ; ax = 0
-               mov cx,tftp_clear_words
-               rep stosw
-               pop es
-               xor si,si
+               call free_socket
                stc
 .bytes_left:
                ret
@@ -2271,6 +2287,35 @@ genipopt:
                popad
                ret
 
+;
+; Call the receive loop while idle.  This is done mostly so we can respond to
+; ARP messages, but perhaps in the future this can be used to do network
+; console.
+;
+check_for_arp:
+               pushad
+               push ds
+               push es
+               mov ax,cs
+               mov ds,ax
+               mov es,ax
+               mov di,packet_buf
+               mov [pxe_udp_read_pkt.status],al        ; 0
+               mov [pxe_udp_read_pkt.buffer],di
+               mov [pxe_udp_read_pkt.buffer+2],ds
+               mov word [pxe_udp_read_pkt.buffersize],packet_buf_size
+               mov eax,[MyIP]
+               mov [pxe_udp_read_pkt.dip],eax
+               mov [pxe_udp_read_pkt.lport],ax         ; 0
+               mov di,pxe_udp_read_pkt
+               mov bx,PXENV_UDP_READ
+               call pxenv
+               ; Ignore result...
+               pop es
+               pop ds
+               popad
+               ret
+
 ; -----------------------------------------------------------------------------
 ;  Common modules
 ; -----------------------------------------------------------------------------
diff --git a/ui.inc b/ui.inc
index 6e05b9b..cbb451c 100644 (file)
--- a/ui.inc
+++ b/ui.inc
@@ -59,6 +59,7 @@ tick_loop:    push dx
                cmp dx,ax                       ; Has the timer advanced?
                je tick_loop
                pop cx
+               DO_IDLE
                loop time_loop                  ; If so, decrement counter
 
                ; Timeout!!!!