270 lines
7.2 KiB
C
270 lines
7.2 KiB
C
/* -----------------------------------------------------------------------
|
|
*
|
|
* 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 */
|