From 16f5c17703a99c5fdef488274a037962b2fb72c1 Mon Sep 17 00:00:00 2001 From: hpa Date: Tue, 25 Nov 2003 04:12:43 +0000 Subject: [PATCH] - Handle ARP requests while idle in pxelinux - Actually reallocate sockets correctly in pxelinux --- NEWS | 5 +++++ conio.inc | 4 +++- isolinux.asm | 7 ++++++ ldlinux.asm | 7 ++++++ pxelinux.asm | 73 ++++++++++++++++++++++++++++++++++++++++++++++++------------ ui.inc | 1 + 6 files changed, 82 insertions(+), 15 deletions(-) diff --git a/NEWS b/NEWS index c796e80..26d8267 100644 --- 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 diff --git a/conio.inc b/conio.inc index 7dc1572..58c7e3a 100644 --- 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] diff --git a/isolinux.asm b/isolinux.asm index 7b92fd4..e8e9806 100644 --- a/isolinux.asm +++ b/isolinux.asm @@ -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 diff --git a/ldlinux.asm b/ldlinux.asm index b39c905..251b0f1 100644 --- a/ldlinux.asm +++ b/ldlinux.asm @@ -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 diff --git a/pxelinux.asm b/pxelinux.asm index fd2877a..1a2f488 100644 --- a/pxelinux.asm +++ b/pxelinux.asm @@ -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 --- 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!!!! -- 2.7.4