iPXE
Functions
fakedhcp.c File Reference

Fake DHCP packets. More...

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <ipxe/settings.h>
#include <ipxe/netdevice.h>
#include <ipxe/dhcppkt.h>
#include <ipxe/fakedhcp.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static int copy_encap_settings (struct dhcp_packet *dest, struct settings *source, unsigned int encapsulator)
 Copy settings to DHCP packet.
static int copy_settings (struct dhcp_packet *dest, struct settings *source)
 Copy settings to DHCP packet.
int create_fakedhcpdiscover (struct net_device *netdev, void *data, size_t max_len)
 Create fake DHCPDISCOVER packet.
int create_fakedhcpack (struct net_device *netdev, void *data, size_t max_len)
 Create fake DHCPACK packet.
int create_fakepxebsack (struct net_device *netdev, void *data, size_t max_len)
 Create fake PXE Boot Server ACK packet.

Detailed Description

Fake DHCP packets.

Definition in file fakedhcp.c.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
static int copy_encap_settings ( struct dhcp_packet dest,
struct settings source,
unsigned int  encapsulator 
) [static]

Copy settings to DHCP packet.

Parameters:
destDestination DHCP packet
sourceSource settings block
encapsulatorEncapsulating setting tag number, or zero
Return values:
rcReturn status code

Definition at line 50 of file fakedhcp.c.

References data, DHCP_EB_ENCAP, DHCP_ENCAP_OPT, DHCP_MAX_OPTION, DHCP_MIN_OPTION, DHCP_VENDOR_ENCAP, dhcppkt_store(), fetch_raw_setting_copy(), free, len, setting::name, rc, setting::tag, and tag.

Referenced by copy_settings().

                                                             {
        struct setting setting = { .name = "" };
        unsigned int subtag;
        unsigned int tag;
        void *data;
        int len;
        int rc;

        for ( subtag = DHCP_MIN_OPTION; subtag <= DHCP_MAX_OPTION; subtag++ ) {
                tag = DHCP_ENCAP_OPT ( encapsulator, subtag );
                switch ( tag ) {
                case DHCP_EB_ENCAP:
                case DHCP_VENDOR_ENCAP:
                        /* Process encapsulated settings */
                        if ( ( rc = copy_encap_settings ( dest, source,
                                                          tag ) ) != 0 )
                                return rc;
                        break;
                default:
                        /* Copy setting, if present */
                        setting.tag = tag;
                        len = fetch_raw_setting_copy ( source, &setting, &data);
                        if ( len >= 0 ) {
                                rc = dhcppkt_store ( dest, tag, data, len );
                                free ( data );
                                if ( rc != 0 )
                                        return rc;
                        }
                        break;
                }
        }

        return 0;
}
static int copy_settings ( struct dhcp_packet dest,
struct settings source 
) [static]

Copy settings to DHCP packet.

Parameters:
destDestination DHCP packet
sourceSource settings block
Return values:
rcReturn status code

Definition at line 94 of file fakedhcp.c.

References copy_encap_settings().

Referenced by create_fakedhcpack(), and create_fakepxebsack().

                                                     {
        return copy_encap_settings ( dest, source, 0 );
}
int create_fakedhcpdiscover ( struct net_device netdev,
void *  data,
size_t  max_len 
)

Create fake DHCPDISCOVER packet.

Parameters:
netdevNetwork device
dataBuffer for DHCP packet
max_lenSize of DHCP packet buffer
Return values:
rcReturn status code

Used by external code.

Definition at line 109 of file fakedhcp.c.

References DBG, dhcp_create_request(), dhcp_last_xid, DHCPDISCOVER, rc, and strerror().

Referenced by efi_pxe_fake_all().

                                                           {
        struct dhcp_packet dhcppkt;
        struct in_addr ciaddr = { 0 };
        int rc;

        if ( ( rc = dhcp_create_request ( &dhcppkt, netdev, DHCPDISCOVER,
                                          dhcp_last_xid, ciaddr, data,
                                          max_len ) ) != 0 ) {
                DBG ( "Could not create DHCPDISCOVER: %s\n",
                      strerror ( rc ) );
                return rc;
        }

        return 0;
}
int create_fakedhcpack ( struct net_device netdev,
void *  data,
size_t  max_len 
)

Create fake DHCPACK packet.

Parameters:
netdevNetwork device
dataBuffer for DHCP packet
max_lenSize of DHCP packet buffer
Return values:
rcReturn status code

Used by external code.

Definition at line 136 of file fakedhcp.c.

References copy_settings(), DBG, dhcp_create_packet(), dhcp_last_xid, DHCPACK, netdev_settings(), NULL, rc, and strerror().

Referenced by create_fakepxebsack(), efi_pxe_fake_all(), and nbi_prepare_dhcp().

                                                      {
        struct dhcp_packet dhcppkt;
        int rc;

        /* Create base DHCPACK packet */
        if ( ( rc = dhcp_create_packet ( &dhcppkt, netdev, DHCPACK,
                                         dhcp_last_xid, NULL, 0,
                                         data, max_len ) ) != 0 ) {
                DBG ( "Could not create DHCPACK: %s\n", strerror ( rc ) );
                return rc;
        }

        /* Merge in globally-scoped settings, then netdev-specific
         * settings.  Do it in this order so that netdev-specific
         * settings take precedence regardless of stated priorities.
         */
        if ( ( rc = copy_settings ( &dhcppkt, NULL ) ) != 0 ) {
                DBG ( "Could not set DHCPACK global settings: %s\n",
                      strerror ( rc ) );
                return rc;
        }
        if ( ( rc = copy_settings ( &dhcppkt,
                                    netdev_settings ( netdev ) ) ) != 0 ) {
                DBG ( "Could not set DHCPACK netdev settings: %s\n",
                      strerror ( rc ) );
                return rc;
        }

        return 0;
}
int create_fakepxebsack ( struct net_device netdev,
void *  data,
size_t  max_len 
)

Create fake PXE Boot Server ACK packet.

Parameters:
netdevNetwork device
dataBuffer for DHCP packet
max_lenSize of DHCP packet buffer
Return values:
rcReturn status code

Used by external code.

Definition at line 178 of file fakedhcp.c.

References dhcphdr::ciaddr, copy_settings(), create_fakedhcpack(), DBG, dhcp_create_packet(), dhcp_last_xid, DHCPACK, dhcp_packet::dhcphdr, fetch_ipv4_setting(), find_settings(), netdev_settings(), NULL, PROXYDHCP_SETTINGS_NAME, PXEBS_SETTINGS_NAME, rc, and strerror().

Referenced by efi_pxe_fake_all().

                                                       {
        struct dhcp_packet dhcppkt;
        struct settings *proxy_settings;
        struct settings *pxebs_settings;
        int rc;

        /* Identify available settings */
        proxy_settings = find_settings ( PROXYDHCP_SETTINGS_NAME );
        pxebs_settings = find_settings ( PXEBS_SETTINGS_NAME );
        if ( ( ! proxy_settings ) && ( ! pxebs_settings ) ) {
                /* No PXE boot server; return the regular DHCPACK */
                return create_fakedhcpack ( netdev, data, max_len );
        }

        /* Create base DHCPACK packet */
        if ( ( rc = dhcp_create_packet ( &dhcppkt, netdev, DHCPACK,
                                         dhcp_last_xid, NULL, 0,
                                         data, max_len ) ) != 0 ) {
                DBG ( "Could not create PXE BS ACK: %s\n",
                      strerror ( rc ) );
                return rc;
        }

        /* Populate ciaddr */
        fetch_ipv4_setting ( netdev_settings ( netdev ), &ip_setting,
                             &dhcppkt.dhcphdr->ciaddr );

        /* Merge in ProxyDHCP options */
        if ( proxy_settings &&
             ( ( rc = copy_settings ( &dhcppkt, proxy_settings ) ) != 0 ) ) {
                DBG ( "Could not copy ProxyDHCP settings: %s\n",
                      strerror ( rc ) );
                return rc;
        }

        /* Merge in BootServerDHCP options, if present */
        if ( pxebs_settings &&
             ( ( rc = copy_settings ( &dhcppkt, pxebs_settings ) ) != 0 ) ) {
                DBG ( "Could not copy PXE BS settings: %s\n",
                      strerror ( rc ) );
                return rc;
        }

        return 0;
}