[syslinux] PXE stack access via com32

jesse barker jessebarker5 at yahoo.com
Mon Jan 8 11:19:16 PST 2007


Peter,

Thanks for all of your help.  Nearly simultaneous with your last reply, I took a chance and set the buffer size to 0, and got back success (but, of course, no valid cached info, due to having provided a zero-sized buffer).  When I got your reply, I was definitely reassured to see precious little difference between your code and mine (including the PXENV argument struct).  It turns out that the discrepancy that made all the difference (setting pxeStackArgs.buffer_size == sizeof(BOOTPLAYER)) was based upon the questionable definition of 'BOOTPLAYER' in the PXE spec itself.  Because of the vendor details union definition, I derived a value for 'BOOTP_DHCPVEND' based upon the struct portion, rather than researching the real value more thoroughly, so I ended up with a buffer size that was too small for the reply data, and it failed (my bad).

cheers,
Jesse

----- Original Message ----
From: H. Peter Anvin <hpa at zytor.com>
To: jesse barker <jessebarker5 at yahoo.com>
Cc: syslinux at zytor.com
Sent: Monday, January 8, 2007 10:39:16 AM
Subject: Re: [syslinux] PXE stack access via com32

jesse barker wrote:
> 
> Sorry, I was referring strictly to the comboot API docs which doesn't define anything to interpret bit 1 of eflags (I was loosely hoping it might indicate some undocumented error).
> 
> At any rate, have you seen anything in my description of what I'm seeing that might give some indication of what's wrong?  Do you (or anyone that you know is using this functionality) have any (com32) examples of PXE stack access that are known to work?  I might be able to work backwards from there (at this point I have nothing to indicate incorrect use of the API, unless one of the data structure definitions in the PXE spec is wrong).
> 

This program seems to work for me.

    -hpa

/* ----------------------------------------------------------------------- *
 *   
 *   Copyright 2007 H. Peter Anvin - All Rights Reserved
 *
 *   Permission is hereby granted, free of charge, to any person
 *   obtaining a copy of this software and associated documentation
 *   files (the "Software"), to deal in the Software without
 *   restriction, including without limitation the rights to use,
 *   copy, modify, merge, publish, distribute, sublicense, and/or
 *   sell copies of the Software, and to permit persons to whom
 *   the Software is furnished to do so, subject to the following
 *   conditions:
 *   
 *   The above copyright notice and this permission notice shall
 *   be included in all copies or substantial portions of the Software.
 *   
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 *
 * ----------------------------------------------------------------------- */

/*
 * pxetest.c
 *
 * Test of accessing the PXE stack from COM32; specifically obtain the
 * cached DHCP return packet.
 */

#include <inttypes.h>
#include <com32.h>
#include <stdio.h>
#include <string.h>
#include <console.h>

struct s_PXENV_GET_CACHED_INFO
{
  uint16_t Status;
  uint16_t PacketType;
  uint16_t BufferSize;
  uint16_t Buffer_offs, Buffer_seg;
  uint16_t BufferLimit;
};

#define PXENV_PACKET_TYPE_DHCP_DISCOVER    1
#define PXENV_PACKET_TYPE_DHCP_ACK    2
#define PXENV_PACKET_TYPE_DHCP_REPLY    3

#define DHCP_MAX_PACKET    2048

static int get_dhcp_packet(char *buf)
{
  static com32sys_t rin;
  com32sys_t rout;
  char *bufp = __com32.cs_bounce + sizeof(struct s_PXENV_GET_CACHED_INFO);
  struct s_PXENV_GET_CACHED_INFO *parm = (void *)__com32.cs_bounce;

  rin.eax.w[0] = 0x0009;
  rin.ebx.w[0] = 0x0071;    /* PXENV_GET_CACHED_INFO */
  rin.edi.w[0] = OFFS(parm);
  rin.es = SEG(parm);

  memset(parm, 0, sizeof *parm);
  parm->PacketType = PXENV_PACKET_TYPE_DHCP_ACK;
  parm->Buffer_offs = OFFS(bufp);
  parm->Buffer_seg = SEG(bufp);
  parm->BufferSize = DHCP_MAX_PACKET;

  __intcall(0x22, &rin, &rout);

  if ( rout.eflags.l & EFLAGS_CF ) {
    printf("Unable to invoke PXE stack\n");
    return -1;
  }

  if ( rout.eax.w[0] ) {
    printf("PXE stack returned exit code %d\n", rout.eax.w[0]);
    return -1;
  }

  memcpy(buf, bufp, parm->BufferSize);
  return parm->BufferSize;
}

int main(void)
{
  char pxe_packet[DHCP_MAX_PACKET];
  int i, j, len;
  
  openconsole(&dev_stdcon_r, &dev_stdcon_w);

  if ((len = get_dhcp_packet(pxe_packet)) < 0)
    return 1;

  for (i = 0; i < len; i += 16) {
    for (j = 0; j < 16; j++) {
      if (i+j >= len)
    break;
      if (j)
    putchar(' ');
      printf("%02x", pxe_packet[i+j]);
    }
    putchar('\n');
  }

  return 0;
}




__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 




More information about the Syslinux mailing list