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 
49 typedef struct {
50           uint16_t            offset;
51           uint16_t            segment;
52 } __packed SEGOFF16_t;
53 
54 typedef struct {
55           uint16_t            Seg_Addr;
56           uint32_t            Phy_Addr;
57           uint16_t            Seg_Size;
58 } __packed SEGDESC_t;
59 
60 typedef   uint16_t            SEGSEL_t;
61 typedef   uint16_t            PXENV_STATUS_t;
62 typedef   uint32_t            IP4_t;
63 typedef   uint32_t            ADDR32_t;
64 typedef   uint16_t            UDP_PORT_t;
65 
66 #define   MAC_ADDR_LEN                  16
67 typedef   uint8_t                       MAC_ADDR[MAC_ADDR_LEN];
68 
69 /* PXENV+ */
70 typedef 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 */
94 typedef 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
118 typedef 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
128 typedef struct {
129           PXENV_STATUS_t      Status;
130 } __packed t_PXENV_UNDI_STARTUP;
131 
132 #define   PXENV_UNDI_CLEANUP            0x0002
133 typedef struct {
134           PXENV_STATUS_t      Status;
135 } __packed t_PXENV_UNDI_CLEANUP;
136 
137 #define   PXENV_UNDI_INITIALIZE                   0x0003
138 typedef 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
147 typedef 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
154 typedef 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
160 typedef struct {
161           PXENV_STATUS_t      Status;
162 } __packed t_PXENV_UNDI_SHUTDOWN;
163 
164 #define   PXENV_UNDI_OPEN                         0x0006
165 typedef 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
178 typedef struct {
179           PXENV_STATUS_t      Status;
180 } __packed t_PXENV_UNDI_CLOSE;
181 
182 #define   PXENV_UNDI_TRANSMIT           0x0008
183 typedef 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
201 typedef 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
214 typedef 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
220 typedef 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
226 typedef 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
232 typedef 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
255 typedef 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
267 typedef struct {
268           PXENV_STATUS_t      Status;
269 } __packed t_PXENV_UNDI_CLEAR_STATISTICS;
270 
271 #define   PXENV_UNDI_INITIATE_DIAGS     0x000F
272 typedef struct {
273           PXENV_STATUS_t      Status;
274 } __packed t_PXENV_UNDI_INITIATE_DIAGS;
275 
276 #define   PXENV_UNDI_FORCE_INTERRUPT    0x0010
277 typedef struct {
278           PXENV_STATUS_t      Status;
279 } __packed t_PXENV_UNDI_FORCE_INTERRUPT;
280 
281 #define   PXENV_UNDI_GET_MCAST_ADDRESS  0x0011
282 typedef 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
289 typedef 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
319 typedef 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
328 typedef 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
358 typedef struct {
359           PXENV_STATUS_t      Status;
360 } __packed t_PXENV_STOP_UNDI;
361 
362 #define   PXENV_TFTP_OPEN                         0x0020
363 typedef 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
373 typedef struct {
374           PXENV_STATUS_t      Status;
375 } __packed t_PXENV_TFTP_CLOSE;
376 
377 #define   PXENV_TFTP_READ                         0x0022
378 typedef 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
386 typedef 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
401 typedef 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
410 typedef 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
416 typedef struct {
417           PXENV_STATUS_t      status;
418 } __packed t_PXENV_UDP_CLOSE;
419 
420 #define   PXENV_UDP_READ                          0x0032
421 typedef 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
434 typedef 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
445 typedef 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
452 typedef 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  */
469 typedef 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
516 typedef struct {
517           PXENV_STATUS_t      Status;
518 } __packed t_PXENV_START_BASE;
519 
520 #define   PXENV_STOP_BASE                         0x0076
521 typedef 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