Annotation of qemu/roms/ipxe/src/net/fakedhcp.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (C) 2008 Michael Brown <[email protected]>.
                      3:  *
                      4:  * This program is free software; you can redistribute it and/or
                      5:  * modify it under the terms of the GNU General Public License as
                      6:  * published by the Free Software Foundation; either version 2 of the
                      7:  * License, or any later version.
                      8:  *
                      9:  * This program is distributed in the hope that it will be useful, but
                     10:  * WITHOUT ANY WARRANTY; without even the implied warranty of
                     11:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     12:  * General Public License for more details.
                     13:  *
                     14:  * You should have received a copy of the GNU General Public License
                     15:  * along with this program; if not, write to the Free Software
                     16:  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     17:  */
                     18: 
                     19: FILE_LICENCE ( GPL2_OR_LATER );
                     20: 
                     21: #include <stdint.h>
                     22: #include <stdlib.h>
                     23: #include <stdio.h>
                     24: #include <errno.h>
                     25: #include <string.h>
                     26: #include <ipxe/settings.h>
                     27: #include <ipxe/netdevice.h>
                     28: #include <ipxe/dhcppkt.h>
                     29: #include <ipxe/fakedhcp.h>
                     30: 
                     31: /** @file
                     32:  *
                     33:  * Fake DHCP packets
                     34:  *
                     35:  */
                     36: 
                     37: /**
                     38:  * Copy settings to DHCP packet
                     39:  *
                     40:  * @v dest             Destination DHCP packet
                     41:  * @v source           Source settings block
                     42:  * @v encapsulator     Encapsulating setting tag number, or zero
                     43:  * @ret rc             Return status code
                     44:  */
                     45: static int copy_encap_settings ( struct dhcp_packet *dest,
                     46:                                 struct settings *source,
                     47:                                 unsigned int encapsulator ) {
                     48:        struct setting setting = { .name = "" };
                     49:        unsigned int subtag;
                     50:        unsigned int tag;
                     51:        int len;
                     52:        int check_len;
                     53:        int rc;
                     54: 
                     55:        for ( subtag = DHCP_MIN_OPTION; subtag <= DHCP_MAX_OPTION; subtag++ ) {
                     56:                tag = DHCP_ENCAP_OPT ( encapsulator, subtag );
                     57:                switch ( tag ) {
                     58:                case DHCP_EB_ENCAP:
                     59:                case DHCP_VENDOR_ENCAP:
                     60:                        /* Process encapsulated settings */
                     61:                        if ( ( rc = copy_encap_settings ( dest, source,
                     62:                                                          tag ) ) != 0 )
                     63:                                return rc;
                     64:                        break;
                     65:                default:
                     66:                        /* Copy setting, if present */
                     67:                        setting.tag = tag;
                     68:                        len = fetch_setting_len ( source, &setting );
                     69:                        if ( len < 0 )
                     70:                                break;
                     71:                        {
                     72:                                char buf[len];
                     73: 
                     74:                                check_len = fetch_setting ( source, &setting,
                     75:                                                            buf, sizeof (buf));
                     76:                                assert ( check_len == len );
                     77:                                if ( ( rc = dhcppkt_store ( dest, tag, buf,
                     78:                                                            sizeof(buf) )) !=0)
                     79:                                        return rc;
                     80:                        }
                     81:                        break;
                     82:                }
                     83:        }
                     84: 
                     85:        return 0;
                     86: }
                     87: 
                     88: /**
                     89:  * Copy settings to DHCP packet
                     90:  *
                     91:  * @v dest             Destination DHCP packet
                     92:  * @v source           Source settings block
                     93:  * @ret rc             Return status code
                     94:  */
                     95: static int copy_settings ( struct dhcp_packet *dest,
                     96:                           struct settings *source ) {
                     97:        return copy_encap_settings ( dest, source, 0 );
                     98: }
                     99: 
                    100: /**
                    101:  * Create fake DHCPDISCOVER packet
                    102:  *
                    103:  * @v netdev           Network device
                    104:  * @v data             Buffer for DHCP packet
                    105:  * @v max_len          Size of DHCP packet buffer
                    106:  * @ret rc             Return status code
                    107:  *
                    108:  * Used by external code.
                    109:  */
                    110: int create_fakedhcpdiscover ( struct net_device *netdev,
                    111:                              void *data, size_t max_len ) {
                    112:        struct dhcp_packet dhcppkt;
                    113:        struct in_addr ciaddr = { 0 };
                    114:        int rc;
                    115: 
                    116:        if ( ( rc = dhcp_create_request ( &dhcppkt, netdev, DHCPDISCOVER,
                    117:                                          ciaddr, data, max_len ) ) != 0 ) {
                    118:                DBG ( "Could not create DHCPDISCOVER: %s\n",
                    119:                      strerror ( rc ) );
                    120:                return rc;
                    121:        }
                    122: 
                    123:        return 0;
                    124: }
                    125: 
                    126: /**
                    127:  * Create fake DHCPACK packet
                    128:  *
                    129:  * @v netdev           Network device
                    130:  * @v data             Buffer for DHCP packet
                    131:  * @v max_len          Size of DHCP packet buffer
                    132:  * @ret rc             Return status code
                    133:  *
                    134:  * Used by external code.
                    135:  */
                    136: int create_fakedhcpack ( struct net_device *netdev,
                    137:                         void *data, size_t max_len ) {
                    138:        struct dhcp_packet dhcppkt;
                    139:        int rc;
                    140: 
                    141:        /* Create base DHCPACK packet */
                    142:        if ( ( rc = dhcp_create_packet ( &dhcppkt, netdev, DHCPACK, NULL, 0,
                    143:                                         data, max_len ) ) != 0 ) {
                    144:                DBG ( "Could not create DHCPACK: %s\n", strerror ( rc ) );
                    145:                return rc;
                    146:        }
                    147: 
                    148:        /* Merge in globally-scoped settings, then netdev-specific
                    149:         * settings.  Do it in this order so that netdev-specific
                    150:         * settings take precedence regardless of stated priorities.
                    151:         */
                    152:        if ( ( rc = copy_settings ( &dhcppkt, NULL ) ) != 0 ) {
                    153:                DBG ( "Could not set DHCPACK global settings: %s\n",
                    154:                      strerror ( rc ) );
                    155:                return rc;
                    156:        }
                    157:        if ( ( rc = copy_settings ( &dhcppkt,
                    158:                                    netdev_settings ( netdev ) ) ) != 0 ) {
                    159:                DBG ( "Could not set DHCPACK netdev settings: %s\n",
                    160:                      strerror ( rc ) );
                    161:                return rc;
                    162:        }
                    163: 
                    164:        return 0;
                    165: }
                    166: 
                    167: /**
                    168:  * Create fake PXE Boot Server ACK packet
                    169:  *
                    170:  * @v netdev           Network device
                    171:  * @v data             Buffer for DHCP packet
                    172:  * @v max_len          Size of DHCP packet buffer
                    173:  * @ret rc             Return status code
                    174:  *
                    175:  * Used by external code.
                    176:  */
                    177: int create_fakepxebsack ( struct net_device *netdev,
                    178:                          void *data, size_t max_len ) {
                    179:        struct dhcp_packet dhcppkt;
                    180:        struct settings *proxy_settings;
                    181:        struct settings *pxebs_settings;
                    182:        int rc;
                    183: 
                    184:        /* Identify available settings */
                    185:        proxy_settings = find_settings ( PROXYDHCP_SETTINGS_NAME );
                    186:        pxebs_settings = find_settings ( PXEBS_SETTINGS_NAME );
                    187:        if ( ( ! proxy_settings ) && ( ! pxebs_settings ) ) {
                    188:                /* No PXE boot server; return the regular DHCPACK */
                    189:                return create_fakedhcpack ( netdev, data, max_len );
                    190:        }
                    191: 
                    192:        /* Create base DHCPACK packet */
                    193:        if ( ( rc = dhcp_create_packet ( &dhcppkt, netdev, DHCPACK, NULL, 0,
                    194:                                         data, max_len ) ) != 0 ) {
                    195:                DBG ( "Could not create PXE BS ACK: %s\n",
                    196:                      strerror ( rc ) );
                    197:                return rc;
                    198:        }
                    199: 
                    200:        /* Merge in ProxyDHCP options */
                    201:        if ( proxy_settings &&
                    202:             ( ( rc = copy_settings ( &dhcppkt, proxy_settings ) ) != 0 ) ) {
                    203:                DBG ( "Could not copy ProxyDHCP settings: %s\n",
                    204:                      strerror ( rc ) );
                    205:                return rc;
                    206:        }
                    207: 
                    208:        /* Merge in BootServerDHCP options, if present */
                    209:        if ( pxebs_settings &&
                    210:             ( ( rc = copy_settings ( &dhcppkt, pxebs_settings ) ) != 0 ) ) {
                    211:                DBG ( "Could not copy PXE BS settings: %s\n",
                    212:                      strerror ( rc ) );
                    213:                return rc;
                    214:        }
                    215: 
                    216:        return 0;
                    217: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.