summaryrefslogtreecommitdiffstats
path: root/src/net/udp
Commit message (Collapse)AuthorAgeFilesLines
...
* [build] Rename gPXE to iPXEMichael Brown2010-04-204-46/+46
| | | | | | | | | | | 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>
* [dhcp] Keep multiple DHCP offers received, and use them intelligentlyJoshua Oreman2010-01-221-86/+228
| | | | | | | | | | | | | | | | | | | | | | Instead of keeping only the best IP and PXE offers, store all of them, and pick the best to use just before a request is sent. This allows priority differentiation to work even when lower-priority offers provide PXE options, and improves robustness at sites with broken PXE servers intermingled with working ones: when a ProxyDHCP request times out, instead of giving up, we try the next PXE offer we've received. It also allows us to avoid breaking up combined IP+PXE offers, which can be important with some firewall configurations. This behavior matches that of most vendor PXE ROMs. Store a reference to the DHCPOFFER packet in the offer structure, so that when registering settings after a successful ACK we can register the proxy PXE settings we originally received; this removes the need for a nonstandard duplicate REQUEST/ACK to port 67 of proxy servers like dnsmasq that provide PXE options in the OFFER. Total cost: 450 bytes uncompressed. Signed-off-by: Marty Connor <mdc@etherboot.org>
* [dhcp] Add generic facility for using cached network settingsJoshua Oreman2010-01-201-1/+21
| | | | | | | | | | | | | | | | | | | | | | When a DHCP session is started (using autoboot or a command-line `dhcp net0'), check whether the new setting use-cached (DHCP option 175.178) is TRUE; if so, skip DHCP and rely on currently registered settings. This lets one combine a static IP with autoboot. Before checking the use-cached setting, call a weak get_cached_dhcpack() hook that can be implemented by particular builds of gPXE supporting some fashion of retrieving a cached DHCPACK packet. If one is available, it is registered as an options source, and then either that packet's option 175.178 or the user's prior manual use-cached setting can allow skipping duplicate DHCP. Using cached packets is not the default because DHCP servers are often configured to give gPXE different options than they give a vendor PXE client; in order to break the infinite loop of PXE chaining, one would need to load a gPXE with an embedded image that does something more than autoboot. Signed-off-by: Marty Connor <mdc@etherboot.org>
* [tftp] Abort requests with error code 0Stefan Hajnoczi2010-01-181-2/+2
| | | | | | | | | There is no defined error code for aborting a request but 0 is commonly used. This patch switches the abort request error code from TFTP_ERR_UNKNOWN_TID (5) to 0. Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com> Signed-off-by: Marty Connor <mdc@etherboot.org>
* [tftp] Make TFTP size requests abort transfer with an errorThomas Horsten2010-01-181-0/+73
| | | | | | | | | | | | | | | | | | | | | | | | | | | | pxenv_tftp_get_fsize is an API call that PXE clients can call to obtain the size of a remote file. It is implemented by starting a TFTP transfer with pxe_tftp_open, waiting for the response and then stopping the transfer with pxe_tftp_close(). This leaves the session hanging on the TFTP server and it will try to resend the packet repeatedly (verified with tftpd-hpa) until it times out. This patch adds a method "tftpsize" that will abort the transfer after the first packet is received from the server. This will terminate the session on the server and is the same behaviour as Intel's PXE ROM exhibits. Together with a qemu patch to handle the ERROR packet (submitted to qemu's mailing list), this resolves a specific issue where booting pxegrub with qemu's TFTP server would be slow or hang. I've tested this against qemu's tftp server and against my normal boot infrastructure (tftpd-hpa). Booting pxegrub and loading extra files now produces a trace similar to Intel's PXE client and there are no spurious retransmits from tftpd any more. Signed-off-by: Thomas Horsten <thomas@horsten.com> Signed-off-by: Milan Plzik <milan.plzik@gmail.com> Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com> Signed-off-by: Marty Connor <mdc@etherboot.org>
* [tftp] Remove unnecessary delay when opening a connectionStefan Hajnoczi2010-01-151-2/+9
| | | | | | | | | | | | | The retry timer is used to retransmit TFTP packets lost on the network, and to start a new connection. There is an unnecessary delay while waiting for name resolution because the timer period is fixed and cannot be shortened when name resolution completes. This patch keeps the timer period at zero while name resolution takes place so that no time is lost once before sending the first packet. Reported-by: Thomas Horsten <thomas@horsten.com> Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com> Signed-off-by: Marty Connor <mdc@etherboot.org>
* [tftp] Allow fetching larger files by wrapping block numberStefan Hajnoczi2010-01-151-3/+6
| | | | | | | | | This patch adds TFTP support for files larger than 65535 blocks by wrapping the 16-bit block number. Reported-by: Mark Johnson <johnson.nh@gmail.com> Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com> Signed-off-by: Marty Connor <mdc@etherboot.org>
* [dhcp] Assume PXE options are in DHCPOFFER only if boot menu is includedJoshua Oreman2010-01-151-2/+2
| | | | | | | | | | | | | IBM's Tivoli Provisioning Manager for OS Deployment, when acting as a ProxyDHCP server, sends an initial offer with a vendor class of "PXEClient" and vendor-encapsulated options that have nothing to do with PXE. To differentiate between this case and the case of a ProxyDHCP server that sends all PXE options in its initial offer, modify gPXE to check for the presence of an encapsulated PXE boot menu option (43.9) instead of simply checking for the existence of any encapsulated options at all. This is the same check used by the Intel vendor PXE ROM. Signed-off-by: Marty Connor <mdc@etherboot.org>
* [dhcp] Accept ProxyDHCP replies of type DHCPOFFERJoshua Oreman2010-01-151-1/+1
| | | | | | | | | | The PXE standard provides examples of ProxyDHCP responses being encoded both as type DHCPOFFER and DHCPACK, but currently we only accept DHCPACKs. Since there are PXE servers in existence that respond to ProxyDHCPREQUESTs with DHCPOFFERs, modify gPXE's ProxyDHCP pruning logic to treat both types of responses equally. Signed-off-by: Marty Connor <mdc@etherboot.org>
* [dhcp] Ensure message type is first DHCP optionShao Miller2010-01-141-0/+1
| | | | | | | | | | | Apparently, the DHCP relay logic on a Nortel 470-48T layer 2 switch cares about the order of DHCP options. Specifically, it requires that the DHCP message type option be the first option present in the DHCP packet. We achieve this by having this option appear first in our dhcp_request_options_data array, which pre-populates DHCP requests. Signed-off-by: Marty Connor <mdc@etherboot.org>
* [settings] Add Bus ID settingShao Miller2009-12-141-4/+2Star
| | | | | | | | Users can find the bus type and PCI IDs for a network interface with: netX/busid Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
* [pxebs] Correct endianness of PXE typeJoshua Oreman2009-10-241-2/+2
| | | | | | | | | | The PXE type field is canonically little-endian, but the pxebs command treats it as big-endian in converting the type number passed on the command line to a field value to search against. Fix, to prevent the necessity of incantations like "pxebs net0 1536" to select menu item #6. Signed-off-by: Michael Brown <mcb30@etherboot.org> Modified-by: Michael Brown <mcb30@etherboot.org>
* [dhcp] Fall back to using the hardware address to populate the chaddr fieldMichael Brown2009-08-121-11/+43
| | | | | | | | | | | | | | | | | | | | | | | | For IPoIB, the chaddr field is too small (16 bytes) to contain the 20-byte IPoIB link-layer address. RFC4390 mandates that we should pass an empty chaddr field and rely on the DHCP client identifier instead. This has many problems, not least of which is that a client identifier containing an IPoIB link-layer address is not very useful from the point of view of creating DHCP reservations, since the QPN component is assigned at runtime and may vary between boots. Leave the DHCP client identifier as-is, to avoid breaking existing setups as far as possible, but expose the real hardware address (the port GUID) via the DHCP chaddr field, using the broadcast flag to instruct the DHCP server not to use this chaddr value as a link-layer address. This makes it possible (at least with ISC dhcpd) to create DHCP reservations using host declarations such as: host duckling { fixed-address 10.252.252.99; hardware unknown-32 00:02:c9:02:00:25:a1:b5; }
* [dhcp] Choose ProxyDHCP port based on presence of PXE optionsMichael Brown2009-05-221-6/+22
| | | | | | | | | | | | | | | | | | | | | | | If the ProxyDHCPOFFER already includes PXE options (i.e. option 60 is set to "PXEClient" and option 43 is present) then assume that the ProxyDHCPREQUEST can be sent to port 67, rather than port 4011. This is a reasonable assumption, since in that case the ProxyDHCP server has already demonstrated by responding to the DHCPDISCOVER that it is listening on port 67. (If the ProxyDHCP server were not listening on port 67, then the standard DHCP server would have been configured to respond with option 60 set to "PXEClient" but no option 43 present.) The PXE specification is ambiguous on this point; the specified behaviour covers only the cases in which option 43 is *not* present in the ProxyDHCPOFFER. In these cases, we will continue to send the ProxyDHCPREQUEST to port 4011. This change is required in order to allow us to interoperate with dnsmasq, which listens only on port 67. (dnsmasq relies on unspecified behaviour of the Intel PXE stack, which it seems will retain the ProxyDHCPOFFER as an options source and never issue a ProxyDHCPREQUEST, thereby enabling dnsmasq to omit listening on port 4011.)
* [tftp] Process OACKs even if malformedMichael Brown2009-05-201-12/+28
| | | | | | | | | | | IBM Tivoli PXE Server 5.1.0.3 is reported to send trailing garbage bytes at the end of the OACK packet, which causes gPXE to reject the packet and abort the TFTP transfer. Work around the problem by processing as much as possible of the OACK, and treating name/value parsing errors as non-fatal. Reported-by: Shao Miller <Shao.Miller@yrdsb.edu.on.ca>
* [dhcp] Send broadcast PXE boot server discovery requests to port 67Michael Brown2009-05-201-6/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We currently send all boot server discovery requests to port 4011. Section 2.2.1 of the PXE spec states that boot server discovery packets should be "sent broadcast (port 67), multicast (port 4011), or unicast (port 4011)". Adjust our behaviour so that any boot server discovery packets that are sent to the broadcast address are directed to port 67 rather than port 4011. This is required for operation with dnsmasq as a PXE server, since dnsmasq listens only on port 67, and relies upon this (specified) behaviour. This change may break some setups using the (itself very broken) Linux PXE server from kano.org.uk. This server will, in its default configuration, listen only on port 4011. It never constructs a boot server list (PXE_BOOT_SERVERS, option 43.8), and uses the wrong definitions for the discovery control bits (PXE_DISCOVERY_CONTROL, option 43.6). The upshot is that it will always instruct the client to perform multicast and broadcast discovery only. In setups lacking a valid multicast route on the server side, this used to work because gPXE would eventually give up on the (non-responsive) multicast address and send a broadcast request to port 4011, which the Linux PXE server would respond to. Now that gPXE correctly sends this broadcast request to port 67 instead, it is never seen by the Linux PXE server, and the boot fails. The fix is to either (a) set up a multicast route correctly on the server side before starting the PXE server, or (b) edit /etc/pxe.conf to contain the server's unicast address in the "multicast_address" field (a hack that happens to work). Suggested-by: Simon Kelley <simon@thekelleys.org.uk>
* [dhcp] Perform ProxyDHCP only if we do not already have PXE optionsMichael Brown2009-05-201-2/+6
| | | | | | | | | | This prevents gPXE from wasting time attempting to contact a ProxyDHCP server on port 4011 if the DHCP response already contains the relevant PXE options. This behaviour is hinted at (though not explicitly specified) in the PXE spec, and seems to match what the Intel client does. Suggested-by: Simon Kelley <simon@thekelleys.org.uk>
* [legal] Add a selection of FILE_LICENCE declarationsMichael Brown2009-05-184-0/+8
| | | | | Add FILE_LICENCE declarations to almost all files that make up the various standard builds of gPXE.
* [xfer] Implement xfer_vreopen() to properly handle redirectionsMichael Brown2009-03-304-6/+6
| | | | | When handling a redirection event, we need to close the existing connection before opening the new connection.
* [tables] Incorporate table data type information into table definitionMichael Brown2009-03-131-2/+2
| | | | | | | Eliminate the potential for mismatches between table names and the table entry data type by incorporating the data type into the definition of the table, rather than specifying it explicitly in each table accessor method.
* [tables] Redefine methods for accessing linker tablesMichael Brown2009-03-131-5/+3Star
| | | | | | | | | | | | | | | Intel's C compiler (icc) chokes on the zero-length arrays that we currently use as part of the mechanism for accessing linker table entries. Abstract away the zero-length arrays, to make a port to icc easier. Introduce macros such as for_each_table_entry() to simplify the common case of iterating over all entries in a linker table. Represent table names as #defined string constants rather than unquoted literals; this avoids visual confusion between table names and C variable or type names, and also allows us to force a compilation error in the event of incorrect table names.
* [dhcp] Use a default user-class of "gPXE"Michael Brown2009-02-171-0/+2
| | | | | This change makes it possible to break the PXE-chaining infinite loop even when restricted to a Windows DHCP server.
* [xfer] Make consistent assumptions that xfer metadata can never be NULLMichael Brown2009-02-152-15/+3Star
| | | | | | | | | | | | | 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()).
* [pxe] Obey lists of PXE Boot Servers and associated Discovery Control bitsMichael Brown2009-02-051-29/+169
| | | | | | | | Various combinations of options 43.6, 43.7 and 43.8 dictate which servers we send Boot Server Discovery requests to, and which servers we should accept responses from. Obey these options, and remove the explicit specification of a single Boot Server from start_pxebs() and dependent functions.
* [iobuf] Add iob_disown() and use it where it simplifies codeMichael Brown2009-02-012-8/+5Star
| | | | | | | | | | | | | | | | | | | | | | | | | 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.
* [dhcp] Send user class in DHCP requestsMichael Brown2009-02-011-2/+25
|
* [tftp] Guard against invalid data block numbersMichael Brown2009-02-011-0/+5
| | | | | | | | A TFTP DATA packet with a block number of zero (representing a negative offset within the file) could potentially cause problems. Fixed by explicitly rejecting such packets. Identified by Stefan Hajnoczi <stefanha@gmail.com>.
* [dhcp] Split PXE menuing code out of dhcp.cMichael Brown2009-02-011-902/+679Star
| | | | | | | | | The DHCP client code now implements only the mechanism of the DHCP and PXE Boot Server protocols. Boot Server Discovery can be initiated manually using the "pxebs" command. The menuing code is separated out into a user-level function on a par with boot_root_path(), and is entered in preference to a normal filename boot if the DHCP vendor class is "PXEClient" and the PXE boot menu option exists.
* [dns] Append local domain to relative namesStefan Hajnoczi2009-01-271-11/+65
| | | | | | | | | | | | | | | Try to qualify relative names in the DNS resolver using the DHCP Domain Name. For example: DHCP Domain Name: etherboot.org (Relative) Name: www yields: www.etherboot.org Only names with no dots ('.') will be modified. A name with one or more dots is unchanged.
* [tftp] Temporary fix for conveying TFTP block size to callersMichael Brown2009-01-271-1/+19
| | | | | | | | | | | | | | | | | | | | | pxe_tftp.c assumes that the first seek on its data-transfer interface represents the block size. Apart from being an ugly hack, this will also screw up file size calculation for files smaller than one block. The proper solution would be to extend the data-transfer interface to support the reporting of stat()-like data. This is not going to happen until the cost of adding interface methods is reduced (a fix I have planned since June 2008). In the meantime, abuse the xfer_window() method to return the block size, since it is not being used for anything else and is vaguely justifiable. Astonishingly, having returned the incorrect TFTP blocksize via PXENV_TFTP_OPEN for almost a year seems not to have affected any of the test cases run during that time; this bug was found only when someone tried running the heavily-patched version of pxegrub found in OpenSolaris.
* [dhcp] Include support for PXE boot menusMichael Brown2009-01-251-13/+193
| | | | | | | | | PXE dictates a mechanism for boot menuing, involving prompting the user with a variable message, waiting for a predefined keypress, displaying a boot menu, and waiting for a selection. This breaks the currently desirable abstraction that DHCP is a process that can happen in the background without any user interaction.
* [dhcp] Clarify language surrounding ProxyDHCPMichael Brown2009-01-231-50/+51
| | | | | | Remove the lazy assumption that ProxyDHCP == "DHCP with option 60 set to PXEClient", and explicitly separate the notion of ProxyDHCP from the notion of packets containing PXE options.
* [dhcp] Handle missing ProxyDHCP serversMichael Brown2009-01-231-1/+8
| | | | | | | | | | | | | | | | It is possible to configure a DHCP server to hand out PXE options without a ProxyDHCP server present. This requires setting option 60 to "PXEClient", which will cause gPXE to attempt ProxyDHCP. We assume in several places that dhcp->proxydhcpack is set to the DHCPACK packet containing option 60 set to "PXEClient". When we transition into ProxyDHCPREQUEST, set dhcp->proxydhcpack=dhcp->dhcpack so that this assumption holds true. We ought to rename several references to "proxydhcp" to something more accurate, such as "pxedhcp". Treating a single DHCP response as potentially both DHCPOFFER and ProxyDHCPOFFER does make the code smaller, but the variable names get confusing.
* [dhcp] Pass PXE boot menu item to PXE Boot ServerMichael Brown2009-01-231-70/+118
| | | | | | | | Pick out the first boot menu item from the boot menu (option 43.9) and pass it to the boot server as the boot menu item (option 43.71). Also improve DHCP debug messages to include more details of the packets being transmitted.
* [dhcp] Add preliminary support for PXE Boot ServersMichael Brown2009-01-211-1/+92
| | | | | | | | | Some PXE configurations require us to perform a third DHCP transaction (in addition to the real DHCP transaction and the ProxyDHCP transaction) in order to retrieve information from a "Boot Server". This is an experimental implementation, since the actual behaviour is not well specified in the PXE spec.
* [dhcp] Centralise DHCP successful state transitionsMichael Brown2009-01-211-19/+35
| | | | | | | Move all the DHCP state transition logic into a single function dhcp_next_state(). This will make it easier to add support for PXE Boot Servers, since it abstracts away the difference between "mark DHCP as complete" and "transition to boot server discovery".
* [dhcp] Allow for missing server ID in ProxyDHCPACKMichael Brown2009-01-211-9/+13
| | | | | | | | | | | | The Linux PXE server (http://www.kano.org.uk/projects/pxe) does not set the server identifier in its ProxyDHCP responses. If the server ID is missing, do not treat this as an error. This resolves the "vague and unsettling memory" mentioned in commit fdb8481d ("[dhcp] Verify server identifier on ProxyDHCPACKs"). Note that we already accept ProxyDHCPOFFERs without a server identifier; they get treated as potential BOOTP packets.
* [dhcp] Include gPXE version number within DHCP requestMichael Brown2009-01-081-0/+4
|
* [x86_64] Fix assorted 64-bit compilation errors and warningsMichael Brown2008-11-191-2/+2
| | | | | | Remove various 32-bit assumptions scattered throughout the codebase. The code is still not necessarily 64-bit clean, but will at least compile.
* [settings] Add the notion of a "tag magic" to numbered settingsMichael Brown2008-10-301-1/+1
| | | | | | | | | | | | | | | | | | | Settings can be constructed using a dotted-decimal notation, to allow for access to unnamed settings. The default interpretation is as a DHCP option number (with encapsulated options represented as "<encapsulating option>.<encapsulated option>". In several contexts (e.g. SMBIOS, Phantom CLP), it is useful to interpret the dotted-decimal notation as referring to non-DHCP options. In this case, it becomes necessary for these contexts to ignore standard DHCP options, otherwise we end up trying to, for example, retrieve the boot filename from SMBIOS. Allow settings blocks to specify a "tag magic". When dotted-decimal notation is used to construct a setting, the tag magic value of the originating settings block will be ORed in to the tag number. Store/fetch methods can then check for the magic number before interpreting arbitrarily-numbered settings.
* [tftp] Add EUNIQ_xx values to differentiate the many EINVAL errorsMichael Brown2008-10-221-7/+16
|
* [dhcp] Accept BOOTP as well as DHCPMichael Brown2008-09-251-7/+9
|
* [dhcp] Do not restrict minimum retry time for ProxyDHCPREQUESTMichael Brown2008-08-131-0/+1
| | | | | | | | | | | The ProxyDHCPREQUEST is a unicast packet, so the first request will almost always be lost due to not having the IP address in the ARP cache. If the minimum retry time is set to one second (as per commit ff2b6a5), then ProxyDHCP will time out and give up before managing to successfully transmit a request. The DHCP timers need to be reworked anyway, so this mild hack is acceptable for now.
* [retry] Added configurable timeouts to retry timerAndrew Schran2008-08-121-0/+2
| | | | | | | | New min_timeout and max_timeout fields in struct retry_timer allow users of this timer to set their own desired minimum and maximum timeouts, without being constrained to a single global minimum and maximum. Users of the timer can still elect to use the default global values by leaving the min_timeout and max_timeout fields as 0.
* [dhcp] Work around a bug in Altiris RDPMichael Brown2008-08-011-2/+2
| | | | | | | Altiris erroneously cares about the ordering of DHCP options, and will get confused if we don't construct them in the order it expects. This is observed (so far) only when attempting to deploy 64-bit Win2k3.
* [dhcp] Verify DHCP server source portMichael Brown2008-07-101-16/+45
| | | | | | Verifying server ID and DHCP transaction ID is insufficient to differentiate between DHCPACK and ProxyDHCPACK when the DHCP server and Proxy DHCP server are the same machine.
* [tftp] Strip the initial '/' to keep Windows TFTP servers happy.Michael Brown2008-07-031-6/+19
|
* [dhcp] Verify server identifier on ProxyDHCPACKsMichael Brown2008-07-011-7/+25
| | | | | | | | | | Perform the same test for a matching DHCP_SERVER_IDENTIFIER on ProxyDHCPACKs as we do for DHCPACKs. Otherwise, a retransmitted DHCPACK can end up being treated as the ProxyDHCPACK. I have a vague and unsettling memory that this test was deliberately omitted, but I can't remember why, and can't find anything in the VC logs.
* [slam] Add support for SLAM window lengths of greater than one packetMichael Brown2008-06-111-11/+30
| | | | | | | | | | | Add the definition of SLAM_MAX_BLOCKS_PER_NACK, which is roughly equivalent to a TCP window size; it represents the maximum number of packets that will be requested in a single NACK. Note that, to keep the code size down, we still limit ourselves to requesting only a single range per NACK; if the missing-block list is discontiguous then we may request fewer than SLAM_MAX_BLOCKS_PER_NACK blocks.
* [slam] Implement SLAM flow controlMichael Brown2008-06-111-107/+85Star
| | | | | | | | | | | | | | | | On any fast network, or with any driver that may drop packets (e.g. Infiniband, which has very small RX rings), the traditional usage of the SLAM protocol will result in enormous numbers of packet drops and a consequent large number of retransmissions. By adapting the client behaviour, we can force the server to act more like a multicast TFTP server, with flow control provided by a single master client. This behaviour should interoperate with any traditional SLAM client (e.g. Etherboot 5.4) on the network. The SLAM protocol isn't actually documented anywhere, so it's hard to define either behaviour as compliant or otherwise.