void OS::udp_open(void) { t_PXENV_TFTP_CLOSE *tftp_close_param = (t_PXENV_TFTP_CLOSE *)lzalloc(sizeof(t_PXENV_TFTP_CLOSE)); xassert(tftp_close_param); pxeapi_call(PXENV_TFTP_CLOSE, (uint8_t *)tftp_close_param); // printf("TFTP close returns: %d\n", tftp_close_param->Status); lfree(tftp_close_param); t_PXENV_UDP_OPEN *pxe_open_param = (t_PXENV_UDP_OPEN *)lzalloc(sizeof(t_PXENV_UDP_OPEN)); xassert(pxe_open_param); pxe_open_param->src_ip = os->ip.s_addr; pxeapi_call(PXENV_UDP_OPEN, (uint8_t *)pxe_open_param); // printf("PXE UDP open returns: %d\n", pxe_open_param->status); lfree(pxe_open_param); }
int OS::udp_read(void *buf, const size_t len, uint32_t *from_ip) { int ret = 0; t_PXENV_UDP_READ *pxe_read_param = (t_PXENV_UDP_READ *)lzalloc(sizeof(t_PXENV_UDP_READ) + len); xassert(pxe_read_param); char *buf_reloc = (char *)pxe_read_param + sizeof(*pxe_read_param); pxe_read_param->s_port = htons(UDP_PORT_NO); pxe_read_param->d_port = htons(UDP_PORT_NO); pxe_read_param->buffer.seg = SEG(buf_reloc); pxe_read_param->buffer.offs = OFFS(buf_reloc); pxe_read_param->buffer_size = len; pxeapi_call(PXENV_UDP_READ, (uint8_t *)pxe_read_param); if ((pxe_read_param->status == PXENV_STATUS_SUCCESS) && (pxe_read_param->s_port == htons(UDP_PORT_NO))) { memcpy(buf, buf_reloc, pxe_read_param->buffer_size); *from_ip = pxe_read_param->src_ip; ret = pxe_read_param->buffer_size; } lfree(pxe_read_param); return ret; }
/* Returns the status code from PXE (0 on success), or -1 on invocation failure */ int pxe_get_nic_type(t_PXENV_UNDI_GET_NIC_TYPE *gnt) { com32sys_t regs; t_PXENV_UNDI_GET_NIC_TYPE *lgnt; lgnt = lzalloc(sizeof *lgnt); if (!lgnt) return -1; memset(®s, 0, sizeof regs); regs.eax.w[0] = 0x0009; regs.ebx.w[0] = PXENV_UNDI_GET_NIC_TYPE; regs.es = SEG(lgnt); /* regs.edi.w[0] = OFFS(lgnt); */ __intcall(0x22, ®s, ®s); memcpy(gnt, lgnt, sizeof(t_PXENV_UNDI_GET_NIC_TYPE)); lfree(lgnt); if (regs.eflags.l & EFLAGS_CF) return -1; return gnt->Status; }
bool is_gpxe(void) { const struct syslinux_version *sv; com32sys_t reg; struct s_PXENV_FILE_CHECK_API *fca; bool gpxe; sv = syslinux_version(); if (sv->filesystem != SYSLINUX_FS_PXELINUX) return false; /* Not PXELINUX */ fca = lzalloc(sizeof *fca); if (!fca) return false; fca->Size = sizeof *fca; fca->Magic = 0x91d447b2; memset(®, 0, sizeof reg); reg.eax.w[0] = 0x0009; reg.ebx.w[0] = 0x00e6; /* PXENV_FILE_API_CHECK */ /* reg.edi.w[0] = OFFS(fca); */ reg.es = SEG(fca); __intcall(0x22, ®, ®); gpxe = true; if (reg.eflags.l & EFLAGS_CF) gpxe = false; /* Cannot invoke PXE stack */ if (reg.eax.w[0] || fca->Status) gpxe = false; /* PXE failure */ if (fca->Magic != 0xe9c17b20) gpxe = false; /* Incorrect magic */ if (fca->Size < sizeof *fca) gpxe = false; /* Short return */ /* XXX: The APIs to test for should be a passed-in option */ if (!(fca->APIMask & (1 << 5))) gpxe = false; /* No FILE EXEC */ lfree(fca); return gpxe; }
void OS::udp_write(const void *buf, const size_t len, uint32_t to_ip) { t_PXENV_UDP_WRITE *pxe_write_param = (t_PXENV_UDP_WRITE *)lzalloc(sizeof(t_PXENV_UDP_WRITE) + len); xassert(pxe_write_param); char *buf_reloc = (char *)pxe_write_param + sizeof(*pxe_write_param); pxe_write_param->ip = to_ip; pxe_write_param->src_port = htons(UDP_PORT_NO); pxe_write_param->dst_port = htons(UDP_PORT_NO); pxe_write_param->buffer.seg = SEG(buf_reloc); pxe_write_param->buffer.offs = OFFS(buf_reloc); pxe_write_param->buffer_size = len; memcpy(buf_reloc, buf, len); pxeapi_call(PXENV_UDP_WRITE, (uint8_t *)pxe_write_param); lfree(pxe_write_param); }