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