syslinux/gpxe/src/include/gpxe/dhcp.h
<<
>>
Prefs
   1#ifndef _GPXE_DHCP_H
   2#define _GPXE_DHCP_H
   3
   4/** @file
   5 *
   6 * Dynamic Host Configuration Protocol
   7 *
   8 */
   9
  10FILE_LICENCE ( GPL2_OR_LATER );
  11
  12#include <stdint.h>
  13#include <gpxe/in.h>
  14#include <gpxe/list.h>
  15#include <gpxe/refcnt.h>
  16#include <gpxe/tables.h>
  17#include <gpxe/uuid.h>
  18#include <gpxe/netdevice.h>
  19#include <gpxe/uaccess.h>
  20
  21struct job_interface;
  22struct dhcp_options;
  23struct dhcp_packet;
  24
  25/** BOOTP/DHCP server port */
  26#define BOOTPS_PORT 67
  27
  28/** BOOTP/DHCP client port */
  29#define BOOTPC_PORT 68
  30
  31/** PXE server port */
  32#define PXE_PORT 4011
  33
  34/** Construct a tag value for an encapsulated option
  35 *
  36 * This tag value can be passed to Etherboot functions when searching
  37 * for DHCP options in order to search for a tag within an
  38 * encapsulated options block.
  39 */
  40#define DHCP_ENCAP_OPT( encapsulator, encapsulated ) \
  41        ( ( (encapsulator) << 8 ) | (encapsulated) )
  42/** Extract encapsulating option block tag from encapsulated tag value */
  43#define DHCP_ENCAPSULATOR( encap_opt ) ( (encap_opt) >> 8 )
  44/** Extract encapsulated option tag from encapsulated tag value */
  45#define DHCP_ENCAPSULATED( encap_opt ) ( (encap_opt) & 0xff )
  46/** Option is encapsulated */
  47#define DHCP_IS_ENCAP_OPT( opt ) DHCP_ENCAPSULATOR( opt )
  48
  49/**
  50 * @defgroup dhcpopts DHCP option tags
  51 * @{
  52 */
  53
  54/** Padding
  55 *
  56 * This tag does not have a length field; it is always only a single
  57 * byte in length.
  58 */
  59#define DHCP_PAD 0
  60
  61/** Minimum normal DHCP option */
  62#define DHCP_MIN_OPTION 1
  63
  64/** Subnet mask */
  65#define DHCP_SUBNET_MASK 1
  66
  67/** Routers */
  68#define DHCP_ROUTERS 3
  69
  70/** DNS servers */
  71#define DHCP_DNS_SERVERS 6
  72
  73/** Syslog servers */
  74#define DHCP_LOG_SERVERS 7
  75
  76/** Host name */
  77#define DHCP_HOST_NAME 12
  78
  79/** Domain name */
  80#define DHCP_DOMAIN_NAME 15
  81
  82/** Root path */
  83#define DHCP_ROOT_PATH 17
  84
  85/** Vendor encapsulated options */
  86#define DHCP_VENDOR_ENCAP 43
  87
  88/** PXE boot server discovery control */
  89#define DHCP_PXE_DISCOVERY_CONTROL DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 6 )
  90
  91/** PXE boot server discovery control bits */
  92enum dhcp_pxe_discovery_control {
  93        /** Inhibit broadcast discovery */
  94        PXEBS_NO_BROADCAST = 1,
  95        /** Inhibit multicast discovery */
  96        PXEBS_NO_MULTICAST = 2,
  97        /** Accept only servers in DHCP_PXE_BOOT_SERVERS list */
  98        PXEBS_NO_UNKNOWN_SERVERS = 4,
  99        /** Skip discovery if filename present */
 100        PXEBS_SKIP = 8,
 101};
 102
 103/** PXE boot server multicast address */
 104#define DHCP_PXE_BOOT_SERVER_MCAST DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 7 )
 105
 106/** PXE boot servers */
 107#define DHCP_PXE_BOOT_SERVERS DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 8 )
 108
 109/** PXE boot server */
 110struct dhcp_pxe_boot_server {
 111        /** "Type" */
 112        uint16_t type;
 113        /** Number of IPv4 addresses */
 114        uint8_t num_ip;
 115        /** IPv4 addresses */
 116        struct in_addr ip[0];
 117} __attribute__ (( packed ));
 118
 119/** PXE boot menu */
 120#define DHCP_PXE_BOOT_MENU DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 9 )
 121
 122/** PXE boot menu */
 123struct dhcp_pxe_boot_menu {
 124        /** "Type" */
 125        uint16_t type;
 126        /** Description length */
 127        uint8_t desc_len;
 128        /** Description */
 129        char desc[0];
 130} __attribute__ (( packed ));
 131
 132/** PXE boot menu prompt */
 133#define DHCP_PXE_BOOT_MENU_PROMPT DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 10 )
 134
 135/** PXE boot menu prompt */
 136struct dhcp_pxe_boot_menu_prompt {
 137        /** Timeout
 138         *
 139         * A value of 0 means "time out immediately and select first
 140         * boot item, without displaying the prompt".  A value of 255
 141         * means "display menu immediately with no timeout".  Any
 142         * other value means "display prompt, wait this many seconds
 143         * for keypress, if key is F8, display menu, otherwise select
 144         * first boot item".
 145         */
 146        uint8_t timeout;
 147        /** Prompt to press F8 */
 148        char prompt[0];
 149} __attribute__ (( packed ));
 150
 151/** PXE boot menu item */
 152#define DHCP_PXE_BOOT_MENU_ITEM DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 71 )
 153
 154/** PXE boot menu item */
 155struct dhcp_pxe_boot_menu_item {
 156        /** "Type"
 157         *
 158         * This field actually identifies the specific boot server (or
 159         * cluster of boot servers offering identical boot files).
 160         */
 161        uint16_t type;
 162        /** "Layer"
 163         *
 164         * Just don't ask.
 165         */
 166        uint16_t layer;
 167} __attribute__ (( packed ));
 168
 169/** Requested IP address */
 170#define DHCP_REQUESTED_ADDRESS 50
 171
 172/** Lease time */
 173#define DHCP_LEASE_TIME 51
 174
 175/** Option overloading
 176 *
 177 * The value of this option is the bitwise-OR of zero or more
 178 * DHCP_OPTION_OVERLOAD_XXX constants.
 179 */
 180#define DHCP_OPTION_OVERLOAD 52
 181
 182/** The "file" field is overloaded to contain extra DHCP options */
 183#define DHCP_OPTION_OVERLOAD_FILE 1
 184
 185/** The "sname" field is overloaded to contain extra DHCP options */
 186#define DHCP_OPTION_OVERLOAD_SNAME 2
 187
 188/** DHCP message type */
 189#define DHCP_MESSAGE_TYPE 53
 190#define DHCPNONE 0
 191#define DHCPDISCOVER 1
 192#define DHCPOFFER 2
 193#define DHCPREQUEST 3
 194#define DHCPDECLINE 4
 195#define DHCPACK 5
 196#define DHCPNAK 6
 197#define DHCPRELEASE 7
 198#define DHCPINFORM 8
 199
 200/** DHCP server identifier */
 201#define DHCP_SERVER_IDENTIFIER 54
 202
 203/** Parameter request list */
 204#define DHCP_PARAMETER_REQUEST_LIST 55
 205
 206/** Maximum DHCP message size */
 207#define DHCP_MAX_MESSAGE_SIZE 57
 208
 209/** Vendor class identifier */
 210#define DHCP_VENDOR_CLASS_ID 60
 211
 212/** Client identifier */
 213#define DHCP_CLIENT_ID 61
 214
 215/** Client identifier */
 216struct dhcp_client_id {
 217        /** Link-layer protocol */
 218        uint8_t ll_proto;
 219        /** Link-layer address */
 220        uint8_t ll_addr[MAX_LL_ADDR_LEN];
 221} __attribute__ (( packed ));
 222
 223/** TFTP server name
 224 *
 225 * This option replaces the fixed "sname" field, when that field is
 226 * used to contain overloaded options.
 227 */
 228#define DHCP_TFTP_SERVER_NAME 66
 229
 230/** Bootfile name
 231 *
 232 * This option replaces the fixed "file" field, when that field is
 233 * used to contain overloaded options.
 234 */
 235#define DHCP_BOOTFILE_NAME 67
 236
 237/** User class identifier */
 238#define DHCP_USER_CLASS_ID 77
 239
 240/** Client system architecture */
 241#define DHCP_CLIENT_ARCHITECTURE 93
 242
 243/** Client network device interface */
 244#define DHCP_CLIENT_NDI 94
 245
 246/** UUID client identifier */
 247#define DHCP_CLIENT_UUID 97
 248
 249/** UUID client identifier */
 250struct dhcp_client_uuid {
 251        /** Identifier type */
 252        uint8_t type;
 253        /** UUID */
 254        union uuid uuid;
 255} __attribute__ (( packed ));
 256
 257#define DHCP_CLIENT_UUID_TYPE 0
 258
 259/** Etherboot-specific encapsulated options
 260 *
 261 * This encapsulated options field is used to contain all options
 262 * specific to Etherboot (i.e. not assigned by IANA or other standards
 263 * bodies).
 264 */
 265#define DHCP_EB_ENCAP 175
 266
 267/** Priority of this options block
 268 *
 269 * This is a signed 8-bit integer field indicating the priority of
 270 * this block of options.  It can be used to specify the relative
 271 * priority of multiple option blocks (e.g. options from non-volatile
 272 * storage versus options from a DHCP server).
 273 */
 274#define DHCP_EB_PRIORITY DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x01 )
 275
 276/** "Your" IP address
 277 *
 278 * This option is used internally to contain the value of the "yiaddr"
 279 * field, in order to provide a consistent approach to storing and
 280 * processing options.  It should never be present in a DHCP packet.
 281 */
 282#define DHCP_EB_YIADDR DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x02 )
 283
 284/** "Server" IP address
 285 *
 286 * This option is used internally to contain the value of the "siaddr"
 287 * field, in order to provide a consistent approach to storing and
 288 * processing options.  It should never be present in a DHCP packet.
 289 */
 290#define DHCP_EB_SIADDR DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x03 )
 291
 292/** Keep SAN drive registered
 293 *
 294 * If set to a non-zero value, gPXE will not detach any SAN drive
 295 * after failing to boot from it.  (This option is required in order
 296 * to perform a Windows Server 2008 installation direct to an iSCSI
 297 * target.)
 298 */
 299#define DHCP_EB_KEEP_SAN DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x08 )
 300
 301/*
 302 * Tags in the range 0x10-0x7f are reserved for feature markers
 303 *
 304 */
 305
 306/** Skip PXE DHCP protocol extensions such as ProxyDHCP
 307 *
 308 * If set to a non-zero value, gPXE will not wait for ProxyDHCP offers
 309 * and will ignore any PXE-specific DHCP options that it receives.
 310 */
 311#define DHCP_EB_NO_PXEDHCP DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xb0 )
 312
 313/** Network device descriptor
 314 *
 315 * Byte 0 is the bus type ID; remaining bytes depend on the bus type.
 316 *
 317 * PCI devices:
 318 * Byte 0 : 1 (PCI)
 319 * Byte 1 : PCI vendor ID MSB
 320 * Byte 2 : PCI vendor ID LSB
 321 * Byte 3 : PCI device ID MSB
 322 * Byte 4 : PCI device ID LSB
 323 */
 324#define DHCP_EB_BUS_ID DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xb1 )
 325
 326/** Network device descriptor */
 327struct dhcp_netdev_desc {
 328        /** Bus type ID */
 329        uint8_t type;
 330        /** Vendor ID */
 331        uint16_t vendor;
 332        /** Device ID */
 333        uint16_t device;
 334} __attribute__ (( packed ));
 335
 336/** Use cached network settings
 337 *
 338 * Cached network settings may be available from a prior DHCP request
 339 * (if running as a PXE NBP), non-volatile storage on the NIC, or
 340 * settings set via the command line or an embedded image. If this
 341 * flag is not set, it will be assumed that those sources are
 342 * insufficient and that DHCP should still be run when autobooting.
 343 */
 344#define DHCP_EB_USE_CACHED DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xb2 )
 345
 346/** BIOS drive number
 347 *
 348 * This is the drive number for a drive emulated via INT 13.  0x80 is
 349 * the first hard disk, 0x81 is the second hard disk, etc.
 350 */
 351#define DHCP_EB_BIOS_DRIVE DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xbd )
 352
 353/** Username
 354 *
 355 * This will be used as the username for any required authentication.
 356 * It is expected that this option's value will be held in
 357 * non-volatile storage, rather than transmitted as part of a DHCP
 358 * packet.
 359 */
 360#define DHCP_EB_USERNAME DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xbe )
 361
 362/** Password
 363 *
 364 * This will be used as the password for any required authentication.
 365 * It is expected that this option's value will be held in
 366 * non-volatile storage, rather than transmitted as part of a DHCP
 367 * packet.
 368 */
 369#define DHCP_EB_PASSWORD DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xbf )
 370
 371/** Reverse username
 372 *
 373 * This will be used as the reverse username (i.e. the username
 374 * provided by the server) for any required authentication.  It is
 375 * expected that this option's value will be held in non-volatile
 376 * storage, rather than transmitted as part of a DHCP packet.
 377 */
 378#define DHCP_EB_REVERSE_USERNAME DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xc0 )
 379
 380/** Reverse password
 381 *
 382 * This will be used as the reverse password (i.e. the password
 383 * provided by the server) for any required authentication.  It is
 384 * expected that this option's value will be held in non-volatile
 385 * storage, rather than transmitted as part of a DHCP packet.
 386 */
 387#define DHCP_EB_REVERSE_PASSWORD DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xc1 )
 388
 389/** gPXE version number */
 390#define DHCP_EB_VERSION DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xeb )
 391
 392/** iSCSI primary target IQN */
 393#define DHCP_ISCSI_PRIMARY_TARGET_IQN 201
 394
 395/** iSCSI secondary target IQN */
 396#define DHCP_ISCSI_SECONDARY_TARGET_IQN 202
 397
 398/** iSCSI initiator IQN */
 399#define DHCP_ISCSI_INITIATOR_IQN 203
 400
 401/** Maximum normal DHCP option */
 402#define DHCP_MAX_OPTION 254
 403
 404/** End of options
 405 *
 406 * This tag does not have a length field; it is always only a single
 407 * byte in length.
 408 */
 409#define DHCP_END 255
 410
 411/** @} */
 412
 413/**
 414 * Count number of arguments to a variadic macro
 415 *
 416 * This rather neat, non-iterative solution is courtesy of Laurent
 417 * Deniau.
 418 *
 419 */
 420#define _VA_ARG_COUNT(  _1,  _2,  _3,  _4,  _5,  _6,  _7,  _8,          \
 421                        _9, _10, _11, _12, _13, _14, _15, _16,          \
 422                       _17, _18, _19, _20, _21, _22, _23, _24,          \
 423                       _25, _26, _27, _28, _29, _30, _31, _32,          \
 424                       _33, _34, _35, _36, _37, _38, _39, _40,          \
 425                       _41, _42, _43, _44, _45, _46, _47, _48,          \
 426                       _49, _50, _51, _52, _53, _54, _55, _56,          \
 427                       _57, _58, _59, _60, _61, _62, _63,   N, ... ) N
 428#define VA_ARG_COUNT( ... )                                             \
 429        _VA_ARG_COUNT ( __VA_ARGS__,                                    \
 430                        63, 62, 61, 60, 59, 58, 57, 56,                 \
 431                        55, 54, 53, 52, 51, 50, 49, 48,                 \
 432                        47, 46, 45, 44, 43, 42, 41, 40,                 \
 433                        39, 38, 37, 36, 35, 34, 33, 32,                 \
 434                        31, 30, 29, 28, 27, 26, 25, 24,                 \
 435                        23, 22, 21, 20, 19, 18, 17, 16,                 \
 436                        15, 14, 13, 12, 11, 10,  9,  8,                 \
 437                         7,  6,  5,  4,  3,  2,  1,  0 )
 438
 439/** Construct a DHCP option from a list of bytes */
 440#define DHCP_OPTION( ... ) VA_ARG_COUNT ( __VA_ARGS__ ), __VA_ARGS__
 441
 442/** Construct a DHCP option from a list of characters */
 443#define DHCP_STRING( ... ) DHCP_OPTION ( __VA_ARGS__ )
 444
 445/** Construct a byte-valued DHCP option */
 446#define DHCP_BYTE( value ) DHCP_OPTION ( value )
 447
 448/** Construct a word-valued DHCP option */
 449#define DHCP_WORD( value ) DHCP_OPTION ( ( ( (value) >> 8 ) & 0xff ),   \
 450                                         ( ( (value) >> 0 ) & 0xff ) )
 451
 452/** Construct a dword-valued DHCP option */
 453#define DHCP_DWORD( value ) DHCP_OPTION ( ( ( (value) >> 24 ) & 0xff ), \
 454                                          ( ( (value) >> 16 ) & 0xff ), \
 455                                          ( ( (value) >> 8  ) & 0xff ), \
 456                                          ( ( (value) >> 0  ) & 0xff ) )
 457
 458/** Construct a DHCP encapsulated options field */
 459#define DHCP_ENCAP( ... ) DHCP_OPTION ( __VA_ARGS__, DHCP_END )
 460
 461/**
 462 * A DHCP option
 463 *
 464 * DHCP options consist of a mandatory tag, a length field that is
 465 * mandatory for all options except @c DHCP_PAD and @c DHCP_END, and a
 466 * payload.  
 467 */
 468struct dhcp_option {
 469        /** Tag
 470         *
 471         * Must be a @c DHCP_XXX value.
 472         */
 473        uint8_t tag;
 474        /** Length
 475         *
 476         * This is the length of the data field (i.e. excluding the
 477         * tag and length fields).  For the two tags @c DHCP_PAD and
 478         * @c DHCP_END, the length field is implicitly zero and is
 479         * also missing, i.e. these DHCP options are only a single
 480         * byte in length.
 481         */
 482        uint8_t len;
 483        /** Option data */
 484        uint8_t data[0];
 485} __attribute__ (( packed ));
 486
 487/**
 488 * Length of a DHCP option header
 489 *
 490 * The header is the portion excluding the data, i.e. the tag and the
 491 * length.
 492 */
 493#define DHCP_OPTION_HEADER_LEN ( offsetof ( struct dhcp_option, data ) )
 494
 495/** Maximum length for a single DHCP option */
 496#define DHCP_MAX_LEN 0xff
 497
 498/**
 499 * A DHCP header
 500 *
 501 */
 502struct dhcphdr {
 503        /** Operation
 504         *
 505         * This must be either @c BOOTP_REQUEST or @c BOOTP_REPLY.
 506         */
 507        uint8_t op;
 508        /** Hardware address type
 509         *
 510         * This is an ARPHRD_XXX constant.  Note that ARPHRD_XXX
 511         * constants are nominally 16 bits wide; this could be
 512         * considered to be a bug in the BOOTP/DHCP specification.
 513         */
 514        uint8_t htype;
 515        /** Hardware address length */
 516        uint8_t hlen;
 517        /** Number of hops from server */
 518        uint8_t hops;
 519        /** Transaction ID */
 520        uint32_t xid;
 521        /** Seconds since start of acquisition */
 522        uint16_t secs;
 523        /** Flags */
 524        uint16_t flags;
 525        /** "Client" IP address
 526         *
 527         * This is filled in if the client already has an IP address
 528         * assigned and can respond to ARP requests.
 529         */
 530        struct in_addr ciaddr;
 531        /** "Your" IP address
 532         *
 533         * This is the IP address assigned by the server to the client.
 534         */
 535        struct in_addr yiaddr;
 536        /** "Server" IP address
 537         *
 538         * This is the IP address of the next server to be used in the
 539         * boot process.
 540         */
 541        struct in_addr siaddr;
 542        /** "Gateway" IP address
 543         *
 544         * This is the IP address of the DHCP relay agent, if any.
 545         */
 546        struct in_addr giaddr;
 547        /** Client hardware address */
 548        uint8_t chaddr[16];
 549        /** Server host name (null terminated)
 550         *
 551         * This field may be overridden and contain DHCP options
 552         */
 553        char sname[64];
 554        /** Boot file name (null terminated)
 555         *
 556         * This field may be overridden and contain DHCP options
 557         */
 558        char file[128];
 559        /** DHCP magic cookie
 560         *
 561         * Must have the value @c DHCP_MAGIC_COOKIE.
 562         */
 563        uint32_t magic;
 564        /** DHCP options
 565         *
 566         * Variable length; extends to the end of the packet.  Minimum
 567         * length (for the sake of sanity) is 1, to allow for a single
 568         * @c DHCP_END tag.
 569         */
 570        uint8_t options[0];
 571};
 572
 573/** Opcode for a request from client to server */
 574#define BOOTP_REQUEST 1
 575
 576/** Opcode for a reply from server to client */
 577#define BOOTP_REPLY 2
 578
 579/** BOOTP reply must be broadcast
 580 *
 581 * Clients that cannot accept unicast BOOTP replies must set this
 582 * flag.
 583 */
 584#define BOOTP_FL_BROADCAST 0x8000
 585
 586/** DHCP magic cookie */
 587#define DHCP_MAGIC_COOKIE 0x63825363UL
 588
 589/** DHCP minimum packet length
 590 *
 591 * This is the mandated minimum packet length that a DHCP participant
 592 * must be prepared to receive.
 593 */
 594#define DHCP_MIN_LEN 552
 595
 596/** Timeouts for sending DHCP packets */
 597#define DHCP_MIN_TIMEOUT ( 1 * TICKS_PER_SEC )
 598#define DHCP_MAX_TIMEOUT ( 10 * TICKS_PER_SEC )
 599
 600/** Maximum time that we will wait for ProxyDHCP responses */
 601#define PROXYDHCP_MAX_TIMEOUT ( 2 * TICKS_PER_SEC )
 602
 603/** Maximum time that we will wait for Boot Server responses */
 604#define PXEBS_MAX_TIMEOUT ( 3 * TICKS_PER_SEC )
 605
 606/** Settings block name used for DHCP responses */
 607#define DHCP_SETTINGS_NAME "dhcp"
 608
 609/** Settings block name used for ProxyDHCP responses */
 610#define PROXYDHCP_SETTINGS_NAME "proxydhcp"
 611
 612/** Setting block name used for BootServerDHCP responses */
 613#define PXEBS_SETTINGS_NAME "pxebs"
 614
 615extern void * dhcp_chaddr ( struct net_device *netdev, uint8_t *hlen,
 616                            uint16_t *flags );
 617extern int dhcp_create_packet ( struct dhcp_packet *dhcppkt,
 618                                struct net_device *netdev, uint8_t msgtype,
 619                                const void *options, size_t options_len,
 620                                void *data, size_t max_len );
 621extern int dhcp_create_request ( struct dhcp_packet *dhcppkt,
 622                                 struct net_device *netdev,
 623                                 unsigned int msgtype, struct in_addr ciaddr,
 624                                 void *data, size_t max_len );
 625extern int start_dhcp ( struct job_interface *job, struct net_device *netdev );
 626extern int start_pxebs ( struct job_interface *job, struct net_device *netdev,
 627                         unsigned int pxe_type );
 628
 629/* In environments that can provide cached DHCP packets, this function
 630 * should look for such a packet and call store_cached_dhcpack() with
 631 * it if it exists.
 632 */
 633__weak_decl ( void, get_cached_dhcpack, ( void ), (), );
 634
 635extern void store_cached_dhcpack ( userptr_t data, size_t len );
 636
 637#endif /* _GPXE_DHCP_H */
 638
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.