------------------------ README.TXT ------------------------
mTCP TCP/IP Applications
2011-05-20 Version
Michael Brutman (mbbrutman@yahoo.com)

Home page: http://www.brutman.com/mTCP
Comments?  Email me!


Introduction

mTCP is a TCP/IP stack and adaptions of some well known TCP/IP applications
designed to run on older x86 personal computers running DOS.  It is
designed to work with an Ethernet card and a packet driver.  Basic
features include:

 - ARP support for finding the IP addresses of other machines on the network
 - A simple UDP implementation
 - A high performance TCP implementation


The stack is implemented as a static library that is compiled into the
application.  This approach allows for better performance and per-
application customization not possible with other approaches, such as
a DOS TSR.  At the moment the following applications are available:

 - DHCP client
 - IRC client
 - FTP client
 - FTP server
 - Telnet client
 - Simple NTP (Network Time Protocol) client
 - the "Ping" utility
 - the "Netcat" utility



Features

Some of the design goals are:

 - Configuration flexibility: A lot of features are enabled and disabled
   at compile time using #defines so that the TCP/IP code can be tailored
   to each application.
 - High performance: Even on the slowest PC dating back to 1981 one can
   get raw TCP socket performance well in excess of 70KB/sec.  (This is
   dependent upon the Ethernet card being used.)
 - Small space requirements: The library is compact without cutting key
   features.  Buffer sizes are configurable.  All of the applications
   run comfortably on a 256KB machine and many will run with less.
 - Extensive tracing: Nobody likes a bug and a comprehensive tracing
   mechanism helps find and squash bugs after the code leaves my hands.
 - Robustness: The library and applications are pretty rigorously tested.
   Some of the apps have been left running for days at a time with no
   unexplained memory leaks or crashes.  The correctness of the TCP/IP
   and other protocols are checked against a variety of target machines.
 - Usability: DHCP configuration makes it easy to use on a modern network.
   Command line options and the configuration file are not made needlessly
   complicated.


Some of the more advanced features of mTCP are:

 - Automatic detection and retransmit of lost packets
 - Support for multiple open sockets
 - Support for listening sockets to write server applications
 - DNS resolving (using UDP packets only at the moment)
 - TCP zero window support
 - IP fragment reassembly and automatic sending of UDP fragments.
   (Not needed for TCP.)


And some of the limitations:

 - Minimal support for IP and TCP header options
 - Only one gateway may be configured
 - Only one nameserver may be configured
 - Not terribly sophisticated flow control.  (To be improved)
 
In general, I implemented a set of features that makes sense for a
small machine.  There is enough implemented to allow the machine to
interoperate well with a variety of other machines and not violate
specifications.
 


Goals

There are a few goals for the project:

 - Develop a TCP/IP library that others can use for their own applications.
 - Encourage network programming on old hardware. (Because it is fun!)
 - Get a Telnet BBS running comfortably on a vintage PCjr. :-)



Tested machines/environments

This is a partial list of the machines and environments I have used:

  Machines:

    Pretty much any decent original IBM or clone machine will work just
    fine.  I've used a variety of machines with a wide array of options.

    Machines: IBM PCjr, IBM PC, IBM XT, IBM AT, Epson Equity II,
      Compaq Portable, Generic 80386-40, Generic Pentium 133,
      PS/2 L40SX laptop, etc.

    CPUs: 8088, 8086, V20, 80286, 80386, 80486, Pentium, etc ...

    Video cards: Monochrome, CGA, EGA and VGA

    Ethernet cards: The only requirement is a good packet driver.
    Cards that I have tested or know to work are:

      - Xircom PE3-10BT (parallel port Ethernet adapter)
      - 3Com 3C503 (ISA)
      - Novell NE1000 (ISA)
      - Novell NE2000 (ISA)
      - Western Digital/SMC 80x3 series (ISA)
      - LinkSys LNE100 (PCI)
      - Intel EtherExpress 8/16


    OS: DOS 2.1 or better is a requirement.

  Environments:

    DOSBox: http://www.dosbox.com

      DOSBox runs under Windows and is designed to support games, although
      many regular DOS applications run fine.  DOSBox itself does not
      emulate an Ethernet card.  To get an emulated Ethernet card use the
      H-A-L 9000 'megabuild' of DOSBox, which includes all sorts of extra
      goodies including NE2000 emulation. (http://home.arcor.de/h-a-l-9000/)

    VMWare and VirtualBox

      These both emulate a machine that you can install DOS onto.  Both
      have some form of Ethernet emulation that allows you to use a packet
      driver from within the virtual machine.



Support

The latest mTCP code and docs can be found at the home page.  If you have
questions or comments I can be reached at mbbrutman@yahoo.com.

If you are having a problem getting the mTCP applications running please
try to give me a good idea of your machine setup, your network
configuration, and the symptoms you are experiencing.  If I don't know the
answer off the top of my head we'll generate some traces and try to figure
it out.



Regards,
Mike


More information: http://www.brutman.com/mTCP

Created June 21st, 2010, Last updated May 20th, 2011
(C)opyright Michael B. Brutman, mbbrutman@yahoo.com

------------------------ SETUP.TXT ------------------------
Configuring mTCP Applications
2011-05-20 Version
Michael Brutman (mbbrutman@yahoo.com)

Home page: http://www.brutman.com/mTCP


Contents

  Introduction
  General Requirements
  Pre-requisites
  Loading the packet driver
  Creating the configuration file
  Setting the MTCPCFG environment variable
  Running the DHCP Client
  Configuring by Hand (Static addresses)
  List of networking related parameters
  Other configuration parameters in the configuration file
  More on the MTU setting
  SLIP and PPP users
  How the configuration file works


Introduction

  mTCP is a library that implements ARP, IP, UDP, TCP, DNS resolving
  and a few other useful features.  Applications that use the mTCP
  library have common configuration requirements, mostly related to
  setting up TCP/IP addresses and telling the mTCP library code how
  to talk to the packet driver for your Ethernet card.  This
  document explains how to setup the basic parameters for applications
  that use mTCP.  Each individual application (like IRCjr) may have
  some additional setup that needs to be done.


General requirements

  PC compatible machine (including the PCjr and most 'near' clones)
  8088 processor or better
  128 to 256KB RAM (depends on the application)
  Display: CGA, EGA, VGA or MDA
  Supported Ethernet card with packet driver or SLIP/PPP connection
  DOS 2.1 or newer (DOS 3.3 or newer recommended)


Pre-requisites

  Your Ethernet hardware has to be installed and you should know
  what IRQ and port settings you have configured on the card.


Loading the packet driver

  Note: SLIP and PPP users, please see the separate section for usage
  notes specfic to SLIP and PPP.

  mTCP does almost everything except talk to your Ethernet card.  There
  are a lot of Ethernet cards out there and they all use different
  hardware and look different at the hardware level.  To make mTCP able
  to use a wide variety of Ethernet cards a piece of code called a 'packet
  driver' gets loaded first.  Each Ethernet card comes with a packet driver
  designed for that specific Ethernet card and that packet driver is
  responsible for making the Ethernet card look like a standard device.
  mTCP talks to the packet driver in a generic way while the packet
  driver converts the requests to something meaningful for your Ethernet
  card.  That keeps mTCP from having to know the details of every Ethernet
  card out there - it just has to know how to talk to packet drivers.

  You have to have the correct packet driver for your Ethernet card. A
  lot of packet drivers can be found at http://www.crynwr.com/drivers/.
  That site covers most of the classic cards like the 3Com 3C503, the
  NE1000, the Western Digital/SMC 8xx3 series, etc.  If you have a newer
  card on the PCI bus you can try the manufacturer's web site, or look
  for the CD-ROM that came with the card - the packet driver will be in
  the DOS software directory.  A lot of PCI cards have packet drivers, but
  I imagine that as DOS becomes a distant memory that will be less likely.

  The parameters on the packet drivers will vary but one that you will
  always have to provide is the software interrupt number that the packet
  driver is going to take control of.  The software interrupt number is the
  address of the 'service' that the packet driver is going to provide to
  mTCP applications, and that service is the ability to send and receive
  packets on the Ethernet hardware.

  Note that the software interrupt number has nothing to do with the
  configuration of the Ethernet hardware. The software interrupt number
  is assigned by you and you are telling the packet driver which software
  interrupt to use. Software interrupt numbers are usually in the range
  of 0x60 (hex) to 0x66 (hex). You need to pick one that is not in use
  already but since most DOS software does not these software interrupts
  0x60 is usually available. This is in contrast to hardware interrupt
  numbers, which is what the Ethernet card uses to signal to the computer
  that new packets have arrived. Hardware interrupts are set on the card
  using jumpers or by configuration software that comes with the card.

  Here is an example showing an NE2000 clone card being loaded using the
  default I/O ports and IRQ3 . It is also being told to use software
  interrupt 0x60:

    ne2000 0x60 3

  Here is another example featuring an older Western Digital 8003 card:

    smc_wd 0x60 0x03 0x280 0xD000

  In this example the software interrupt to use is 0x60, the IRQ is 3,
  the I/O  ports start at 0x280, and the shared memory address for the
  RAM on the card is  going to be located at 0xD000:0000 in memory.

  For a general discussion on packet drivers see the DOS Packet Drivers
  page (http://www.brutman.com/Dos_Networking/packet_drivers.html).



Creating the configuration file

  Next it is time to create the configuration file. You generally have
  to do this just once.

  mTCP requires a configuration file to tell it things like the IP
  address to use, where the nameservers are, etc. There are two ways
  to create this configuration file:

    * DHCP Configuration: DHCP is a network protocol that allows a
      machine to find out what its IP address, netmask, and other
      parameters are automatically.  If you have a cable modem,
      DSL modem, or router on your network that assigns addresses
      to machines automatically then you can use this method.
    * Setup the machine by hand.  You will provide a set of required
      IP addresses that describe your network.  This is recommended
      for advanced users who understand their network.

  If you are going to use DHCP you can get by with just two lines
  in the configuration file. One line tells mTCP which software
  interrupt to use to talk to the packet driver. The other assigns
  a hostname to your machine. Here is an example of a minimum
  configuration file for mTCP:

    PACKETINT 0x60
    HOSTNAME PCjr

  Just create a file with these lines, substitute in the correct software
  interrupt value and hostname for your machine, and you can move onto
  the next step. (The PACKETINT parameter here needs to be set to whatever
  software interrupt you told the packet driver to use. Hostname can be
  whatever you like, but don't make it too long or use punctuation.)

  If you are going to use static configuration you have a little more
  work. Here are the lines you need to add and fill in correctly:

    PACKETINT 0x60
    IPADDR 192.168.2.6
    NETMASK 255.255.255.0
    GATEWAY 192.168.2.1
    NAMESERVER 68.115.71.53
    MTU 1500
    HOSTNAME PCjr

  And of course, fill in the correct values for your network.

  All of the mTCP programs read the configuration file each time they
  start.  Besides holding network parameters the configuration file
  can hold configuration settings for the applications. Those additional
  settings are documented by each application.



Setting the MTCPCFG environment variable

  Next you need to set an environment variable to point to the
  configuration file.  All of the mTCP code looks for the environment
  variable first - if it doesn't find it, it doesn't run.  If the
  environment variable is set correctly then the mTCP code will be
  able to find the configuration file.

    set MTCPCFG=c:\packet\tcp.cfg

  That's it!  You can put this in AUTOEXEC.BAT or another batch file
  that you run before you start using mTCP. Be sure to put the location
  of your file in place of "c:\packet\tcp.cfg". I suggest using a full
  path name starting with a drive letter (as shown above) so that mTCP
  can always find the file. Another good idea is to place the mTCP
  programs on your PATH so that you can find the mTCP programs no matter
  what subdirectory or drive you are in.



Running the DHCP Client

  If you are using a 'static' configuration, skip this section.

  If you have the packet driver loaded and the MTCPCFG environment
  variable pointing at a good configuration file you are ready to run
  DHCP.  DHCP is really simple to run - just type dhcp and go! If your
  setup is correct and it makes contact with a DHCP server on the
  network it will get an IP address and other settings and write them
  to the configuration file for you.

***NOTE: I have replaced 'DHCP.EXE' with my own DHCP.COM which can also
***configure WATTCP applications (and saved some space). to configure
***mTCP with DHCP.COM, type: DHCP/M       use: DHCP ? for more details.
*** Dave D.

  Here is a sample session from one of my systems:

    E:\MTCP>set mtcpcfg=e:\mtcp\tcp.cfg

    E:\MTCP>dhcp
    mTCP DHCP Client by M Brutman (mbbrutman@yahoo.com) (C)opyright 2008-2010
      Version: Jul  5 2010 (Watcom)

    DHCP request sent, waiting for response.  Press [ESC] to abort.

    IPADDR = 192.168.2.101
    NETMASK = 255.255.255.0
    GATEWAY = 192.168.2.1
    NAMESERVER = 24.159.193.40
    LEASE_TIME = 86400 seconds

    Settings written to 'e:\mtcp\tcp.cfg'

    IP: TcpRcv: 0 UdpRcv: 4 IcmpRcv: 0 PW: 0 CSumE: 0 ProtE: 0
    Packets: Sent 2: Rcvd: 5 Dropped: 0 LowFreeBufCount: 8


  Now you can run one of the mTCP applications, like Telnet, FTP or IRCjr.

  Note that you only have to run DHCP.EXE once in a while.  The exact
  timing depends on your DHCP server, but a good rule of thumb is once
  a day before you start using mTCP applications. If your machine is
  acting strange and can't connect to other machines it will not hurt
  you to run DHCP.EXE again - the DHCP server might have dropped your
  machine due to a reset or a short lease time.  (In the example above
  my DHCP server handed out an address that was good for 86,400 seconds,
  which works out to 24 hours.)



Configuring by Hand (Static addresses)

  If you have the packet driver loaded and the MTCPCFG environment
  variable pointing at a good configuration file then you are ready
  to run the mTCP applications right now.

  The next section has a detailed description of all of the networking
  parameters that might be interesting if your are configuring by hand.



List of networking related parameters

  These are the common parameters used by the TCP/IP stack.  Program
  specific parameters are discussed in the next session.


    PACKETINT

      This is the software interrupt number that the packet driver
      is listening on.  This has to match the software interrupt number
      that you told the packet driver to use.  It is specified in
      hexadecimal notation.  (eg: 0x60)

      This is always required for Static and DHCP setups.


    IPADDR

      IP address of this machine (eg: 192.168.2.3)

      Required for Static setups, filled in by DHCP on dynamic setups.


    NETMASK

      Network mask setting for your local area network (eg: 255.255.255.0)
      The network mask is used to determine if a target for a packet is on
      your local network or on a remote network.  Packets going to a
      remote network need to have a GATEWAY configured.

      Required for Static setups, filled in by DHCP on dynamic setups.


    GATEWAY

      The IP address of your router (eg: 192.168.2.1)

      Optional for Static setups, filled in by DHCP on dynamic setups.
      If you don't provide this or if you set it wrong you will not be
      able to communicate with machines that are not directly connected
      to your LAN.


    MTU

      The MTU size for your Ethernet (typically 1500).  A setting of
      1500 provides the best performance, but might not work perfectly
      on mixed networks where fragmentation is possible.  A setting of
      576 should be safe for almost all environments.  SLIP and PPP
      users will have a smaller value depending on their SLIP or
      PPP connection.

      Please see the separate section on MTU for a more detailed
      discussion.

      Optional for static setups and dynamic setups.


    NAMESERVER

      The IP address of your nameserver (eg: 68.115.71.53)

      Optional for Static setups, filled in by DHCP on dynamic setups.
      If you don't provide this or if you set it wrong you will not
      be able to convert machine names to IP addresses.


    HOSTNAME

      The hostname of your machine.  The hostname can be up to twenty
      characters, and should conform to internet standards.  (Avoid
      punctuation and you should be fine.)

      Optional for static setups and dynamic setups.



Other configuration parameters in the configuration file

  The mTCP configuration file can be used for more than network
  configuration.  Other mTCP applications will read it to look for their
  configuration settings.

  In general, you can put anything you want in the configuration file.
  Lines that the DHCP client don't understand will be left unaltered.
  Here are the rules:

  * Blank lines are ok
  * Lines should never exceed 75 characters
  * If you use the DHCP client, it will rewrite the configuration file
    and write new values for IPADDR, NETMASK, GATEWAY, and NAMESERVER.
    The previous values will be lost, but no other lines in the file
    will be altered.
  * Other mTCP programs read but do not alter the file.  They will skip
    lines that they do not understand.

  So for example, here is a more complex mTCP configuration file:

    DHCPVER DHCP Client version Apr 26 2009
    TIMESTAMP Sun Apr 26 17:59:54 2009

    # Parms for my machine
    #
    packetint 0x60
    mtu 1500
    hostname DOSBox

    # IRCjr parms
    #
    ircjr_nick Brut_DOSBox
    ircjr_user Brutman
    ircjr_name Brutman on IRCjr for DOS
    ircjr_connect_timeout 15
    ircjr_register_timeout 60

    # FTP parms
    #
    ftp_connect_timeout 15

    # DHCP generated settings will appear here
    #
    IPADDR 192.168.2.102
    NETMASK 255.255.255.0
    GATEWAY 192.168.2.1
    NAMESERVER 24.159.193.40
    LEASE_TIME 86400


  Note that the DHCP client adds/releaces the first two lines of the file
  and the last five lines of the file.  The rest of the lines in the file
  are kept as is for the other applications.

  Configuration parameters for each application are documented by that
  application.  The sample file above is just a sample; it is not
  complete, and possibly not accurate. ;-)



More on the MTU setting

  MTU stands for 'Maximum Transmission Unit' and it tells the TCP/IP stack
  how big of a packet it can send on the local network.  Bigger packets
  generally mean less overhead.

  In a world where all networks are built using the same technology the
  MTU setting would not be needed.  But that is not our world.  Ethernet
  predominates, but there are other physical transports out there that
  you might not be aware of that you are using.  Your Ethernet traffic can
  be transmitted over many different things that don't look like Ethernet
  before it reaches its final destination.

  TCP/IP uses 'fragments' to deal with this problem.  If a packet is too
  big to pass from one network to another the gateway machine will break
  the packet into fragments suitable for the next network.  It is possible
  that a single packet will be broken into fragments multiple times over the
  course of its journey.  The receiving side is responsible for gathering
  all of the fragments for an IP packet together and reassembling them.

  While this process works it is not ideal.  It causes a performance
  loss as the packets are fragmented by the gateways and a bigger performance
  loss when the fragments reach their final destination and have to be
  reassembled.  In addition to the performance loss, it requires quite
  a bit of memory too.  And losing a fragment hurts performance even more
  because all of the other fragments for that packet have to be thrown
  away.

  In the real world fragments are rare.  Most modern servers using TCP
  sockets do some form of path MTU discovery to determine the largest
  packet that can be sent without causing fragments to be created.
  For a TCP socket it works very well and you will have to work hard to
  try to get a server to send you a packet that needs fragmenting.

  On the other hand, that mechanism is not applicable to UDP packets.
  A server sending a UDP packet has no choice about how to 'chunk' the
  data to avoid fragmentation; it has to send what the application says
  to send.  Most UDP based programs avoid sending large packets that will
  be fragmented, but there are exceptions.  (NFS and programs sending
  streaming video data are two notable exceptions.)

  mTCP supports the reassembly of fragmented packets, with some restrictions.
  There is a limit on the total size of the fragmented packet that is set
  at compile time, and there is a limit to the number of fragments that
  can be reassembled at the same time.  Currently those limits are set at
  1500 bytes per packet, and 4 packets at a time.  While low, those limits
  will protect you against a server on a standard Ethernet that goes
  through a misconfigured gateway that causes fragments to be created.
  (For UDP applications that require larger packets that can be set at
  compile time when such an application is created.  There are no such
  applications available at the moment.)

  Even though mTCP can reassemble fragments there are still all sorts
  of fragment related dangers floating around out there:

  - Some TCP/IP servers set the 'Dont Fragment' bit on their packets
    If the packet needs fragmentation at a gateway and this bit is
    set, the packet effectively gets dropped at the gateway.  mTCP will
    have no knowledge and no way to get around the dropped packets, other
    than mysterious timeouts from the application.  While the server might
    be trying to avoid additional overhead caused by fragmentation, it is
    really doing a disservice by forcing these packets to be dropped.  (I'd
    rather get the data slowly than not get it at all.)

  - Some home router/firewalls throw fragments away rather than try to
    process them correctly.  This is especially true when NAT (Network
    Address Translation) is used.


  The good news is that you have some control over the problem.

  Applications that use TCP sockets will tell the remote side what their
  MSS (Maximum Segment Size) is.  (MSS is based on MTU.)  This happens
  during the socket connect and once the remote side knows your MSS it
  will not knowingly send you a packet that needs to be fragmented.
  (Something in the middle might cause fragmentation, so it is still
  possible.  MTU path discovery is supposed to avoid that danger by
  actively probing all gateways between the server and your machine.)

  If you are having problem with dropped packets on a TCP socket, set
  your MTU to 576.  That is guaranteed to work on all gateways and
  all routers.  This is also the default for mTCP if you do not specify
  an MTU size.

  UDP should not have this problem; if an application knowingly sends
  a large packet it will not turn on the Dont Fragment bit in the IP
  header.  Doing so would effectively break the application, as the data
  would never be able to get out.  On a large UDP packet fragmentation
  is the only solution; there is no concept of MSS.  Most UDP packets
  used by mTCP never exceed 512 bytes of data, so fragmentation is not
  an issue.

  For best performance set MTU has large as you can.  For Ethernet that
  value is usually 1500 bytes.  This minimizes the overhead of the
  protocol headers and minimizes interrupt handling.
 
  If you are having strange connection issues you might be bumping into
  a fragmentation problem.  Many times there is no warning message because
  the packets just simply don't arrive, and the ICMP messages get sent
  directly to the server, not the mTCP code.  If this happens set your
  MTU to 576 and try again.

  SLIP and PPP connections generally have smaller MTU settings which may
  cause fragmentation.  This is unavoidable; consider it part of the joy
  of using low speed point-to-point links.  Your local gateway that is
  providing the SLIP or PPP connectivity will generate fragments that
  mTCP will have to reassemble.



SLIP and PPP Notes

  I designed and implemented everything all of this code assuming
  Ethernet.  Quite a bit down the road somebody pointed out that my
  code was inaccessible to an entire class of people using SLIP (Serial
  Line IP) and PPP, which is often used on dialup.

  I've tested the code using SLIP and PPP.  Here are the key things
  you need to be aware of.

  - You need to use a packet driver that simulates Ethernet.
  SLIPPR and CSLIPPER can do this for SLIP connections, and DOSPPP
  can do this for PPP connections.  For SLIPPR use the "ether" option to
  do this.  For DOSPPP use the EPPPD program.


  - mTCP assumes that ARP is necessary, which is completely wrong on
  a point to point connection.  It will not get a response to an ARP
  query for the gateway, and it will time out.  To avoid this set
  the following environment variable:

    set MTCPSLIP=true

  Do this for both SLIP and PPP.

  This environment variable stuffs a bogus ARP entry into the mTCP
  ARP table for your gateway.  That allows it to immediately send
  packets to the gateway without sending an ARP request.  The
  Ethernet address in the sent packets will be wrong, but nothing
  is looking at it anyway.


  - I've tested configurations using static addressing.  You will
  have to find a way to pass the IP address, netmask, etc. to mTCP
  using it's configuration file.


  - It's beyond the scope of this document to explain addressing
  in a point-to-point configuration.  Here is something to keep in
  mind though.

  If you use the smallest possible netmask (255.255.255.252) you can
  easily create a configuration that works.  With that netmask only
  the last two bits are signifigant.  Considering the last two bits
  only:

    <30 bits of netmask>.0 - reserved address meaning 'this host'
    <30 bits of netmask>.1 - usable, good for the gateway address
    <30 bits of netmask>.2 - usable, good for your address
    <30 bits of netmask>.3 - IP broadcast address for this network

  Setting up your netmask and addresses like this is simple and should
  avoid routing problems.  Basically you force mTCP to always send
  things to the gateway because nothing else is on your subnet.

  SLIP and PPP generally use smaller MTU settings than other networks
  because their transport layer is slower.  Be sure that the mTCP MTU
  setting reflects what your SLIP or PPP connection is using. 
  Depending on the application, servers and gateways you may experience
  some fragmentation, especially on UDP packets.  (TCP generally avoids
  this by using the MTU setting to compute MSS.)


How the configuration file works

  At the beginning of time, mTCP used environment variables for all
  of the configuration.  This worked well until the IRC client came
  along and I had to start increasing the size of the DOS environment
  space.  Then came the DHCP client - I couldn't find a way to set
  environment variables from within the DHCP client and make them stick
  for the next program without writing out a file.  At that point the
  configuration file was born.

  When the DHCP client starts up it reads the PACKETINT and HOSTNAME
  parameters from the configuration file and ignores the rest.
  (HOSTNAME is optional.)  It then tries to communicate with the DHCP
  server on your network.  If it gets an address from the DHCP server
  it will write a new configuration file.  All of the contents of the
  old configuration file are copied, except for the IPADDR, NETMASK,
  GATEWAY, NAMESERVER, and LEASE_TIME parameters which get updated
  with new values at the end of the file.

  Having DHCP write a configuration file has an interesting side effect.
  It means that at its core, every mTCP application assumes static network
  addressing.  They all read the configuration file to get the network
  parameters, and they can't tell if the network parameters were set by
  a human or a machine.

  At startup each application looks for the MTCPCFG environment variable
  and tries to read the configuration file.  It makes one pass to get the
  networking parameters that it needs to initialize the TCP/IP stack.

  If an application has other configuration parameters that it needs to
  read it will reopen the configuration file and scan for them.  The
  format for a parameter is a single token that represents the parameter
  name, a space for a delimeter, and then the value of the parameter.  The
  entire rest of the line is assumed to be the parameter.  Lines must be
  under 75 characters in total length.




More information: http://www.brutman.com/mTCP

Created July 31st, 2008, Last updated May 20th, 2011
(C)opyright Michael B. Brutman, mbbrutman@yahoo.com

------------------------ FTP.TXT ------------------------
mTCP FTP client
2011-05-20 Version
Michael Brutman (mbbrutman@yahoo.com)


Introduction

  This is an FTP client like many other FTP clients you have
  probably used before.  Features include fairly high performance,
  low memory requirements, and compatibility with a wide
  selection of FTP servers.


Hardware requirements:

  8088 processor or better
  180KB available RAM (using standard buffer sizes)
  CGA, Monochrome (MDA), EGA or VGA display
  Supported Ethernet card, SLIP or PPP connection


Software requirements:

  DOS 2.1 or newer (DOS 3.3 or newer recommended)
  Packet driver for your Ethernet card, SLIP or PPP connection


Setup instructions

  FTP is built using the mTCP library.  The setup instructions for
  mTCP can be found in SETUP.TXT.


Using FTP

  FTP uses the following syntax:

    ftp [-port <n>] <ftp_server_addr>

  Options are:

    -help               Show basic help text
    -port <n>           Connect using port <n> instead of port 21


  You have to specify the FTP server address on the command line.
  After the control socket is opened you will be prompted for a
  user ID and password.  After that you get a command line just like
  on other FTP command line clients.

  Here are some of the commands:

    dir         - directory list (full details)
    ls          - directory list (names only)
    pager       - Pause ls or dir output after approximately n lines

    cd          - change to a directory
    cdup        - move up one directory
    pwd         - print current working directory

    lcd         - local change directory
    lmd         - local make directory

    ascii       - Set transfer type to 'ASCII'
    image       - Set transfer type to 'image' or 'binary'
    get         - Get a file
    put         - Send a file
    mget        - get multiple files
    mput        - put multiple files

    prompt      - Toggle mget/mput prompting on or off
    xfermode    - Set default transfer mode - see section below

    delete      - Delete a file
    mkdir       - Make directory
    rmdir       - Remove directory
    rename      - rename a file on the server

    quote       - Send a command to the FTP server directly
    quit        - Quit
    shell       - Shell to DOS
    interactive - Switch from script file to keyboard input

   
  The program captures Ctrl-Break and Ctrl-C.  If you use Ctrl-Break
  during a file transfer or directory listing the current operation
  will stop (prematurely) and you will be returned to the command
  line after a brief delay.  If you use Ctrl-Break or Ctrl-C at the
  command line the program will end. (This might take up to 20
  seconds depending on the state of the sockets, so please be
  patient.)

  The shell command should be used with care.  With the shell
  command you can do local directory listings, rename local files,
  look inside of files, and do most normal things.  Keep in mind that
  while you are at the DOS command prompt the mTCP code is not
  servicing the socket connection - if you stay in DOS too long you
  might lose your connection to the FTP server.


Transfer modes

  The xfermode command requires a little explanation.

  In the beginning of time FTP servers always sent data by doing a
  connect to the FTP client, which was listening for the incoming
  connection on a default port.  The FTP server in NCSA telnet
  does this.  I will call this 'Classic' mode and you can tell this
  FTP client to handle data transfers this way.

  'Classic' mode is only useful for ancient FTP servers that can't
  do anything else.  Most modern FTP servers will not connect to an
  FTP client on the default ports and most firewalls/routers
  wouldn't allow it anyway.

  'Port' mode is the current default for many clients.  Instead of
  having the FTP server connect to the client on default ports, the
  client will tell the FTP server exactly what port it should use
  for the connection.  This is slightly better than Classic mode,
  and should be usable on more FTP servers, firewalls and routers.

  'Passive' mode is probably the best and most compatible mode to
  use with modern FTP servers.  It turns things around by making
  the client connect to the FTP server to make data connections
  instead of having the FTP server connect to the client.  (From
  the standpoint of the FTP server it is 'passive' and it waits
  for a connection from the client.)  This will work with almost
  any firewall and router.  This is the mode I'd recommend using
  too.


Filenames and Quoting

  DOS does not allow a filename to have a space in it.  However,
  you may find that FTP servers running real operating systems
  do support filenames and directory names with spaces in them.

  FTP supports adding quotes around filenames and directory
  names so that you can work with these servers.  (You still have
  to provide a legal DOS filename for receiving files.)

  If you need to specify a filename that has the double quote
  character in it use two double quote characters in a row.  This
  will result in one double quote character being sent.  If you have
  to deal with embedded spaces at the same time, add an extra set of
  quotes to enclose the entire parameter.

  Examples:

    You enter ...    -> The server sees

    "Spacey name"    -> Spacey name  (All one parm)
    ""QuoteChar""    -> "QuoteChar"  (All one parm)
    ""Quote Char""   -> Uh oh ..  you get "Quote as one parm
                        and Char" as the second parm.  That is
                        because the two sets of double quotes
                        collapse into a single double quote, but
                        do not do anything to mark it all as one
                        parameter.
    """Quote Char""" -> "Quote Char" (All one parm).  Note the
                        usage of the triple quotes.



Command line editing

  If you are using FTP interactively you can take advantage of the
  command line editor.  It does all that you would expect it to do:
  backspace, delete, insert, home, end, etc.  It also includes a
  ten line command buffer so that you can recall older commands
  easily without retyping them.



Scripting support

  FTP will take input from a file redirected to stdin.  This allows
  you to automate some simple tasks, like logging in to fetch a
  file.

  Here are some notes for using this support:

  - Because you have to start FTP with stdin redirected from a file,
    you will probably have to include your login information as the
    first two lines of the script file.

  - FTP will interpret "end of file" as "quit".  So when the script
    ends, so does FTP.

  - If you don't want FTP to quit when it hits the end of the script
    file, add the "interactive" command to the end of the file.
    This will tell FTP to start reading from the keyboard again.



Advanced Configuration Parameters

  The following are optional configuration settings that you can
  put in your mTCP configuration file.  See SETUP.TXT for how
  to make changes to that file.

    FTP_CONNECT_TIMEOUT <n>

      Set the timeout for a socket connection to n seconds.  The
      default timeout is 10 seconds.


    FTP_TCP_BUFFER <n>

      Set the size of buffer used by TCP for receiving data to n bytes.
      The default is 8192 bytes.  For best performance this should
      be set to a multiple of 1024 (1KB).  The default is reasonable
      compromise between size and performance.  You can go lower
      to conserve memory or up to 16384 bytes to improve performance.


    FTP_FILE_BUFFER <n>

      This controls the size of the buffer used to read and write
      files.  The default is 8192 bytes.  For best performance this
      should be set to a multiple of 1024 bytes.  The default is a
      reasonable compromise between size and performance.  The
      maximum size is 32768 bytes.


    FTP_MLIST_BUFFER <n>

      When you use MGET or MPUT FTP has to fetch a list of files
      from the server or from your local machine.  This buffer
      holds that list of files.  If the list of files is too long
      the MGET or MPUT command will fail.

      One solution is to change your filespec so that the list of
      be transfered is smaller, and use multiple MGET or MPUTS to
      do what you need.  The other solution is to increase this
      buffer size.  The default size is 4096 bytes, which is plenty
      for most usage.  The maximum size is 16384 bytes.
    


Environment variables

  Previous versions of FTP used environment variables to set
  buffer sizes.  This version (and future versions) looks for those
  settings in the configuration parameters described in the previous
  section.



Limitations

  * FTP will not respond to ICMP ping while waiting for keyboard
    input.  This will be fixed eventually.


Support

  Have a comment or need help?  Please email me at mbbrutman@yahoo.com.  You
  can also start a thread on http://www.brutman.com/forums (Mike's PCjr Page)
  in the "Programming" area.


Recent changes

  2011-01-02:

    Fix handling of multi-line error messages

  2010-11-27:

    Misc TCP library changes to improve handling when buffers
      are full.
    Add sending and receiving rate at end of transfers.
    Watcom runtime workaround: improve compatibility with older machines


  2010-10-20:

    Add lmd command (local make directory)
    Add command line editing with a 10 command recall buffer



More information: http://www.brutman.com/mTCP

Created January 18th, 2009, Last updated May 20th, 2011
(C)opyright Michael B. Brutman, mbbrutman@yahoo.com

------------------------ TELNET.TXT ------------------------
mTCP Telnet client
2011-05-20 Version
Michael Brutman (mbbrutman@yahoo.com)


Introduction

This is a small telnet client like other telnet clients that you
have probably used before.  Besides communicating with a telnet server
using the telnet protocol it also emulates a standard 'ANSI' terminal.
This telnet client features excellent screen updating performance and
a small memory footprint.


Hardware requirements

  8088 processor or better
  165KB available RAM (using standard backscroll buffer)
  CGA, Monochrome (MDA), EGA or VGA display
  Supported Ethernet card, SLIP or PPP connection


Software requirements

  DOS 2.1 or newer (DOS 3.3 or newer recommended)
  Packet driver for your Ethernet card, SLIP or PPP connection


Setup instructions

  Telnet is built using the mTCP library. The setup instructions for mTCP
  can be found in SETUP.TXT.


Using Telnet

  Telnet uses the following syntax:

    telnet [options] <telnet_server_addr> [port]

  where <telnet_server_addr> is the name or numerical IP address of the
  telnet server you wish to connect to and [port] is an optional port
  to connect on.  By default port is 23, which is the standard telnet
  server port.

  Options are:

    -help                      Show basic help text
    -debug_ansi                Create telnet.log with some extra debug info
    -debug_telnet              Create telnet.log with some extra debug info
    -sessiontype <telnet|raw>  Force telnet mode or raw mode

  Under normal operation if you connect to port 23 on a server you will be
  operating in telnet mode.  This means that the telnet client will expect
  to receive telnet options from the server, and will reply and try to
  negotiate option settings.  If you connect to any port besides port 23
  you will be operating in raw mode, where the telnet client will not
  respond to telnet options and will not try to negotiate option settings.

  If you need to connect to a real telnet server on a non-standard port then
  use the -sessiontype option to tell the telnet client to do telnet option
  negotiation even if you are not connecting on port 23.  You probably
  will never need to specify raw mode but it is there if you need it.

  To make the screen performance tolerable on older machines telnet will
  take incoming data and render the current screen on a virtual buffer
  before trying to repaint the real screen.  This approach uses a little
  bit more memory, but it dramatically improves the performance ot the
  screen handling, especially when scrolling large amounts of data.
  You will notice that the screen will pause and stop updating while
  the machine is getting flooded with incoming data - this is normal and
  it is keeping you from dying a slow and agonizing death while the display
  adapter scrolls.  A nice side-effect of the virtual buffer approach is
  that you get backscroll capability for free - if something does scroll
  past the screen you can hit Page Up and Page Dn to browse around.


Telnet protocol features and limitations

  This isn't a fully compliant telnet client implementation.  It has the
  following limitations:

    - SGA (Server Go Ahead) must be enabled on both sides of the connection.
      Most servers expect this behavior, as a TCP/IP socket is a full
      duplex connection.
    - This client will not do local line editing.
    - This client does not support the telnet Data Mark command.  This is
      not a big issue, but it means that you don't have an easy way to tell
      the server to squelch a flood of output if it happens.  At Ethernet
      speeds this should not be a big problem.

  It does properly support the following telnet options:

    - Binary transfer - it will be requested and used if available
    - Echoing - it will request or let the server offer to do echoing.  You
      can also turn on local echoing.
    - Terminal type - it will send the terminal type if asked for it
    - Window size - it will send the window size in rows and columns if asked

  Other options such as passing the environment variables are not supported,
  but that is not a big deal considering that you are connecting from a DOS
  machine.  (If you have a burning desire for a missing option let me know.)


ANSI Emulation Notes

  Full blown ANSI terminal emulation is a complicated mess.  All of the
  different variations of ANSI emulation over the years have not helped
  anything either.  To put it politely, I've done the best I can and you
  might still see screen rendering problems.

  That being said, I've tried to do a reasonable good job of interpreting
  ANSI escape sequences and rendering them properly.  The ANSI emulation
  does not depend on ANSI.SYS or any other console device driver - it is
  all internal to the program.  I used a few sources to determine the
  required set of escape sequences, including the Linux TERMCAP entries
  for a few ANSI-like terminals, including the generic ANSI terminal
  definition and a few related PC flavors.  The emulation is good enough
  for me to write this documentation using VI, browse in text mode with
  Lynx, run the 'screen' program to get a few virtual terminals, use
  the 'info' command to browse the terminfo writeup, and run some of the
  more complicated 'system-config-*' commands provided with Fedora.

  Here are a few notes to improve your experience:

    Unicode:

      This telnet client doesn't have Unicode support in it, so
      sending a three byte sequence to it and hoping that you will get a
      Unicode character will not work.  The easiest way to supress the
      bogus Unicode characters is to set your LANG enviroment variable
      so that it doesn't trigger Unicode support.  For example, on my
      recent Linux boxes LANG looks like this:

        echo $LANG
        en_US.UTF-8

      Set it to en_US instead like this: export LANG=en_US

    Codepages:

      The standard codepage built into the monochrome card or the
      CGA card is codepage 437.  No other codepages are possible if you are
      using these two video cards.  Set Lynx to use codepage 437 to avoid
      getting weird characters.

      EGA and VGA users may be able to get other codepages loaded into memory
      using country.sys and other DOS configuration commands.  I have not
      experimented with this yet, but in theory you should be able to use
      other codepages with telnet by doing that.  (If you try this out please
      let me know how it works!)

    Terminal Types:

      By default if the telnet server asks type type of terminal is
      connecting this code will report back as 'ANSI'.  This happens during
      telnet option negotiation.

      If you want to experiment with other terminal types supported by your
      system then you can change the string that gets reported.  See the
      section entitled 'Advanced Setup' for instructions on how to do this.

      If you just want to make a temporary change most Unix systems have a
      TERM variable in the environment that you can alter.

      Depending on your system there may be several suitable terminal types
      to explore.  Older Linux systems have over 20 variants of ANSI terminals
      to choose from.  Newer Linux systems might just have 'ANSI' and
      'PCANSI' to choose from.  Look in /usr/share/terminfo/ for possible
      termcap definitions to play with.  If you want to make a custom termcap
      for this program contact me and I'll tell you exactly what I
      implemented.

    Monochrome Adapter Users:

      The monochrome adapter does not display color, but it does have the
      ability to underline characters properly.  If you are on a true
      monochrome display adapter (MDA) then you should set your terminal type
      to 'pcansi-mono', or something similar that tells the server that you
      have a terminal with true underlining capability.  The standard ANSI
      setting will work, but will not enable underlining.


Special note: Telnet BBSes and MUDs

  Not everything out there claiming to be a telnet server is actually running
  a compliant telnet server that does telnet option negotiation.  A lot of
  telnet BBBes and multi-user dungeons fall into this category.  If you are
  having trouble trying to connect to something that is not a standard
  telnet server, try using the "-sessiontype raw" option.  You will still get
  ANSI emulation but all of the telnet protocol negotiation code will be
  disabled.  This is done automatically when you connect to anything other
  than port 23.

  Assuming that works, you might need to turn on local echoing using Alt-E.


[Enter] key handling

  The Telnet standard spells out that a "newline" character is comprised
  of a CR (carriage return) followed by an LF (line feed).  CR by itself
  or LF by itself is not technically a newline.

  By default when you press the [Enter] key Telnet will send a CR/LF
  pair.  Some telnet servers are loose in their interpretation of the
  spec and will accept either CR or LF by themselves as a newline.  If
  this happens it will look like you are pressing the [Enter] key
  twice each time you use it.

  If you are being plagued by a server that does this you can use
  Alt-N to select whether Telnet will send a CR/LF, CR or LF when
  the [Enter] key is pressed.  The help screen will show you the
  current setting.

  Regardless of this setting you can always send a CR by pressing
  Ctrl-M and send a LF by pressing CTRL-J.


Advanced setup

  There are some options that you can specify in the MTCPCFG file to
  override default behavior, such as the initial state of toggles.
  Below is the list:

    TELNET_VIRTBUFFER_PAGES n    Replace n with a number from 1 to 8
    TELNET_CONNECT_TIMEOUT  n    N is time in seconds to wait for a connection
    TELNET_AUTOWRAP n            Use 0 for autowrap off (default), 1 for on
    TELNET_SENDBSASDEL n         Use 1 to send DEL chars when Backspace is hit
    TELNET_TERMTYPE termtype     Report 'termtype' as your terminal type
                                 during telnet option negotiation
    TELNET_SEND_NEWLINE chars    Send [Enter] as chars (see below)

  By default the number of Virtual Buffer Pages is 4, the connection timeout
  is 10 seconds, autowrap is turned on and sending DEL chars when the
  Backspace key is hit is on.  The terminal type string is set to 'ANSI'.

  The valid values for TELNET_SEND_NEWLINE are "CR/LF", "CR", or "LF".
  The default is CR/LF, which is what the telnet standard calls for.
  (See the section on [Enter] key handling above for details.)

  Examples:

    TELNET_SEND_NEWLINE CR/LF    (Default: send both CR and LF)
    TELNET_SEND_NEWLINE CR       (Send just a CR)
    TELNET_SEND_NEWLINE LF       (Send just an LF)


Special Keys sent to your server at runtime

  Cursor keys (Up, Down, Left Right)
  Home
  Insert
  Back-Tab (shift Tab)


Special keys interpreted locally

  PageUp and PageDown: Go up and down through the backscroll buffer

  Alt-H: Show a combined help and status screen
  Alt-B: Toggle sending DEL chars when the Backspace key is used on and off
  Alt-E: Toggle local echoing on and off
  Alt-N: Toggle between sending [Enter] as CR/LF, CR or LF
  Alt-R: Refresh the screen from our local virtual buffer.  (Should not
         be needed unless I have a screen drawing problem)
  Alt-W: Toggle automatic wrapping around the right margin on and off
  Alt-X: Exit the program (Ctrl-Break does this too)

  When you use one of the toggle options a single beep means it was
  turned off, while a beep followed quickly by a higher pitched beep
  means it was turned on.


Support

  Have a comment or need help?  Please email me at mbbrutman@yahoo.com.  You
  can also start a thread on http://www.brutman.com/forums (Mike's PCjr Page)
  in the "Programming" area.


Recent changes

  2010-05-18:

    Add Alt-N to toggle between sending [Enter] as CR/LF, CR or LF

  2010-11-27:

    Misc TCP library changes to improve handling when buffers
      are full.
    Watcom runtime workaround: improve compatibility with older machines

  2010-06-21:

    Ported to Open Watcom.  Note: The CGA snow code has been removed
    temporarily.

  2010-04-22:

    Maintenance release for the underlying TCP library.  TCP checksums
    should be computed correctly all of the time now, and are much faster.

  2010-03-21: Fix a bug involving servers with high numbered telnet options.

  2009-12-27:

    Add local echoing toggle
    Bug fix: [Enter] key should send CR/LF, not just CR
    Bug fix: Monochrome displays were freezing
    Bug fix: Monochrome displays were not underlining
    Add -sessiontype command line option and implement raw mode

  2009-12-12: Add support for cursor position reporting


More information: http://www.brutman.com/mTCP

Created November 2009, Last updated May 20th, 2011
(C)opyright Michael B. Brutman, mbbrutman@yahoo.com
