Give the step() method a pointer to the containing object, rather than
a pointer to the process. This is consistent with the operation of
interface methods, and allows a single function to serve as both an
interface method and a process step() method.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
ftp_data_deliver() does nothing except pass through the received data
to the xfer interface, and so can be eliminated by using a
pass-through interface.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Booting from an HTTP SAN will require HTTP range requests, which are
defined only in HTTP/1.1 and above. HTTP/1.1 mandates support for
"Transfer-Encoding: chunked", so we must support it.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Improve the appearance of the "config" user interface by ensuring that
settings appear in some kind of logical order.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The default initiator IQN is "iqn.2000-09.org.etherboot:UNKNOWN".
This is problematic for two reasons:
a) the etherboot.org domain (and hence the associated IQN namespace)
is not under the control of the iPXE project, and
b) some targets (correctly) refuse to allow concurrent connections
from different initiators using the same initiator IQN.
Solve both problems by changing the default initiator IQN to be
iqn.2010-04.org.ipxe:<hostname> if a hostname is set, or
iqn.2010-04.org.ipxe:<uuid> if no hostname is set.
Explicit initiator IQNs set via DHCP option 203 are not affected by
this change.
Unfortunately, this change is likely to break some existing
configurations, where ACL rules have been put in place referring to
the old default initiator IQN. Users may need to update ACLs, or
force the use of the old IQN using an iPXE script line such as
set initiator-iqn iqn.2000-09.org.etherboot:UNKNOWN
or a dhcpd.conf option such as
option iscsi-initiator-iqn "iqn.2000-09.org.etherboot:UNKNOWN"
Signed-off-by: Michael Brown <mcb30@ipxe.org>
After a more accurate reading of RFC 3720, it becomes clear how NOPs
are supposed to work. The current implementation (which just ignores
NOP-Ins) is sufficient to cope with NOP-Ins sent to update CmdSN, but
will need to be extended before it can cope with NOP-Ins sent as iSCSI
keepalives.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some iSCSI targets (observed with a Synology DS207+ NAS) send
unsolicited NOP-Ins to the initiator. RFC 3720 is remarkably unclear
and possibly self-contradictory on how NOPs are supposed to work, but
it seems as though we can legitimately just ignore any unsolicited
NOP-In PDU.
Reported-by: Marc Lecuyer <marc@maxiscreen.com>
Originally-implemented-by: Thomas Miletich <thomas.miletich@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit 5f4ab0d ("[iscsi] Randomise a portion of the ISID to force new
session instantiation") introduced a regression by randomising the
ISID on each call to iscsi_start_login(), which may be called more
than once per connection, rather than on each call to
iscsi_open_connection(), which is guaranteed to be called only once
per connection. This is incorrect behaviour that causes our
connection to be rejected by some iSCSI targets (observed with a
COMSTAR target under OpenSolaris).
Fix by generating the ISID in iscsi_open_connection(), and storing the
randomised ISID as part of the session state.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When a connection to an iSCSI target is broken without gracefully
closing the TCP socket, a subsequent connection attempt may fail
because the target believes that we are attempting session
reinstatement (see RFC3720 section 5.3.1). This has been observed
using the Microsoft iSCSI target.
Section 9.1.1 of RFC3720 states that initiators should use a stable
ISID, however section 5.3.1 shows that the only way to explicitly
request that a new session be created is to use a new ISID.
Fix by randomising the "qualifier" portion of the ISID.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The block device interface used in gPXE predates the invention of even
the old gPXE data-transfer interface, let alone the current iPXE
generic asynchronous interface mechanism. Bring this old code up to
date, with the following benefits:
o Block device commands can be cancelled by the requestor. The INT 13
layer uses this to provide a global timeout on all INT 13 calls,
with the result that an unexpected passive failure mode (such as
an iSCSI target ACKing the request but never sending a response)
will lead to a timeout that gets reported back to the INT 13 user,
rather than simply freezing the system.
o INT 13,00 (reset drive) is now able to reset the underlying block
device. INT 13 users, such as DOS, that use INT 13,00 as a method
for error recovery now have a chance of recovering.
o All block device commands are tagged, with a numerical tag that
will show up in debugging output and in packet captures; this will
allow easier interpretation of bug reports that include both
sources of information.
o The extremely ugly hacks used to generate the boot firmware tables
have been eradicated and replaced with a generic acpi_describe()
method (exploiting the ability of iPXE interfaces to pass through
methods to an underlying interface). The ACPI tables are now
built in a shared data block within .bss16, rather than each
requiring dedicated space in .data16.
o The architecture-independent concept of a SAN device has been
exposed to the iPXE core through the sanboot API, which provides
calls to hook, unhook, boot, and describe SAN devices. This
allows for much more flexible usage patterns (such as hooking an
empty SAN device and then running an OS installer via TFTP).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iPXE has never supported SEEK_END; the usage of "whence" offers only
the options of SEEK_SET and SEEK_CUR and so is effectively a boolean
flag. Further flags will be required to support additional metadata
required by the Fibre Channel network model, so repurpose the "whence"
field as a generic "flags" field.
xfer_seek() has always been used with SEEK_SET, so remove the "whence"
field altogether from its argument list.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Remove data-xfer as an interface type, and replace data-xfer
interfaces with generic interfaces supporting the data-xfer methods.
Filter interfaces (as used by the TLS layer) are handled using the
generic pass-through interface capability. A side-effect of this is
that deliver_raw() no longer exists as a data-xfer method. (In
practice this doesn't lose any efficiency, since there are no
instances within the current codebase where xfer_deliver_raw() is used
to pass data to an interface supporting the deliver_raw() method.)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Standardise on using ref_init() to initialise an embedded reference
count, to match the coding style used by other embedded objects.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Access to the gpxe.org and etherboot.org domains and associated
resources has been revoked by the registrant of the domain. Work
around this problem by renaming project from gPXE to iPXE, and
updating URLs to match.
Also update README, LOG and COPYRIGHTS to remove obsolete information.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit 3d9dd93 introduced a regression in HTTP: if a URI without a
path is specified (e.g. http://netboot.me), we send the empty string
as our GET request. Reintroduce an extra slash when uri->path is NULL,
to turn this into the expected GET /.
Reported-by: Kyle Kienapfel <doctor.whom@gmail.com>
Signed-off-by: Joshua Oreman <oremanj@rwcr.net>
Signed-off-by: Marty Connor <mdc@etherboot.org>
The default user and password are used for anonymous FTP by default.
This patch adds support for an explicit user name and password in an FTP
URI:
imgfetch ftp://user:password@server.com/path/to/file
Edited-by: Stefan Hajnoczi <stefanha@gmail.com>. Bugs are my fault.
Signed-off-by: Marty Connor <mdc@etherboot.org>
Currently, handling of URI escapes is ad-hoc; escaped strings are
stored as-is in the URI structure, and it is up to the individual
protocol to unescape as necessary. This is error-prone and expensive
in terms of code size. Modify this behavior by unescaping in
parse_uri() and escaping in unparse_uri() those fields that typically
handle URI escapes (hostname, user, password, path, query, fragment),
and allowing unparse_uri() to accept a subset of fields to print so
it can be easily used to generate e.g. the escaped HTTP path?query
request.
Signed-off-by: Joshua Oreman <oremanj@rwcr.net>
Signed-off-by: Marty Connor <mdc@etherboot.org>
Avoid passing credentials in the iBFT that were available but not
required for login. This works around a problem in the Microsoft
iSCSI initiator, which will refuse to initiate sessions if the CHAP
password is fewer than 12 characters, even if the target ends up not
asking for CHAP authentication.
The documentation in xfer.h and xfer.c does not say that the metadata
parameter is optional in calls such as xfer_deliver_iob_meta() and the
deliver_iob() method. However, some code in net/ is prepared to
accept a NULL pointer, and xfer_deliver_as_iob() passes a NULL pointer
directly to the deliver_iob() method.
Fix this mess of conflicting assumptions by making everything assume
that the metadata parameter is mandatory, and fixing
xfer_deliver_as_iob() to pass in a dummy metadata structure (as is
already done in xfer_deliver_iob()).
There are many functions that take ownership of the I/O buffer they
are passed as a parameter. The caller should not retain a pointer to
the I/O buffer. Use iob_disown() to automatically nullify the
caller's pointer, e.g.:
xfer_deliver_iob ( xfer, iob_disown ( iobuf ) );
This will ensure that iobuf is set to NULL for any code after the call
to xfer_deliver_iob().
iob_disown() is currently used only in places where it simplifies the
code, by avoiding an extra line explicitly setting the I/O buffer
pointer to NULL. It should ideally be used with each call to any
function that takes ownership of an I/O buffer. (The SSA
optimisations will ensure that use of iob_disown() gets optimised away
in cases where the caller makes no further use of the I/O buffer
pointer anyway.)
If gcc ever introduces an __attribute__((free)), indicating that use
of a function argument after a function call should generate a
warning, then we should use this to identify all applicable function
call sites, and add iob_disown() as necessary.
This brings us in to line with Linux definitions, and also simplifies
adding x86_64 support since both platforms have 2-byte shorts, 4-byte
ints and 8-byte long longs.
-Wformat-nonliteral is not enabled by -Wall and needs to be explicitly
specified.
Modified the few files that use nonliteral format strings to work with
this new setting in place.
Inspired by a patch from Carl Karsten <carl@personnelware.com> and an
identical patch from Rorschach <r0rschach@lavabit.com>.
The domain etherboot.org was actually registered on 2000-01-09, not
2000-09-01. (To put it another way, it was registered on 1/9/2000 (US
date format) rather than 1/9/2000 (sensible date format); this may
illuminate the cause of the error.)
"iqn.2000-09.org.etherboot:" is still valid as per RFC3720, but may be
surprising to users, so change it to something less unexpected.
Thanks to the anonymous contributor for pointing this one out.
When an error reply (not 1xx, 2xx or 3xx) was received, ftp_reply()
invoked ftp_done() to close connections, but did not return, and the
rest of code in this function could try to send commands to the closed
control connection.
Signed-off-by: Sergey Vlasov <vsu@altlinux.ru>
Based on a patch contributed by Sergey Vlasov <vsu@altlinux.ru> :
In my testing with "qemu -net user" the 226 response to RETR was
often received earlier than final packets of the data connection;
this caused the received file to become truncated without any error
indication. Fix this by adding an intermediate state FTP_TRANSFER
between FTP_RETR and FTP_QUIT, so that the transfer is considered to
be complete only when both the end of data connection is encountered
and the final reply to the RETR command is received.
Return the most appropriate of EACCES, EPERM, ENODEV, ENOTSUP, EIO or
EINVAL depending on the exact error returned by the target, rather than
just always returning EPERM.
Also, ensure that error strings exist for these errors.
Some EMC targets will fail if we advertise that we can authenticate with
CHAP, but the target is configured to allow unauthenticated access to that
target. We advertise AuthMethod=CHAP,None; the target should (I think)
select AuthMethod=None for unprotected targets. IETD does this, but an
EMC Celerra NS83 doesn't.
Fix by offering only AuthMethod=None if the user hasn't supplied a
username and password; this means that we won't be offering CHAP
authentication unless the user is expecting to use it (in which case the
target is presumably configured appropriately).
Many thanks to Alessandro Iurlano <alessandro.iurlano@gmail.com> for
reporting and helping to diagnose this problem.
gPXE is not compliant with the HTTP/1.1 specification (RFC 2616),
since it lacks support for "Transfer-Encoding: chunked". gPXE is,
however, compliant with the HTTP/1.0 specification (RFC 1945), which
does not require "Transfer-Encoding: chunked" to be supported.
The only HTTP/1.1 feature that gPXE uses is the "Host:" header, but
servers universally accept that one from HTTP/1.0 clients as an
optional extension (it is obligatory for HTTP/1.1). gPXE does not,
for example, appear to support connection caching. Advertising as a
HTTP/1.0 client will typically make the server close the connection
immediately upon sending the last data, which is actually beneficial
if we aren't going to keep the connection alive anyway.
Allow for settings to be described by something other than a DHCP option
tag if desirable. Currently used only for the MAC address setting.
Separate out fake DHCP packet creation code from dhcp.c to fakedhcp.c.
Remove notion of settings from dhcppkt.c.
Rationalise dhcp.c to use settings API only for final registration of the
DHCP options, rather than using {store,fetch}_setting throughout.
Allow port numbers in iSCSI redirection.
Wait for SCSI status, not just the final data-in (which may be followed
by an explicit SCSI Response PDU if the S bit is not set).
We didn't specify values for MaxRecvDataSegmentLength and
MaxBurstLength (to save space, since we were happy with the
RFC-defined default values of 8kB and 256kB respectively). However,
the OpenSolaris target (incorrectly) assumes default values of zero
for these parameters.
The upshot was that the OpenSolaris target would get stuck in an
endless loop trying to send us the first 512-byte sector, zero bytes
at a time, and would eventually run out of memory and core-dump.
Fixed by explicitly specifying the default values for these two
parameters.