| /* ----------------------------------------------------------------------- |
| * |
| * 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 */ |