[http://www.cs.mcgill.ca/~nwilli/n05]

308-537B		Internet Programming				n05

		  Login and File Transfer Protocols

Rlogin	(port 513, rfc 1282, WRS 26)	Remote login			47 l.

Rlogin is newer and simpler than telnet, and is restricted to login between
UNIX hosts. RFC 1282, by B. Kantor, is dated 1991.

Because rlogin sends and receives non-ascii characters across the socket, we
cannot use telnet to port 513, but must write a (Java) program to show the
exchanges. Here is the dialog that initiates the application.

c "\0"				sends 0 byte
c "tim\0tim\0xterm/9600\0"	three strings each terminated with 0 byte:
				- user client login name
				- user server login name
				- user terminal type and user terminal speed
s "\0"				null string

From here, the exchange might continue, except for further subtleties.
s 0x80				request window size
c 0xffff737300180050244014aA	window size is 24*80 chars, 580*330 pixels
s <UNIX greeting...>
d <client commands/UNIX & application responses>
c logout	OR user gives client "~." or "~^D", in which case client closes

The first further subtlety is that the server commands (0x80 is one of four)
are sent in TCP "urgent" mode, which requires setting a bit in the TCP header.
This is too low level for Java and for us.

Urgent mode is not really needed for the server command to request the window
size, but it is needed for one other command, so the server uses urgent mode
for all four of its commands. The command that needs urgent mode is 0x02,
"flush output". The server sends this as an acknowledgement of an interrupt
character (^C or ^?) sent by the client. The client passes this from the user,
following a ^Q from the user to stop the screen display: ^Q is not passed to
the server, but the interrupt is. The way the client stops the data flow is by
advertizing a window size of 0. For the server to get any instructions through
to the client in this circumstance, it must alert the client that an instruction
is coming, hence the urgent mode.

One of the things that the client should implement is supression of the echoing
of user input to the screen when (if) the server requests a password. Rlogin
still transmits the password in cleartext. Password transmission can be
avoided by using .rhosts files, but this is even less secure.

One of the things the server must do is pass all the commands it receives to the
login shell. Java can do this with the Runtime class.


Telnet	(port 23, rfc 854,855, WRS 26)					346 l.
Much earlier than rlogin (RFC 854 was written by Jonathan Postel and Joyce
Reynolds in 1983), telnet was conceived as a universal terminal emulator and
connection between arbitrary systems, not just UNIX systems. It did this by
defining a minimal canonical "terminal", the Network Virtual Terminal (NVT)
which must be supported by any system using telnet.

The NVT is a bi-directional terminal (with both "keyboard" and "printer")
which
 - operates in half-duplex mode: data cannot be sent both ways simultaneously
   (full-duplex), but the receiver must wait until the sender is finished
   and sends a go-ahead (GA);
 - is line-buffered: data is collected in a buffer and sent a line at a time,
   to reduce exchanges across the network;
 - does echoing locally: data is not echoed across the network, saving further
   traffic;
 - supports US-ASCII 32--126 plus specials (NUL (0) noop, LF (10), CR (13);
   BEL (7), BS (8), HT (9), VT (11), FF (12)).
Conceptually, there is an NVT at each end of the line. (This symmetry means
that telnet can be used as a protocol between terminals (linking) or between
processes (distributed computation). We will see that client and server are
treated symmetrically by telnet as a rule, although there are instances where
the client is intended to be a terminal and symmetry is not supported.)

NVT also supports seven control "keys" beyond the US-ASCII 128. (If the system
supporting the NVT on one side has no corresponding function, a key may be
undefined.)
  IP (interrupt process)
  AO (abort output) perhaps until next CRLF and prompt: don't IP
  AYT (are you there?) there may have been a lull in the exchange
  EC (erase character)
  EL (erase line)
  BRK (break) defined differently by different systems, e.g., attn
  DM (data mark) to support Synch.
Synch serves as a non-local break and is delivered by TCP urgent mode. It might
be used to convey a user-defined "out-of-band" symbol, say STOP:
	IP; Synch (i.e., DM in urgent mode); STOP; DM

Most current terminals and server hosts support features well beyond this
minimal design for the NVT. The designers of telnet anticipated this, and
future extensions generally, by providing a facility to negotiate more
advanced capablities on both sides.

As we have seen, telnet serves many roles. We have seen it act as client to
other servers by using their port numbers. We have seen it in login mode, by
specifying its own port, 23, or no port at all. The basic mode has no arguments.
Here is an example.

u  telnet
d  telnet> toggle options
t  Will show option processing.
d  telnet> open opus
t  Trying 132.206.3.77...
t  Connected to opus.cs.mcgill.ca.
t  Escape character is '^]'.		    see line
 1 SENT DO SUPPRESS GO AHEAD			17
 2 SENT WILL TERMINAL TYPE			10,23,24
 3 SENT WILL NAWS				11,12
 4 SENT WILL TSPEED				18
 5 SENT WILL LFLOW				19
 6 SENT WILL LINEMODE				20
 7 SENT WILL ENVIRON				16,27,28
 8 SENT DO STATUS				21
 9 SENT WILL XDISPLOC				13,25,26
10 RCVD DO TERMINAL TYPE
11 RCVD DO NAWS
12 SENT IAC SB NAWS 0 80 (80) 0 24 (24)
13 RCVD DO XDISPLOC
14 RCVD DO 39					15,22
15 SENT WONT 39
16 RCVD DO ENVIRON
17 RCVD WILL SUPPRESS GO AHEAD
18 RCVD DONT TSPEED
19 RCVD DONT LFLOW
20 RCVD DONT LINEMODE
21 RCVD WONT STATUS
22 RCVD DONT 39
23 RCVD IAC SB TERMINAL-TYPE SEND
24 SENT IAC SB TERMINAL-TYPE IS "XTERM"
25 RCVD IAC SB X-DISPLAY-LOCATION SEND
26 SENT IAC SB X-DISPLAY-LOCATION IS "farley:0.0"
27 RCVD IAC SB ENVIRON SEND 
28 SENT IAC SB ENVIRON IS VAR "DISPLAY" VALUE "farley:0.0"
			  VAR "PRINTER" VALUE "hpp"


o  SunOS 5.6

29 RCVD WILL ECHO				30,31,32,33
30 SENT DO ECHO
31 RCVD DO ECHO					kludge to find age of host
32 SENT WONT ECHO				client is later 4.2BSD:urgent OK
33 login: RCVD DONT ECHO
u  tim
d  Password: 
o  Last login: Wed Feb  2 15:33:56 from hfarley.CS.McGil
o  Sun Microsystems Inc.   SunOS 5.6       Generic August 1997
o  You have new mail.
o  Terminal type is unknown
o  Wednesday February  2 15:36:13 EST 2000
o  opus% 

The bulk of this example is the option negotiation, which we forced telnet to
reveal by the command  toggle options . Before we look at this, we note a few
of the basic commands telnet can respond to.

 open [-l user] [-a] host-name [port]	connects to host-name
 close					closes the connection
 logout					forcibly logs out the user and closes
 help					(or ?) helps with commands
 quit					quit telnet

We also used  toggle . Along with  set  and  unset , this allows the variables
that control telnet to be changed (archie evidently got its ideas here).
Finally,  send  allows the keyboard user of telnet to send all of the seven
special keypresses across the network, plus some others.

Option negotiation to extend these services is symmetrical: either end may send
offers, refusals, or requests using the commands WILL, WONT, DO, or DONT.
 WILL is offer to begin performing;	 DO (DONT) is +ve (-ve) acknowledgment
 WONT is refusal to continue to perform; DONT is required response
 DO is request to begin performing;	 WILL (WONT) is +ve (-ve) acknowledgment
 DONT is request to stop performing;	 WONT is required response
Only one response is allowed for WONT and DONT because the NVT is the minimum
configuration presumed, and neither end should be able to insist on a higher
level of service. It follows from this that, for all the options defined, WONT
and DONT are the defaults.

This option negotiation is very active at initial connect, but not restricted to
then. We look at the dialogs that took place in the example above.

- Since half-duplex requires go-ahead signals but TCP is full-duplex and is
fully supported by the client, the client asks the server to suppress the
go-ahead, and the server agrees. (RFC 858)
	 1 SENT DO SUPPRESS GO AHEAD
	17 RCVD WILL SUPPRESS GO AHEAD
- The client is able to do all character processing, including backspace, erase
line (EL), etc., and has a line buffer, so it offers to send whole, edited,
lines to the server, but the server refuses. (RFC 1184)
	 6 SENT WILL LINEMODE
	20 RCVD DONT LINEMODE
So we are in character-at-a-time mode, which is rather expensive. WRS (p.412)
compares linemode (with telnet) and character mode (as used by rlogin) for the
 date  command: character mode sends seven times as many bytes across the
connection as linemode.
		  line		character
		86 bytes	611 bytes
The server initiates an option right at the end, offering to do the echoing
of what the user types at the client. This means that the terminal does not
have to print characters as they are typed on its keyboard, but needs only
to print what it receives from the server. The client accepts this proposal.
	29 RCVD WILL ECHO
	30 SENT DO ECHO

Although these three negotiations are spread over the the whole exchange, we
discuss them first because they are related. RFC 858 says (quoted by RFC 1184)
      "In many TELNET implementations it will be desirable to couple the
      SUPRESS-GO-AHEAD option to the echo option so that when the echo
      option is in effect, the SUPPRESS-GO-AHEAD option is in effect
      simultaneously: both of these options will normally have to be in
      effect simultaneously to effect what it commonly understood to be
      character at a time echoing by the remote computer."
The reverse reading of this is often interpreted by telnet implementors to
mean that _without_ both of these options, we are in linemode. WRS (p.405)
calls this "line at a time" or "kludge line mode", and gives an example in
which _both_ options are turned off. RFC 1184 points out that some
implementations of this kludge line mode will include the editing characters
in the buffer, and send them, too, rather than doing the editing locally.)

This does not apply to our example: both are turned on. (Note: _suppress_
go-ahead is turned on, not go-ahead.)

Returning to the ECHO negotiation, something strange now happens in our example.
Although the server has offered, and the client accepted the offer, to echo, the
server now asks the client to echo, which the client refuses. The server thus
responds to the WONT with a mandatory DONT, because it is changing status.
	31 RCVD DO ECHO
	32 SENT WONT ECHO
	33 RCVD DONT ECHO
Of course, the client has replied properly: if the client were to echo as well
as the server (which was already agreed), there would be an endless loop of
echoes. But why did the server try to get the client to echo? According to WRS
(p.409), this is another kludge. The server does this for a reason unrelated to
echo but to find out if the client supports the telnet urgent mode correctly:
a client which responds WILL ECHO is probably old and does not support urgent
mode. (So if we want to fake a telnet client in Java, we should get it to
respond WILL ECHO at this point, then we do not have to worry about setting
urgent bits in the TCP headers.)

There are some further simple exchanges in our example. Each is initiated by
the client and rejected by the server. The client offers to tell its terminal
speed (RFC 1079).
	 4 SENT WILL TSPEED
	18 RCVD DONT TSPEED
The client is willing to local flow control, if the server asks it to process
the ^S and ^Q commands (cf. 0x10 and 0x20 in rlogin). (RFC 1372)
	 5 SENT WILL LFLOW
	19 RCVD DONT LFLOW
The client asks the server for the server's understanding of telnet status
(e.g., WILL ECHO, DO SUPPRESS-GO-AHEAD, etc.). (RFC 859)
	 8 SENT DO STATUS
	21 RCVD WONT STATUS

Four more complicated exchanges illustrate suboption negotiation. Clearly only
very few negotiations can be completed with just WILL WONT DO DONT. The telnet
designers extended these with suboptions, bracketed by SB..SE (suboption begin,
suboption end). The first example involves the terminal type. The client
volunteers this information and a couple of exchanges are needed before it can
send it. Note that the server must ask explicitly. (RFC 1091)
	 2 SENT WILL TERMINAL TYPE
	10 RCVD DO TERMINAL TYPE
	23 RCVD IAC SB TERMINAL-TYPE SEND IAC SE
	24 SENT IAC SB TERMINAL-TYPE IS "XTERM" IAC SE
We will mention IAC later. The SEND and IS subcommands are often part of the
list following SB. (The SE is supposed to be there: it may have been removed
before the display.)
(RFC 1408)
	 7 SENT WILL ENVIRON
	16 RCVD DO ENVIRON
	27 RCVD IAC SB ENVIRON SEND IAC SE 
	28 SENT IAC SB ENVIRON IS VAR "DISPLAY" VALUE "farley:0.0"
				  VAR "PRINTER" VALUE "hpp" IAC SE
(The line break in 28 was not in the message.)
(RFC 1096)
	 9 SENT WILL XDISPLOC
	13 RCVD DO XDISPLOC
	25 RCVD IAC SB X-DISPLAY-LOCATION SEND IAC SE
	26 SENT IAC SB X-DISPLAY-LOCATION IS "farley:0.0" IAC SE

A shorter exchange suffices to Negotiate About Window Size. The client does not
wait after the server's DO, and announces an 80 by 24 character window. We can
see why later: the client must be able to send a new window size spontaneously.
(RFC 1073)
	 3 SENT WILL NAWS
	11 RCVD DO NAWS
	12 SENT IAC SB NAWS 0 80 0 24 IAC SE
(The (80) and (24) are not in the message.)

Finally, the server initiates a request for 39, whatever that is, which the
client refuses, so the server replies with mandatory DONT.
	14 RCVD DO 39
	15 SENT WONT 39
	22 RCVD DONT 39

We notice two different behaviours when DO is the initial request. For ECHO
and 39, the sequence was DO, WONT, DONT. For STATUS, it was just DO, WONT.
Telnet has rules to avoid an endless loop of requests and acknowledgments.
Here are the relevant two.
  a) Req is only to change option status: never use to announce your mode.
  b) Ack is only if status changed: never ack if you're already there.

All the negotations shown in the above example occurred at the beginning of
the telnet session. Later negotiations can take place. For example, if the
client resizes heir window, a new NAWS will happen.
	[change window size]
	opus% SENT IAC SB NAWS 0 80 (80) 0 25 (25)

An admirable aspect of telnet is that it was designed both to work immediately
with 1983 technology and to go on working with unforseeable advances. The
options and suboptions were designed to be open-ended, so that telnet could
take advantage of the latest capabilities and not have to be replaced at great
expense to a large installed base of software. We can see that the basic options
were laid down in 1983 (TRANSMIT-BINARY, ECHO, SUPPRESS-GO-AHEAD, STATUS, etc.),
and that further options keep on being added (NAWS, TERMINAL-SPEED, LFLOW in
1988, TERMINAL-TYPE, XDISPLOC in 1989, LINEMODE in 1990, ENVIRON in 1993,..).

We must now talk about the format of telnet commands. They must fit into the
data stream across the telnet port, and yet not get confused with user data
when it is transferred. Clearly, the simple commands (such as IP, AO, AYT, EC,
EL, BRK, DM) need only occupy one byte, the option commands (WILL, WONT, DO,
DONT followed by ECHO, NAWS, etc.) can be encoded in two, and the subotion
commands require a variable number of bytes (e.g., SB NAWS <parameters> SE).
These bytes can also all have their high bit set, by having values >127, to
reduce the chance of collisions with ordinary data. However, telnet can
transmit binary data (the TRANSMIT-BINARY option), so the commands are not yet
entirely safe.

The solution is to have a meta-command, byte 0xff (255), precede every command.
This is called IAC, interpret-as-command, and we have seen it in the examples
above. In fact, IAC is used before every command, although we did not show it
everywhere above. This means that telnet commands are 2, 3, and more bytes long,
including the IAC prefix.

So a more complete transcript of the session above would start
 1 SENT IAC DO SUPPRESS GO AHEAD
 2 SENT IAC WILL TERMINAL TYPE
 3 SENT IAC WILL NAWS
and so on. Every command is so prefixed.

The commands are now safe from confusion with data, except .. what if the data
contains a 0xff byte? Telnet must inspect the data and "quote" any such byte
by doubling it before transmission, then unquote double bytes by removing one.

Here are the codes for the telnet commands (RFC 1060, WRS p.402).

      NAME               CODE              MEANING
       EOF		  236	 End-of-file
       SUSP		  237	 Suspend current process (job control)
       ABORT		  238	 Abort process
       EOR		  239	 End of record
       SE                 240    End of subnegotiation parameters.
       NOP                241    No operation.
       Data Mark          242    The data stream portion of a Synch.
                                 This should always be accompanied
                                 by a TCP Urgent notification.
       Break              243    NVT character BRK.
       Interrupt Process  244    The function IP.
       Abort output       245    The function AO.
       Are You There      246    The function AYT.
       Erase character    247    The function EC.
       Erase Line         248    The function EL.
       Go ahead           249    The GA signal.
       SB                 250    Indicates that what follows is
                                 subnegotiation of the indicated option.
       WILL (option code) 251    Indicates the desire to begin performing, or
				 confirmation that you are now performing, the
                                 indicated option.
       WONT (option code) 252    Indicates the refusal to perform, or continue
				 performing, the indicated option.
       DO (option code)   253    Indicates the request that the other party
				 perform, or confirmation that you are expecting
                                 the other party to perform, the indicated
				 option.
       DONT (option code) 254    Indicates the demand that the other party stop
				 performing, or confirmation that you are no
                                 longer expecting the other party to perform,
				 the indicated option.
       IAC                255    Data Byte 255.

The suboptions can also be encoded, one byte per symbol. (RFC 1060, WRS p. 403)
 			Option			RFC
			 0 transmit binary	 856
 			 1 echo			 857
  			 3 suppress go ahead	 858
			 5 status		 859
			 6 timing mark		 860
			24 terminal type	1091
			31 window size		1073
			32 terminal speed	1079
			33 remote flow control	1372
			34 linemode		1184
			35 X display location	1096
			36 environment varbles	1408


FTP	(port 20,21, rfc 959, WRS 27)	File Transfer Protocol		302 l.

Jon Postel and Joyce Reynolds wrote RFC 959 in 1985. Like telnet, ftp is
intended to work between different hosts and operating systems. It is meant
specifically to transfer files either way across a connection. It allows any
data to be transferred, not just telnet's NVT ASCII. It does this by operating
_two_ TCP channels instead of just one: one for commands, which is always open
during a session; and one for data in any format.

Here is a sample session, using the UNIX ftp client with the debug option turned
on to show the ftp commands sent by the client (prefixed "--->") as well as the
responses of the server (prefixed with 3-digit reply codes, like SMTP: these are
normally displayed).

(The session downloads the Internet Official Protocol Standards RFC, 2500
(which summarizes the current protocol standards, WRS p.15) and then starts to
download the Host Requirements RFC, 1122 (review of and corrections to earlier
important RFCs), but I aborted the transfer when I saw how big the file is. I
then listed the parent directory before quitting.

u ftp -d NIS.NSF.NET
f Connected to NIS.NSF.NET.
f 220 nic.merit.edu FTP server (Version wu-2.6.0(1) Wed Oct 20 16:53:27 EDT 1999) 
d Name (NIS.NSF.NET:tim): anonymous
f ---> USER anonymous
f 331 Guest login ok, send your complete e-mail address as password.
d Password: tim@cs.mcgill.ca					      not echoed
f ---> PASS XXXX
f 230-
f 230-   NOTICE: This system is operated by the Merit Network, Inc.
f 230-   You must follow the Merit Acceptable Use Policy described in
f 230-   /michnet/policies/acceptable.use.policy.
f 230-
f 230-   The local time is Mon Feb  7 15:01:15 2000.
f 230-   You are user 10 out of a maximum of 100 users.
f 230-
f 230 Guest login ok, access restrictions apply.
f ---> SYST
f 215 UNIX Type: L8
f Remote system type is UNIX.
f Using binary mode to transfer files.
d ftp> cd /internet/documents/rfc
f ---> CWD /internet/documents/rfc
f 250 CWD command successful.
d ftp> get rfc2500.txt
f ---> TYPE I
f 200 Type set to I.
f ftp: setsockopt (ignored): Operation not permitted
f ---> PORT 132,206,54,134,7,158                                hfarley:1950
f 200 PORT command successful.
f ---> RETR rfc2500.txt
f 150 Opening BINARY mode data connection for rfc2500.txt (78845 bytes).
f 226 Transfer complete.
f 78845 bytes received in 15.9 secs (4.8 Kbytes/sec)
f ftp> get rfc1122.txt
d ftp: setsockopt (ignored): Operation not permitted
f ---> PORT 132,206,54,134,7,160				hfarley:1952
f 200 PORT command successful.
f ---> RETR rfc1122.txt
f 150 Opening BINARY mode data connection for rfc1122.txt (291327 bytes).
                                                                        ^C
f receive aborted
f waiting for remote to finish abort
f 426 Transfer aborted. Data connection closed.
f 226 Abort successful
f 16384 bytes received in 2.55 secs (6.3 Kbytes/sec)
d ftp> put rfc0959.txt
f ---> TYPE I
f 200 Type set to I.
f ftp: setsockopt (ignored): Operation not permitted
f ---> PORT 132,206,54,134,4,38					hfarley:1062
f 200 PORT command successful.
f ---> STOR rfc0959.txt
f 553 rfc0959.txt: Permission denied on server. (Upload)
d ftp> cdup
f ---> CDUP
f 250 CWD command successful.
d ftp> pwd
f ---> PWD
f 257 "/internet/documents" is current directory.
d ftp> ls
f ---> TYPE A
f 200 Type set to A.
f ftp: setsockopt (ignored): Operation not permitted
f ---> PORT 132,206,54,134,7,168				hfarley:1960
f 200 PORT command successful.
f ---> LIST
f 150 Opening ASCII mode data connection for /bin/ls.
f total 332
f -rw-r--r--   1 218      merit        2471 May 29  1998 INDEX.documents
f drwxr-xr-x   3 218      merit        4096 Dec 16 13:22 bcp
f drwxr-xr-x   3 218      merit        4096 Nov  4 17:45 fyi
f drwxr-xr-x   3 224      ietf         8192 Feb  7 05:47 iesg
f drwxr-xr-x 186 224      ietf        18432 Feb  7 05:49 ietf
f -rw-r--r--   1 8819     20           2927 Nov 10 17:21 index.html
f drwxr-xr-x   2 224      ietf       221184 Feb  7 05:50 internet-drafts
f drwxr-xr-x   3 218      merit       71680 Feb  5 18:39 rfc
f drwxr-xr-x   3 218      merit        6144 Jun  3  1999 std
f 226 Transfer complete.
d ftp> bye
f ---> QUIT
f 221-You have transferred 539482 bytes in 5 files.
f 221-Total traffic for this session was 542050 bytes in 6 transfers.
f 221-Thank you for using the FTP service on nic.merit.edu.
f 221 Goodbye.

This session illustrates a number of the central aspects of the ftp protocol.
First we see that each time we do a  get  or an  ls , ftp issues a PORT command
to tell the server how to open a data connection. This second channel (in
addition to the command channel which remains open) is created by the client and
actively opened by the server.

The PORT command does this, followed by six bytes for IP address (4 bytes) and
port number (2 bytes, high-order first). This channel is closed by the sender
when "Transfer complete". (In fact, closing the socket signals EOF for ascii
data.) Notice that the ports the client has created for data are numbers 1950,
1952, 1062, and 1960 in this example: not only is this not one single port, but
also it is not the port, 20, that the server always uses. This illustrates a
channel connecting to different ports at either end. (A Java server would use
	Socket t= new Socket("hfarley", 1950, hostIP, 20);
where 	hostIP= InetAddress.getLocalHost();)

The client then issues a RETR (for get) or a LIST (for ls) to download the data.
RETR causes ftp to go into binary mode (type I: image) and fetch the remote file
to a local file of the same name (overriding any existing file of that name).
LIST causes it to go into ascii mode (type A) and display the remote directory
listing on the local terminal. There is also a STOR command ( put  in the ftp
user interface) which transfers data from client to server: anonymous ftp will
not permit this.

(The default transfer mode is type A, but in this case the server told the
client, in response to the SYST query, that it, too runs UNIX, so type I is
used.)

A transfer may be aborted by the user typing the interrupt key (in this case,
^C). The ftp client sends the telnet interrupt, IAC IP, followed by the telnet
synch signal in urgent mode, IAC DM, followed by the ftp comand ABOR (not shown)
and <CRLF>, \r\n. If the server is equipped to detect this, it stops the
transfer after clearing its buffer queue.

We can change directory: CWD and its special case CDUP.

Notice that, after the USER and PASS commands to establish the user, the client
issues SYST to determine the operating system of the server. The reply, "UNIX
Type: L8", tells any client also running on a UNIX system with 8 bits per byte
to use just <LF> (\n) instead of the telnet <CRLF> (\r\n) to terminate lines:
this saves both sides from inspecting every character in ascii mode transfers
to translate from \n to \r\n and back again.

We have seen 12 of basic ftp's 33 commands, plus ABOR.
	USER <name>
	PASS <passwd>
	SYST
	CWD <directory path>
	CDUP
	TYPE A | I
	PORT n1,n2,n3,n4,n5,n6		IP n1.n2.n3.n4	port n5*256 + n6
	RETR <file>
	STOR <file>
	PWD
	LIST
	ABOR
	QUIT

We have seen two of ftp's four possible
 - file types (ASCII, image, EBCDIC, local),		TYPE	A | I | E | 
one of the three possible
 - format controls (nonprint, telnet, FORTRAN),			N | T | C
one of three possible
 - structures (file, record, page),			STRU	F | R
and one of three possible
 -transmission modes (stream, block, compressed).	MODE	S | B | C
Of the 72 different possibilities arising, the two possible combinations we
have seen are the usual ones. On UNIX systems, they are the only ones. In any
case, page structures and compressed transmission are discouraged. (There are
better ways to compress than run-length encoding, which is the specified
compression method.)

We can use telnet to mimic only part of an ftp session, since two channels must
be open at once. Here is a way of running a Java program in background to deal
with the data channel, while telnet can be used for the communications channel.
Here is the session. We show the Java program for the data connection at the
end. (Note that this program does not fully imitate the FTP data connection:
it sets up only one port and reuses is, whereas FTP (because of reasons deep
inside TCP), uses a different port for every connection.)

u java FTPdataConn &
j use PORT 132,206,54,134,5,56

u telnet NIS.NSF.NET 21
t Trying 198.108.1.48...
t Connected to NIS.NSF.NET.
t Escape character is '^]'.
f 220 nic.merit.edu FTP server (Version wu-2.6.0(1) Wed Oct 20 16:53:27 EDT 1999) ready.
u USER anonymous
f 331 Guest login ok, send your complete e-mail address as password.
u PASS tim@cs.mcgill.ca
f 230-
f 230-   NOTICE: This system is operated by the Merit Network, Inc.
f 230-   You must follow the Merit Acceptable Use Policy described in
f 230-   /michnet/policies/acceptable.use.policy.
f 230-
f 230-   The local time is Mon Feb  7 19:00:28 2000.
f 230-   You are user 5 out of a maximum of 100 users.
f 230-
f 230 Guest login ok, access restrictions apply.
u SYST
f 215 UNIX Type: L8
u CWD /internet/documents/rfc
f 250 CWD command successful.
u CDUP
f 250 CWD command successful.
u TYPE A
f 200 Type set to A.
u PORT 132,206,54,134,5,56
f 200 PORT command successful.
u LIST              
j data connection established by ftp server
f 150 Opening ASCII mode data connection for /bin/ls.
f total 332
f -rw-r--r--   1 218      merit        2471 May 29  1998 INDEX.documents
f drwxr-xr-x   3 218      merit        4096 Dec 16 13:22 bcp
f drwxr-xr-x   3 218      merit        4096 Nov  4 17:45 fyi
f drwxr-xr-x   3 224      ietf         8192 Feb  7 05:47 iesg
f drwxr-xr-x 186 224      ietf        18432 Feb  7 05:49 ietf
f -rw-r--r--   1 8819     20           2927 Nov 10 17:21 index.html
f drwxr-xr-x   2 224      ietf       221184 Feb  7 05:50 internet-drafts
f drwxr-xr-x   3 218      merit       71680 Feb  5 18:39 rfc
f drwxr-xr-x   3 218      merit        6144 Jun  3  1999 std
f 226 Transfer complete.
u CDUP
f 250 CWD command successful.
u PORT 132,206,54,134,5,56
f 200 PORT command successful.
u LIST
j data connection established by ftp server
f 150 Opening ASCII mode data connection for /bin/ls.
f total 17
f -rw-r--r--   1 218      merit        4542 Jun  1  1998 INDEX.internet
f drwxr-sr-x   3 218      merit        2048 Nov 10 12:03 connectivity
f drwxr-xr-x   9 root     system       2048 Nov  4 17:52 documents
f drwxr-sr-x   3 218      merit        2048 Dec 16  1996 newsletters
f drwxr-sr-x   8 218      merit        2048 Dec  9  1996 nren
f drwxr-sr-x   3 218      merit        2048 Jul 28  1998 providers
f drwxr-sr-x   3 218      merit        2048 Jul 29  1998 routing.policies
f 226 Transfer complete.
u QUIT
f 221-You have transferred 0 bytes in 0 files.
f 221-Total traffic for this session was 2099 bytes in 2 transfers.
f 221-Thank you for using the FTP service on nic.merit.edu.
f 221 Goodbye.
t Connection closed by foreign host.


// Data connection handler for ftp
// This handles only RETR TYPE A data
// Usage java FTPdataConn [> outputfile]
// Run it concurrently with a telnet or other session to do control connection
import java.io.*;
import java.net.*;
class FTPdataConn
{ public static void main(String[] args)
  { try
    { ServerSocket dataServer= new ServerSocket(0);	// port unspecified
      int thisPort= dataServer.getLocalPort();		// get any free port
      byte[] thisIPaddress= new byte[4];
      thisIPaddress= InetAddress.getLocalHost().getAddress();	// farley
      System.err.println("use PORT " + (thisIPaddress[0]& 0xff) +","
	+ (thisIPaddress[1]& 0xff) +"," + (thisIPaddress[2]& 0xff) +","
	+ (thisIPaddress[3]& 0xff) +","			// mask eff. adds 256
	+ (thisPort>>8) + "," + (thisPort & 0xff));
	// PORT command for telnet session running concurrently
      while(true)
      { Socket dataSocket= dataServer.accept();
	System.err.println("data connection established by ftp server");
	new FTPdataThread(dataSocket).start();
      }
    } catch(Exception e) { System.err.println("Error: " + e); }
  } // main
} // FTPdataConn

class FTPdataThread extends Thread
{ public FTPdataThread(Socket socketArg) { dataSocket= socketArg; }

  public void run()
  { DataInputStream is= null;
    PrintStream os= null;
    try
    { is= new DataInputStream(dataSocket.getInputStream());
      String input= is.readLine();		// read file from socket
      while(input!=null)			// server !closes socket at eof
      { System.out.println(input);		// copy
        input= is.readLine();			// read file from socket
      }
      dataSocket.close();
    } catch(IOException ioe) { System.err.println(ioe); }
  } // run

  private Socket dataSocket;
} // FTPdataThread


NNTP	(port 119, rfc 977)


