From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1XAhoy-0008Fo-69 for mharc-grub-devel@gnu.org; Fri, 25 Jul 2014 11:54:12 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34559) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XAhoq-0008Dj-7Q for grub-devel@gnu.org; Fri, 25 Jul 2014 11:54:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XAhof-0005of-CS for grub-devel@gnu.org; Fri, 25 Jul 2014 11:54:04 -0400 Received: from mail-lb0-x232.google.com ([2a00:1450:4010:c04::232]:59233) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XAhof-0005oS-4P for grub-devel@gnu.org; Fri, 25 Jul 2014 11:53:53 -0400 Received: by mail-lb0-f178.google.com with SMTP id c11so3615619lbj.9 for ; Fri, 25 Jul 2014 08:53:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=XfDQODbIHFkQG6XWeZv3AZwvMe/EmxjvZo2SAJiI14w=; b=CTlN2F0GzdVuuYyKUHJN6pycG75Ra95QynQX3+gxR9gqEfGXlEltqjq7pFvVHPNZAZ npW9dJIhujLOwaoNUBkJ6X9BfCU3K6xxEZoVSGlcg8kc710E3IZoOw6Qv81g2AFcmsY3 OKsutC4YKZNrzxgTAf3tH/L24uXvekkfpDkhRHPpun2Gga5yvUm7nYkbwKIdg476IwSm 4/K2orlA6UV/mkKWFaKwhGqqDrNvqVctTP653DkcGOWrdzrtE7fsSwlpYTOSlTJ86AkE AbfO5ZATXVh0rRge77kO0TCz90KIuOJFplWXjT2eCZ6rWiE9TaPDosOqC0KD7ce44yep czdw== X-Received: by 10.112.148.10 with SMTP id to10mr3412515lbb.77.1406303632042; Fri, 25 Jul 2014 08:53:52 -0700 (PDT) Received: from localhost.localdomain (ppp94-29-76-101.pppoe.spdop.ru. [94.29.76.101]) by mx.google.com with ESMTPSA id w7sm6824206laj.9.2014.07.25.08.53.51 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 25 Jul 2014 08:53:51 -0700 (PDT) From: Andrey Borzenkov To: grub-devel@gnu.org Subject: [PATCH] fix PXE transmit failure if P_UNKNOWN is not supported Date: Fri, 25 Jul 2014 19:53:42 +0400 Message-Id: <1406303622-31501-1-git-send-email-arvidjaar@gmail.com> X-Mailer: git-send-email 1.8.4.5 X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:4010:c04::232 Cc: Beeblebrox X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list Reply-To: The development of GNU GRUB List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 25 Jul 2014 15:54:10 -0000 Some PXE stacks do not support P_UNKNOWN in UNDI TRANSMIT; nothing is sent at all. So strip Ethernet header for known frame types and let PXE stack add it. PXE implementation that fail is e.g. 64bit_foxconn with PXE-2.0 (build 082) NIC: SIS900 PXE BootROM v1.09 Hook Int19 Reported-By: Beeblebrox Tested-By: Beeblebrox --- grub-core/net/drivers/i386/pc/pxe.c | 46 ++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/grub-core/net/drivers/i386/pc/pxe.c b/grub-core/net/drivers/i386/pc/pxe.c index e8c0b22..3d78bdd 100644 --- a/grub-core/net/drivers/i386/pc/pxe.c +++ b/grub-core/net/drivers/i386/pc/pxe.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -38,6 +39,11 @@ GRUB_MOD_LICENSE ("GPLv3+"); #define SEGOFS(x) ((SEGMENT(x) << 16) + OFFSET(x)) #define LINEAR(x) (void *) ((((x) >> 16) << 4) + ((x) & 0xFFFF)) +#define P_UNKNOWN 0 +#define P_IP 1 +#define P_ARP 2 +#define P_RARP 3 + struct grub_pxe_undi_open { grub_uint16_t status; @@ -256,22 +262,56 @@ grub_pxe_send (struct grub_net_card *dev __attribute__ ((unused)), struct grub_pxe_undi_transmit *trans; struct grub_pxe_undi_tbd *tbd; char *buf; + grub_uint8_t *dst; + grub_uint16_t type; trans = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; grub_memset (trans, 0, sizeof (*trans)); + dst = (void *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + 128 - 6); + /* First 6 bytes are destination address */ + grub_memcpy (dst, pack->data, 6); + + /* Some PXE stacks do not support P_UNKNOWN. So strip Ethernet + header for known protocols and let PXE implementation add it */ + grub_memcpy (&type, pack->data + 12, 2); + switch (type) + { + case grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_IP): + trans->protocol = P_IP; + break; + case grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_ARP): + trans->protocol = P_ARP; + break; + /* grub does not use RARP */ + default: + trans->protocol = P_UNKNOWN; + break; + } + if (trans->protocol) + { + grub_err_t err; + + err = grub_netbuff_pull (pack, 14); + if (err) + return err; + if (dst[0] == 0xff && dst[1] == 0xff && dst[2] == 0xff && + dst[3] == 0xff && dst[4] == 0xff && dst[5] == 0xff) + trans->xmitflag = 1; + else + trans->dest = SEGOFS ((grub_addr_t) dst); + } + tbd = (void *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + 128); grub_memset (tbd, 0, sizeof (*tbd)); buf = (void *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + 256); grub_memcpy (buf, pack->data, pack->tail - pack->data); - trans->tbd = SEGOFS ((grub_addr_t) tbd); - trans->protocol = 0; tbd->len = pack->tail - pack->data; tbd->buf = SEGOFS ((grub_addr_t) buf); grub_pxe_call (GRUB_PXENV_UNDI_TRANSMIT, trans, pxe_rm_entry); if (trans->status) - return grub_error (GRUB_ERR_IO, N_("couldn't send network packet")); + return grub_error (GRUB_ERR_IO, N_("couldn't send network packet, PXE status: 0x%04x"), trans->status); return 0; } -- tg: (0901e78..) e/pxe-send-fix (depends on: master)