blob: 15252fff7cdbcf5876b31951e6215ca2ce9485b9 [file] [log] [blame]
/* -----------------------------------------------------------------------
*
* Copyright 1999-2008 H. Peter Anvin - All Rights Reserved
* Copyright 2009-2011 Intel Corporation; author: H. Peter Anvin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 53 Temple Place Ste 330,
* Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
/*
* pxe.h
*
* PXE opcodes
*
*/
#ifndef PXE_H
#define PXE_H
#include <syslinux/pxe_api.h>
#include <syslinux/config.h>
#include <fcntl.h> /* For OK_FLAGS_MASK */
#include "fs.h" /* Mostly for FILENAME_MAX */
/*
* Some basic defines...
*/
#define PKTBUF_SIZE 2048 /* Used mostly by the gPXE backend */
#define is_digit(c) (((c) >= '0') && ((c) <= '9'))
#define BOOTP_OPTION_MAGIC htonl(0x63825363)
#define MAC_MAX 32
/*
* structures
*/
struct pxenv_t {
uint8_t signature[6]; /* PXENV+ */
uint16_t version;
uint8_t length;
uint8_t checksum;
segoff16_t rmentry;
uint32_t pmoffset;
uint16_t pmselector;
uint16_t stackseg;
uint16_t stacksize;
uint16_t bc_codeseg;
uint16_t bc_codesize;
uint16_t bc_dataseg;
uint16_t bc_datasize;
uint16_t undidataseg;
uint16_t undidatasize;
uint16_t undicodeseg;
uint16_t undicodesize;
segoff16_t pxeptr;
} __packed;
struct pxe_t {
uint8_t signature[4]; /* !PXE */
uint8_t structlength;
uint8_t structcksum;
uint8_t structrev;
uint8_t _pad1;
segoff16_t undiromid;
segoff16_t baseromid;
segoff16_t entrypointsp;
segoff16_t entrypointesp;
segoff16_t statuscallout;
uint8_t _pad2;
uint8_t segdesccnt;
uint16_t firstselector;
pxe_segdesc_t seg[7];
} __packed;
enum pxe_segments {
PXE_Seg_Stack = 0,
PXE_Seg_UNDIData = 1,
PXE_Seg_UNDICode = 2,
PXE_Seg_UNDICodeWrite = 3,
PXE_Seg_BC_Data = 4,
PXE_Seg_BC_Code = 5,
PXE_Seg_BC_CodeWrite = 6
};
struct bootp_t {
uint8_t opcode; /* BOOTP/DHCP "opcode" */
uint8_t hardware; /* ARP hreadware type */
uint8_t hardlen; /* Hardware address length */
uint8_t gatehops; /* Used by forwarders */
uint32_t ident; /* Transaction ID */
uint16_t seconds; /* Seconds elapsed */
uint16_t flags; /* Broadcast flags */
uint32_t cip; /* Cient IP */
uint32_t yip; /* "Your" IP */
uint32_t sip; /* Next Server IP */
uint32_t gip; /* Relay agent IP */
uint8_t macaddr[16]; /* Client MAC address */
uint8_t sname[64]; /* Server name (optional) */
char bootfile[128]; /* Boot file name */
uint32_t option_magic; /* Vendor option magic cookie */
uint8_t options[1260]; /* Vendor options */
} __attribute__ ((packed));
struct netconn;
struct netbuf;
struct efi_binding;
/*
* Our inode private information -- this includes the packet buffer!
*/
struct pxe_conn_ops {
void (*fill_buffer)(struct inode *inode);
void (*close)(struct inode *inode);
int (*readdir)(struct inode *inode, struct dirent *dirent);
};
union net_private {
struct net_private_lwip {
struct netconn *conn; /* lwip network connection */
struct netbuf *buf; /* lwip cached buffer */
} lwip;
struct net_private_tftp {
uint32_t remoteip; /* Remote IP address (0 = disconnected) */
uint16_t localport; /* Local port number (0=not in use) */
} tftp;
struct net_private_efi {
struct efi_binding *binding; /* EFI binding for protocol */
uint16_t localport; /* Local port number (0=not in use) */
} efi;
};
struct pxe_pvt_inode {
union net_private net; /* Network stack private data */
uint16_t tftp_remoteport; /* Remote port number */
uint32_t tftp_filepos; /* bytes downloaded (including buffer) */
uint32_t tftp_blksize; /* Block size for this connection(*) */
uint16_t tftp_bytesleft; /* Unclaimed data bytes */
uint16_t tftp_lastpkt; /* Sequence number of last packet (HBO) */
char *tftp_dataptr; /* Pointer to available data */
uint8_t tftp_goteof; /* 1 if the EOF packet received */
uint8_t tftp_unused[3]; /* Currently unused */
char *tftp_pktbuf; /* Packet buffer */
struct inode *ctl; /* Control connection (for FTP) */
const struct pxe_conn_ops *ops;
};
#define PVT(i) ((struct pxe_pvt_inode *)((i)->pvt))
/*
* Variable externs
*/
extern struct syslinux_ipinfo IPInfo;
extern t_PXENV_UNDI_GET_INFORMATION pxe_undi_info;
extern t_PXENV_UNDI_GET_IFACE_INFO pxe_undi_iface;
extern uint8_t MAC[];
extern char BOOTIFStr[];
extern uint8_t MAC_len;
extern uint8_t MAC_type;
extern uint8_t DHCPMagic;
extern uint32_t RebootTime;
extern char boot_file[];
extern char path_prefix[];
extern char LocalDomain[];
extern uint32_t dns_server[];
extern uint16_t APIVer;
extern far_ptr_t PXEEntry;
extern uint8_t KeepPXE;
extern far_ptr_t InitStack;
extern bool have_uuid;
extern uint8_t uuid_type;
extern uint8_t uuid[];
struct url_info;
struct url_scheme {
const char *name;
void (*open)(struct url_info *, int, struct inode *, const char **);
int ok_flags;
};
/* Flags which can be specified in url_scheme.ok_flags */
#define OK_FLAGS_MASK (O_DIRECTORY|O_WRONLY)
extern const struct url_scheme url_schemes[];
/*
* Compute the suitable gateway for a specific route -- too many
* vendor PXE stacks don't do this correctly...
*/
static inline uint32_t gateway(uint32_t ip)
{
if ((ip ^ IPInfo.myip) & IPInfo.netmask)
return IPInfo.gateway;
else
return 0;
}
/*
* functions
*/
/* pxeisr.inc */
extern uint8_t pxe_irq_vector;
extern void pxe_isr(void);
extern far_ptr_t pxe_irq_chain;
extern void pxe_poll(void);
/* isr.c */
void pxe_init_isr(void);
void pxe_start_isr(void);
int reset_pxe(void);
/* pxe.c */
struct url_info;
bool ip_ok(uint32_t);
int pxe_getc(struct inode *inode);
void free_socket(struct inode *inode);
/* undiif.c */
int undiif_start(uint32_t ip, uint32_t netmask, uint32_t gw);
void undiif_input(t_PXENV_UNDI_ISR *isr);
/* dhcp_options.c */
void parse_dhcp_options(const void *, int, uint8_t);
void parse_dhcp(const void *, size_t);
/* idle.c */
void pxe_idle_init(void);
void pxe_idle_cleanup(void);
/* tftp.c */
void tftp_open(struct url_info *url, int flags, struct inode *inode,
const char **redir);
/* gpxeurl.c */
void gpxe_open(struct inode *inode, const char *url);
#define GPXE 0
/* http.c */
void http_open(struct url_info *url, int flags, struct inode *inode,
const char **redir);
/* http_readdir.c */
int http_readdir(struct inode *inode, struct dirent *dirent);
/* ftp.c */
void ftp_open(struct url_info *url, int flags, struct inode *inode,
const char **redir);
/* ftp_readdir.c */
int ftp_readdir(struct inode *inode, struct dirent *dirent);
/* tcp.c */
const struct pxe_conn_ops tcp_conn_ops;
extern void gpxe_init(void);
extern int pxe_init(bool quiet);
#endif /* pxe.h */