RFC 929

Proposed Host-Front End Protocol

πŸ“… published December 1984, from ietf

RFC 929: PROPOSED HOST-FRONT END PROTOCOL πŸŽ€

Okay bestie, this one is from the Network Working Group and dated December 1984 πŸ“…. Three authors slid into the author list: Joel Lilienkamp (SDC), Richard Mandell (SDC), and Michael Padlipsky (Mitre Corp.) πŸ‘‘. Its status is a proposal for a standard (not a standard itself, the doc is very clear about that πŸ’…). The title block doesn't list anything it obsoletes or updates, so there's no drama there ✨.


Status Of This Memo ✨

Before you dive in, the authors want you to know a few things, and they're kind of iconic about it πŸ’–. First and foremost, IT IS A PROPOSAL FOR A STANDARD, NOT A STANDARD ITSELF 🫢. Next, it assumes you've already read RFC 928, which is the intro to this doc, so go read that first πŸ“š. Next, the "final cut" on this version was done by the author of RFC 928, not the main author of this doc. So if the style bothers you, blame the RFC 928 person, who's totally used to it 😭, and not the main author, who might be completely innocent πŸ™ˆ.

Editing at a distance got too hard to manage, so the author who's typing it personally is also fiddling with it personally πŸ’…. That includes sticking their own section on the Conceptual Model in before Joel's words start, instead of leaving it in the Introduction. MAP πŸ¦‹

Also, this is not a finished document 🌸. The plan is to eventually add appendices for all the protocol offloadings. Those appendices would describe how each protocol uses its own special parameters, and even how it interprets the standard per-command parameters 🧚. They haven't waited for all of those appendices to be written before putting this out, though. They do have notes on how to handle FTP, and UDP will be pretty straightforward. But finishing them would've pushed everything into another calendar year, which would've been very annoying... not to say embarrassing πŸ’€.

It's not finished with respect to what's already here either 🌈. The plan is to revise the protocol based on what people learn from volunteer test implementations πŸ“. It also turns out it isn't feasible to iron out every known wrinkle yet. For example, the response codes almost certainly need clarification and expansion ✨. And at least one of the authors doesn't think mandatory initial parameters need control flags πŸ€”. Still, trying too hard for polish would mean sitting in subcommittee for the rest of forever πŸ˜΅β€πŸ’«. So what you see is what they've got, but it's definitely not meant to be what you or they are stuck with forever πŸ¦‹.

This RFC proposes a protocol for the ARPA-Internet community and asks for discussion and suggestions for improvements πŸ’œ. Distribution of this memo is unlimited πŸŽ€.


Conceptual Model 🧚

Okay so there are two fundamental motivations for doing outboard processing πŸ’…. The first one is to conserve the Hosts' resources (CPU cycles and memory) in a resource sharing intercomputer network. You do this by offloading as much of the required networking software from the Hosts to Outboard Processing Environments (or "Network Front-Ends") as you possibly can πŸ”₯. The second one is to make it easier to procure implementations of the various intercomputer networking protocols for the different types of Host in a typical heterogeneous intercomputer network. You do this by using common implementations in the OPE πŸ’–. A third motivation, basing a network security approach on trusted mandatory OPEs, won't be covered here, but it's definitely worth a mention πŸ‘‘.

Neither of the first two motivations should be allowed to detract from the underlying, assumed desire to do true intercomputer networking 🫢. So it's further assumed that OPEs will be attached to Hosts through a flexible attachment strategy, as described in [1] ✨. In practice, at the software level, an explicit Host-Front End Protocol (H-FP) gets used between Hosts and OPEs 🌸. That's way better than having OPEs pretend to be devices or device controllers that Host operating systems already "know," because that would mean adding new code into the Host πŸ™ˆ.

For reasons covered in the Introduction, the H-FP breaks down into three layers πŸ¦‹. The Link layer lets bits get exchanged between Host and OPE πŸ’œ. The Channel layer lets those bit streams get demultiplexed and flow controlled 🌈. (Both the Channel and Link layers can use preexisting per-Host mechanizations, just so you remember πŸ“.) The Command (or "Service Access") layer is the main focus right now πŸ”₯. It's the distributed processing mechanism that lets processes on Hosts manipulate protocol interpreters (PIs) in OPEs on their behalf ✨. For convenience, it'll be called "the H-FP" from here on πŸ’…. Quick side note: the Link and Channel layers can be seen as roughly equivalent to the inboard processing investment for a Host-comm subnet processor PI and device driver. So in real terms, the resource savings from outboard processing come from making the H-FP "smaller" than the inboard implementations of the protocols it lets get offloaded πŸ‘‘.

Here's the crucial property: conceptually, the H-FP stands as the interface between a (Host) process and a PI, which is actually outboard πŸŽ€. Usually the model is a closed subroutine interface, though in some cases you have to appeal to an interprocess communication mechanism model instead 🧚. The interactions between cooperating H-FP PIs sort of mimic subroutine or IPC calls, from the point of view of Host processes calling their own H-FP PIs. Those H-FP PIs are, of course, interfacing through those same kinds of mechanisms themselves 🫢. Another way to put it: "if the protocols were inboard," the processes invoking the H-FP wouldn't know the difference 😭. So the H-FP is kind of a roundabout way of letting Host processes "get at" various PIs πŸ’–.

Of course, the mechanization of this concept can't be super literal πŸ™ˆ. The Hosts and the OPEs are different processors, so we're not picturing parameters getting passed through in an exact fashion πŸ’…. Still, in broad terms the model is just a somewhat funny interface between a process and a PI πŸ¦‹. (Also, this doesn't rule out events that prompt the OPE to start an exchange of commands with the Host. Check the Introduction for more on "Symmetric Begins" if that's your thing 🌈.)

Interaction Discipline ✨

okay bestie, this part is where the Host and the OPE actually start talking to each other πŸ’¬ The interaction has to give processes (or protocol interpreters) in the Host a proper interface to the protocol interpreters that got offloaded to the OPE πŸ¦‹. But here's the catch: it can't make the Host do more work than it would have done running those protocols inboard, or the whole point of having an OPE gets cancelled out πŸ’€ no cap, that would be so not it.

Channel Level Interaction 🌸

okay so, as we said before, the Channel level (working together with the Link level) does two big jobs πŸ’…. It demultiplexes the traffic coming up from the Link level into separate data streams, and it does flow control between the Host and the OPE on a per stream basis πŸŽ€. These still hold even if the Host-OPE attachment is DMA 🫢.

The data streams are bidirectional πŸ”. In this doc, the basic unit moved by the Channel level is called a "chunk" πŸ“. The reason for the name is that the H-FP lets the Channel level be any one of several protocols, and each one has its own vocab. For example, a chunk on an X.25 Channel is a packet, but a chunk on the DTI H-FP channel is a message πŸ“¦. The Command level is kinda "more efficient" when chunks are allowed to be big πŸ’–, but since the Channel protocol can be so many different things, we can't assume anything about chunk size πŸ™ˆ.

Each data stream is fully asynchronous ⚑. A Channel protocol user can send data at any time once the channel has been properly opened (the Command level's logic might make some actions pointless though πŸ€·β€β™€οΈ). The Channel protocol's data transfer is reliable πŸ”’, which means delivery in the correct order, no duplicates, and bit errors get checked. All the retransmission, error checking and duplicate detection is handled by this protocol, totally transparent to the user ✨. (If the attachment is DMA, stream identification and chunk length still have to be provided πŸ’….)

Flow control at the Channel level is there to stop the OPE and the Host from flooding each other's resources with too many transmissions 🌊. In general, this flow control should not directly affect what the outboard protocol interpreters are doing 🧚. On the other hand, it has the same effect as explicit interface events that provide flow control between the user and the protocol interpreter, like the Allocate event in the TCP interface spec from MIL-STD 1778 πŸ‘‘. So those events don't need to be communicated explicitly at the Command level πŸ’œ. (If the attachment is DMA, flow control must still be provided for.)

If Hosts want an OPE attached through a Link level that gives physical demultiplexing (like a group of RS232 ports), then trying to skip reliability and explicit flow control is at their own peril πŸ’€. We didn't choose to help with that, but we didn't rule it out either πŸ™ˆ. (It would totally violate the spirit of the thing, though 😭.)

Command Level Interaction πŸŽ€

The H-FP is built around a small set of commands 🧸, each applied separately to a given Channel level channel. The commands are simple, but flexible enough to offload the interpreters for a huge number of protocols at different levels of the hierarchy 🌈. That flexibility comes partly from the fact that most protocol interfaces look pretty similar, plus something called "protocol idiosyncratic parameters" πŸ¦‹. These get defined for each offloaded protocol interpreter in the OPE. Using them doesn't complicate the OPE's basic design, because the OPE has to be customised for each offloaded protocol anyway, and all it has to do with those parameters is pass them along to the offloaded interpreter πŸ’…. So an interface tailored to a particular protocol can be made in a straightforward, cost-effective way πŸ’Έ.

The command dialog is more or less asynchronous πŸ’«. Commands can be issued at basically any time (except while another command is pending, more on that below), and there's no need for dummy traffic on a channel when no commands are going πŸ™…β€β™€οΈ.

Every command has a response πŸ“¬. The response indicates, at a level that depends partly on the offloaded protocol interpreter, whether the command was executed successfully and, if it wasn't, why πŸ€”. Often, making the response means talking to the protocol interpreter first πŸ—£οΈ.

When a command is issued, the issuer must wait for a response before another command is issued πŸ”’. So the Host and the OPE do a lock-step command/response dialog πŸ‘―. There are two big exceptions though 🫣:

  • The abrupt form of the End command can be issued at any time to cancel any previously issued commands and say "we don't want services anymore" πŸ›‘.
  • The Signal command. Since a Signal is out-of-band and usually super important, making it wait on a response would be undesirable 🚨. So a Signal can be issued while commands (other than Signal) are pending πŸ™Œ. However, a Signal should not be issued before a successful response to the Begin command has been received ⚠️.

Since it's possible for more than one command of different types to be pending at once, you need a way to tell the responses apart πŸ•΅οΈβ€β™€οΈ. Since there are never two commands of the same type pending, including the command name in the response is enough to do the trick βœ….

bestie, the two big exceptions are the abrupt End and Signal. Everything else waits its turn πŸ™ƒ

A special case is the Transmit command 🎁. Details are in the next section, but basically Transmit invokes the data transfer services of the offloaded protocol (when the Host issues it), or signals that new data has arrived from the network (when the OPE issues it) πŸ“‘. The interfaces for these events vary a LOT between protocols πŸŒ€. Some block until the data is accepted by the remote counterpart (or "peer") protocol interpreter, and others don't 🫠. So there's a special parameter that says what kind of Transmit interface this is πŸŽ›οΈ. It can either require that the response be generated immediately after the Transmit command is determined to be complete and formed properly, or indicate that the response shouldn't be generated until the appropriate interface event comes from the remote protocol interpreter ⏳. The default for all Transmit commands can be set up using the Begin command and changed using the Condition command πŸ”§. The default can also be temporarily overridden by specifying a parameter with a particular Transmit command πŸ’«. The net result? The Host gets to decide, within reason, just how lock-stepped transmissions are πŸ”. (It's assumed the usual case will be immediate responses, which moves the burden of buffering over to the OPE 🧠, as long as that "makes sense" with the offloaded protocol in play πŸ™ƒ.)

Some protocols give you a block-oriented data transfer service instead of a stream-oriented one 🧱. With that kind of service, the data tied to a transfer request is treated as one integral unit. On the way across the network, the protocol may let those units be grouped or fragmented, but the receiving end has to deliver the data in the original, integral units πŸ“¦. Protocols that work this way include some datagram protocols like IP and UDP, and also some connection protocols like NBS TP 🌐.

To cater to these types of protocols 🎯, it's a convention that commands, their parameters, and any associated data get transferred between the Host and the OPE in a single chunk 🍱. Any data associated with an H-FP command is treated as an integral unit, used in the corresponding service request to the outboard protocol interpreter or delivered as a complete unit to the process in the Host πŸ’Œ. Stream-oriented protocols like TCP won't be adversely affected by this convention πŸ’–.

Now, for Channel protocols that can't handle arbitrarily large chunks πŸ™ˆ, the Command level needs a mechanism to link multiple chunks into one command πŸ”—. The goal is to move as much of the buffering burden as possible from the Host to the OPE 🧠. The plan: an indication at the beginning of each chunk tells you whether it's an integral command, a fragment with more fragments still on the way, or the final fragment of a command 🧩. The details are in the section on the syntax of commands and responses πŸ“–.

Last thing: it's a convention for this H-FP that any data associated with a command must start on a word boundary (as defined by the local system) πŸ“. That means padding is needed inside the commands πŸ› οΈ. Padding is only used to fill up to the next appropriate boundary, and it has no semantic significance to the command interpreter. Two commands that are identical except for the amount of padding should behave identically πŸ₯°. The details of the padding are in the syntax section too 🌷.

and that's the interaction discipline, bestie πŸŒˆπŸ’–

Syntax Rules πŸ’…

At the Command Level, the Host and the OPE talk to each other using commands and responses πŸ—£οΈ. A command is a request for some particular action 🎯, and the response tells you whether that action succeeded or flopped πŸ’€.

All commands and responses are coded in ASCII characters. (Nothing precludes OPEs from accepting EBCDIC from Hosts that use it in native mode, but that is not required πŸ™ƒ.) These characters get sent in whatever way is convenient for the Host, and the OPE is flexible enough to interpret them. (Basically, OPEs are expected to accommodate Host idiosyncracies, like using 7-bit ASCII in a 9-bit field 🫢.) This approach has some seriously good perks ✨:

  • Adaptabilities in most Hosts: Most Hosts can generate and interpret ASCII character streams. So integrating H-FP into a Host won't need difficult software 🧚.
  • Script generation: Test and operational command scripts will be simpler to generate, since they won't need special characters ✍️.
  • Terminal Operation: Simple command streams make it way easier to turn an OPE into a generic virtual terminal support machine. That's super useful during development and testing πŸ› οΈ.
  • Testing: No special hardware is needed to interpret commands and responses. A terminal or data line analyzer will do πŸ”.

The specific format for commands and responses is coming up in the sections below. In those sections, the quote character " is used to indicate strings, and the symbols < and > (referred to as angle brackets) are used as meta-characters πŸŽ€.

Syntax of Commands

Remember the interaction discipline section? πŸ‘€ As hinted there, a chunk can carry either a complete command or just a fragment of one. The way this works is that the first character position in the chunk acts as a chunk usage identifier. A C in the first position means the chunk holds a single, complete command. An F means the chunk is the first part of a multichunk command. An M means the chunk is a middle part (neither the first nor the last chunk) of a command. And an L means the chunk is the last chunk of a multichunk command πŸ¦‹. Here are the sequences of chunks that are legal, where the letter is the chunk usage identifier in each chunk and the angle brackets enclose a chunk:

<C>
<F><L>
<F><M><M><L>

And these ones are NOT legal 🚫:

<L>
<M><L>
<F><C>

How you handle multiple chunks around the OPE's buffering limits is up to the ingenuity of OPE builders 🧠. The spirit of it is to take as much as you can, so the Host doesn't have to do the buffering itself πŸ’–.

A command always begins right after the indicator character, with possible spaces in between. That means a chunk can contain at most one complete command πŸ™…β€β™€οΈ. The end of the command (not counting the data) is marked by a newline (written as <nl> in this document) that does not appear inside a quoted string. The end of the data is marked by the end of the last chunk 🏁.

Commands are ASCII strings. The command identifier is the first word of the chunk, and it's made of at least the first two letters of the command, in upper or lower case. So BE, Be, bE, and be all identify the Begin command πŸ”₯. You can add more letters if you want, to make the command stream easier to read πŸ“–.

Following the command identifier is a list of parameters. These are also ASCII strings, although the exact format depends on the parameter. The data being transmitted is NOT treated as a control parameter, though, so it doesn't need to be ASCII 🌈.

Parameters are separated by one or more spaces. Tabs, newlines, and other white space are not legal parameter separators 🚫.

Parameter strings can be quoted using the " character. Anything between the " characters is part of the parameter, including spaces and newlines 🌸. A " that is part of the parameter is written inside a quoted string as "".

The order of the parameters within a command matters a lot for how the Host and the OPE interpret them πŸ‘‘. Optional parameters can be skipped by using ,, to indicate a NULL parameter. A NULL parameter takes its default value πŸ“. There's also an alternative: every parameter has a MULTICS/UNIX style Control Argument/Flag that identifies it, so you don't have to write NULL placeholders for every skipped parameter. The flag is one or two ASCII characters, and either upper or lower case works πŸŽ€. For example, say the fourth parameter of a command has the flag -p, and the user wants the first three parameters to be null. They could write:

command -p value

or

command -P value

instead of

command ,, ,, ,, value

if that's more convenient for the Host πŸ’…. Flagged parameters still have to appear in the correct sequence within the command, though 🧚.

Some commands come with data. Any such data goes into the chunk after all the parameters and the unquoted newline πŸ“¦. You can add padding by putting spaces between the end of the final parameter string and the newline, so the data starts on a word boundary. The OPE will always pad to a host word boundary. Padding by hosts is optional 🫧.

Syntax of Responses

Responses are really just a special form of command πŸͺ„. It's expected that all responses will fit into a single channel chunk, although the multichunk mechanisms described above can still be used for responses if needed 🧩. The string that uniquely identifies the response command is RE (and Re, rE, and re are also permitted) πŸ’œ.

After the response command identifier comes the original command identifier, so the response can be matched to the right command 🎯. Then comes a three ASCII digit response code, a set of protocol idiosyncratic parameters, and a textual message πŸ“. The protocol idiosyncratic parameters are used to transfer interface information between the Host and the OPE, and they may not be needed when off-loading some protocol interpreters πŸ€·β€β™€οΈ. The textual message is meant for humans to read and understand the response codes, and the protocol does not require it πŸ™ˆ. The three digits uniquely identify the semantics of the response, at least within the context of a particular command and a particular outboarded protocol interpreter πŸ”‘.

Responses are grouped numerically by the type of information they convey. The first digit tells you the group, and the last two digits qualify the reply further. Here's the grouping, exactly as written πŸ“Š:

0XX Successful:  The command was executed successfully. The
    response code may contain further information.

1XX Conditional Success:  The command was executed successfully,
    but not exactly according to the service and flow control
    suggestions.  If those suggestions were particularly important
    to the requester, he may wish to issue an End command.  The
    response code contains information on what suggestion or
    suggestions could not be followed.

2XX Command Level Error:  An error at the command level has
    occurred.  This could include requesting services of a
    protocol not supported, or a problem in the way those services
    were requested.  This level does not include problems with the
    syntax of the command or its parameters.

3XX Syntax and Parameter Errors:  An error in the syntax of the
    command or a problem with one of its parameters has occurred.
    A problem with a parameter may be other than syntactical, such
    as illegal address.

4XX Off-loaded Protocol Interpreter Problems:  Some problem with
    the particular off-loaded protocol has occurred.

5XX Local OPE Internal Problems:  Problems, such as insufficient
    OPE resources, or problems with OPE to subnet interface.

6XX Security Problem:  Some problem with Host, network, or OPE
    security has occurred.  The response code indicates the
    problem.

7XX Reserved for Future Expansion

8XX Reserved for Future Expansion

9XX Protocol Idiosyncratic Errors:  Some error occurred that is
    idiosyncratic to the particular off-loaded protocol being
    used.  The response code indicates the error.

Description of the Commands πŸ“£

As mentioned above, Host and OPE communication at the Command Level happens through commands and responses πŸ’¬. Commands can be issued by either the Host or the OPE, and they're used to stimulate activity in the other entity. Some commands only make sense in one direction, though 🧭. A response says that the activity the command started has been completed. Its code tells you whether the command succeeded or failed, and it might include other related info too πŸ“¬.

Each command has its own set of parameters. The order of those parameters matters for the protocols to work correctly πŸ”. You can find more about command parameter syntax in the syntax descriptions above ⬆️.

The commands are:

  • Begin: initiates communication between a process in the Host and an off-loaded protocol interpreter in the OPE. (A Channel level stream/connection will usually have been opened as a step beforehand. Every other command, except No-op, applies to a stream where a successful Begin has already been done πŸš€.)
  • Transmit: transmits data between a process in the Host and an off-loaded protocol interpreter in the OPE πŸ“€.
  • Signal: causes an out-of-band signal to be sent by the off-loaded protocol interpreter to its peer, or indicates that such a signal has arrived from the remote side ⚑.
  • Condition: alters the off-loaded protocol interpreter's operational characteristics πŸŽ›οΈ.
  • Status: transfers status requests or information between a process in the Host and an off-loaded protocol interpreter in the OPE πŸ“Š.
  • End: indicates that services from the off-loaded protocol interpreter are no longer required, or will no longer be provided πŸ‘‹.
  • No-op: performs no operation, but helps with testing πŸ§ͺ.

These commands get their own sections coming up πŸŽ€. Each of those sections covers the purpose of the command, a description of each parameter used with it, a list of responses for it, an example of it, and a set of notes for the implementor πŸ“š. (An appendix will eventually be provided for each protocol offloading, showing the use of its protocol idiosyncratic parameters as well as the general parameters on a per-command basis. At first, only representative offloadings will get appendices, with the others added once the protocol gains acceptance 🌟.)

Begin

Purpose of the Begin Command

The purpose of a Begin command is to kick off the conversation between the Host and the OPE on a particular stream or channel. (The channel gets opened as a separate step, obviously.) What a Begin means depends on who sent it. ✨

  • If the Host sent it, some process on the Host wants a protocol that got offloaded to the OPE πŸ’β€β™€οΈ. The user's request sets up a channel connection between the Host and the OPE, and then a Begin goes to the Command interpreter in the OPE.
  • If the OPE sent it, a protocol interpreter in the OPE has data for some Host process that the OPE doesn't know about yet πŸ‘€. Like, an incoming UDP datagram showing up on a new port, or a case where the Host never sent a Begin for UDP at all. (Incoming TCP connection requests are a little different: they get answered as a response to the user's Passive Open request, which already caused a Begin from the Host. But a TCP connection request aimed at a port where no Listen was ever issued will make the OPE generate a Begin, so be ready for that one 🫣.)

As mentioned earlier, a Host isn't required to support two-way Begins. Not every Host has to handle Begins coming from the OPE 🌸.

Parameters of the Begin Command

The Begin command has a bunch of parameters attached to it πŸŽ€. They carry the info the offloaded protocol needs to give a decent level of network service: the protocol, source and destination addresses, and type of service and flow control advice. We'll go through each one in detail below.

Protocol

The protocol parameter names the offloaded protocol in the OPE that the Begin is aimed at, or the one that sent the Begin to the Host πŸ¦‹. Say the user wants TCP services and the TCP software got offloaded into the OPE. Then the Protocol parameter for that Begin is TCP. Easy peasy.

There are two kinds of protocol parameters, generic and specific πŸ’œ. A generic parameter says what type of protocol service is needed, but doesn't name the actual protocol. This is useful because a Host process can get network services without knowing which protocol is doing the work, which is great when none of the specific details of a particular protocol matter. For example, the user might pick a generic Host-to-Host connection protocol, and later (down the road) end up getting service from either TCP or the NBS Transport Protocol, depending on the network or even the foreign Host in question. A specific protocol parameter names one particular protocol, like TCP, that has to be used for that channel πŸ”₯.

The valid entries for the protocol field are:

   Generic   Specific  Comment

   GIP       IP        Datagram Internetwork Protocol
   HHP       TCP       Connection Transport/Host-Host Protocol
   GDP       UDP       Datagram Transport/Host-Host Protocol
   VTP       TEL       Virtual Terminal (Telnet) Protocol
   GFP       FTP       File Transfer Protocol
   MAIL      SMTP      Mail Transfer Protocol
   PROX      PROX      Proximate Net Interface Protocol

(Quick side note, and this one's kind of a vibe: that last line, PROX, is there so a process on an OPE'd Host can reach the PI of the Network Interface Protocol for whatever the proximate network happens to be 🧚. Honestly, that only makes sense in specialized setups. But people have thought about "pumping bits at a peripheral" on a LAN, and the spec doesn't want to shut that door. Even if it's hard on lots of LANs to tell apart raw-mode traffic coming back from normal IP traffic, and even if admin rules might block skipping IP even when the tech would allow it, "the protocol" should still have a hook that goes straight to the L I protocol in play 🫢.)

There is no default value for this parameter. If it isn't present, the Begin command is in error πŸ’€. The control flag for this parameter is -pr.

Active/Passive

The Active/Passive parameter says whether the sender of the Begin wants to be the Active or the Passive user of the protocol 🌈. This matters most for connection-oriented protocols like TCP, where a user might actively try to set up the connection, or just sit back and wait for the remote side to make the first move. It also lets some process become the Host "fielder" for incoming traffic on a connectionless protocol like IP πŸ“.

Active is requested with the single character "A". Passive is indicated with the character "P". The default value for this parameter is "A". Also, when the OPE issues the Begin command, the value must be "A" πŸ’…. The control flag for this parameter is -ap.

Foreign Address Primary Component

H-FP addressing is two-level πŸ’–. Every address has two components, primary and secondary. What those two actually mean is protocol-specific, but there are some general rules that hold everywhere. The primary component says where the protocol should deliver the info. The secondary component says which recipient at that location should get it. For example, for TCP the primary component is the Host's Internet Address and the secondary is the TCP port. For IP, the primary is again the Host's Internet Address, and the secondary is the IP ULP field. Some protocols only have one level of addressing, or the secondary level can be figured out from other info (Telnet is one of those). In those cases, only the primary component gets used. That's why the secondary component parameter shows up later in the parameter list πŸ¦‹.

The Foreign Address Primary Component parameter holds the primary component of the destination address. It can be numeric or symbolic πŸ”₯. (This means the OPE can run a Name Server type of protocol if that makes sense, and the Host doesn't have to keep its own in-board name-to-address table. Lowkey genius, no cap 🧠.) The default value for this parameter is "Any Host". That only really makes sense for Passive Begins. The control flag for this parameter is -fp.

Mediation Level

The mediation level parameter tells the OPE how much of the protocol's work the Host wants it to handle πŸ‘‘. One extreme is the Host wanting to stay totally uninvolved. The other is the Host wanting to make every single decision itself. What exactly the setting means depends on the particular offloaded protocol.

Here's an example, because this one's iconic. A full inboard Telnet implementation gives the Host a bunch of jobs: negotiating and providing protocol options, translating between local and network character codes and formats, and watching the well-known socket for incoming connection requests 😭. When Telnet is outboard, mediation level says which of those jobs belong to the Host and which belong to the OPE. With no OPE mediation, the Host handles all the option negotiation and all the format conversions. With full OPE mediation, the OPE does all the option negotiation and all the format conversions. An in-between level could have the OPE handle regular option negotiation, format conversion, and socket monitoring, while the Host deals with any options the OPE doesn't know about 🌸.

The parameter is one ASCII digit. The value 9 means full OPE mediation, and 0 means no OPE mediation. Other values can be defined for some protocols (like that intermediate Telnet level we just talked about) πŸ“. The default value for this parameter is 9. The control flag for this parameter is -m.

Transmit Response Discipline

The Transmit Response Discipline parameter sets what the OPE should do about generating responses to Transmit commands πŸŽ€. Basically, it decides when the OPE's response to a transmit command happens: right away, or later.

This value is one ASCII character. "N" is for nonblocking Transmit commands, which means the response should be generated as soon as the command has been checked for correctness (so the syntax is fine and the parameters look reasonable) πŸ’…. In other words, the OPE has the data sitting in its queue, but it hasn't necessarily sent it out to the net yet. "B" is for blocking Transmit commands, which means the response waits until the protocol interpreter has successfully transmitted the data 🫢. (Obviously, that doesn't count if the Transmit command was badly formed.) The default value for this parameter is "N", meaning a nonblocking Transmit command. The control flag for this parameter is -tr.

(Heads up, this one's a bit subtle: depending on the protocol, "successfully transmitted" might mean an acknowledgment came back from the foreign Host. But for other protocols, it might only mean the bits got handed from the OPE to the proximate net πŸ‘€.)

Foreign Address Secondary Component

The addressing mechanisms this level of H-FP supports are covered above πŸ’…. The Foreign Address Secondary Component parameter holds the value of the destination address's secondary component πŸ¦‹. Some protocols don't need this parameter, or can figure it out from other info, so its default is NULL ✨. Heads up though: a NULL secondary component might be an error for some protocols πŸ™ˆ. You can write it numerically or symbolically, and the control flag is -fs πŸŽ€.

(Ngl, this next bit is so interesting 🧚. It's intended to be "legal" to specify a Secondary Component that isn't the Well-Known Socket for the protocol in play. In that case, the given protocol's virtualizing should be applied to the stream, because that's what the other side is expecting πŸ’œ. This is for stuff like a Terminal-Terminal protocol that just "does Telnet" to a socket that isn't the usual Logger 🌈.)

Local Address Secondary Component

The Local Address Secondary Component parameter holds the value of the local address's secondary component 🌸. (The primary component is assumed to be the default for the Host, but it can be changed too, see below πŸ‘‘.) Some protocols don't need this parameter, or can get it from other information. Sometimes the OPE already knows the value and doesn't need it at all 🫢. The default is NULL. You can write it numerically or symbolically, and the control flag is -ls πŸ’–.

Begin Timeout Interval

After a Begin command is issued, a timer can be started ⏱️. If the requested activity can't be done within some timed interval, the Begin command may expire 😭. An expired Begin command returns a response code showing a Begin timeout happened πŸ’€. The Begin Timeout Interval parameter is how long the timer runs before that timeout hits πŸ“.

It's written as a string of ASCII digits giving the interval in seconds πŸ”’. The default is infinity, meaning the Begin command will literally never time out β™ΎοΈβœ¨. The control flag is -bt πŸ¦‹.

Type of Service Advice

The Type of Service Advice parameter says what service characteristics the user wants from the offloaded protocol πŸ’…. It covers the precedence of the data transfer, plus whether high throughput, fast response time, or a low error rate is the main goal πŸ”₯.

The format is a letter right next to a digit, with no spaces in between πŸŽ€. The letter T means high throughput is desired. R means minimal response time is the goal. E means low error rates are the goal. N means there are no special service requirements to pass along 🌈. The digit right after the letter is the precedence level, where zero is the lowest and nine is the highest πŸ‘‘. What it actually means depends on which service options the protocol offers 🧚. The default is the lowest precedence (ROUTINE) with no special service requests πŸ’œ. The control flag is -ts ⭐.

Flow Control Advice

The Flow Control Advice parameter says what flow characteristics the user wants ✨. Some apps, like file transfer, work better when data goes in big chunks πŸ“¦. More interactive apps do better with smaller pieces πŸ’¬. So this parameter tells the protocol whether to use large or small data blocks 🫢. It only matters for stream or connection-oriented protocols, where the user sends more than one piece of data πŸ¦‹.

It's a single ASCII digit πŸ”’. A value of 0 means send relatively small blocks (like character or line oriented apps), and 9 means send relatively large blocks (like block or file oriented apps) πŸ“. Numbers in between are sizes between those extremes 🌸. The character N means no special flow control advice is given πŸ™ˆ. How this gets interpreted depends on the particular protocol in the OPE πŸ’…. The default is no flow control advice, so the protocol in the OPE just runs on whatever info it already has 🌈. The control flag is -fc πŸŽ€.

Local Address Primary Component

This parameter holds the local address primary component 🏠. Most of the time, both the Host and the OPE already know this component, so this parameter is rarely needed 😴. It's handy if the Host wants to pick one of several valid addresses though πŸ‘‘. The control flag is -lp πŸ’–.

Security

The security parameters hold a set of security level, compartment, community of interest, and handling restriction info πŸ”. Right now, security is handled by doing all processing at system high level or at a single level πŸ›‘οΈ. So these parameters are probably redundant, since the security info is already known πŸ€·β€β™€οΈ. Later on they might be needed though, so a field is provided for them πŸ¦‹. The control flag is -s ✨.

Protcol Idiosyncratic Parameters

The remaining parameters are protocol idiosyncratic, meaning each offloaded protocol can have its own set of these 🧚. They get documented alongside the description of that offloaded protocol πŸ“–. Their default is NULL, unless a particular offloaded protocol says otherwise πŸ’œ. The control flag for this whole set is -pi, which marks the first protocol idiosyncratic parameter 🌈. Control flags for the other ones must be defined for each offloaded protocol πŸŽ€.

Data

After the Protocol Idiosyncratic Parameters (if there are any) and the required <nl>, the rest of the chunk gets read as data to transmit, but only if the protocol in play allows data at this point πŸ’¬. In connection oriented protocols, data may or may not be allowed when the connection starts πŸ”—. But in connectionless protocols, it totally makes sense to let the H-FP Begin command carry data πŸ“¨. (This will come in handy later when we get to the Condition command πŸ‘€.)

Responses

These are the responses that have been identified for the Begin command πŸ“‹:

   000    Command completed successfully
   101    Throughput not available; using maximum
   102    Reliability not available; using maximum
   103    Delay not available; using minimum
   110    Flow Control advice not followed; smaller blocks used
   111    Flow Control advice not followed; larger blocks used
   201    Failed; Begin not implemented in this direction
   202    Failed; timeout
   203    Failed; Begin command on already active channel
   300    Problem with multiple chunks
   301    Syntax problem with Begin command
   302    Protocol not supported in OPE/Host
   303    Active service not available
   304    Passive service not available
   305    Invalid Foreign Address Primary Component
   306    Invalid Transmit Discipline
   307    Invalid Foreign Address Secondary Component
   308    Invalid Local Address Secondary Component
   309    Invalid Timeout Interval
   310    Invalid Type of Service Advice
   311    Invalid Flow control Advice
   312    Invalid Local Address Primary Component
   401    Protocol Interpreter in OPE not responding
   402    Remote Protocol Interpreter not available
   403    Failed; insufficient protocol interpreter resources
   501    Failed; insufficient OPE resources
   601    Request violates security policy
   602    Security parameter problem

Protocol idiosyncratic responses get defined for each offloaded protocol too 🧩.

Example of Begin Command

The Begin command is the most complex one in the H-FP Command Level 🀯. When the offloaded protocol is TCP, Begin is what opens TCP connections πŸ”Œ. Here's one example: an inboard Telnet interpreter issues a Begin command to open a TCP connection to ISIA, with no begin timeout interval πŸ’»:

C BE TCP A ISIA 9 N 23 ,, ,, N0 S <nl>

Where:

  • TCP The code for the protocol TCP
  • A Indicates Active Begin
  • ISIA The name of a Host at USC-ISI
  • 9 Mediation Level 9: Full OPE mediation
  • N Non-blocking transmit
  • 23 Destination Telnet Port
  • ,, skip over parameters (Local Address Secondary, Begin Timeout Interval)
  • N0 Type of Service Advice: No special Advice, Normal Precedence
  • S Flow Control Advice: use small blocks

This command makes the OPE invoke the TCP interpreter to generate the initial SYN packet to the well-known Telnet socket on Host ISIA 🎯. It also tells the OPE to do all TCP related processing through the Mediation Level 🧠, accept the default Local Address parameters, and set the Begin Timeout Interval to infinity ♾️. The TCP connection's precedence is Normal, and the TCP interpreter is told the data stream will mostly be small blocks πŸ’–.

Notes to the Implementor

Response 203 might seem silly to some readers, but it's there in case somebody goofed while using the Channel Layer πŸ™ƒ.


Transmit

Purpose of the Transmit Command

The Transmit command lets the process in the Host send data through an off-loaded protocol interpreter in the OPE πŸ“€. It also lets the OPE deliver data it received from the network to the process in the Host πŸ“₯. Transmit is especially relevant to connection and stream type protocols 🌊, though it has uses for connectionless protocols too πŸ¦‹. Once the Begin command is issued successfully and the proper Response comes back, Transmit commands can be sent on that channel πŸŽ€. What the Transmit command means depends on whether the Host or the OPE issued it πŸ‘‘βœ¨.

  • If the Host issues the Transmit command, a process in the Host wants to send data to the destination set up by the off-loaded protocol interpreter, which was (usually) started by an earlier Begin command on that H-FP channel. πŸ’Œ
  • If the OPE issues the command, the OPE has received data meant for a process in the Host, coming in from a connection or stream of the off-loaded protocol that was set up by an earlier Begin command on that H-FP channel. πŸ“¬

Parameters of the Transmit Command

okay so the Transmit command has one parameter, and it's optional πŸŽ€ It lets you temporarily override the response discipline for just that one transmit. Some protocols also have their own protocol-idiosyncratic parameters 🧚 The transmit command also carries data. All parameters must precede the data to be transmitted. No skipping ahead, bestie! πŸ’…

Response Discipline Override

this one is giving "choose your vibe for this one message" πŸ¦‹ The Response Discipline Override parameter sets the response discipline for that single Transmit Command, overriding the default. You use one ASCII character to pick it. N means non-blocking: don't hold up, just send back a response as soon as the data is handed to the protocol interpreter in the OPE ⚑ B means blocking: the response waits until the data has actually been sent to the destination 🫢 If you don't pick one, the default is whatever the Transmit Command response discipline is currently set to. Using this parameter doesn't change that default. If you want to change the default itself, you use the Condition command instead πŸ’œ The control flag for this parameter is -rd.

Protocol-Idiosyncratic Parameters

any other parameters on Transmit are protocol-idiosyncratic, which means each off-loaded protocol has its own set, and they're documented alongside the description of that protocol 🌈 Their default is NULL, unless a particular off-loaded protocol says otherwise. The control flag for this whole group is -pi, which marks the first protocol-idiosyncratic parameter. Control flags for the rest must be defined for each off-loaded protocol. πŸ”₯

Responses

these are the Transmit responses we've got so far πŸ‘‘

000    Transmit Command completed successfully
201    Transmit Command not appropriate
300    Problem with multiple chunks
301    Syntax problem with Transmit Command
302    Invalid Transmit Command Response Discipline
401    Protocol Interpreter in OPE not responding
402    Failure in remote protocol interpreter
403    Failed; insufficient protocol interpreter resources
501    Failed; insufficient OPE resources
601    Request violates security policy

and on top of those, every off-loaded protocol gets its own protocol-idiosyncratic responses too 🌸

Example of Transmit Command

the transmit command is basically the TCP write call in disguise πŸ“ Here's what it looks like:

C TR N <nl> <DATA>

so N asks for non-blocking discipline, <nl> is the newline that has to end the command (it's required, no exceptions πŸ™ˆ), and <DATA> is the user's data that's getting sent.

Notes to the Implementor

ngl this part is a lifesaver 😭 If you get a 403 or a 501 response and you sent multiple chunks, it probably makes sense to retry with a single chunk. If you already sent a single chunk, it makes sense to wait a bit and try a few more times before you give up on the stream or channel. Patience is cute, periodt ✨


Condition

Purpose of the Condition Command

the main job of Condition is to let a process change the characteristics that were first set up by the Begin command. (Yes, "condition" is a verb here, iykyk πŸ’…) Those characteristics include the addresses, the mediation level, the type of service, and the flow control parameters from Begin. They can also include protocol-idiosyncratic ones πŸ¦‹ Condition is usually thought of as a Host-to-OPE command, but it can also be used OPE-to-Host in some contexts 🌈

Condition is a generic command, so it might not get much use in some off-loaded protocols. In others, only a few of its parameters make sense. For example, changing the destination address of a TCP connection means closing one connection and opening another πŸ™ƒ So it usually makes more sense to issue an End command first, then a Begin with the new address. But for protocols like IP or UDP, changing the address on every datagram is a totally reasonable move πŸ’–

Parameters of the Condition Command

the Condition command takes the same parameters as Begin πŸŽ€ Any parameter you include gives the new value for that characteristic. Anything you leave out keeps its current value.

You can change any characteristic that was set in the Begin command with Condition, but some don't really make sense to change, at least for some protocols πŸ™ˆ For example, once a connection is open, changing the Foreign Address Primary or Secondary Components isn't a great idea. That goes against current versions of TCP, and you'd have to close the existing connection and open a new one to the other address. Earlier versions of TCP did let connections move around, though 🧚 If an off-loaded protocol that supports that feature were implemented in the OPE, then changing the Secondary Address Components would be a reasonable thing to do.

Responses

the Condition responses are the same as the Begin responses πŸ’…

Example of Condition Command

Condition can get pretty complex and can be used for lots of things 🌈 One imagined use is changing the type of service advice for the channel. Here's an example, which also shows you can skip parameters:

C -ts T <nl>

this tells the offloaded PI on the current channel to try to achieve high throughput (in how it uses the comm subnet(s) in play) πŸš€

Notes to the Implementor


Signal

Purpose of Signal Command

the Signal command exists so processes can send and receive out-of-band signals or info between the Host and the OPE, which lets you use the out-of-band signaling services of the off-loaded protocol πŸ”₯ What Signal means depends on who sent it:

  • If the Host issued the Signal command, a process in the Host wants to send out-of-band data or an out-of-band signal.
  • If the OPE issued the Signal command, out-of-band data or an out-of-band signal showed up for the process on the channel in the Host. πŸ“¬

Parameters of the Signal Command

the basic version of Signal has no parameters at all, and it either sends an out-of-band signal or reports one received πŸ’Œ Some protocols, like the NBS Transport Protocol, let the user send data along with the signal, so data is allowed to ride along with the Signal command 🫢 Signal can also have protocol-idiosyncratic parameters. If it does, those come before the data.

Protocol-Idiosyncratic Parameters

the Signal parameters are protocol-idiosyncratic, so every off-loaded protocol has its own set 🌸 Their default value is whatever they were previously. Control flags for multiple protocol-idiosyncratic parameters must be defined for each off-loaded protocol.

Responses

these are the Signal responses we've got πŸ‘‘

000    Command completed successfully
201    Command not appropriate
300    Problem with multiple chunks
301    Syntax problem with Command
401    Protocol Interpreter in OPE not responding
402    Failure in remote protocol interpreter
403    Failed; insufficient protocol interpreter resources
501    Failed; insufficient OPE resources
601    Request violates security policy

and yep, protocol-idiosyncratic responses get defined for each off-loaded protocol too ✨

Example of Signal Command

the big use case for Signal when you're offloading a connection protocol is sending an out-of-band signal with no data πŸ“ The command for that is:

C SI <nl>

Notes to the Implementor

some protocols only allow one outstanding signal at a time πŸ™ˆ For those, whether the OPE buffers several signals is an implementation choice. Still, a really careful OPE could make a strong case for sending a 202 response back to the Host in those cases πŸ’œ

there's some debate about how to handle "expedited data" in some protocols, especially ISO ones πŸ€” It might be better to treat it as a protocol-idiosyncratic parameter on the Transmit command rather than using Signal, even though Signal is the closest match to an out-of-band signal in that protocol. If you do use Signal for it, the expedited data should not be passed as ASCII, and it should show up after the command-terminating newline character (plus any padding with space characters) πŸŽ€


Status

Purpose of Status Command

the Status command lets the Host ask the OPE for status info, and the OPE can ask the Host too πŸ¦‹ It covers status requests for a conventional protocol interface. For example, in TCP you can ask what state a particular connection is in πŸ’–

Parameters of the Status Command

the Status command's parameters tell you whether it's a request or a response, and they carry the status information itself 🧚

Request/Report

Okay so the Q/R bit is the first thing in the Status command 🫢. It's a single ASCII character. Q means it's a request (a query), and R means it's a report πŸ’…. A report can show up because someone sent a query, or because certain protocol mechanisms generated it on their own, so don't assume every report answers a question πŸ‘€.

Protocol-Idiosyncratic Parameters

Every protocol has its own drama πŸŽ€. The parameters for the status command depend on which protocol is being offloaded, so each offloaded protocol gets its own set. If you don't specify one, it keeps its previous value ✨. One of these parameters says what kind of status info is being sent or asked for, and then there's a value (or a set of values) holding the actual status info. The status info should be the last item in the command, bestie πŸ’–. The control flag for this whole set is -pi, which marks the first protocol-idiosyncratic parameter 🧚. Control flags for the other protocol-idiosyncratic parameters must be defined for each offloaded protocol, so each protocol has to sort out its own flags πŸ™ˆ.

Responses

Here are the responses for the Status command πŸ’œ:

000    Command completed successfully
201    Command not appropriate
300    Problem with multiple chunks
301    Syntax problem with Command
302    Inappropriate status request
303    Inappropriate status response
401    Protocol Interpreter in OPE not responding
402    Failure in remote protocol interpreter
403    Failed; insufficient protocol interpreter resources
501    Failed; insufficient OPE resources
601    Request violates security policy
9xx    Protocol Idiosyncratic status responses

Example of Status Command

The status command can get really complicated, depending on the protocol and the type of status info 🌈. One possible use is when you're offloading TCP and you want to request the status service. For that, the status command would look like this:

C ST Q <nl>

Notes to the Implementor

There are no notes for this one, so nothing to add here 🌸.


End

Purpose of the End Command

The End command is how you say "I don't need the services of the offloaded protocol anymore" πŸ¦‹. What it means depends on who sends it.

  • If the Host issues the End command, it means the process in the Host no longer requires the services of the offloaded protocol.
  • If the OPE issues the End command, it means the remote entity has no more data to send (e.g., the off-loaded protocol is TCP and the remote user has issued a TCP close).

Parameters of the End Command

There's one parameter for the End command, and it decides whether the termination is "graceful" or "abrupt" (see below) πŸ“.

Graceful/Abrupt

The Graceful/Abrupt parameter says how the End gets handled. A graceful End lets data that's still in transit reach its destination before the service actually shuts down ✨. An abrupt End happens immediately, so any data sent from the Host that's still pending in the OPE gets thrown away, and no new incoming data is sent to the Host from the OPE πŸ’€.

This parameter is one single ASCII character. G means graceful and A means abrupt. The default is graceful πŸ’–.

Responses

Here are the responses for the End command πŸŽ€:

000    Command completed successfully
201    Command not appropriate
300    Problem with multiple chunks
301    Syntax problem with Command
302    Illegal Type of End Command
401    Protocol Interpreter in OPE not responding
402    Failure in remote protocol interpreter
403    Failed; insufficient protocol interpreter resources
501    Failed; insufficient OPE resources
601    Request violates security policy

Protocol idiosyncratic responses will also be defined for each off-loaded protocol 🧚.

Example of End Command

The End command is pretty straightforward πŸ’…. It's a chunk with just the chunk usage identifier, the end command string, and the parameter that says whether the end is graceful or abrupt. A valid (abrupt) End command looks like this:

C EN A <nl>

Notes to the Implementor

Once an End has been issued in a given direction, any other commands on the channel in the same direction are in error and should be responded to appropriately πŸ™ˆ.


No-op

Purpose of the No-op Command

The No-op command does nothing, and that's the whole point 😭. It lets the Host and OPE have a dialog that doesn't change the state of communication activities. That's useful for debugging, and for supporting features of certain protocols (e.g., Telnet's Are You There command) 🌸.

Parameters of the No-op Command

There are no parameters for the No-op command 🫢.

Responses

There are only two legal responses to the No-op command πŸ”₯:

000    No-op Command Completed Correctly
300    Problem with multiple chunks

Example of No-op Command

The No-op command is super simple πŸ’œ. It's a chunk with only the chunk usage identifier and the command string, followed by the newline. One valid No-op command is:

C NO <nl>

Notes to the Implementor

No-ops are for testing and initial synchronization πŸ§ͺ. (The latter use is not mandatory, however. That is, no exchange of No-ops is required at start-up time, but it is conceivable that some implementations might want to do it just for exercise.) They are also traditional πŸ‘‘.

References

(References [1]-[3] will be available in M. A. Padlipsky's "The Elements of Networking Style", Prentice Hall, 1985.)

[1] Padlipsky, M. A., "The Host-Front End Protocol Approach", MTR-3996, Vol. III, MITRE Corp., 1980.

[2] Padlipsky, M. A., "The Elements of Networking Style", M81-41, MITRE Corp., 1981.

[3] Padlipsky, M. A., "A Perspective on the ARPANET Reference Model", M82-47, MITRE Corp., 1982.

[4] Bailey, G., "Network Access Protocol", S-216,718, National Security Agency Central Security Service, 1982.

[5] Day, J. D., G. R. Grossman, and R. H. Howe, "WWMCCS Host to Front End Protocol", 78012.C-INFE.14, Digital Technology Incorporated, 1979.

1.3. The Transmit Command ✨

okay bestie, we're officially at the Transmit command πŸ’… the rest of this appendix picks up right from here, so keep scrolling πŸ¦‹πŸ’–

The Transmit command is used by the Host process to tell the off-loaded TCP interpreter to send data to a remote site over the TCP connection tied to the command's channel. The OPE uses it to hand incoming data from the connection over to the process in the Host. πŸ’Œ

1.3.1. Specialized Usage ✨

The Transmit command has to be able to handle all the fancy features of the Send and Deliver Event. Those special features are Urgent, Push, and changing the ULP Timeout action and/or interval. πŸ’…

Urgent is how we say that some point further along in the data stream has been marked URGENT by the sender. The actual Urgent bit travels out-of-band, but it carries a pointer tied to the sequence numbers of the in-band data. So the urgency has to be shown in the Transmit command, not the Signal command. 🚨

Push is a TCP Send Event feature that tells the data in the Transmit command to go out right away (within the flow control limits), instead of waiting for more send commands or a timeout. Push is indicated in the Transmit command, and it means the same thing when it's sent from the OPE to the Host. If the Host implementation doesn't do any internal queuing, the flag doesn't mean anything. 🫢

The TCP Send event lets the user change the "ULP timeout action" and/or the "ULP timeout interval" for that connection. Once changed, the new values stick for the rest of the connection, unless they get changed again later with another Send. This H-FP feature is handled using the Transmit Command. πŸ¦‹

1.3.2. Protocol-Idiosyncratic Parameters πŸŽ€

The three features above are handled with protocol-idiosyncratic parameters, so let's break them down. πŸ’–

The first one is the Urgent parameter. From the interface's point of view, it's just a flag that says the data is urgent. (The actual Urgent pointer is the off-loaded TCP interpreter's job, since it's the one keeping track of the sequence numbers.) When the Host process issues it, the Urgent flag means the stream should be marked. When the OPE issues it, it means the receiver should go into (or stay in) Urgent receive mode. If the flag isn't set in a Transmit issued by the OPE, the receiver should stay in (or go back to) non-urgent receive mode. The value of this parameter is "U" if Urgent is set, or "N" if it isn't. The default value is "N". Since this is the first protocol-idiosyncratic parameter for the Transmit command, it doesn't need a special flag and can be indicated using -pi. 🌸

The second one is the Push flag. Only the Host issues this parameter, since there's no Push in the TCP Deliver event. Its value is "P" for push, or "N" for normal. The default is "N", and its control flag is -pu. πŸ“

The third one is the ULP timeout action and value parameter. The action part tells the offloaded interpreter whether to abort the connection on a timeout or report it to the inboard user. The value part is the numerical timeout interval. The format is the same as in the Begin command: one letter followed right away (no spaces) by an ASCII number. The letter can be either "R" or "A", which means the ULP timeout should cause a report or an abort, respectively. The number is read as the timeout interval in seconds. The default interpretation is the parameter's previous value. Its control flag is -ul. ⏰

1.3.3. Examples of the Command 🧚

Here's a Transmit command issued by a Host process:

C TR -pi N P R160 <nl> <DATA>

Here <DATA> is the data inside the chunk. This one is for a non-urgent but pushed TCP Send event, and it also resets the timeout action and interval to Report with a value of 160 seconds. The response mode (that is, nonblocking) comes from the Begin command and isn't affected by the transmit. πŸ’œ

Here's a Transmit command issued by the OPE:

C TR -pi N <nl> <DATA>

Again, <DATA> is the data inside the chunk. This one is for a non-urgent delivery (presumably right after an earlier Urgent delivery). 🌈

1.4. The Condition Command 🌷

The Condition command is used to change the transmission characteristics of the connection. The parameters that actually make sense to change with TCP are the Transmit Response discipline, the Type of Service, and the Flow Control Advice. πŸŽ€

1.4.1. Specialized Usage 🫧

There isn't any particularly specialized usage of the Condition command with an offloaded TCP interpreter. Nothing to see here, bestie. πŸ™ˆ

1.4.2. Protocol-Idiosyncratic Parameters πŸ’…

There are no protocol-idiosyncratic parameters for the Condition command with off-loaded TCP. It would be possible to change the ULP timeout action values with a Condition command. However, that's done with the Transmit command instead, which matches the interface in MIL-STD 1778 more closely. We propose that the Condition command not provide this capability. πŸ“‹

1.4.3. Examples of the Command ✨

Here's an example of the Condition command used to change the flow control advice for a connection:

C CO -fc 1 <nl>

This says that relatively small transmission units are now expected. 🐣

1.5. The Signal Command 🚫

As we currently understand it, TCP's URGENT feature is an INband signal rather than a true out-of-band signal (and at least one of us deeply regrets this 😭). The actual URGENT bit is sent out-of-band, but it contains an URGENT pointer that ties the URGENT to its position in the data stream. What the URGENT actually means is left up to the higher level protocol. For example, Telnet says to discard all data up to the URGENT pointer. 🧐

The Signal command is allowed to cross a pending Transmit in the H-FP channel. So it would be potentially dangerous to implement the interface to TCP URGENT using the Signal command, because the wrong sequence number could end up as the urgent pointer. πŸ’€ Barring persuasive arguments to the contrary, it is proposed that Signal should not be used with TCP. πŸ›‘

1.6. The Status Command πŸ”

The Status command maps directly to the TCP Status event when a Host process issues it. It's also used for the TCP error event when the OPE issues it. There's currently some question about how information from lower protocol levels (for example, ICMP error messages) should be reported to TCP users. Once those issues are sorted out, there may be other uses for the Status command. We'd love to hear other ideas for the Status command in this report. πŸ’Œ

1.6.1. Specialized Usage πŸ¦‹

The major specialized usage of the Status command is providing the error reporting service. This usage is a form of the Status generated by the OPE. 🚨

1.6.2. Protocol-Idiosyncratic Parameters 🌸

When used as a TCP Status request (a command issued by the Host process), there are no protocol-idiosyncratic parameters for the Status command. The OPE responds with the TCP status. πŸ“

When used as a TCP error report (a command issued by the OPE), there is one protocol-idiosyncratic parameter for the Status command. It's an error description in the form of a text string. It doesn't need a special control flag, since the flag -pi is unambiguous and there are no other protocol-idiosyncratic parameters. πŸŽ€

1.6.3. Examples of the Command 🧚

Here's an example of the Status command issued by the Host process to ask for status information:

C ST Q <nl>

The status information comes back in the response to the status command. πŸ’–

Here's an example of the Status command issued by the OPE to report an error from the TCP interpreter:

C ST R -pi "Connection already exists" <nl>

This gets issued when a TCP open (HFP Begin) is sent to a connection that's already opened (foreign). 😀

1.7. The End Command πŸ‘‘

The End command is used to say that TCP services are no longer needed. So it can be mapped to either the TCP Graceful Close or the TCP Abort events. It's also used as the TCP Closing response (as opposed to the OPE's response to the close command) when the OPE issues it. πŸŒ™

1.7.1. Specialized Usage ⭐

Because TCP's close is two-way, the Host and the OPE might want to gracefully terminate the connection at the exact same instant. If that happens, both the Host and the OPE would issue End commands at the same time. To be ready for this, it's necessary to make this the normal graceful closing sequence. In other words, both the Graceful Close request and the Closing response are mapped to End commands. A response to one of those commands only means the command was received and executed, not that the connection is actually fully closed. The connection is gracefully closed once both End commands have been issued and both successful responses have been received. 🫢

An abrupt end is different, since it doesn't need a two-way exchange. Only the Host or the OPE needs to issue it for the connection to be aborted. πŸ’₯

1.7.2. Protocol-Idiosyncratic Parameters 🫧

There are no protocol-idiosyncratic parameters for the End command used with TCP. Easy peasy. 🍰

1.7.3. Examples of the Command 🌈

Here's the End command used to indicate either a TCP Close request (from the Host process) or a TCP Closing response (from the OPE):

C EN G <nl>

And here's the End command used as an Abort request (from the Host process) or as a Terminate response:

C EN A <nl>

2. Command Level Interface to an Off-loaded Telnet 🧸

This appendix talks about how to use the commands described in the body of this document to build an interface between a Host process and an off-loaded interpreter of the Telnet protocol. It's giving layered, it's giving intentional. πŸ¦‹

Okay so the interface here is totally not a formal interface πŸ’… There are a few reasons for that, like there's no widely accepted standard interface to Telnet, and Telnet is headerless πŸ™ˆ So the interface ends up looking a LOT like the actual Telnet data stream. Iconic, honestly.

2.1. The Begin Command ✨

The Begin command is the one you use to start Telnet connections πŸ¦‹

2.1.1. Specialized Usage

Okay, the Begin command has three major specialized usages πŸŽ€ The first is the meaning of the Mediation Level parameter. The second is how the number of incoming Telnet connections gets handled. The third is what the secondary address components mean.

So the mediation level controls which Telnet activities get done by the OPE and which ones the Host controls 🧚 It's been decided that all monitoring of the Telnet Socket should be done by the OPE, no debate. Mediation level 9 is the default, and it means the Host wants zero involvement in Telnet operation πŸ™…β€β™€οΈ Level 5 means the protocol-idiosyncratic parameters on this Begin command list which incoming options the Host wants to handle. Everything else, plus all NVT translations, gets handled by the OPE. Level 0 means the Host handles all the options, but all the NVT translations still happen in the OPE (see Section B.1.3) πŸ’œ

The Host can accept connections in two ways. It can field Begins the OPE generates, or it can issue passive Begins to the OPE 🌸 The Host might want to cap how many incoming Telnet connections it handles at once, and it can do that by rejecting OPE-generated Begins above some number, or by limiting how many passive Begins it issues. BUT here's the plot twist 😭 precedence constraints mean the Host actually has to issue some extra passive Begins, or accept extra Begins from the OPE, beyond the max it's normally willing to support. That way high-priority service requests can still get in, possibly by preempting lower priority stuff. Main character energy for the important requests πŸ‘‘

The secondary address component is how you refer to specific ports. Normally you only bother with it when the standard or default ports aren't being used, like special purpose apps or testing πŸ“

2.1.2. Protocol-Idiosyncratic Parameters

The protocol-idiosyncratic parameters for the Telnet Begin command are the identifiers for the options the host wants to negotiate when using mediation level 5 🫢 On any other mediation level, these parameters just aren't used.

2.1.3. Examples of the Command

Here's an example of a passive Begin for an outboard Telnet protocol ✨

   C BE TEL P ,, 5 N -fc 0 -pi 9 <nl>

And here's what each piece means πŸŽ€

  • TEL is the code for the Telnet Protocol
  • P is a passive Begin
  • ,, skips the Foreign Address Primary Component
  • 5 means the Mediation Level is 5
  • N means Non Blocking Transmits
  • -fc skips over parameters up to Flow Control Advice
  • S means Small Blocks are appropriate for Telnet
  • -pi skips over parameters to the Protocol Idiosyncratic List of Options to be Handled by the Host
  • 9 is the Option Code for the Line Length Option

No remote address component is specified here, because the Host will accept connections from any Host 🌈 Same deal with local addresses: none are specified, because the default well-known socket for this Host is used. In this example the Host says it'll handle the line length option (number 9), and all the other options get handled in the OPE πŸ’…

Here's an example of an active Begin for an outboard Telnet protocol πŸ¦‹

   C BE TEL A ISIA 5 N -fc 0 -pi 9 <nl>

This one is basically the same as the passive command, except it specifies a remote primary address component to identify the intended Host πŸ’– No remote secondary component is specified, because the well-known socket at that Host is used. No local secondary address components are specified either, since the connection can come from any available socket of the appropriate type that the OPE picks 🧚

2.2. The Transmit Command ✨

The Transmit Command is what you use to send data across a Telnet connection πŸ’Œ

2.2.1. Specialized Usage

The Transmit command is how data gets sent over the Telnet connection 🌸 There's one specialized thing about it when it's used with an outboard Telnet interpreter: the Go Ahead feature of Telnet, which supports half-duplex devices πŸŽ€

Go Ahead is a protocol idiosyncratic parameter to the Transmit. It's only used if the Host will support it, though πŸ™ˆ Honest opinion from the authors: Go Ahead is probably not a proper thing for the default case πŸ’…

Go Aheads are a matter between the Host and the terminal. It's hard to offload generating Go Aheads to the OPE, because the OPE isn't really aware of the semantics of the communication between the Host and the terminal 😭 So the OPE doesn't know when the Host is done transmitting and willing to pass "the turn" back to the terminal. Similarly, when the remote site gives up control, the OPE includes Go Ahead in its TR.

But we don't think this Go Ahead problem is an indictment of outboard processing πŸ’œ It just shows that functionality not found in a Host can't necessarily be provided by the OPE. So here's a note for the implementor: if the Host cannot generate the protocol-idiosyncratic Go Ahead parameter, then the DO Suppress Go Ahead must be issued immediately after the connection is established 🫢

2.2.2. Protocol Idiosyncratic Parameters

The protocol idiosyncratic parameter is the Go Ahead indicator πŸ¦‹ When it's present, the character "G" means the Go Ahead can be sent to the other end of the connection, but only after the data for that Transmit command has been sent. When the character is any other value, or is absent, the Go Ahead should not be sent πŸ™…β€β™€οΈ

2.2.3. Examples of the Command

Here's an example of the Transmit command πŸ“

   C TR -pi G <nl> <DATA>

With this command, the Go Ahead gets passed to the other side after the data is sent ✨

2.3. The Condition Command 🌈

The Condition command is used with Telnet to change the transmission characteristics and to enable or disable Telnet options on a Telnet connection πŸ’…

2.3.1. Specialized Usage

The Condition command has a specialized usage with Telnet, on top of its normal one πŸŽ€ It's used to control the option selection and negotiation process, when that selection is done by the Host. Right now that happens at mediation levels 5 and 1, but not at level 9 🧚

There's a set of protocol-idiosyncratic parameters defined for this, and they're based heavily on the Telnet negotiation and subnegotiation mechanisms πŸ’– For simple negotiations there are two parameters: a negotiation type (from the set {DO, DONT, WILL, WONT}), followed by the code (numeric) or name (symbolic) for the desired option. The option codes are listed below. The big difference between the H-FP interface to Telnet and the internal Telnet protocol is that extra parameters come along with the request (DO or WILL). The Telnet protocol subnegotiation is used internally to carry that info in the Telnet data stream, and option-specific, protocol-idiosyncratic parameters are used for those extra parameters 🌸

Both the Host and the OPE can issue these Condition commands 😭 When the Host issues one, it means the user wants to enable or disable a particular option. The OPE then issues the appropriate negotiation commands (i.e., IAC <DO> <code>) in the Telnet data stream. When the results of the option negotiation are available, the OPE generates a response. For the types DO and WILL, a 000 Response indicates the appropriate acceptance (WILL or DO, respectively). A nonzero Response code may indicate negotiation failure or negotiation rejection (among other things). For the types DONT and WONT, a 000 Response indicates the option will be disabled. A negotiation rejection should not be expected in those cases πŸ“

When the OPE issues the Condition command, it means the other end of the connection is negotiating a change πŸ‘‘ In that case the response from the Host tells you the Host's desired action for the option negotiation. Again, valid requests to disable options (DONT and WONT requests) should always get a 000 Response πŸ’€

2.3.2. Protocol-Idiosyncratic Parameters

There are two protocol-idiosyncratic parameters for primary negotiation using the Condition command πŸ¦‹ They're the negotiation type and the option code. The negotiation type is one of the set {DO, DONT, WILL, WONT}. The option code is a numeric value that identifies the option being negotiated. The values here match the codes used in the actual Telnet negotiation. The codes are:

   Option Name     Option Code       Short Name

   Transmit Binary           0       Binary
   Echo                      1       Echo
   Suppress Go-Ahead         3       SuppressGA
   Approximate Message Size  4       NAMS
   Status                    5       Status
   Timing Mark               6       TimingMark
   RCTE                      7       RCTE
   Line Length               8       LineLength
   Page Size                 9       PageSize
   Carriage Return Disp     10       CRDisp
   Horizontal Tabstops      11       HTabStops
   Horizontal Tab Disp      12       HTabDisp
   Formfeed Disposition     13       FFDisp
   Vertical Tabstops        14       VTabStops
   Vertical Tab Disposition 15       VTabDisp
   Linefeed Disposition     16       LFDisp
   Extended ASCII           17       ExASCII
   Logout                   18       Logout
   Data Entry Terminal      20       DET
   Terminal Type            24       TermType
   Extended options list   255       ExOptions

Okay bestie, so other options not listed here can totally be used too πŸ’… Just make sure the code number is the same as the option code used in Telnet negotiation, because that's how everyone stays on the same page 🫢

2.3.2.1. Simple Options ✨

Options that don't need any extra parameters use the simple negotiation mechanisms we covered briefly above, and you can get the full tea in the Telnet documentation πŸ“š No additional parameters are needed for these. The options in this group are Transmit Binary, Echo, Suppress Go Ahead, Status, Timing Mark, and Logout πŸ¦‹

2.3.2.2. Approximate Message Size Option πŸŽ€

The Approximate Message Size option takes two parameters πŸ’– The first one tells you whether the approximate message size being negotiated applies to the local end or the remote end of the connection. It uses DS and DR, and the way those work is kind of a vibe 🌈

DS means the size applies to the sender of the command. So if the Host issues the command, DS means the local end of the connection. If the OPE issues it, DS means the remote end.

DR means the size applies to the receiver of the command. So if the Host issues the command, DR means the remote end. If the OPE issues it, DR means the local end.

This convention matches the Telnet subnegotiation mechanisms, so it's giving consistency πŸ™Œ The second parameter is an ASCII encoded numeric value, and it's the character count of the message size πŸ”’

2.3.3. Line Width and Page Size Options πŸ“

The Line Width and Page Size options need two extra parameters 🌸 The first one says whether the line width or page size being negotiated applies to the local or remote end, and it uses the DS and DR convention we just talked about. The second parameter is an ASCII encoded numeric value, and it gets interpreted like this (assuming the Condition command was issued by the Host):

  • 0 means the Host requests that it handle the length or size considerations for the direction shown by the first parameter.
  • 1 to 253 means the Host requests that the remote end handle the size or length considerations for the direction shown by the first parameter. The Host also suggests that the value given be used as the size or length.
  • 254 means the Host requests that the remote end handle the size or length considerations for the direction shown by the first parameter. The Host suggests that the size or length be treated as infinity ♾️
  • 255 means the Host requests that the remote end handle the tabstop considerations, and it suggests nothing about what the value should be 🧚

If the Condition command is issued by the OPE, then the roles of the Host and the remote end flip πŸ”„

2.3.4. Tabstop Options πŸ“

The Horizontal and Vertical Tabstops options need two option-specific parameters πŸ’œ The first one is either DR or DS, like we covered before. The second one is a list of one or more ASCII encoded numeric values, separated by spaces. Assuming the Host issues the Condition command, each value gets interpreted individually like this:

  • 0 means the Host requests that it handle tabstops for the direction shown by the first parameter.
  • 1 to 250 means the Host requests that the remote end handle the tabstop considerations for the direction shown by the first parameter. The Host also suggests that the value or values given be used as the tabstops.
  • 255 means the Host requests that the remote end handle the tabstop considerations for the direction shown by the first parameter, and it suggests nothing about what the value should be πŸ€·β€β™€οΈ

If the Condition command is issued by the OPE, the roles of the Host and the remote end get reversed πŸ”

2.3.5. Character Disposition Options 🌷

The Carriage Return Disposition, Horizontal Tab Disposition, Formfeed Disposition, Vertical Tab Disposition, and Linefeed Disposition options are all character disposition options from the H-FP point of view πŸ‘‘ They need two option-specific parameters. The first one is the DR or DS code we talked about earlier. The second one is a single ASCII encoded numeric value, and assuming the Host issued the Condition command, it works like this:

  • 0 means the Host requests that it handle the character disposition for this connection.
  • 1 to 250 means the Host suggests that the remote end handle the character disposition considerations. The value given should be taken as the number of nulls to insert into the data stream after the particular format character being subnegotiated 🫧
  • 251 means the Host suggests that the remote end handle the character disposition considerations, and it recommends replacing the character with a simplified character that's similar to it but not identical. For example, replace a tab with a space, or a formfeed with a newline 🍬
  • 252 means the Host suggests that the remote end handle the character disposition considerations, and it recommends discarding the character πŸ—‘οΈ
  • 253 means the Host suggests that the remote end handle the character disposition, and it recommends simulating the effect of the character using other characters, such as spaces or linefeeds ✨
  • 254 means the Host suggests that the remote end handle the character disposition considerations, and it recommends waiting for additional data before sending more data ⏳
  • 255 means the Host suggests that the remote end handle the tabstop considerations, and it suggests nothing about what the value should be πŸ’…

Some of the codes between 251 and 254 aren't used with some character disposition options, so don't be shook 😭 For the details, check out the ARPANET documentation.

If the Condition command is issued by the OPE, the roles of the Host and the remote end get reversed πŸ”„

2.3.5.1. RCTE Option πŸ¦‹

The Remote Controlled Transmission and Echoing option needs parameters for its sets of break characters and transmit characters πŸ’– It has two option-idiosyncratic parameters. The first is a list of the character classes that make up the set of break characters, as defined in the RCTE documentation. The second is a list of character classes that make up the set of transmit characters, also as defined in the RCTE documentation. Because both classes are optional and can be any length, each list has to be preceded by -bc (break characters) or -tc (transmit characters) so nothing gets mixed up πŸŽ€ The character classes are:

1 Upper Case Letters   A through Z
2 Lower Case Letters   a through z
3 Digits  0 through 9
4 Format effectors  <BS> <CR> <LF> <FF> <HT> <VT>
5 Non-format control codes, plus <ESC> and <DEL>
6 Punctuation  . , ; : ? !
7 Grouping    { [ ( < > ) ] }
8 Misc  ' ` " / \ % @ $ &   + - * = ^ _ | ~
9 <space>

2.3.5.2. Extended Option List 🧚

The Extended Option List option needs a parameter that carries the number of the option on the extended list 🌈 So when it's used for this, there's exactly one option-specific parameter for the Condition command, and it's the number of the option on the extended option list. That number can be written in ASCII using octal, decimal, or hexadecimal format πŸ”’

2.3.5.3. Terminal Extension Options 🌸

The Extended ASCII, SUPDUP, and Data Entry Terminal options of Telnet were all trying to level up the basic Telnet data stream beyond the simple, scroll mode terminal model it was originally built on πŸ“Ί

Honestly, all of these have limitations 😭 Extended ASCII doesn't have a standardized interpretation of the bit patterns into extended ASCII characters. SUPDUP was actually an independent mode where a totally different virtual terminal protocol got used, and the option just existed to switch to and from that protocol. Data Entry Terminal needs excessive overhead of subnegotiation for every use of extended features. And none of them have the big win of widespread implementation and use πŸ’€

This appendix doesn't go into detail on how these options should be handled. What's clear is that the Condition command could be used to start and stop using these options. The actual sending of characters related to the extended terminal features should be handled by the Transmit command, either as part of the normal Host-to-OPE data stream or by using protocol-idiosyncratic parameters 🫢

Then there's the Terminal Type option, which is newer and definitely worth a mention πŸ’œ It lets one end of a connection ask for information about the terminal at the other end, or send information about the terminal at the local end. That's super convenient for systems that support a wide variety of terminals, but it clearly doesn't follow the model of reducing the MxN problem with a virtual terminal πŸ™ˆ In the H-FP context, though, it's pretty straightforward to use. You only need to send the terminal type to the other end and activate the Binary Transmission Option, and you're good to go ✨

2.3.5.4. Status Option ✨

The Status option gets turned on through Telnet's normal negotiation mechanism πŸ’…. But the actual status info moves between the OPE and the Host through the Status command 🧚. So the details of status negotiation don't matter to the interface with the outboard Telnet 🌸.

2.3.6. Examples of the Command ✨

Here's a super clear example of the Host telling the OPE to negotiate with the other side so that remote echo happens πŸŽ€:

C CO -pi DO 1 <nl>

The 1 is the option code for ECHO from the table above πŸ¦‹. Every simple option up there uses this exact same basic format, so once you get this one, you've got them all πŸ’–.

The options with extra parameters are just straightforward extensions of that syntax 🌈. For example, the Host could use Condition to set the approximate message size like this πŸ‘‘:

C CO -pi DO 4 DS 1024

The 4 is the Option Code for the Approximate Message Size option ✨. The DS says the Host's message size should be set πŸ’…, and 1024 is the size they want πŸ“.

2.4. The Signal Command πŸ”₯

The Signal command is how Telnet gets its Interrupt Process and Abort Output services πŸ¦‹.

2.4.1. Specialized Usage πŸ’œ

The Signal command works with an outboard Telnet interpreter to connect to the Telnet synch mechanism 🫢. This mechanism takes a protocol-idiosyncratic parameter that says which command is being "synched" 🌸. Normally, this Signal mechanism is only going to be used with the Interrupt Process and Abort Output Telnet signals πŸ’…. When the Host issues the Signal command, it goes through the Channel (out-of-band) to the OPE πŸš€. The Telnet interpreter there then issues the matching Telnet signal and synch sequence πŸŽ€. And when the OPE gets one of those sequences, it immediately sends a Signal back to the Host ✨. A Host or OPE generally wouldn't reject a Signal command unless it's badly formed πŸ™ˆ.

2.4.2. Protocol-Idiosyncratic Parameters 🌈

The Telnet protocol-idiosyncratic parameter for the Signal command tells you which Telnet signal is being issued πŸ’–. Usually it's either "IP" or "AO", meaning Interrupt Process or Abort Output πŸ“. If it's left out, the default is "IP" πŸ¦‹.

2.4.3. Examples of the Command 🧚

Here's an example of a Telnet Signal Command, this time sending an Interrupt Process signal πŸ’…:

C SI IP <nl>

2.5. The Status Command πŸ’œ

The Status command is how Telnet gets info about the Telnet connection and which options are in effect πŸ‘‘.

2.5.1. Specialized Usage ✨

The Status command has one special thing it does when it's talking to an outboard Telnet interpreter 🌸. It sends and receives the Telnet Protocol status request subnegotiation message to and from the data stream 🫢. But before you can invoke the status command for this, the user has to have already issued the Condition Status command, since that's what gets the ability to request status negotiated πŸ”₯. When the OPE gets a valid Status request command, it immediately responds to the user with the status πŸ’…. The OPE can also issue a status to ask for the Host's negotiated positions πŸ¦‹.

2.5.2. Protocol-Idiosyncratic Parameters 🌈

The Status query command has no protocol-idiosyncratic parameters, bestie πŸ™Œ. The Status Response command has exactly one πŸ’–. It's an ASCII string with the status of the various options, but only the ones that aren't at their default values πŸ“.

2.5.3. Examples of the Command πŸŽ€

Here's an example of a Status Query command πŸ’…:

C ST Q

And here's an example of a Status Response command 😭:

F ST R "WILL ECHO  DO SUPPRESS-GO-AHEAD
L WILL STATUS  DO STATUS" <nl>

Look at this one, it's so iconic 🧚. The opening quote is in the first chunk, and the closing quote is in the last chunk 🫢. That's how parameters get to span chunk boundaries 🌈.

2.6. The End Command πŸ¦‹

The End command is used to end the Telnet connection, either gracefully or abruptly πŸ’”.

2.6.1. Specialized Usage πŸ’œ

Ending a Telnet connection gracefully takes End commands from both the Host and the OPE πŸ‘‘. But this specialized usage is exactly the same as the one for the outboard TCP interface, so nothing new here ✨.

2.6.2. Examples of the Command 🌸

Here's the graceful End command 🫢:

C EN G <nl>

The abrupt End command looks pretty much the same πŸ’….

2.7. The No-op Command ✨

The No-op command is how the Host figures out if the OPE is active, and the other way around too πŸ‘€.

2.7.1. Specialized Usage πŸ”₯

The No-op command has one specialized use when offloading Telnet πŸŽ€. It provides the Telnet Are You There (AYT) feature πŸ¦‹. When the OPE gets an (AYT) message, it issues a No-op command to the Host πŸš€. Once it gets the Host's response, it sends the appropriate response back in the data stream πŸ’–.

2.7.2. Protocol Idiosyncratic Parameters 🌈

The No-op command has no protocol-idiosyncratic parameters πŸ™ˆ.

2.7.3. Examples of the Command πŸ’…

Here's an example of the No-op command πŸ“:

C NO <nl>

3. FTP Offloading 🧚

TBS 🌸

4. Mail Offloading πŸ’Œ

TBS 🫢

5. Whatever Offloading 🌈

TBS πŸ’œ

TBS nominally means To Be Supplied, but really it means: we'll argue through these once we get enough positive feedback on the others (and on the H-FP as a whole) πŸ˜­πŸ’…

πŸ“¦ where this page comes from