iPXE
fakedhcp.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
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., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27#include <stdint.h>
28#include <stdlib.h>
29#include <stdio.h>
30#include <errno.h>
31#include <string.h>
32#include <ipxe/settings.h>
33#include <ipxe/netdevice.h>
34#include <ipxe/dhcppkt.h>
35#include <ipxe/fakedhcp.h>
36
37/** @file
38 *
39 * Fake DHCP packets
40 *
41 */
42
43/**
44 * Copy settings to DHCP packet
45 *
46 * @v dest Destination DHCP packet
47 * @v source Source settings block
48 * @v encapsulator Encapsulating setting tag number, or zero
49 * @ret rc Return status code
50 */
52 struct settings *source,
53 unsigned int encapsulator ) {
54 struct setting setting = { .name = "" };
55 unsigned int subtag;
56 unsigned int tag;
57 void *data;
58 int len;
59 int rc;
60
61 for ( subtag = DHCP_MIN_OPTION; subtag <= DHCP_MAX_OPTION; subtag++ ) {
62 tag = DHCP_ENCAP_OPT ( encapsulator, subtag );
63 switch ( tag ) {
64 case DHCP_EB_ENCAP:
66 /* Process encapsulated settings */
67 if ( ( rc = copy_encap_settings ( dest, source,
68 tag ) ) != 0 )
69 return rc;
70 break;
71 default:
72 /* Copy setting, if present */
73 setting.tag = tag;
74 len = fetch_raw_setting_copy ( source, &setting, &data);
75 if ( len >= 0 ) {
77 free ( data );
78 if ( rc != 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 */
95static 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 */
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 dhcp_last_xid, ciaddr, data,
118 max_len ) ) != 0 ) {
119 DBG ( "Could not create DHCPDISCOVER: %s\n",
120 strerror ( rc ) );
121 return rc;
122 }
123
124 return 0;
125}
126
127/**
128 * Create fake DHCPACK packet
129 *
130 * @v netdev Network device
131 * @v data Buffer for DHCP packet
132 * @v max_len Size of DHCP packet buffer
133 * @ret rc Return status code
134 *
135 * Used by external code.
136 */
138 void *data, size_t max_len ) {
139 struct dhcp_packet dhcppkt;
140 int rc;
141
142 /* Create base DHCPACK packet */
143 if ( ( rc = dhcp_create_packet ( &dhcppkt, netdev, DHCPACK,
145 data, max_len ) ) != 0 ) {
146 DBG ( "Could not create DHCPACK: %s\n", strerror ( rc ) );
147 return rc;
148 }
149
150 /* Merge in globally-scoped settings, then netdev-specific
151 * settings. Do it in this order so that netdev-specific
152 * settings take precedence regardless of stated priorities.
153 */
154 if ( ( rc = copy_settings ( &dhcppkt, NULL ) ) != 0 ) {
155 DBG ( "Could not set DHCPACK global settings: %s\n",
156 strerror ( rc ) );
157 return rc;
158 }
159 if ( ( rc = copy_settings ( &dhcppkt,
160 netdev_settings ( netdev ) ) ) != 0 ) {
161 DBG ( "Could not set DHCPACK netdev settings: %s\n",
162 strerror ( rc ) );
163 return rc;
164 }
165
166 return 0;
167}
168
169/**
170 * Create fake PXE Boot Server ACK packet
171 *
172 * @v netdev Network device
173 * @v data Buffer for DHCP packet
174 * @v max_len Size of DHCP packet buffer
175 * @ret rc Return status code
176 *
177 * Used by external code.
178 */
180 void *data, size_t max_len ) {
181 struct dhcp_packet dhcppkt;
182 struct settings *proxy_settings;
183 struct settings *pxebs_settings;
184 int rc;
185
186 /* Identify available settings */
187 proxy_settings = find_settings ( PROXYDHCP_SETTINGS_NAME );
188 pxebs_settings = find_settings ( PXEBS_SETTINGS_NAME );
189 if ( ( ! proxy_settings ) && ( ! pxebs_settings ) ) {
190 /* No PXE boot server; return the regular DHCPACK */
191 return create_fakedhcpack ( netdev, data, max_len );
192 }
193
194 /* Create base DHCPACK packet */
195 if ( ( rc = dhcp_create_packet ( &dhcppkt, netdev, DHCPACK,
197 data, max_len ) ) != 0 ) {
198 DBG ( "Could not create PXE BS ACK: %s\n",
199 strerror ( rc ) );
200 return rc;
201 }
202
203 /* Populate ciaddr */
205 &dhcppkt.dhcphdr->ciaddr );
206
207 /* Merge in ProxyDHCP options */
208 if ( proxy_settings &&
209 ( ( rc = copy_settings ( &dhcppkt, proxy_settings ) ) != 0 ) ) {
210 DBG ( "Could not copy ProxyDHCP settings: %s\n",
211 strerror ( rc ) );
212 return rc;
213 }
214
215 /* Merge in BootServerDHCP options, if present */
216 if ( pxebs_settings &&
217 ( ( rc = copy_settings ( &dhcppkt, pxebs_settings ) ) != 0 ) ) {
218 DBG ( "Could not copy PXE BS settings: %s\n",
219 strerror ( rc ) );
220 return rc;
221 }
222
223 return 0;
224}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" retur dest)
Definition string.h:151
uint32_t dhcp_last_xid
Most recent DHCP transaction ID.
Definition dhcp.c:125
int dhcp_create_packet(struct dhcp_packet *dhcppkt, struct net_device *netdev, uint8_t msgtype, uint32_t xid, const void *options, size_t options_len, void *data, size_t max_len)
Create a DHCP packet.
Definition dhcp.c:945
int dhcp_create_request(struct dhcp_packet *dhcppkt, struct net_device *netdev, unsigned int msgtype, uint32_t xid, struct in_addr ciaddr, void *data, size_t max_len)
Create DHCP request packet.
Definition dhcp.c:1008
int dhcppkt_store(struct dhcp_packet *dhcppkt, unsigned int tag, const void *data, size_t len)
Store value of DHCP packet setting.
Definition dhcppkt.c:165
DHCP packets.
ring len
Length.
Definition dwmac.h:226
uint64_t tag
Identity tag.
Definition edd.h:1
const struct setting ip_setting
uint8_t data[48]
Additional event data.
Definition ena.h:11
Error codes.
int create_fakedhcpdiscover(struct net_device *netdev, void *data, size_t max_len)
Create fake DHCPDISCOVER packet.
Definition fakedhcp.c:110
static int copy_encap_settings(struct dhcp_packet *dest, struct settings *source, unsigned int encapsulator)
Copy settings to DHCP packet.
Definition fakedhcp.c:51
int create_fakepxebsack(struct net_device *netdev, void *data, size_t max_len)
Create fake PXE Boot Server ACK packet.
Definition fakedhcp.c:179
int create_fakedhcpack(struct net_device *netdev, void *data, size_t max_len)
Create fake DHCPACK packet.
Definition fakedhcp.c:137
static int copy_settings(struct dhcp_packet *dest, struct settings *source)
Copy settings to DHCP packet.
Definition fakedhcp.c:95
Fake DHCP packets.
static struct net_device * netdev
Definition gdbudp.c:53
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
#define DHCP_MIN_OPTION
Minimum normal DHCP option.
Definition dhcp.h:63
#define DHCPACK
Definition dhcp.h:202
#define DHCP_EB_ENCAP
Etherboot-specific encapsulated options.
Definition dhcp.h:357
#define DHCP_VENDOR_ENCAP
Vendor encapsulated options.
Definition dhcp.h:93
#define DHCPDISCOVER
Definition dhcp.h:198
#define DHCP_MAX_OPTION
Maximum normal DHCP option.
Definition dhcp.h:542
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
#define DHCP_ENCAP_OPT(encapsulator, encapsulated)
Construct a tag value for an encapsulated option.
Definition dhcp.h:41
#define PXEBS_SETTINGS_NAME
Setting block name used for BootServerDHCP responses.
Definition dhcp.h:717
#define PROXYDHCP_SETTINGS_NAME
Settings block name used for ProxyDHCP responses.
Definition dhcp.h:714
Configuration settings.
String functions.
Network device management.
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition netdevice.h:587
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
int fetch_raw_setting_copy(struct settings *settings, const struct setting *setting, void **data)
Fetch value of setting.
Definition settings.c:822
int fetch_ipv4_setting(struct settings *settings, const struct setting *setting, struct in_addr *inp)
Fetch value of IPv4 address setting.
Definition settings.c:913
struct settings * find_settings(const char *name)
Find settings block.
Definition settings.c:407
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
A DHCP packet.
Definition dhcppkt.h:21
struct dhcphdr * dhcphdr
The DHCP packet contents.
Definition dhcppkt.h:25
struct in_addr ciaddr
"Client" IP address
Definition dhcp.h:644
IP address structure.
Definition in.h:42
A network device.
Definition netdevice.h:353
A setting.
Definition settings.h:24
uint64_t tag
Setting tag, if applicable.
Definition settings.h:44
A settings block.
Definition settings.h:133