Annotation of qemu/roms/ipxe/src/net/fakedhcp.c, revision 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.