diff --git a/lib/libstand/bootp.c b/lib/libstand/bootp.c index 35ccf7a74400..c440c982c54d 100644 --- a/lib/libstand/bootp.c +++ b/lib/libstand/bootp.c @@ -37,6 +37,7 @@ * SUCH DAMAGE. * * @(#) Header: bootp.c,v 1.4 93/09/11 03:13:51 leres Exp (LBL) + * $FreeBSD$ */ #include @@ -80,8 +81,9 @@ struct in_addr dhcp_serverip; /* Fetch required bootp infomation */ void -bootp(sock) +bootp(sock, flag) int sock; + int flag; { struct iodesc *d; register struct bootp *bp; @@ -124,7 +126,19 @@ bootp(sock) bp->bp_vend[4] = TAG_DHCP_MSGTYPE; bp->bp_vend[5] = 1; bp->bp_vend[6] = DHCPDISCOVER; - bp->bp_vend[7] = TAG_END; + + /* + * If we are booting from PXE, we want to send the string + * 'PXEClient' to the DHCP server so you have the option of + * only responding to PXE aware dhcp requests. + */ + if (flag & BOOTP_PXE) { + bp->bp_vend[7] = TAG_CLASSID; + bp->bp_vend[8] = 9; + bcopy("PXEClient", &bp->bp_vend[9], 9); + bp->bp_vend[18] = TAG_END; + } else + bp->bp_vend[7] = TAG_END; #else bp->bp_vend[4] = TAG_END; #endif @@ -161,7 +175,13 @@ bootp(sock) bp->bp_vend[20] = 4; leasetime = htonl(300); bcopy(&leasetime, &bp->bp_vend[21], 4); - bp->bp_vend[25] = TAG_END; + if (flag & BOOTP_PXE) { + bp->bp_vend[25] = TAG_CLASSID; + bp->bp_vend[26] = 9; + bcopy("PXEClient", &bp->bp_vend[27], 9); + bp->bp_vend[36] = TAG_END; + } else + bp->bp_vend[25] = TAG_END; expected_dhcpmsgtype = DHCPACK; diff --git a/lib/libstand/bootp.h b/lib/libstand/bootp.h index 7435e3cdbbb0..ed9101f3ea89 100644 --- a/lib/libstand/bootp.h +++ b/lib/libstand/bootp.h @@ -18,6 +18,8 @@ * University. Carnegie Mellon makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. + * + * $FreeBSD$ */ @@ -117,6 +119,12 @@ struct bootp { #define DHCPRELEASE 7 #endif +/* + * bootp flags + */ +#define BOOTP_NONE 0x0000 /* No flags */ +#define BOOTP_PXE 0x0001 /* Booting from PXE. */ + /* * "vendor" data permitted for CMU bootp clients. */ diff --git a/lib/libstand/net.h b/lib/libstand/net.h index 47ff0a0d2e20..24534afcaaca 100644 --- a/lib/libstand/net.h +++ b/lib/libstand/net.h @@ -114,7 +114,7 @@ ssize_t sendrecv(struct iodesc *, void *, size_t); /* bootp/DHCP */ -void bootp(int); +void bootp(int, int); /* Utilities: */ char *ether_sprintf(u_char *); diff --git a/sys/boot/common/dev_net.c b/sys/boot/common/dev_net.c index c88dae708d25..884366f1e1ee 100644 --- a/sys/boot/common/dev_net.c +++ b/sys/boot/common/dev_net.c @@ -68,6 +68,7 @@ #include #include #include +#include #include #include "dev_net.h" @@ -217,7 +218,7 @@ net_getparams(sock) * use RARP and RPC/bootparam (the Sun way) to get them. */ if (try_bootp) - bootp(sock); + bootp(sock, BOOTP_NONE); if (myip.s_addr != 0) goto exit; if (debug) diff --git a/sys/boot/i386/libi386/pxe.c b/sys/boot/i386/libi386/pxe.c index fa3a4f229fc3..0357cbe31309 100644 --- a/sys/boot/i386/libi386/pxe.c +++ b/sys/boot/i386/libi386/pxe.c @@ -41,6 +41,7 @@ #include #include +#include #include #include "btxv86.h" #include "pxe.h" @@ -276,7 +277,7 @@ pxe_open(struct open_file *f, ...) * the proper information, fall back to the server * which brought us to life and a default rootpath. */ - bootp(pxe_sock); + bootp(pxe_sock, BOOTP_PXE); if (rootip.s_addr == 0) rootip.s_addr = bootplayer.sip; if (!rootpath[1]) diff --git a/sys/boot/i386/libi386/pxe.h b/sys/boot/i386/libi386/pxe.h index c6bc4d0bc00a..3c9f2ff09f9b 100644 --- a/sys/boot/i386/libi386/pxe.h +++ b/sys/boot/i386/libi386/pxe.h @@ -498,7 +498,9 @@ typedef struct { uint8_t d[BOOTP_DHCPVEND]; /* raw array of vendor/dhcp options */ struct { uint8_t magic[4]; /* DHCP magic cookie */ +# ifndef VM_RFC1048 # define VM_RFC1048 0x63825363L /* ? */ +# endif uint32_t flags; /* bootp flags/opcodes */ uint8_t pad[56]; /* I don't think intel knows what a union does... */