1/*	$OpenBSD: pxe.h,v 1.7 2016/06/10 18:36:06 jcs Exp $ */
2/*	$NetBSD: pxe.h,v 1.1 2002/02/16 03:37:40 thorpej Exp $	*/
3
4/*
5 * Copyright (c) 2000 Alfred Perlstein <alfred@freebsd.org>
6 * All rights reserved.
7 * Copyright (c) 2000 Paul Saab <ps@freebsd.org>
8 * All rights reserved.
9 * Copyright (c) 2000 John Baldwin <jhb@freebsd.org>
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 *    notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 *    notice, this list of conditions and the following disclaimer in the
19 *    documentation and/or other materials provided with the distribution.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34/*
35 * Note that these structures and types are named according to
36 * the Intel PXE documentation.
37 */
38
39#define	S_SIZE(s)	s, sizeof(s) - 1
40
41#define	IP_STR		"%d.%d.%d.%d"
42#define	IP_ARGS(ip)					\
43	(int)(ip >> 24) & 0xff, (int)(ip >> 16) & 0xff, \
44	(int)(ip >> 8) & 0xff, (int)ip & 0xff
45
46#define	MAC_STR		"%02x:%02x:%02x:%02x:%02x:%02x"
47#define	MAC_ARGS(mac)					\
48	mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]
49
50typedef struct {
51	uint16_t		offset;
52	uint16_t		segment;
53} __packed SEGOFF16_t;
54
55typedef struct {
56	uint16_t		Seg_Addr;
57	uint32_t		Phy_Addr;
58	uint16_t		Seg_Size;
59} __packed SEGDESC_t;
60
61typedef	uint16_t		SEGSEL_t;
62typedef	uint16_t		PXENV_STATUS_t;
63typedef	uint32_t		IP4_t;
64typedef	uint32_t		ADDR32_t;
65typedef	uint16_t		UDP_PORT_t;
66
67#define	MAC_ADDR_LEN		16
68typedef	uint8_t			MAC_ADDR[MAC_ADDR_LEN];
69
70/* PXENV+ */
71typedef struct {
72	uint8_t		Signature[6];	/* 'PXENV+' */
73	uint16_t	Version;	/* MSB = major, LSB = minor */
74	uint8_t		Length;		/* structure length */
75	uint8_t		Checksum;	/* checksum pad */
76	SEGOFF16_t	RMEntry;	/* SEG:OFF to PXE entry point */
77	/* don't use PMOffset and PMSelector (from the 2.1 PXE manual) */
78	uint32_t	PMOffset;	/* Protected mode entry */
79	SEGSEL_t	PMSelector;	/* Protected mode selector */
80	SEGSEL_t	StackSeg;	/* Stack segment address */
81	uint16_t	StackSize;	/* Stack segment size (bytes) */
82	SEGSEL_t	BC_CodeSeg;	/* BC Code segment address */
83	uint16_t	BC_CodeSize;	/* BC Code segment size (bytes) */
84	SEGSEL_t	BC_DataSeg;	/* BC Data segment address */
85	uint16_t	BC_DataSize;	/* BC Data segment size (bytes) */
86	SEGSEL_t	UNDIDataSeg;	/* UNDI Data segment address */
87	uint16_t	UNDIDataSize;	/* UNDI Data segment size (bytes) */
88	SEGSEL_t	UNDICodeSeg;	/* UNDI Code segment address */
89	uint16_t	UNDICodeSize;	/* UNDI Code segment size (bytes) */
90	SEGOFF16_t	PXEPtr;		/* SEG:OFF to !PXE struct,
91					   only present when Version > 2.1 */
92} __packed pxenv_t;
93
94/* !PXE */
95typedef struct {
96	uint8_t		Signature[4];
97	uint8_t		StructLength;
98	uint8_t		StructCksum;
99	uint8_t		StructRev;
100	uint8_t		reserved_1;
101	SEGOFF16_t	UNDIROMID;
102	SEGOFF16_t	BaseROMID;
103	SEGOFF16_t	EntryPointSP;
104	SEGOFF16_t	EntryPointESP;
105	SEGOFF16_t	StatusCallout;
106	uint8_t		reserved_2;
107	uint8_t		SegDescCn;
108	SEGSEL_t	FirstSelector;
109	SEGDESC_t	Stack;
110	SEGDESC_t	UNDIData;
111	SEGDESC_t	UNDICode;
112	SEGDESC_t	UNDICodeWrite;
113	SEGDESC_t	BC_Data;
114	SEGDESC_t	BC_Code;
115	SEGDESC_t	BC_CodeWrite;
116} __packed pxe_t;
117
118#define	PXENV_START_UNDI		0x0000
119typedef struct {
120	PXENV_STATUS_t	Status;
121	uint16_t	ax;
122	uint16_t	bx;
123	uint16_t	dx;
124	uint16_t	di;
125	uint16_t	es;
126} __packed t_PXENV_START_UNDI;
127
128#define	PXENV_UNDI_STARTUP		0x0001
129typedef struct {
130	PXENV_STATUS_t	Status;
131} __packed t_PXENV_UNDI_STARTUP;
132
133#define	PXENV_UNDI_CLEANUP		0x0002
134typedef struct {
135	PXENV_STATUS_t	Status;
136} __packed t_PXENV_UNDI_CLEANUP;
137
138#define	PXENV_UNDI_INITIALIZE		0x0003
139typedef struct {
140	PXENV_STATUS_t	Status;
141	ADDR32_t	ProtocolIni;	/* Phys addr of a copy of the
142					   driver module */
143	uint8_t		reserved[8];
144} __packed t_PXENV_UNDI_INITIALIZE;
145
146
147#define	MAXNUM_MCADDR		8
148typedef struct {
149	PXENV_STATUS_t	Status;
150	uint16_t	MCastAddrCount;
151	MAC_ADDR	McastAddr[MAXNUM_MCADDR];
152} __packed t_PXENV_UNDI_MCAST_ADDRESS;
153
154#define	PXENV_UNDI_RESET_ADAPTER	0x0004
155typedef struct {
156	PXENV_STATUS_t	Status;
157	t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf;
158} __packed t_PXENV_UNDI_RESET;
159
160#define	PXENV_UNDI_SHUTDOWN		0x0005
161typedef struct {
162	PXENV_STATUS_t	Status;
163} __packed t_PXENV_UNDI_SHUTDOWN;
164
165#define	PXENV_UNDI_OPEN			0x0006
166typedef struct {
167	PXENV_STATUS_t	Status;
168	uint16_t	OpenFlag;
169	uint16_t	PktFilter;
170#	define FLTR_DIRECTED	0x0001
171#	define FLTR_BRDCST	0x0002
172#	define FLTR_PRMSCS	0x0003
173#	define FLTR_SRC_RTG	0x0004
174
175	t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf;
176} __packed t_PXENV_UNDI_OPEN;
177
178#define	PXENV_UNDI_CLOSE		0x0007
179typedef struct {
180	PXENV_STATUS_t	Status;
181} __packed t_PXENV_UNDI_CLOSE;
182
183#define	PXENV_UNDI_TRANSMIT		0x0008
184typedef struct {
185	PXENV_STATUS_t	Status;
186	uint8_t		Protocol;
187#	define P_UNKNOWN	0
188#	define P_IP		1
189#	define P_ARP		2
190#	define P_RARP		3
191
192	uint8_t		XmitFlag;
193#	define XMT_DESTADDR	0x0000
194#	define XMT_BROADCAST	0x0001
195
196	SEGOFF16_t	DestAddr;
197	SEGOFF16_t	TBD;
198	uint32_t	Reserved[2];
199} __packed t_PXENV_UNDI_TRANSMIT;
200
201#define	MAX_DATA_BLKS		8
202typedef struct {
203	uint16_t	ImmedLength;
204	SEGOFF16_t	Xmit;
205	uint16_t	DataBlkCount;
206	struct	DataBlk {
207		uint8_t		TDPtrType;
208		uint8_t		TDRsvdByte;
209		uint16_t	TDDataLen;
210		SEGOFF16_t	TDDataPtr;
211	} DataBlock[MAX_DATA_BLKS];
212} __packed t_PXENV_UNDI_TBD;
213
214#define	PXENV_UNDI_SET_MCAST_ADDRESS	0x0009
215typedef struct {
216	PXENV_STATUS_t	Status;
217	t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf;
218} __packed t_PXENV_UNDI_SET_MCAST_ADDR;
219
220#define	PXENV_UNDI_SET_STATION_ADDRESS	0x000A
221typedef struct {
222	PXENV_STATUS_t	Status;
223	MAC_ADDR	StationAddress;		/* Temp MAC address to use */
224} __packed t_PXENV_UNDI_SET_STATION_ADDR;
225
226#define	PXENV_UNDI_SET_PACKET_FILTER	0x000B
227typedef struct {
228	PXENV_STATUS_t	Status;
229	uint8_t		filter;			/* see UNDI_OPEN (0x0006) */
230} __packed t_PXENV_UNDI_SET_PACKET_FILTER;
231
232#define	PXENV_UNDI_GET_INFORMATION	0x000C
233typedef struct {
234	PXENV_STATUS_t	Status;
235	uint16_t	BaseIo;			/* Adapter base I/O address */
236	uint16_t	IntNumber;		/* Adapter IRQ number */
237	uint16_t	MaxTranUnit;		/* Adapter maximum transmit
238						   unit */
239	uint16_t	HwType;			/* Type of protocol at the
240						   hardware addr */
241#	define ETHER_TYPE	1
242#	define EXP_ETHER_TYPE	2
243#	define IEEE_TYPE	6
244#	define ARCNET_TYPE	7
245
246	uint16_t	HwAddrLen;		/* Length of hardware address */
247	MAC_ADDR	CurrentNodeAddress;	/* Current hardware address */
248	MAC_ADDR	PermNodeAddress;	/* Permanent hardware address */
249	SEGSEL_t	ROMAddress;		/* Real mode ROM segment
250						   address */
251	uint16_t	RxBufCt;		/* Receive queue length */
252	uint16_t	TxBufCt;		/* Transmit queue length */
253} __packed t_PXENV_UNDI_GET_INFORMATION;
254
255#define	PXENV_UNDI_GET_STATISTICS	0x000D
256typedef struct {
257	PXENV_STATUS_t	Status;
258	uint32_t	XmitGoodFrames;		/* Number of successful
259						   transmissions */
260	uint32_t	RcvGoodFrames;		/* Number of good frames
261						   received */
262	uint32_t	RcvCRCErrors;		/* Number of frames with
263						   CRC errors */
264	uint32_t	RcvResourceErrors;	/* Number of frames dropped */
265} __packed t_PXENV_UNDI_GET_STATISTICS;
266
267#define	PXENV_UNDI_CLEAR_STATISTICS	0x000E
268typedef struct {
269	PXENV_STATUS_t	Status;
270} __packed t_PXENV_UNDI_CLEAR_STATISTICS;
271
272#define	PXENV_UNDI_INITIATE_DIAGS	0x000F
273typedef struct {
274	PXENV_STATUS_t	Status;
275} __packed t_PXENV_UNDI_INITIATE_DIAGS;
276
277#define	PXENV_UNDI_FORCE_INTERRUPT	0x0010
278typedef struct {
279	PXENV_STATUS_t	Status;
280} __packed t_PXENV_UNDI_FORCE_INTERRUPT;
281
282#define	PXENV_UNDI_GET_MCAST_ADDRESS	0x0011
283typedef struct {
284	PXENV_STATUS_t	Status;
285	IP4_t		InetAddr;		/* IP mulicast address */
286	MAC_ADDR	MediaAddr;		/* MAC multicast address */
287} __packed t_PXENV_UNDI_GET_MCAST_ADDR;
288
289#define	PXENV_UNDI_GET_NIC_TYPE		0x0012
290typedef struct {
291	PXENV_STATUS_t	Status;
292	uint8_t		NicType;		/* Type of NIC */
293#	define PCI_NIC		2
294#	define PnP_NIC		3
295#	define CardBus_NIC	4
296
297	union {
298		struct {
299			uint16_t	Vendor_ID;
300			uint16_t	Dev_ID;
301			uint8_t		Base_Class;
302			uint8_t		Sub_Class;
303			uint8_t		Prog_Intf;
304			uint8_t		Rev;
305			uint16_t	BusDevFunc;
306			uint16_t	SubVendor_ID;
307			uint16_t	SubDevice_ID;
308		} pci, cardbus;
309		struct {
310			uint32_t	EISA_Dev_ID;
311			uint8_t		Base_Class;
312			uint8_t		Sub_Class;
313			uint8_t		Prog_Intf;
314			uint16_t	CardSelNum;
315		} pnp;
316	} info;
317} __packed t_PXENV_UNDI_GET_NIC_TYPE;
318
319#define	PXENV_UNDI_GET_IFACE_INFO	0x0013
320typedef struct {
321	PXENV_STATUS_t	Status;
322	uint8_t		IfaceType[16];		/* Name of MAC type in ASCII. */
323	uint32_t	LinkSpeed;		/* Defined in NDIS 2.0 spec */
324	uint32_t	ServiceFlags;		/* Defined in NDIS 2.0 spec */
325	uint32_t	Reserved[4];		/* must be 0 */
326} __packed t_PXENV_UNDI_GET_NDIS_INFO;
327
328#define	PXENV_UNDI_ISR			0x0014
329typedef struct {
330	PXENV_STATUS_t	Status;
331	uint16_t	FuncFlag;		/* PXENV_UNDI_ISR_OUT_xxx */
332	uint16_t	BufferLength;		/* Length of Frame */
333	uint16_t	FrameLength;		/* Total length of receiver
334						   frame */
335	uint16_t	FrameHeaderLength;	/* Length of the media header
336						   in Frame */
337	SEGOFF16_t	Frame;			/* receive buffer */
338	uint8_t		ProtType;		/* Protocol type */
339	uint8_t		PktType;		/* Packet Type */
340#	define PXENV_UNDI_ISR_IN_START		1
341#	define PXENV_UNDI_ISR_IN_PROCESS	2
342#	define PXENV_UNDI_ISR_IN_GET_NEXT	3
343
344	/* one of these will be returned for PXENV_UNDI_ISR_IN_START */
345#	define PXENV_UNDI_ISR_OUT_OURS		0
346#	define PXENV_UNDI_ISR_OUT_NOT_OUTS	1
347
348	/*
349	 * one of these will be returned for PXEND_UNDI_ISR_IN_PROCESS
350	 * and PXENV_UNDI_ISR_IN_GET_NEXT
351	 */
352#	define PXENV_UNDI_ISR_OUT_DONE		0
353#	define PXENV_UNDI_ISR_OUT_TRANSMIT	2
354#	define PXENV_UNDI_ISR_OUT_RECEIVE	3
355#	define PXENV_UNDI_ISR_OUT_BUSY		4
356} __packed t_PXENV_UNDI_ISR;
357
358#define	PXENV_STOP_UNDI			0x0015
359typedef struct {
360	PXENV_STATUS_t	Status;
361} __packed t_PXENV_STOP_UNDI;
362
363#define	PXENV_TFTP_OPEN			0x0020
364typedef struct {
365	PXENV_STATUS_t	Status;
366	IP4_t		ServerIPAddress;
367	IP4_t		GatewayIPAddress;
368	uint8_t		FileName[128];
369	UDP_PORT_t	TFTPPort;
370	uint16_t	PacketSize;
371} __packed t_PXENV_TFTP_OPEN;
372
373#define	PXENV_TFTP_CLOSE		0x0021
374typedef struct {
375	PXENV_STATUS_t	Status;
376} __packed t_PXENV_TFTP_CLOSE;
377
378#define	PXENV_TFTP_READ			0x0022
379typedef struct {
380	PXENV_STATUS_t	Status;
381	uint16_t	PacketNumber;
382	uint16_t	BufferSize;
383	SEGOFF16_t	Buffer;
384} __packed t_PXENV_TFTP_READ;
385
386#define	PXENV_TFTP_READ_FILE		0x0023
387typedef struct {
388	PXENV_STATUS_t	Status;
389	uint8_t		FileName[128];
390	uint32_t	BufferSize;
391	ADDR32_t	Buffer;
392	IP4_t		ServerIPAddress;
393	IP4_t		GatewayIPAddress;
394	IP4_t		McastIPAddress;
395	UDP_PORT_t	TFTPClntPort;
396	UDP_PORT_t	TFTPSrvPort;
397	uint16_t	TFTPOpenTimeOut;
398	uint16_t	TFTPReopenDelay;
399} __packed t_PXENV_TFTP_READ_FILE;
400
401#define	PXENV_TFTP_GET_FSIZE		0x0025
402typedef struct {
403	PXENV_STATUS_t	Status;
404	IP4_t		ServerIPAddress;
405	IP4_t		GatewayIPAddress;
406	uint8_t		FileName[128];
407	uint32_t	FileSize;
408} __packed t_PXENV_TFTP_GET_FSIZE;
409
410#define	PXENV_UDP_OPEN			0x0030
411typedef struct {
412	PXENV_STATUS_t	status;
413	IP4_t		src_ip;		/* IP address of this station */
414} __packed t_PXENV_UDP_OPEN;
415
416#define	PXENV_UDP_CLOSE			0x0031
417typedef struct {
418	PXENV_STATUS_t	status;
419} __packed t_PXENV_UDP_CLOSE;
420
421#define	PXENV_UDP_READ			0x0032
422typedef struct {
423	PXENV_STATUS_t	status;
424	IP4_t		src_ip;		/* IP of sender */
425	IP4_t		dest_ip;	/* Only accept packets sent to
426					   this IP */
427	UDP_PORT_t	s_port;		/* UDP source port of sender */
428	UDP_PORT_t	d_port;		/* Only accept packets sent to
429					   this port */
430	uint16_t	buffer_size;	/* Size of the packet buffer */
431	SEGOFF16_t	buffer;		/* SEG:OFF to the packet buffer */
432} __packed t_PXENV_UDP_READ;
433
434#define	PXENV_UDP_WRITE			0x0033
435typedef struct {
436	PXENV_STATUS_t	status;
437	IP4_t		ip;		/* dest ip addr */
438	IP4_t		gw;		/* ip gateway */
439	UDP_PORT_t	src_port;	/* source udp port */
440	UDP_PORT_t	dst_port;	/* destination udp port */
441	uint16_t	buffer_size;	/* Size of the packet buffer */
442	SEGOFF16_t	buffer;		/* SEG:OFF to the packet buffer */
443} __packed t_PXENV_UDP_WRITE;
444
445#define	PXENV_UNLOAD_STACK		0x0070
446typedef struct {
447	PXENV_STATUS_t	Status;
448	uint8_t		reserved[10];
449} __packed t_PXENV_UNLOAD_STACK;
450
451
452#define	PXENV_GET_CACHED_INFO		0x0071
453typedef struct {
454	PXENV_STATUS_t	Status;
455	uint16_t	PacketType;	/* type (defined right here) */
456#	define PXENV_PACKET_TYPE_DHCP_DISCOVER  1
457#	define PXENV_PACKET_TYPE_DHCP_ACK       2
458#	define PXENV_PACKET_TYPE_CACHED_REPLY   3
459	uint16_t	BufferSize;	/* max to copy, leave at 0 for
460					   pointer */
461	SEGOFF16_t	Buffer;		/* copy to, leave at 0 for pointer */
462	uint16_t	BufferLimit;	/* max size of buffer in BC dataseg ? */
463} __packed t_PXENV_GET_CACHED_INFO;
464
465
466/* structure filled in by PXENV_GET_CACHED_INFO
467 * (how we determine which IP we downloaded the initial bootstrap from)
468 * words can't describe...
469 */
470typedef struct {
471	uint8_t		opcode;
472#	define BOOTP_REQ	1
473#	define BOOTP_REP	2
474	uint8_t		Hardware;	/* hardware type */
475	uint8_t		Hardlen;	/* hardware addr len */
476	uint8_t		Gatehops;	/* zero it */
477	uint32_t	ident;		/* random number chosen by client */
478	uint16_t	seconds;	/* seconds since did initial
479					   bootstrap */
480	uint16_t	Flags;		/* seconds since did initial
481					   bootstrap */
482#	define BOOTP_BCAST	0x8000		/* ? */
483	IP4_t		cip;		/* Client IP */
484	IP4_t		yip;		/* Your IP */
485	IP4_t		sip;		/* IP to use for next boot stage */
486	IP4_t		gip;		/* Relay IP ? */
487	MAC_ADDR	CAddr;		/* Client hardware address */
488	uint8_t		Sname[64];	/* Server's hostname (Optional) */
489	uint8_t		bootfile[128];	/* boot filename */
490	union {
491#		if 1
492#		define BOOTP_DHCPVEND  1024    /* DHCP extended vendor
493						  field size */
494#		else
495#		define BOOTP_DHCPVEND  312	/* DHCP standard vendor
496						   field size */
497#		endif
498		uint8_t		d[BOOTP_DHCPVEND]; /* raw array of
499						      vendor/dhcp options */
500		struct {
501			uint8_t		magic[4];  /* DHCP magic cookie */
502#			ifndef		VM_RFC1048
503#			define		VM_RFC1048	0x63825363L	/* ? */
504#			endif
505			uint32_t	flags;	   /* bootp flags/opcodes */
506			uint8_t		pad[56];   /* I don't think intel
507						      knows what a union
508						      does... */
509		} v;
510	} vendor;
511} __packed BOOTPLAYER;
512
513#define	PXENV_RESTART_TFTP		0x0073
514#define	t_PXENV_RESTART_TFTP		t_PXENV_TFTP_READ_FILE
515
516#define	PXENV_START_BASE		0x0075
517typedef struct {
518	PXENV_STATUS_t	Status;
519} __packed t_PXENV_START_BASE;
520
521#define	PXENV_STOP_BASE			0x0076
522typedef struct {
523	PXENV_STATUS_t	Status;
524} __packed t_PXENV_STOP_BASE;
525
526#define	PXENV_STATUS_SUCCESS		0
527#define	PXENV_STATUS_FAILURE		1
528/* ...there are tons more, but we don't really care about them right now... */
529