Date: Mon, 17 Feb 2003 20:09:53 -0800 (PST) From: Matthew Dillon <dillon@apollo.backplane.com> To: freebsd-hackers@freebsd.org Subject: DHCP problem with pxeboot over wireless via LinkSys WAP11 Message-ID: <200302180409.h1I49rnR048462@apollo.backplane.com>
next in thread | raw e-mail | index | archive | help
I came across an interesting problem trying to pxeboot a diskless machine over a wireless network. The sequence of events goes like this: network bios: network bios issues DHCP request from 0.0.0.0 (via wireless bridge) my dhcp server replies network bios sets IP address network bios loads pxeboot successfully pxeboot runs: pxeboot issues DHCP request from <IP> (ip assigned by network bios) mh dhcp server replies LinkSys WAP11 eats the reply. poof gone. [repeat until pxeboot gives up] I think the LinkSys is just plain broken but it's weird that the network bios was able to issue a request without the reply getting eaten, and the kernel (once one is able to boot that far) is also able to issue a request and get a reply that isn't eaten. And yet the reply to pxeboot's bootp() request gets eaten by the WAP11 every time. It works fine on a hard line, but blows up through the wireless. Anyone see this before? In anycase, I found a solution, which is to extract the RFC1048 data from the PXE cache in the PXE code. Then if the PXE's bootp() attempt fails (which it does for me :-( ), it can use the data extracted from the PXE cache to set the appropriate variables. This patch is for -stable and it needs a bit of cleaning up, and still has some debugging, and the bootp() call is #if 0'd out to test the PXE cache data interpretation, but once cleaned up I believe it can be committed and, in fact, we might be able to avoid having to call bootp() at all if the PXE cache has all the necessary info. -Matt Matthew Dillon <dillon@backplane.com> Index: i386/libi386/pxe.c =================================================================== RCS file: /home/ncvs/src/sys/boot/i386/libi386/pxe.c,v retrieving revision 1.3.2.9 diff -u -r1.3.2.9 pxe.c --- i386/libi386/pxe.c 15 Mar 2001 08:35:54 -0000 1.3.2.9 +++ i386/libi386/pxe.c 18 Feb 2003 04:02:51 -0000 @@ -96,6 +96,7 @@ extern u_int16_t __pxenvseg; extern u_int16_t __pxenvoff; extern void __pxenventry(void); +extern struct in_addr servip; struct netif_dif pxe_ifs[] = { /* dif_unit dif_nsel dif_stats dif_private */ @@ -256,6 +257,7 @@ char temp[FNAME_SIZE]; int error = 0; int i; + struct iodesc *d; va_start(args, f); devname = va_arg(args, char*); @@ -273,16 +275,49 @@ if (pxe_debug) printf("pxe_open: netif_open() succeeded\n"); } + if (!(d = socktodesc(pxe_sock))) { + printf("pxe_open: bad socket. %d\n", pxe_sock); + return (ENXIO); + } if (rootip.s_addr == 0) { /* + * Try to extract the RFC1048 data from PXE + * + * It turns out that at some wireless bridges/access-points + * eat dhcpd responses to pxeboot's bootp requests. This + * may save us if the bootp() attempt below fails. In fact, + * if we get enough info we can skip the bootp() attempt XXX. + */ + if (dhcp_try_rfc1048(bootplayer.vendor.d, BOOTP_DHCPVEND)) + printf("pxe_open: no RFC1048 data in PXE Cache\n"); + else + printf("pxe_open: loaded RFC1048 data from PXE Cache\n"); + + /* * Do a bootp/dhcp request to find out where our * NFS/TFTP server is. Even if we dont get back * the proper information, fall back to the server * which brought us to life and a default rootpath. */ +#if 0 bootp(pxe_sock, BOOTP_PXE); +#endif + + /* + * Failsafe + */ if (rootip.s_addr == 0) rootip.s_addr = bootplayer.sip; + if (gateip.s_addr == 0) + gateip.s_addr = bootplayer.gip; + if (myip.s_addr == 0) + myip.s_addr = bootplayer.yip; + if (servip.s_addr == 0) + servip = rootip; + if (d->myip.s_addr == 0) + d->myip = myip; + printf("d->MYIP %04x d->servip %04x\n", d->myip.s_addr, servip.s_addr); + if (!rootpath[1]) strcpy(rootpath, PXENFSROOTPATH); @@ -503,6 +538,7 @@ bzero(udpopen_p, sizeof(*udpopen_p)); udpopen_p->src_ip = bootplayer.yip; + pxe_call(PXENV_UDP_OPEN); if (udpopen_p->status != 0) { @@ -549,7 +585,7 @@ { t_PXENV_UDP_WRITE *udpwrite_p = (t_PXENV_UDP_WRITE *)scratch_buffer; bzero(udpwrite_p, sizeof(*udpwrite_p)); - + udpwrite_p->ip = h->destip.s_addr; udpwrite_p->dst_port = h->destport; udpwrite_p->src_port = h->myport; Index: bootp.c =================================================================== RCS file: /home/ncvs/src/lib/libstand/bootp.c,v retrieving revision 1.1.1.1.6.2 diff -u -r1.1.1.1.6.2 bootp.c --- bootp.c 20 Sep 2000 18:37:25 -0000 1.1.1.1.6.2 +++ bootp.c 18 Feb 2003 03:52:34 -0000 @@ -335,6 +335,16 @@ return (-1); } +int +dhcp_try_rfc1048(u_char *cp, u_int len) +{ + expected_dhcpmsgtype = DHCPACK; + if (bcmp(vm_rfc1048, cp, sizeof(vm_rfc1048)) == 0) { + return(vend_rfc1048(cp, len)); + } + return(-1); +} + static int vend_rfc1048(cp, len) register u_char *cp; @@ -356,6 +366,7 @@ while (cp < ep) { tag = *cp++; size = *cp++; + if (tag == TAG_END) break; To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200302180409.h1I49rnR048462>