diff options
Diffstat (limited to 'qemu/roms/ipxe/src/net/dhcppkt.c')
-rw-r--r-- | qemu/roms/ipxe/src/net/dhcppkt.c | 309 |
1 files changed, 0 insertions, 309 deletions
diff --git a/qemu/roms/ipxe/src/net/dhcppkt.c b/qemu/roms/ipxe/src/net/dhcppkt.c deleted file mode 100644 index 4e64f85e4..000000000 --- a/qemu/roms/ipxe/src/net/dhcppkt.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <ipxe/netdevice.h> -#include <ipxe/dhcp.h> -#include <ipxe/dhcpopts.h> -#include <ipxe/dhcppkt.h> - -/** @file - * - * DHCP packets - * - */ - -/**************************************************************************** - * - * DHCP packet raw interface - * - */ - -/** - * Calculate used length of an IPv4 field within a DHCP packet - * - * @v data Field data - * @v len Length of field - * @ret used Used length of field - */ -static size_t used_len_ipv4 ( const void *data, size_t len __unused ) { - const struct in_addr *in = data; - - return ( in->s_addr ? sizeof ( *in ) : 0 ); -} - -/** - * Calculate used length of a string field within a DHCP packet - * - * @v data Field data - * @v len Length of field - * @ret used Used length of field - */ -static size_t used_len_string ( const void *data, size_t len ) { - return strnlen ( data, len ); -} - -/** A dedicated field within a DHCP packet */ -struct dhcp_packet_field { - /** Settings tag number */ - unsigned int tag; - /** Offset within DHCP packet */ - uint16_t offset; - /** Length of field */ - uint16_t len; - /** Calculate used length of field - * - * @v data Field data - * @v len Length of field - * @ret used Used length of field - */ - size_t ( * used_len ) ( const void *data, size_t len ); -}; - -/** Declare a dedicated field within a DHCP packet - * - * @v _tag Settings tag number - * @v _field Field name - * @v _used_len Function to calculate used length of field - */ -#define DHCP_PACKET_FIELD( _tag, _field, _used_len ) { \ - .tag = (_tag), \ - .offset = offsetof ( struct dhcphdr, _field ), \ - .len = sizeof ( ( ( struct dhcphdr * ) 0 )->_field ), \ - .used_len = _used_len, \ - } - -/** Dedicated fields within a DHCP packet */ -static struct dhcp_packet_field dhcp_packet_fields[] = { - DHCP_PACKET_FIELD ( DHCP_EB_YIADDR, yiaddr, used_len_ipv4 ), - DHCP_PACKET_FIELD ( DHCP_EB_SIADDR, siaddr, used_len_ipv4 ), - DHCP_PACKET_FIELD ( DHCP_TFTP_SERVER_NAME, sname, used_len_string ), - DHCP_PACKET_FIELD ( DHCP_BOOTFILE_NAME, file, used_len_string ), -}; - -/** - * Get address of a DHCP packet field - * - * @v dhcphdr DHCP packet header - * @v field DHCP packet field - * @ret data Packet field data - */ -static inline void * dhcp_packet_field ( struct dhcphdr *dhcphdr, - struct dhcp_packet_field *field ) { - return ( ( ( void * ) dhcphdr ) + field->offset ); -} - -/** - * Find DHCP packet field corresponding to settings tag number - * - * @v tag Settings tag number - * @ret field DHCP packet field, or NULL - */ -static struct dhcp_packet_field * -find_dhcp_packet_field ( unsigned int tag ) { - struct dhcp_packet_field *field; - unsigned int i; - - for ( i = 0 ; i < ( sizeof ( dhcp_packet_fields ) / - sizeof ( dhcp_packet_fields[0] ) ) ; i++ ) { - field = &dhcp_packet_fields[i]; - if ( field->tag == tag ) - return field; - } - return NULL; -} - -/** - * Check applicability of DHCP setting - * - * @v dhcppkt DHCP packet - * @v tag Setting tag number - * @ret applies Setting applies within this settings block - */ -static int dhcppkt_applies ( struct dhcp_packet *dhcppkt __unused, - unsigned int tag ) { - - return dhcpopt_applies ( tag ); -} - -/** - * Store value of DHCP packet setting - * - * @v dhcppkt DHCP packet - * @v tag Setting tag number - * @v data Setting data, or NULL to clear setting - * @v len Length of setting data - * @ret rc Return status code - */ -int dhcppkt_store ( struct dhcp_packet *dhcppkt, unsigned int tag, - const void *data, size_t len ) { - struct dhcp_packet_field *field; - void *field_data; - - /* If this is a special field, fill it in */ - if ( ( field = find_dhcp_packet_field ( tag ) ) != NULL ) { - if ( len > field->len ) - return -ENOSPC; - field_data = dhcp_packet_field ( dhcppkt->dhcphdr, field ); - memset ( field_data, 0, field->len ); - memcpy ( dhcp_packet_field ( dhcppkt->dhcphdr, field ), - data, len ); - /* Erase any equivalent option from the options block */ - dhcpopt_store ( &dhcppkt->options, tag, NULL, 0 ); - return 0; - } - - /* Otherwise, use the generic options block */ - return dhcpopt_store ( &dhcppkt->options, tag, data, len ); -} - -/** - * Fetch value of DHCP packet setting - * - * @v dhcppkt DHCP packet - * @v tag Setting tag number - * @v data Buffer to fill with setting data - * @v len Length of buffer - * @ret len Length of setting data, or negative error - */ -int dhcppkt_fetch ( struct dhcp_packet *dhcppkt, unsigned int tag, - void *data, size_t len ) { - struct dhcp_packet_field *field; - void *field_data; - size_t field_len = 0; - - /* Identify special field, if any */ - if ( ( field = find_dhcp_packet_field ( tag ) ) != NULL ) { - field_data = dhcp_packet_field ( dhcppkt->dhcphdr, field ); - field_len = field->used_len ( field_data, field->len ); - } - - /* Return special field, if it exists and is populated */ - if ( field_len ) { - if ( len > field_len ) - len = field_len; - memcpy ( data, field_data, len ); - return field_len; - } - - /* Otherwise, use the generic options block */ - return dhcpopt_fetch ( &dhcppkt->options, tag, data, len ); -} - -/**************************************************************************** - * - * DHCP packet settings interface - * - */ - -/** - * Check applicability of DHCP setting - * - * @v settings Settings block - * @v setting Setting - * @ret applies Setting applies within this settings block - */ -static int dhcppkt_settings_applies ( struct settings *settings, - const struct setting *setting ) { - struct dhcp_packet *dhcppkt = - container_of ( settings, struct dhcp_packet, settings ); - - return ( ( setting->scope == NULL ) && - dhcppkt_applies ( dhcppkt, setting->tag ) ); -} - -/** - * Store value of DHCP setting - * - * @v settings Settings block - * @v setting Setting to store - * @v data Setting data, or NULL to clear setting - * @v len Length of setting data - * @ret rc Return status code - */ -static int dhcppkt_settings_store ( struct settings *settings, - const struct setting *setting, - const void *data, size_t len ) { - struct dhcp_packet *dhcppkt = - container_of ( settings, struct dhcp_packet, settings ); - - return dhcppkt_store ( dhcppkt, setting->tag, data, len ); -} - -/** - * Fetch value of DHCP setting - * - * @v settings Settings block, or NULL to search all blocks - * @v setting Setting to fetch - * @v data Buffer to fill with setting data - * @v len Length of buffer - * @ret len Length of setting data, or negative error - */ -static int dhcppkt_settings_fetch ( struct settings *settings, - struct setting *setting, - void *data, size_t len ) { - struct dhcp_packet *dhcppkt = - container_of ( settings, struct dhcp_packet, settings ); - - return dhcppkt_fetch ( dhcppkt, setting->tag, data, len ); -} - -/** DHCP settings operations */ -static struct settings_operations dhcppkt_settings_operations = { - .applies = dhcppkt_settings_applies, - .store = dhcppkt_settings_store, - .fetch = dhcppkt_settings_fetch, -}; - -/**************************************************************************** - * - * Constructor - * - */ - -/** - * Initialise DHCP packet - * - * @v dhcppkt DHCP packet structure to fill in - * @v data DHCP packet raw data - * @v max_len Length of raw data buffer - * - * Initialise a DHCP packet structure from a data buffer containing a - * DHCP packet. - */ -void dhcppkt_init ( struct dhcp_packet *dhcppkt, struct dhcphdr *data, - size_t len ) { - ref_init ( &dhcppkt->refcnt, NULL ); - dhcppkt->dhcphdr = data; - dhcpopt_init ( &dhcppkt->options, &dhcppkt->dhcphdr->options, - ( len - offsetof ( struct dhcphdr, options ) ), - dhcpopt_no_realloc ); - settings_init ( &dhcppkt->settings, &dhcppkt_settings_operations, - &dhcppkt->refcnt, NULL ); -} |