⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pxe.c

📁 linux下从网卡远程启动
💻 C
字号:
#ifdef FREEBSD_PXEEMU#include "etherboot.h"#include "osdep.h"#include "nic.h"#define UDP_MAX_PAYLOAD	(ETH_MAX_MTU - sizeof(struct iphdr) \			 - sizeof(struct udphdr))struct udppacket_t {	struct iphdr	ip;	struct udphdr	udp;	uint8_t 	payload[UDP_MAX_PAYLOAD];};static int pxeemu_entry(struct v86 *v86_p, int *v86_call_flag,			int pxeemu_func_nr, vm_offset_t pxeemu_func_arg);static pxenv_t pxenv = {        {'P','X','E','N','V','+'},      /* Signature    */        0x0100,                         /* Version      */        sizeof(pxenv_t),                /* Length       */        0,                              /* Checksum     */        {0, 0},                         /* RMEntry      */        (uint32_t)pxeemu_entry,		/* PMOffset     */        0,                              /* PMSelector   */        0,                              /* StackSeg     */        0,                              /* StackSize    */        0,                              /* BC_CodeSeg   */        0,                              /* BC_CodeSize  */        0,                              /* BC_DataSeg   */        0,                              /* BC_DataSize  */        0,                              /* UNDIDataSeg  */        0,                              /* UNDIDataSize */        0,                              /* UNDICodeSeg  */        0,                              /* UNDICodeSize */        {0, 0}                          /* !PXEPtr      */};static jmpbuf		pxeemu_v86call_jbuf;static jmpbuf		pxeemu_entry_jbuf;extern char		pxeemu_nbp_active;#define PXEEMU_EXIT_ADJ		2#define PXENV_EXIT_SUCCESS	(0x0000 + PXEEMU_EXIT_ADJ)#define PXENV_EXIT_FAILURE	(0x0001 + PXEEMU_EXIT_ADJ)#define PXEEMU_EXIT_V86INT	(0x0002 + PXEEMU_EXIT_ADJ)#define PXENV_STATUS_SUCCESS	(PXENV_EXIT_SUCCESS - PXEEMU_EXIT_ADJ)#define PXENV_STATUS_FAILURE	(PXENV_EXIT_FAILURE - PXEEMU_EXIT_ADJ)#define	V86INT()	do {	*pxeemu_v86_flag = 1;			\				if(setjmp(pxeemu_v86call_jbuf) == 0)	\					longjmp(pxeemu_entry_jbuf,	\						PXEEMU_EXIT_V86INT);	\				*pxeemu_v86_flag = 0;			\			} while(0);static struct v86	*v86_p;static int		*pxeemu_v86_flag;static int		pxeemu_func_nr;static vm_offset_t	pxeemu_func_arg;static int		retval;static __inline unsigned int min(unsigned int a, unsigned int b) { return (a < b ? a : b); }static unsigned long pxeemu_nbp_addr = 0x7C00;static int pxe_download(unsigned char *data, unsigned int len, int eof);os_download_t pxe_probe(unsigned char *data, unsigned int len){	if (*((uint32_t *)(data +2)) == 0x42455850L) {		printf("(PXE)");		return pxe_download;	}	return 0;}static int pxe_download(unsigned char *data, unsigned int len, int eof){	memcpy(phys_to_virt(pxeemu_nbp_addr), data, len);	pxeemu_nbp_addr += len;	if (eof) {		uint8_t val, *ptr, counter;				ptr = (uint8_t*) &pxenv;		val = 0;		for(counter = 0; counter < pxenv.Length; ++counter, 			    ++ptr)			val += *ptr;		pxenv.Checksum = 0xff - val + 1;		printf("\n");						__asm__ __volatile__	(			"movb $1, pxeemu_nbp_active\n"			"call _prot_to_real\n"			".code16\n"			"movw %0, %%ax\n"                    			"movw %%ax, %%es\n"			"movl %1, %%ebx\n"			"ljmp $0x0,$0x7c00\n"			".code32\n"			: : "i" (RELOC >> 4), 			"g" (((vm_offset_t)&pxenv) - RELOC));	}	return 0;}static int await_udp_pxe(int ival, void *ptr,	unsigned short ptype, struct iphdr *ip, struct udphdr *udp){	t_PXEENV_UDP_READ *s = ptr;	if (!udp) 		return 0;	if ((s->dest_ip != 0) && (s->dest_ip != ip->dest.s_addr))		return 0;	if ((s->d_port != 0) && (s->d_port != udp->dest))		return 0;	return 1;}static int pxeemu_entry(struct v86 *x_v86_p, int *x_pxeemu_v86_flag,			int x_pxeemu_func_nr, vm_offset_t x_pxeemu_func_arg){	v86_p = x_v86_p;	pxeemu_v86_flag = x_pxeemu_v86_flag;	pxeemu_func_nr = x_pxeemu_func_nr;	pxeemu_func_arg = x_pxeemu_func_arg;	if(*pxeemu_v86_flag == 1)		longjmp(pxeemu_v86call_jbuf, 1);	else {		if( (retval = setjmp(pxeemu_entry_jbuf)) != 0)			goto pxeemu_exit;		/* Switch Stacks */		__asm__("xorl %%eax, %%eax\n"			"movw initsp, %%ax\n"			"addl %0, %%eax\n"			"movl %%eax, %%esp\n"			: : "i" (RELOC));	}	switch(pxeemu_func_nr)	{	    case PXENV_GET_CACHED_INFO:	    { 		t_PXENV_GET_CACHED_INFO *s =				(t_PXENV_GET_CACHED_INFO*) pxeemu_func_arg;		char *buf;				if(s->PacketType != PXENV_PACKET_TYPE_BINL_REPLY		   || s->Buffer.segment != 0 || s->Buffer.offset != 0) {			s->Status = PXENV_STATUS_FAILURE;			retval = PXENV_EXIT_FAILURE;			break;		}		s->Buffer.segment = (RELOC >> 4);		s->Buffer.offset = (((vm_offset_t)&bootp_data) - RELOC);		s->BufferSize = sizeof(struct bootpd_t);		s->BufferLimit = sizeof(struct bootpd_t);		s->Status = PXENV_STATUS_SUCCESS;		retval = PXENV_EXIT_SUCCESS;		break;	    }	    case PXENV_UDP_OPEN:	    {		t_PXENV_UDP_OPEN *s = (t_PXENV_UDP_OPEN*) pxeemu_func_arg;		arptable[ARP_CLIENT].ipaddr.s_addr = s->src_ip;		s->status = PXENV_STATUS_SUCCESS;		retval = PXENV_EXIT_SUCCESS;				break;	    }	    case PXENV_UDP_WRITE:	    {		t_PXENV_UDP_WRITE *s = (t_PXENV_UDP_WRITE*) pxeemu_func_arg;		void *ptr = (void*)(s->buffer.segment << 4)+s->buffer.offset;		struct udppacket_t packet;		int sz;				sz = min(s->buffer_size, UDP_MAX_PAYLOAD);		memcpy(packet.payload, ptr, sz);		sz += sizeof(struct iphdr) + sizeof(struct udphdr);		if(s->src_port == 0)			s->src_port = 2069;	/* XXX #define ??? */		if(udp_transmit(s->ip,				htons(s->src_port), htons(s->dst_port), 				sz, &packet) == 0) 		{    		    s->status = PXENV_STATUS_FAILURE;		    retval = PXENV_EXIT_FAILURE;		} else {		    s->status = PXENV_STATUS_SUCCESS;		    retval = PXENV_EXIT_SUCCESS;		}		break;	    }	    case PXENV_UDP_READ:	    {		t_PXENV_UDP_READ *s = (t_PXENV_UDP_READ*) pxeemu_func_arg;		if(await_reply(await_udp_pxe,			       arptable[ARP_CLIENT].ipaddr.s_addr, 			       s, 0) == 0) 		{			s->status = PXENV_STATUS_FAILURE;			retval = PXENV_EXIT_FAILURE;		} else {			struct udppacket_t *packet = (struct udppacket_t*)&nic.packet[ETH_HLEN];			void *ptr = (void*)(s->buffer.segment << 4);			ptr += s->buffer.offset;			s->src_ip = packet->ip.src.s_addr;			s->s_port = packet->udp.src;			s->buffer_size = min(nic.packetlen 						- sizeof(struct udppacket_t)						+ UDP_MAX_PAYLOAD,					     s->buffer_size);			memcpy(ptr, packet->payload, s->buffer_size);			s->status = PXENV_STATUS_SUCCESS;			retval = PXENV_EXIT_SUCCESS;		}		break;	    }	    case PXENV_UDP_CLOSE:	    {		t_PXENV_UDP_CLOSE *s = (t_PXENV_UDP_CLOSE*) pxeemu_func_arg;		s->status = PXENV_STATUS_SUCCESS;		retval = PXENV_EXIT_SUCCESS;				break;	    }	    case PXENV_UNLOAD_STACK:	    {		t_PXENV_UNLOAD_STACK *s = (t_PXENV_UNLOAD_STACK*) pxeemu_func_arg;		s->Status = PXENV_STATUS_SUCCESS;		retval = PXENV_EXIT_SUCCESS;				break;	    }	    case PXENV_UNDI_SHUTDOWN:	    {		t_PXENV_UNDI_SHUTDOWN *s = (t_PXENV_UNDI_SHUTDOWN*) pxeemu_func_arg;		eth_reset();		s->Status = PXENV_STATUS_SUCCESS;		retval = PXENV_EXIT_SUCCESS;				break;	    }	    default:		printf("Un-implemented PXE API function %d\n", pxeemu_func_nr);		retval = PXENV_EXIT_FAILURE;		break;	}	longjmp(pxeemu_entry_jbuf, retval);pxeemu_exit:		return retval - PXEEMU_EXIT_ADJ;}void pxeemu_console_putc(uint32_t c){	v86_p->ctl = 0;	v86_p->addr = 0x10;	v86_p->eax = c;	v86_p->ebx = 0x7;	V86INT();	return;}#endif /* FREEBSD_PXEEMU *//* * Local variables: *  c-basic-offset: 8 * End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -