CHANGES  (formerly readme.2nd)

If you are programming with the Waterloo TCP library, the following notes
may prove helpful. Latest changes are added at the top.

- - -

******************* Changes version 2.2 dev.rel.10 ******************

* makefile.all change: Added support for Borland on Win32 (preliminary, not
  fully working. Only static library at the moment).

* ./util/mkmake.c changes for S-Lang 2.x; the preprocessor API was changed
  in version 2.0.

* Added Pelles-C support (__POCC__) for Win32 targets.
  Ref: http://www.smorgasbordet.com/pellesc/

* src/iconv/*.* change: Ran these sources through GNU `ident'.

* pcrecv.c change: For UDP sockets, drop packets looped back by NDIS3PKT
  or SwsVpkt drivers under Windows.

* inc/sys/wtypes.h change: Include <stdint.h> for OpenWatcom 1.3 or later.

* ufortify.h change: Add `FORTIFY_GLOBAL_REPLACE' to debug `GlobalAllocPtr()'
  and `GlobalFreePtr()'. Used by packet32.c.

* tcp_fsm.c changes: Carey Evans <carey.evans@gmail.com> rewrote the
  TCP reassembly code in `tcp_process_data()'. Added functions
  `append_out_of_order()', `prepend_out_of_order()' and `copy_in_order()'.

* cpumodel.* changes: Integrated some changes from Carey Evans
  <carey.evans@gmail.com>.

* getnet.c fix: forgot to set `n2->n_addrtype = n->n_addrtype' in
  `ReadNetworksFile()'.

* netaddr.* change: Renamed `inet_atoeth()' to `_inet_atoeth()'.

* Added ./bin/hx-dos.mak for making Watcom + HX-DOS sample programs.

* wdpmi.c change: Added detection of HX-DOS extended programs;
  `dpmi_is_hxdos()'.

* sys/wtime.h change: Don't include <sys/times.h> for MingW. It's no
  longer part of MingW.

* pcdhcp.c change: Call `setdomainname()' with `len+1'. Noted by
  <flavm76@yahoo.com>.

* pctcp.h, <tcp.h> change: Renamed "mtu" and "mss" to "_mtu"/"_mss".
  Due to clashes with OpenSSL etc.

* sys/ioctl.h change: Provide prototype for `ioctl()'.

* Added several typecasts to silence build with gcc 4.0.

* ioctl.c fixes: Carey Evans fixed setting and getting netmask;
  case SIOCGIFNETMASK, SIOCSIFNETMASK and SIOCGIFCONF.

* config.h / packet32.* / winpcap.c change: Win32 only. Added USE_DYN_PACKET
  to load packet.dll dynamically. Thus allowing Watt-32 to work with Win32
  programs on Win-9x/ME.

* winpcap.c change: Replace `printf' with `(*_printf)' in `show_link_details()'.

* transmit.c change: `errno' changed from ENOTCONN to EPIPE if tcp-state
  is wrong or `tcp_tick()' fails.

* receive.c change: `errno' changed from ENOTCONN to EPIPE if `tcp_tick()'
  fails.

* makefile.all change: Use `ml' to assemble under Visual-C and Windows
  (not `tasm').

* tcp_fsm.c bug fix: The detection of keepalive in `tcp_process_ack()'
  was wrong; should be "SEQ = RCV.NXT". Moved that to `tcp_estab_state()'
  and reply with an ACK if we didn't sent anything else.

* gethost.c, gethost6.c, getserv.c, getprot.c, getnet.c changes: Plug the
  memory-leak in `endXent()' functions; only return if `_watt_fatal_error'
  is set (possible on DOS only). Otherwise free the linked lists.

* pcsed.c change: `_eth_join_mcast_group()' tries to set RXMODE_MULTICAST1
  if not already set. If `_pkt_rxmode' is multicast-2 or promiscous, there
  is no need to set mcast-1 or retrieve the multicast list.

* pcpkt.c fix: Changed the `POKEL()' arguments for X32VM and POWERPAK
  targets.

* makefile.all change: No need to use `%WATT_ROOT' for Watcom targets.
  Output rule `$(LINKARG)' only for Win32 target.

* ioctl.c change: Handle `SIOCSIFFLAGS' command, but only for SOCK_PACKET
  type sockets.

* select.c change: New function `handle_ready()' called from `read_select()'.
  But for DOS only.

* misc.c change: In `watt_kbhit()', don't test the unget character (`_cbyte'
  or `ungetchar'). That caused the function to produce fake kbhits after
  `getch()' is called.

* Added test program: src\tests\packet.c for AF_PACKET testing.

* socket.c change: Redesigned Rx-pool logic for AF_PACKET sockets. It
  now uses a `pkt_ringbuf' buffer of `MAX_PACKET_BUFS' (10) receive-
  buffers. To-do: make the number configurable?.

* winmisc.c change: Added `WSAStartup()' for Winsock compatability.

* x32vm.c change: Save and restore ESI, EDI and EBX registers in some
  places.

* tcp_fsm.c change: Limit the Tx buffer size to 6*MSS if using NDIS3PKT
  driver. This is to bypass the limitated buffer count allocated for a
  DOS-box.

* pcpkt.c change: Added config keyword "PKT.TXWAIT" (pkt_txwait).
  This specifies how many msec to wait between retries if Tx fails.
  If using NDIS3PKT, this value is at least 1.


******************* Changes version 2.2 dev.rel.9 *******************

* accept.c change: Added `_sock_sig_pending()' to be able to get out of
  a stuck loop. Changed condition for connected slot; state >= ESTAB and
  state < CLOSED.

* poll.c change: Adapted to handle `MAX_SOCKETS' file/socket handles.
  Does not use djgpp's select(). Added `SOCK_DEBUGF()'.

* poll.h change: Moved this header to ".\inc\sys" since no targets have
  it.

* select.c change: `read_select()' and `write_select()' now uses djgpp's
  own select() when checking standard handles (0-2). This allow testing
  if redirected handles are ready.

* udp_dom.c change: Host-names with a trailing '.' shall not cause resolve()
  to do a recursive DNS lookup. E.g. resolve("foo.") should simply ask for
  address of "foo" and not "foo.domain" etc.

* makefile.all change: Added support for LCC-Win32 compiler (experimental).
  CFLAGS for Digital Mars changed; does not use options `-NS' and `-C'.

* pcpkt*.* change: Adapted for `USE_FAST_PKT' with Pharlap, PowerPak
  and X32VM extenders. This is now default for all 32-bit targets
  except Win32.

* netaddr.c change: `_inet_ntoa()' uses 2 buffers in round-robin if `s'
  is NULL.

* bsdname.c change: Changed initial if-test; check that `s->tcp.hisaddr'
  and `s->tcp.hisport' are non-zero.

* accept.c change: Protect accept-loop with `_sock_crit_start()' and
  `_sock_crit_stop()'.

* socket.h change: `MAX_SOCKETS' increased to 5000. Not really effective
  for djgpp since it is limited by max # of DOS handles that can be
  created.

* config.h / socket.[ch] change: Removed `#define USE_SOCK_PACKET'. Code
  inside it is now default for `USE_BSD_API' code.

* pcdhcp.c change: `set_gateway()' deletes any previous configured gate-
  way if value in W32DHCP.TMP is non-zero.

* watt-32.rc change: Added BUILDER (compiler) to product-version field.
  Removed watt-32.ico statement.

* winpcap.c change: Test if running Win-NT4 or later; winpcap.c doesn't
  work for Win-9x/ME/CE.

* sock_ini.c change: Watcom can use register calls for Win32 targets;
  I.e. don't generate an "#error" message. But a Watcom register-call
  based watt-32.dll will not work with MSVC or MingW programs.

* misc.h change: Watcom uses 'i64' suffix for 64-bit values.


******************* Changes version 2.2 dev.rel.8 *******************

* pcmulti.c change: Fixed input length calculation. Protect against
  multicast-reports looped back by driver (NDIS under Windows).

* sockopt.c change: Set `_multicast_on' if any multicast options are set
  or queried. Added handling of `IP_MULTICAST_TTL' and `IP_MULTICAST_LOOP'
  (allthough alway 0).

* bsddbug.c change: Change to enable use of `OutputDebugString()' under
  Windows. Enabled by "SK_DEBUG.DEVICE = $ODS" in wattcp.cfg.

* pcdbug.c change: Added decoding of T_TXT records in `dns_resource()'.

* pcarp.c change: In `_arp_handler()', print an address conflict warning
  if a duplicate IP is found on the network.

* pctcp.c change: Protect against nmap NULL scans. If we receive a TCP
  segment to a closed port with all flags off, just drop it (don't answer
  with a RST).

* pcdhcp.c change: Call `dhcp_open()' in `DHCP_read_config()' to allocate
  a socket. This is needed by DHCP state functions BOUND and RENEWING
  called in `eval_timers()'.

* pcsed.c change: Changed `_eth_arrived()' to allow being called with
  "type == NULL".

* misc.h change: This file was becoming too big. Moved the timer.c
  prototypes and macros to timer.h.

* packet32.* / winpcap.* changes: No need to have the WinPcap SDK installed.
  Copied <NTDdNdis.h> WinPcap and added BPF structures to Packet.h.
  `pkt_get_stats()' updated to return total statistics.
  Added profiling code in `PacketRequest()'.

* misc.c change: New function `fopen_excl()' that on Windows opens a file
  in share-mode but denying write by other processes.  Uses `fdopen() on
  file-descriptor.

* pcdbug.c change: Refined `is_looped()' to consider the case of Winsock
  sending (with a different source IP-address). Don't consider that a
  looped packet.

* poll.c change: `except' is a pseudo-reserved keyword in Digital-Mars on
  Win32. Undefine it before use.

* pcstat.c change: `tcps_connattempt' is connection attemptes on *output*.
  `tcps_accepts' is connection accepted on *input*. No counter AFAICS for
  attempts to a closed socket (SYN scans).


******************* Changes version 2.2 dev.rel.7 *******************

* pcsed.c change: In `_eth_send()' change how IP loopback-addresses
  should be handled; If "(loopback_mode & LBACK_MODE_WINSOCK)", send
  to WinPcap driver and the packet is sent on the wire. A later vesion
  will try to send to the Winsock loopback provider (a TDI?). The config
  keyword "IP.LOOPBACK" thus changed to a bit-mask.

* ports.c change: Allocate `lport_inuse' from heap. Free in rundown
  function `exit_localport()'.

* bsddebug.[ch] change: `_sock_enter_scope()', `_sock_leave_scope()' and
  `_sock_dbug_flush()' are now macros.
  Whole file only built if "USE_DEBUG" and "USE_BSD_API" are defined.

* udp_dom.c change: Optionally try querying the Windows DNS cache before
  sending a query to the DNS server(s). Enabled by "DOMAIN.WINDNS = 1".
  WIN32 only.

* New file winmisc.c for WIN32 stuff only. New functions `WinDnsQuery*()'
  for querying the Windows global DNS cache for A and PTR records.
  Controlled by `WINDNS_x' bits in `dns_windns'.

* misc.c change: Added `memdbg_init()' for controlled reporting of runtime
  asserts from MSVC's CrtDbg (WIN) and Fortify's reporter. `crtdbg_report()'
  traces to `stderr' and causes a breakpoint on assert failures. Hence the
  debugger attaches to process and gives a stack backtrace. Later a stack-
  walker will be added for finer details.

* misc.[ch] change: Renamed `errno_s' to `_w32_errno'. Increased # of
  `exit_list[]' elements to 40.

* Renamed "WATT32_DLL" to "WATT32_DOS_DLL" to not confuse it with generation
  of a Win32-DLL version. Renamed "USE_BSD_FUNC" to "USE_BSD_API".

* config.h change: Removed "USE_BSD_FORTIFY". Added "USE_CRTDBG" if MSVC
  debug-mode is used. Include <crtdbg.h> in "wattcp.h" only.
  Initialise malloc debugging in `memdbg_init()'. Due to data-segment
  overflow in most program, USE_BSD_FUNC, USE_DHCP etc. are removed for
  all large-models.

* wattcp.h change: Renamed "_DLL" to "WATT32_DLL" due to clash with Visual-C.

* pcpkt.c change: Added asynchronous transmit feature. If this fails in
  `pkt_send()', revert back to normal sync transmit. Enabled by
  "pkt.txmode = async,timeout" in WATTCP.CFG.

* gettod.c change: Test for `user_tick_active' set by `init_timer_isr()'
  and return local-time.

* time.c change: (djgpp) Restore previous SIGALRM handler and interval
  timer value in `exit_timer_isr()'.

* winpcap.c changes: Configuration keywords for Windows only:
  "PCAP.DEVICE"    -> NPF.SYS device-name to use. Default is none which
                      will selects the 1st suitable device found.
  "PCAP.DUMPFILE"  -> Filename for dumping WinPcap details.
  "PCAP.TXRETRIES" -> # of transmit retries.
  "PCAP.TXMODE"    -> Select overlapping transmit mode (not yet).
  "PCAP.RXMODE"    -> Startup receive mode.
  "PCAP.RXBUFS"    -> Number of kernel buffers for NPF.SYS.
  "PCAP.HIGHPRIO"  -> Select real-time priority for the capture thread.

* New files packet32.[ch]: Heavily modified, simplified and ANSI-fied from
  the WinPcap version. With this addition, Watt-32 on Windows actually works
  very well !

* New files winpcap.[ch]: Added Windows and WinPcap support. WinPcap driver
  and SDK is available from http://winpcap.polito.it/.

* configur.bat changes: "depend.wat" renamed to "watt32.dep".

* misc.c etc: Dropped use of `BIG_ENDIAN_MACHINE' define. Test only using
  `USE_BIGENDIAN'.

* pcconfig.c / timer.c change: Splitted "PROFILE" into "PROFILE.ENABLE" and
  "PROFILE.FILE". `profile_init()' now called from `tcp_post_init()'.

* pcdbug.c bug fix: DNS over TCP has a 2-byte length prefix. So call
  `dns_dump()' on `data+2' in `tcp_dump()'.

* pcdbug.c change: Decode `T_MX' resource records in `dns_resource()'.

* gethost?.c change: `h->h_name' is now correctly replaced with CNAME if
  present in udp_dom.c reply. The original query name is then placed in
  `h->h_aliases[0]' (only supports 1 alias per node).

* gethost?.c / udp_dom.c change: Extract alternate list of addresses from
  DNS reply; main address is taken from 1st Resource Record and the remaining
  A-records is put in alternate list `dom_a4list[]' or `dom_a6list[]'. Used
  by `getXbyY()' functions to build the `h->h_addr_list[]' in `fill_hostent()'.

* pcdbug.c change: Added dumping of WINS/WINS-R records in `dns_resource()'.

* connect.c change: Fixed timeout detection in `nblk_connect()'.
  I.e. if there is no "ARP response", use a new `sock->nb_timer' to detect
  this situation. `tcp_no_arp()' already have set the `sock->so_error'.

* New files dynip.[ch], implements a simple dynamic IP update client.
  See ".\bin\dynip.cfg" for configuration. This file could be included from
  "wattcp.cfg".

* sockopt.c change: setting TCP_MAXSEG never fails; asserts the value is
  between MSS_MIN and MSS_MAX. Handle getting/setting SO_DONTLINGER.

* tcp.h change: Set `*statusptr' = -1 on `tcp_tick()' fail.
  To be consistent with other `sock_wait_x' macros.

* tcp_fsm.c change: handle TCP options below. Doesn't do anything with them
  though.

* pcdbug.c change: Print "Alternate Checksum Request/Data" TCP options.
  TCPOPT_CHKSUM_REQ (14) and TCPOPT_CHKSUM_DAT (15) from RFC-1146.

* pcdhcp.c change: Make the default "W32DHCP.TMP" in %TEMP% directory (unless
  overridden by DHCP.CONFIG). Fix for `DHCP_read_config()' returning when it
  shouldn't. Reported by Doug Kaufman.
  Renamed `_dodhcp' to `DHCP_do_boot'.

* strings.c fix: `strreplace()' didn't advance string in the while-loop.
  Reported by Doug Kaufman.

* pcdbug.c change: Print MD5-signature TCP option.

* pctcp.c change: Added insertion and checking of TCP MD5-signature option
  from RFC-2385.

* New file tcp_md5.c: Based on RFC-2385 and tcpdump sources, I made this
  little extension. A single API function `tcp_md5_Secret()' is used to
  calculate the MD5 fingr-print. No function for exchanging secrets with
  other peers.

* shutdown.c change: Sets `socket->so_error = ESHUTDOWN'.

* pcpkt.c change: `release_real_mem()' didn't free DOS memory in the rare
  case when `_pkt_inf->rm_mem.pm_offset' was 0 (Win9x/ME). Now tests that
  `_pkt_inf->rm_mem.rm_offset' is zero before calling DPMI function 101h.
  Reported by Doug Kaufman.

* get_ai.c change: Rewritten to plug a memory leak (`aplist' and `apbuf'
  wasn't freed).

* New files iconv\*.h, idna.* and punycode.* to support internal characters
  in domain-names. Function `IDNA_convert_to_ACE()' called from udp_dom.c
  to convert a domain-name to ACE format. Function `IDNA_convert_from_ACE()'
  called from udp_rev.c to convert result to native charset. Set WATTCP.CFG
  keyword "domain.idna = 0" to disable.

* socket.c etc. change: Removed `USE_LIBPCAP' and added support for
  `SOCK_PACKET' sockets (raw link-layer). Added header <net/if_packet.h>
  from Linux 2.x. Effective only if "USE_SOCK_PACKET" is defined (default
  for all 32-bit targets).

* pcicmp.c change: In `icmp_send_unreach()' limit sending to 20 messages
  per second. Ref. RFC-1812.

* pctcp.c change: In `tcp_opt_timestamp()' send `TSval' as # msec since
  `watt_sock_init()' was called (relative `start_time').

* pctcp.c change: If socket is listening (LF_IS_SERVER), `tcp_sockreset()'
  resets various socket params and goes back to listening.

* pctcp.c fix: `sock_mode()' called with neither TCP_MODE_NAGLE nor
  TCP_MODE_NONAGLE bits set was turning Nagle off.

* pcstat.c change: Added counter for `tcpstats.tcps_closed' when sending
  FIN or RST.

* pctcp.c change: Fixed config keyword "TCP.TIMER.RESET_TO = 0" to mean
  always send a reset for a connection to a closed port. Otherwise, send
  RST maximum once per "TCP.TIMER.RESET_TO" time (default 100 msec).

* makefile.all change: Since some make program have problems with sources
  in multiple directories I moved .c-sources from zlib/ to src/ and prefixed
  with `zl_'.

* config.h change: Added options for zlib `Z_PREFIX' and `FASTEST'.

* pcconfig.* change: `ARG_ATON' renamed to `ARG_ATOIP'.


******************* Changes version 2.2 dev.rel.6 *******************

* pcintr.c change: Save and chain to previous SIGALRM handler (djgpp only).

* misc.h change: Printing a `double' does *not* use "lf" for small/large
  models. Uses "f" as all others.

* timer.c change: Bernd Omenitch <Omenitsch@cashpoint.at> contributed code
  for timer ISRs; init_timer_isr(), exit_timer_isr() and new_int_8().
  Adapted for djgpp, Pharlap and PowerPak also.

* pcconfig.c change: Renamed some "DOMAIN" keywords:
   "domain_list"    -> "domain.suffix" (to agree what Windows et.al calls it).
   "domain_to"      -> "domain.timeout"
   "domain_recurse" -> "domain.recurse"

  Supports old keywords too, but with a deprecated warning (deprecated_key()).
  New experimental keywords:
    "domain.do_ipv6" and "domain.idna" : See wattcp.cfg.

* pctcp.c change: `_udp_cancel()' and `_tcp_cancel()' calls new function
  `sock_reduce_mss()' to reduce MSS in case of an `ICMP_UNREACH_NEEDFRAG'
  code. Has no effect on UDP sockets at the moment (not sure it should have).

* pcicmp.c change: Added test for `ICMP_UNREACH_NEEDFRAG' code. Get `next MTU'
  from ICMP-packet (this is 0 if router doesn't support RFC-1191) and call
  `_*_cancel()'.

* udp_dom.c / udp_rev.c change: Support national characters in DNS name
  (forward and reverse) lookups. Only if compiled with `USE_IDNA' (ref.
  config.h). This is experimental and may not be able to convert every
  charsets to UTF-8 codepoints.

* res_send.c bugfix: Forgot to call `sock_close()' for UDP resolver socket.
  This caused `udp_close()' in a new `udp_open()' to crash since socket
  was free'd but memory was invalid (the wonders of paging under Windows).

* signal.c change: Rewritten to *not* use `setjmp()' and `longjmp()' as
  this is safest when the application also traps SIGINT or ignores SIGINT
  completely (`signal(SIGINT,SIG_IGN)'). Now does *not* trap SIGALRM since
  we really only need to issue EINTR errors for SIGINT.

* select.c change: Now sets `errno' to `EINTR' if a signal was caught and
  return -1. I.e. `_sock_sig_pending()' is non-zero.

* socket.c bugfix: `_TCP_open()' did set "->flags |= LF_NOCLOSE" on non-
  blocking connections causing ECN/CWR flags to be sent in TCP-header.
  Now AND with `tcp_flagMASK'. Should be "->locflags |= LF_NOCLOSE".

* ip4_out.c change: Added a `_ip4_dont_frag' flag (default FALSE) to control
  default DF bit in IP-header. Changed from config via "IP.DONT_FRAG = 0/1".

* pcarp.c change: Make `arp_rexmit_to' configurable; "ARP.RETRANS_TO" in
  WATTCP.CFG. Default is 250 msec.

* socket.c change: Refined `icmp_callback()' to set socket error to ENETUNREACH
  if receiving "ICMP Network Unreachable". Otherwise EHOSTUNREACH on other
  "ICMP Unreachable" codes or ECONNREFUSED on "ICMP Parameter Problem".

* pcdbug.c change: Decode SOA records in DNS debugger.

* pcdbug.c bug-fix: `struct DNS_Hdr' bit-fields was in wrong endian order.
  Added printing of `s->recv_next' ("RCV.NXT") and `s->send-next' ("SND.NXT").

* fcntl.c/ioctl.c change: Non-blocking sockets should have infinite connect
  timeout (or be controlled by calling application). Therefore reset the
  timers `sock->timeout' and `sock->tcp_sock->timeout' when setting SS_NBIO
  flag on socket.

* udp_dom.c change: Don't quit `lookup_domain()' on receiving the wrong
  ID. That could be caused by two rapid requests and crossing responses.
  E.g. called from `getaddrinfo()'.

* udp_rev.c change: `query_init_ip6()' now uses the "ip6.arpa" domain for
  reverse lookup of IPv6 addresses.

* pcdbug.c changes:
   - Prints some of transport layer header in `ip4_orig_dump()'.
   - Prints "RTT-diff" in msec.
   - Rewritten IP4-fragment printing.
   - `write_pcap_packet()' now uses CPU-timestamp from `struct _eth_last'.

* udp_dom.c change: Rewritten `unpack_domain()' to safe-guard against
  trashed DNS-server responses.

* gethost.c fix: Calling `netdb_init()' from `endhostent()' could cause
  recursion problems if `sock_exit()' was called before `endhostent()'.
  It now only checks file and filename. Return if either is NULL.

* tcp_fsm.c / pctcp.c change: Added `tcp_reasm' config-variable to work
  around a bug (?) in TCP reassembly logic. Setting "tcp.reasm = 0"
  (default) prevents inserting a possibly overlapping fragment into the
  receive buffer. Ref. `tcp_ProcessData()'.

* pctcp.c change: In `tcp_options()'; don't send a Timestamp option in a
  FIN segment.

* pcpkt.c change: Fixed the `loadds' pragma for Watcom in `pkt_release()'.
  Previously it had no effect. Now it loads the default DS register.

* chksum.h change: `inchksum()' renamed to `in_checksum()' and
  `inchksum_fast()' renamed to `in_checksum_fast()'. Renamed `*_chksum()'
  to `*_hecksum()' everywhere.

* receive.c change: Added function `recvmsg()' for Linux compatibility.

* tranmsit.c change: Added function `sendmsg()' for Linux compatibility.

* misc.c change: Added function `rundown_add()' and `rundown_run()' for
  controlled calling of "atexit" functions. There is now only one `atexit()'
  function (`sock_exit()') which in normal exits calls `rundown_run()' to
  call all registered rundown functions.  Exceptions and signals are
  handled a bit differently.

* misc.c change: Rewrote the `WATT_ASSERT()' macro to call new function
  `assert_fail()'. Which stores assert cause in a buffer which is also
  printed to debug-file at exit.

* pc_cbrk.* change: Renamed `watcbroke' to `_watt_cbroke' and
  `wathndlcbrk' to `_watt_handle_cbreak'. Added compatibility macros to
  <tcp.h>. Ignore BREAK checking for djgpp-version under Windows (i.e.
  for DOS-versions 7.0+ (Win-9x/ME) or 5.5 (Win-NT+). This seems to trap
  SIGINT generation more reliably. If BREAK checking was on, NTVDM is
  very quick to terminate running program without SIGINT beeing caught.

* signal.c fix: SIGALRM (for djgpp) should be blocked while we're in loops
  in `recv()', `connect()' etc. Use `_sock_sigalrm_pending()' to check if
  SIGALRM was generated and pending and return -1 with `EINTR' set.

* misc.c change: Detect true DOS-version (store to `_watt_os_ver').

* pcicmp.* change: Renamed some structures to make it possible to include
  both "pcicmp.h" and <netinet/ip_icmp.h> in same file (tftp.c).

* socket.* change: `SK_FIRST' is now 3 for all targets to avoid confusing
  socket with standard handles.

* select.c change: It's now possible to call `select_s()' on stdin, stdout
  and stderr (redirected handles not handled, should test with `isatty()'?).

* transmit.c fix: SOCK_DGRAM sockets couldn't be used in `write_s()' and
  `writev_s()'. Now takes `to' address from `socket->remote_addr'.

* pctcp.* change: Removed `_tcp_syn_hook' etc. Added BSD-socket operations
  (BSO_xx) called via `_bsd_socket_hook' instead.

* wattcp.h change: Renamed `sol_callb' to `icmp_callb' since this callback
  is only used for ICMP events.

* gethost6.c change: Added functions `ReverseHosts6List()' and
  `DumpHosts6Cache()' which is called from `_sock_dbug_exit()' at program
  exit (Only if `USE_DEBUG' is defined).

* gethost.c change: Added functions `ReverseHostsList()' and
  `DumpHostsCache()' which is called from `_sock_dbug_exit()' at program
  exit (Only if `USE_DEBUG' is defined).

* pcdhcp.c fixes: `BROADCAST_FLAG' was set in wrong (host) endian format.
  Added flag `dhcp_did_gratuitous_arp' checked from `_arp_check_gateways()'.
  `setdomainname()' was truncating the last character. I.e. use `len+1'
  since DHCP uses Pascal style strings and `setdomainname()' expects max
  `len' to make room for 0-terminator. Same applies to `DHCP_TFTP_SERVER'
  and `DHCP_BOOT_FILENAME' tags.

* sock_ini.c change: Don't call `_get_machine_name()' unless hostname
  is the default ("random-pc").

* pcsed.c change: Added `_eth_mac_len' which is true length of an MAC-
  address (6 for Ethernet, 7 for AX25 etc).

* Added ".\inc\err.h" file for Net/FreeBSD compatibility. Simply includes
  <sys/werrno.h>.

* inc\netinet\in.h change: Added `ss_len' to `struct sockaddr_storage'.
  Not used in Watt-32 library, but some Net/FreeBSD programs requires it.

* pcconfig.c change: Default value for `sock_data_timeout' (DATATIMEOUT
  in WATTCP.CFG) set to zero. Too much confusion caused by the old
  default value of 120 sec.

* strings.h change: Added printf argument check on `_printf'. Needs
  gcc 3.x I think.

* pcstat.c change: New counter for Window update ACKs (tcps_sndwinup).

* tcp_fsm.c change: Fix for closed TCP-window (on our receiving side).
  Added `s->locflag' LF_WINUPDATE. Tested in `tcp_Retransmitter()'.

* pcicmp.c change: Assert there's enough TCP-header data in `orig_ip'
  before calling `tcp_cancel()' for an ICMP_UNREACH message.

* src\tftp.c, bin\tftp\tftp.c and \inc\arpa\tftp.h changes: Fixes for
  receiving > 32 MByte files. Thanks to Alexander Starostin <assur@esc.ru>
  for a patch.

* Fixes from Doug Kaufman:
    - Move the `priorityname[]' and `facilityname[]' out of <sys/syslog.h>
      and into src\syslog.c.
    - Fixed some gcc warning in <sys/cdefs.h>, src\pcdbug.c, src\transmit.c.
    - Fixed name clashes with <sys/syslog.h> in bin\talk program.
    - Various long-file names fixes in some djgpp makefiles and mtr/bping.

* pctcp.c change: Fixed yet again the detection of a reset connection.
  The RST is accepted if SEQ >= RCV.NXT and SEQ <= RCV.NXT-RCV.RWIN+1.
  Note: The RST is checked again in `tcp_estab_state()'

* pctcp.h change: New hook pointer `_bsd_socket_hook' replaces `_ip4_raw_hook',
  `_ip6_raw_hook', `_tcp_syn_hook' and `_tcp_find_hook'.

* socket.c change: New function `socket_op_demux' set in `socket()'.
  Calls various functions for each operation `op'.

* udp_rev.c change: `reverse_resolve*()' now takes an extra parameter
  `size'.

* udp_dom.* change: Rewritten to avoid module-global variables. Renamed
  some structures. Moved udp_rev.h into udp_dom.h. Fixed `extract_cname()'.

* pcconfig.c change: Added `dns_do_ipv6' to config-table.

* misc.c change: Rewrote `intel16()' and `intel()' without the `SWAP*()'
  macros (to prevent gcc 3.3.x warnings).

* udp_dom.c change: Added `dns_do_ipv6' to optionally disable use of
  AAAA records. Handy for programs using `getaddrinfo()' with unspecified
  hints. This causes slowdown because AAAA records are sent before A
  records. Very few host's have an IPv6 address at time beeing.

* udp_rev.c change: Return length of request from `qinit_ip?()' and
  use that in `sock_write()'. Bug fix in `qinit_ip6()'.

* config.h change: Removed USE_ETHERS and merged in USE_BSD_FUNC.

* bsdbug.c change: Compile file with "USE_BSD_FUNC || USE_DEBUG"
  Reported by Nagy Daniel.

* get_xby.h change: Put internal functions in "_w32_" namespace.

******************* Changes version 2.2 dev.rel.5 *******************

* File name changes: Moved all network address functions from udp_nds.c
  and pcbsd.c into netaddr.c.  Moved rest of pcbsd.c to gethost.c.
  Renamed udp_nds.h to netaddr.h.
  Renamed pcbsd.h   to get_xby.h.
  Renamed gxby_r.c  to get_xbyr.c.

* wdpmi.c change: Disabled use of `dpmi_except_handler()'. It's supposed
  to work only wih Causeway DOSX, but doesn't. Due to lack of a good
  Watcom debugger, I've failed to find of why. Any takers?

* getprot.c / getserv.c changes: Sets `h_errno = NETDB_SUCCESS' on success
  and `h_errno = NO_DATA' on fail.

* makefile.all change: Add option `-zc' for Watcom small/large models.
  This puts constants in the code segment to free up the DGROUP for other
  data.

* pcdbug.c change: Experimental support for gzip'ed pcap capture files.

* pctcp.c change: `tcp_write()' speedup; call `tcp_send()' immediately if
  Tx-queue length is above minimum of socket max_seg or MSS. Should ideally
  be the real Path MTU - 40.

* pcdhcp.c change: In `make_boot_header()': Only set `dh_ciaddr' to non-
  zero in BOUND, RENEWING or REBINDING states.

* netaddr.c change: `inet_aton()' no longer checks for non-NULL `adr'
  argument. Return value changed to `int'. Return 1 on success.

* pcarp.c change: Send a gratiotous ARP on startup (in _arp_check_gateways()).
  Controlled by "ARP.GRATIOTOUS = 1"  (default is 0).

* receive.c change: Added function `readv_s()'; reads into a iovec
  structure.

* pcsed.c change: Send to loopback only if destination is 127.x.x.x.

* pcsed.c/pcpkt.c change: Added preliminary support for class 17
  (Token-Ring with expanded RIF).

* ip4_in.c change: New function `_ip4_is_loopback_addr()'.

* udp_rev.c change: Some checks for malformed replies in `getresult()'.
  Assure we don't parse beyond the received packet.

* gethost.c change: Add `dom_cname' as first alias in `gethostbyname()'.

* udp_dom.c change: Extract canonical host name (CNAME) from reply if found
  and store to global `dom_cname[]'.

* get*.c change: All <netdb.h> functions rewritten to return an array of
  NULLs in `*_aliases' fields.  E.g. `gethostbyname()' return with
  `h_aliases[0] = NULL' when there's no aliases for host-name (and not
  `h_aliases = NULL' as previously). And `get*ent()' functions never
  allocates any memory, but returns names and aliases in static buffers.

* misc.c change: Function `setup_dos_xfer_buf()' for Pharlap/X32VM changed
  to allocate a DOS-buffer if `_dx_rmlink_get()' returns a too small DOS
  transfer buffer size (i.e. `_watt_dosTbSize' < 1024). New function
  `free_selector()' called from from atexit-chain and `sock_sig_exit()'.

* pcpkt.c change: `pkt_eth_init()' now returns 0 if okay, else error-code
  from sock_ini.h. Size of `PKT_TMP()' is increased to 64 (for setting
  large multicast lists).

* sock_ini.c change: Moved the booting (BOOTP, DHCP and RARP) to new
  function `tcp_do_boot()'. Only called if at least one `_*on' variable
  is set.  Don't exit if a boot-method isn't enabled (just print a warning).
  New function `sock_init_err()' return textual result of `sock_init()'.
  Variables `survive*' renamed to `survive_*'.

* pcbootp.c change: Set exchange ID `xid' to random value from timer.

* pcdbug.c change: `filter' values defaults to zero. In case WATTCP.CFG
  isn't found we want to see all traffic (broadcast boot messages).

* config.h change: Removed `USE_BSD_*' and `USE_FRAGMENTS' for large
  memory models. Added `USE_DHCP' (since DHCP is more useful than IP
  fragments).

* poll.c change: For djgpp use `select()' to allow `poll()' to work on
  DOS file-handles as well as sockets.

* gethost.c bug fix: `gethostbyaddr()' called `inet_ntoa()' with `addr'
  and not `&addr'.

* tcp_fsm.c / pcpkt.c change: Removed use of `__FUNCTION__'. It's not
  supported by all compilers.

* pcdbug.c change: Added feature "DEBUG.PCAP = 1" allows writing Rx/Tx
  network traffic to be written in libpcap format.

* pcpkt.c change: Accept PKTDRVR vector to be in range 0x20 - 0xFF if
  specified by "PKT.VECTOR = 0xNN". This is to support 1.11+ drivers.

* misc.c change: Include "ioport.h" for __EMX__ so that "extern __inline__"
  functions are included for 'gcc -O0'. But I doubt emx is a possible
  target for Watt-32.

* pcsed.c change: `dpmi_init()' moved to top of `watt_sock_init()'.
  Call `do_exit()' if illegal DOS-extender found. E.g. stubbed to Pharlap,
  but library was compiled for Watcom/DOS4GW.

* wdpmi.c change: `dpmi_init()' now implemented for all Watcom 32-bit
  targets. Assert that run-time `_Extender' value matches compile-time
  DOSX value.

* tcp_fsm.c change: changed the criteria for doing Fast-ACK in
  `tcp_estab_state()'; If we advertised a small window (lss than MSS)
  in last segment, send ACK immediately. Not sure it's a good idea to
  send a dup-ACK if we have missed a segment (s->missed_seg[0]) as this
  will cause excessive ACK-ing.

* wattcp.h change: Added `adv_win' to `_tcp_Socket'. This holds the last
  value of our receive-window sent to peer (in _tcp_send).

* pcdhcp.c change: Added `dhcp_set_config_func()' to allow application
  to handle operations on the transient DHCP configuration; read, write
  or erase. See `struct DHCP_config' and `enum DHCP_config_op' in <tcp.h>.
  Contributed by Riccardo De Agostini.

* pcconfig.c change: New function `tcp_inject_config()' callable from
  application hook (_watt_user_config_fn). Rewritten `tcp_parse_file()'
  to be more robust; stops if ^Z is read, handles VB-style quoted strings,
  etc. Contributed by Riccardo De Agostini.

* sock_ini.c change: Added func-ptr `_watt_user_config_fn'. Handy for
  diskless operation when `_watt_no_config' is set. Contributed by
  Riccardo De Agostini.

* wattcp.h / pctcp.c change: Rearranged `sockmode' bits; The values in
  <tcp.h> in now mapped to `SOCK_MODE*' bits in `sock_setmode()' so that
  e.g. `sock_setmode (TCP_MODE_NONAGLE)' will not inadvertatly turn off
  ASCII mode if that was on.

* strings.c change: Added functions `strrtrim()' (strips trailing blanks
  from a string) and `strntrimcpy()' (strips leading and trailing blanks
  before copying to destination). Contributed by Riccardo De Agostini.
  Renamed `strlcpy()' to `StrLcpy()' in case Watt-32 was compiled with
  djgpp 2.03, but linked with 2.04 (which already has strlcpy). And vice-
  versa.

* pcpkt.c change: The `pkt_receiver_pm()' changed to cdecl. It crashed
  when compiled as register call (Watcom with PharLap).

* makefile.all change: Added option `-W' for gcc. Increased warning to
  `-w4' for HighC. This resulted in a lot of signed/unsigned warnings
  that are now fixed.

* pcbuf.* change: Return value and length arguments changed to `size_t'.
  Argument to `sockstate()' changed to `sock_type *'.

* pcrecv.* change: First argument changed from `_udp_Socket *' to
  `sock_type *'. Because those functions can be used for TCP too.

* sock_ini.c change: In `sock_sig_exit()' call `_exit()' for Watcom too
  (in addition to djgpp and High-C). This prevent a mysterious crash
  in DOS4GW that sometime happens when pressing ^Break. I suspect this
  has to do with nested use of `longjmp()' ??

* pctcp.h change: `DEF_RETRAN_TIME' reduced to 10 (msec). Gives better
  receive-speed on high-speed links with long Round-Trip Times.

* pctcp.c change: In `tcp_abort()' only send RST in states SYNSENT -
  LASTACK. Corrected ACK number check when RST is received; Accept
  ACK if it is "SND.NXT - (SND.NXT - SND.UNA + 1)".

* sockopt.c change: Handle set/get of `SO_KEEPALIVE' option.

* bsdname.c change: `_get_machine_name()' didn't setup the DS:EDX correctly
  for DOS4GW and PowerPak targets.

* pctcp.c change: Flush Tx-buffer before sending RST in `tcp_abort()'.
  Refined RST checking in tcp_handler(); The ACK is allowed to be
  SND.NXT - (SND.NXT - SND.UNA).
  In `tcp_Retransmitter()' reduce the congestion window (s->cwindow) by
  1 if there is data in the Tx-buffer. Thus relaxing sending multiple
  segments in `_tcp_send()' (the peer may have closed without we hearing
  it).

* pctcp.c change: `sock_keepalive()' changed to send 1 byte (only when
  connection is idle). BSD 4.2 will not react on zero-sized keepalive
  probes.

* pcmulti changes: Make sure `check_mcast_reports()' daemon is only added
  once. In `igmp_handler()' return if version is not 1. Renamed `IGMP_QUERY'
  to `IGMPv1_QUERY' and `IGMP_REPORT' to `IGMPv1_REPORT'.

* pctcp.c change: Added `MTU' to RTT-cache. Meant to be used in "Path-MTU
  discovery" when that's finished. Hence use this MTU for next connection
  to the same destination.

* ports.c change: Made the "RAND_LPORT" config-value default to 1;
  (use_rand_lport = TRUE).

* tcp_fsm.c/pcstat.c change: Added counters for received TCP duplicate
  ACKs and bytes. (tcpstats.tcps_rcvduppack and tcpstats.tcps_rcvdupbyte).
  Incremented in `tcp_ProcessData()' when `ldiff < 0'.

* target.h change: Removed "#define read _read" etc. macros for djgpp.

* powerpak.c change: Forgot to save/restore ESI, EDI and EBX in some places.

* tcp_fsm.c change: in `tcp_ProcessAck()', stop RTT-timer (s->rtt_time = 0)
  when all sent data have been ACK'ed (s->send_una == 0).

* pcdbug.c change: Changed printing of SACK blocks. Values are now relative
  to ACK value in TCP-header (as tcpdump does).

* pcpkt.c change: Don't call `parse_config_pass1()' if `_watt_no_config'
  is set.

* ioctl.c change: Allow setting non-blocking `SS_NBIO' state for all
  socket types.


******************* Changes version 2.2 dev.rel.4 *******************

* sock_ini.* / tcp.h change: sock_init() is now a macro to ensure that
  size of tcp_Socket / udp_Socket structures in <tcp.h> are large enough.

* timer.c change: Set `use_rdtsc' to FALSE if for some weird reason we
  failed to estimate the CPU speed.

* pcbuf.c change: `sockerr()' now takes a `const sock_type *' argument.

* wattcp.h change: Added `err_buf' to UDP_TCP_COMMON. Used in those places
  where the error string isn't a CONST string. E.g. in udp_open() when
  ARP fails.

* wattcp.h change: `MAX_WINDOW' increased to 64 kB for 32-bit targets.

* tcp_fsm.c / wattcp.h change:  Added `tx_data' pointer normally pointing
  to `tx_buf[0]'. Then in tcp_fsm.c when setting the peer-window the 1st
  time, a tx-buffer is allocated from heap. This speeds up transmissions
  since we're not limited by the 2kByte Tx-buffer, but by peer's receive
  window. Tx-buffer is freed in `_tcp_unthread()'.

* transmit.c change: Some more checks in `writev_s()'; check that total
  bytes to be sent is below `SSIZE_MAX' and number of vectors is within
  [1..IOV_MAX].

* socket.c change: TCP receive window now configurable with keyword
  "tcp.recv_win". Default value is 16 kByte (DEF_RECV_WIN in pctcp.h).

* pcbuf.c change: Added marker signatures at front and end of recv-
  buffer. Thus reducing the window by 8. Signatures checked in new
  funtion `sock_chkbuf()' called from `tcp_tick()'.

* pctcp.c change: Added a check to test if `tcp_tick()' was reentered
  (e.g. from a daemon). If reentered, this could destroy the current
  input receive buffer (if using USE_FAST_PKT then there's only one
  buffer in pcpkt2.c).

* tcp_fsm.c change: Fixed some bugs in `tcp_ProcessData()'. When a
  segment was dropped, the old logic would in some cases overwrite
  previously received data or put trash in the socket receive buffer.

* target.h etc. changes: Preliminary support for LADsoft's cc386 2.31+
  compiler.

* misc.h change: New macros `WATT_ASSERT()', `RECV_PROFILE()', `DBL_FMT'
  and `GEN_INTERRUPT()'.

* wattcp.h change: Renamed `_tcp_Socket' element `acknum' to `recv_next',
  `seqnum' to `send_next' and `unacked' to `send_una'. That's more
  understandable and in line with BSD's `rcv_nxt', `snd_nxt' and `snd_una'.

* pcarp.c change: Check if it's an ARP-reply before adding/updating the
  ARP cache. Prevent anti-sniffers detecting us if we're in Rx-mode 4 or
  above.

* timer.c change: Make sure `set_timeout()' never returns 0. It will
  only confuse `chk_timeout()'.

* pcrecv.c change: `len' argument changed from `int' to `unsigned' (to
  allow 16-bit code to send >32 kBytes).

* sock_ini.c change: New function `sock_sig_exit()' called for unhandled
  signals (SIGINT, SIGBREAK, SIGPIPE etc.).

* pcpkt.c change: The real-mode callback was working rather flimsy under
  Windows-XP so it was rewritten to use a real-mode stub. For 32-bit
  targets, the stub-code gets copied to DOS-memory at runtime. For 16-
  bit targets the code is run in-place.

* bsdname.c change: Support UDP scokets also in `_getsockname()' and
  `_getpeername()'. Allthough a peer is a misnomer for UDP, it's handy
  to be able to return his address and port.

* select.c change: Don't call `SOCK_YIELD()' on small (less than 1 sec)
  timeouts. `os_yield()' will sometimes block for 250 msec under Win-XP.

* pcpkt.c change: call new function `pkt_reset_handle()' when releasing
  the PKTDRVR handle (in case the application crashed in the receiver
  upcall handler). Only called if "PKT.RESET" is enabled.  Protect
  `get_rmode_data()' with DISABLE() and ENABLE() in some places since
  the packet-driver spec doesn't guarantee the data won't change.

* sock_io.c change: Merged the data-buffer and "\r\n" into one sock_write().
  This avoids 2 UDP packets to be sent in ASCII socket-mode.

* util\mkdep.c change: Installation fix for djgpp version under Win (9x/XP)
  DOS-boxes.  If user unzipped source files under plain DOS or used a
  non-file-case aware tool under Windows (e.g. PkUnzip or an old Info-ZIP)
  all files would be in upper-case and mkdep.exe would also produce
  dependencies in upper-case.  This would confuse e.g. GNU make compiled
  with MingWin (djgpp's gcc and make doesn't seem to mind).  mkdep.exe now
  always produces output in lower-case. Only include ".c" and ".h" files
  in dependency output.

* pcdbug.c change: Rewritten using fopen() API. New function `db_filter()'
  examines packet before printing it.

* bsddbug.c / timer.c changes: use `setvbuf()' to set output file to
  line-buffered.  Use a static file-buffer to avoid malloc crashing in
  exception handler.

* pcpkt.c change: Provision for using near-ptr access if enabled by app.
  Watt-32 doesn't enable it (except for DJ_BUG code). It's kinda dangerous
  as it reduces protection.

* pcpkt.c change: PUSHF/CLI on entry to real-mode callbacks. POPF on exit.
  djgpp version saves/restores FS/GS register as that isn't done in the
  stub-code. (NDIS3PKT under Win-XP assumes FS/GS are unchanged by
  upcall receiver). Print more debug if DJ_BUG is defined.

* bin\common.mak change: Default DOS-extender for wcc386 changed to DOS32A.EXE.
  Ref. http://dos32a.sourceforge.net/
  This extender (included) is superior to DOS4GW.  Requires Watcom's
  stub loader %WATCOM%\BINW\STUB32A.EXE.  I don't recommend using
  PMODEW.EXE since it has some severe bugs (e.g. it truncates file
  opened for append, or fails to seek to end-of-file). CauseWay is also
  very good.

* pcbug.c change: Detect looped packets in `db_dump()'. When running
  NDIS3PKT in promiscous mode (6), all non-broadcast packets sent will
  be received approx 100 msec later. This is how NDIS3 is supposed to
  work.

* makefile.all change: Watcom targets no longer needs `-ms' wmake option.

* strings.h change: Added macro `strlcpy()'. Replaced `strncpy()' with
  `strlcpy()' in some places.

* gethost.c change: Set lower time-limit on a cached entry. `AddHostEnt()'
  selects minimum of `ttl' and `netdbCacheLife'. Upper limit is stil
  `netdbCacheLife' (15 minutes).

* pcpkt.h changes: Prefixed error-code with "PDERR_". Renamed "PD_*"
  classes to "PDCLASS_*".

* pcarp.c change: Add detection of dead default gateways. Function
  `check_dead_gw()' is called from ARP-daemon once each second.
  New WATTCP.CFG keyword "ARP.DEAD_GW_DETECT = 1" enables this feature.
  Feature only compiled in for DOSX targets.

* pcconfig.c change: Order of searching WATTCP.CFG changed to:
   1. location where environment variable "WATTCP.CFG" points to.
   2. location where environment variable "WATTCP_CFG" points to.
   3. in the current directory.
   4. in the directory of the executing program (if DOS 3+ used).
  (i.e. action 3 and 4 swapped).

* pcdhcp.c bug-fix by Greg Bredthauer <grb4@duke.edu>: DHCP_request()
  was putting 2 bytes too much into the DHCP_USER_CLASS and DHCP_CLASS_ID
  tags. Some DHCP servers do require DHCP_CLIENT_ID in DHCP-request
  (optional according to RFC-2131).

******************* Changes version 2.2 dev.rel.3 *******************

* .\bin\*.mak change: Stack requirement for Watcom 32-bit programs
  reduced to 50kByte (option stack=50k).

* .\bin\ping.c change: `cdecl TraceOff()' changed to `MS_CDECL TraceOff()'.

* misc.c change: Don't call `Get_CR4()' in `RDTSC_enabled()'. This is
  an privileged instruction that crashes most DPMI-hosts. Works okay
  under Win-XP though (but always returns 0).

* bsdname.c change: `_getsockname()' now returns -1 if `s->myaddr == 0'
  or `s->mypost == 0'.

* configur.bat / makefile.all change: Recompiled nasm.exe 0.98 with
  latest djgpp 2.03. The old nasm.exe djgpp version often crashed under
  Win-XP.


******************* Changes version 2.2 dev.rel.2 *******************

* .\bin\watcom.mak: Stack reduced to 15kByte to be able to link
  ping.exe and finger.exe in large model. Small-model isn't possible
  anymore :-( Use Borland small-model instead.

* misc.c change: Don't use RDTSC instruction for timing if `use_rdtsc'
  or bit 2 of CR4 is set.

* cpumodel.* change: Added functon `Get_CR4()' to detect if RDTSC
  instruction is disabled. Called via safe wrapper `RDTSC_enabled()'.
  I.e. only true Pentiums are allowed to call `Get_CR4()'.

* pcconfig.c change: Renamed "MTU_DISC" to "TCP.MTU_DISVOVERY" (no effect yet).

* wattcp.h change: Renamed `tcp_Socket' to `_tcp_Socket' and `udp_Socket'
  to `_udp_Socket' due to problem with Doxygen. It has problem with same
  structure to be defined twice (in tcp.h and wattcp.h).

* udp_rev.c: Bug-fix by <Yves-Ferrant@t-online.de>. When reply has *no*
  compressed message, the `getresult()' function failed to find the
  resource-record part.

* transmit.c change: For transmitting to a UDP broadcast socket (SS_PRIV
  set), restore `s->hisaddr' to -1 after `sock_write()'. Restore `hisport'
  to 0. This was needed to get the .\src\tests\udp_*.exe programs to work.

* Added make-target for generating Doxygen documentation (make doxygen).

* Changes to suite Digital Mars: This compiler is wrong in not accepting
  "const <typedef-arrays> *" as function arguments; Example error message:
    pcpkt.h(99) : Error: type qualifiers and static can only appear in
                         outermost array of function parameter.

  Arguments of "const mac_address *" replaced with "const void *" in pcsed.*
  and pcpkt.*.

* Updates for djgpp 2.04 alpha: Added errnos `ELOOP' and `EOVERFLOW'.
  Added hack to <sys/werrno.h> to detect mixing djgpp 2.03 and 2.04 builts.

* pcpkt.c change: In `pkt_receiver_pm()', don't discard packets smaller
  than 60 bytes. Some switches may send smaller packets in e.g. ARP-
  replies.

* sock_ini.c change: No longer exits when `reverse_lookup_myip()' fails.
  Only prints a warning.

* udp_dom.[ch] change: The previous local port `DOM_LOC_PORT' value of
  997 failed to pass some firewall (only allowed ports >= 1024). Value
  is now set to 1415.

* pcdbug.c change: Problem writing huge packets in `DumpData()' due to
  64kByte limitation of `write()'. Calls `db_flush()' when needed.

* pcpkt.c change: Set `_pkterror' to 0 before all PKTDRDR calls.
  Removed `handle' argument to `pkt_get_rcv_mode()' and `pkt_set_rcv_mode()'.

* pcpkt.h change: Receiving fragments require `RX_BUFS >= MAX_FRAGMENT'.
  Hence `RX_BUFS' increased to 50 for DOSX targets. Except for DOS4GW
  where we allocate receive buffer from DOS (64kB max).

* pcping.c change: support sending IP-fragments. ping now can send max.
  65503 byte pings.

* tftp.c change: Added config-keyword "tftp.openmode" for opening local
  file. Handy when transfering texts files from Unix. Default mode is
  "wb" (binary).

* pcdbug.c change: prints contents of ARP-cache in `dbg_dump_stats()'.

* wattcp.h change: `udp_MaxBufSize' reduced to 1520.

* udp_dom.c change: Fail `resolve()' (sets `_resolve_exit') if `udp_open'
  fails. Ask for `DTYPE_AAAA' resource-record if IPv6 address is requested
  ('resolve_ip6()`). Changed `lookup_domain()' to fetch reply into local
  buffer (not overwrite request). Checks that ID received is same as
  sent. Protect `ddextract()' from reading too much from reply; added
  argument `len'. Forgot to call `sock_close()' in one case. Since `dom_sock'
  was on the stack, this resulted in error in `_udp_handler()'.

* pctcp.c changes: `udp_open()' and `tcp_open()' checks the `ip' to
  verify it's not a multihome address. This logic failed for class A
  addresses (sign error).

* ip4_frag.c changes: Support for `MAX_IP_FRAGS' > 1. I.e. we support
  handling of several simulaneous fragment chains (with different IDs).
  Send "ICMP time exceeded" on timeout and *only* if fragment with offset
  0 has been received (ref. RFC-1122).
  Note: Doesn't handle fragments in reverse order yet.

* sys/cdefs.h change: Added define `MS_CDECL cdecl'. This is needed
  when compiling for MS Quick-C/Visual-C in the register call model
  (option -Gr). Because Quick-C/Visual-C insists that signal-handlers,
  atexit functions and var-arg functions must be defined cdecl. But e.g.
  Watcom's register call doesn't need this.

* Renamed `.\bin\makefile.dj' to `djgpp.mak' for consistency.

* powerpak.[ch]: Finished support for Borland's 32-bit PowerPak target.

* wdpmi.c change: Bugfix in `dpmi_lock_region()'. It didn't added the
  segment base-address when calculating linear address. New function
  `dpmi_get_base_address()'. Added `__dpmi_errno' to most calls.

* sock_ini.c / pctcp.c change: Added config-variable "tcp.timer.rto_scale"
  (default is 64). This factor (used in `_tcp_sendsoon') have a tremendous
  impact on speed. I made it configurable until a "correct" value has
  been determined.

* wattcp.h change: Because Visual-C cannot convert from `uint64' to
  `double', I introduced new type `int64'. Used in timer.c (profile_stop
  and profile_dump).

* `inet_ntoa()' moved outside `USE_BSD_FUNC' because function is needed in
  resolver (res_*.c) code.

* A note: on a Pentium 4, the assembly version `inchksum_fast()' is actually
  a bit slower than the C-version `inchksum()' (.\src\chksum.c).  This is
  maybe caused by the larger instruction cache on a P4.

* config.h / timer.c change: `USE_NEW_TIMERS' removed. It is now default
  for targets supporting "long long" (HAVE_UINT64).

* gettod.c change: `gettimeofday2()' rewritten to use RDTSC instruction
  if available (and wanted; use_rdtsc = 1).

* ip4_frag.c change: `check_data_start()' should not checks that `len'
  is a multiple of 8 bytes. Thanks to <mikedos386@yahoo.co.uk> for
  detecting this bugs.

* wattcp.cfg / sock_ini.c change: keyword `NAGLE' renamed to `TCP.NAGLE'.

* pcpkt.c change: Move call to `unlock_code_and_data()' before freeing
  callback, `pkt_inf' memory and selectors. See `pkt_release()'.
  Renamed "ERROR:.." to "PKT-ERROR:..".

* pcpkt.c / pcsed.c: Temporary support for AX.25 drivers.

* pcconfig.c change: Renamed WATTCP.CFG config keyword `TXRETRIES' to
  `PKT.TXRETRIES' Default value is still 2.

* pcpkt.c / nochkstk.h typo: `_MSV_VER' renamed to `_MSC_VER'. This
  prevented Quick-C from working. Stack-checking was generated where
  it shouldn't.

* makefile.all changes: Renamed `BORLAND' to `BORLANDC', `MSOFT' to
  `QUICKC' and `METAWARE' to `HIGHC' (using product name rather than
  company name).

* pcpkt.[ch] change: Added function `pkt_get_stats()' to get pkt-driver
  statistics (this session and total). Called from pcstat.c.

* pcpkt.c + wdpmi.c change: Redefined macro `FP_SEG' for Digital Mars
  (__DMC__) and MSC compilers.

* netaddr.c change: Added function `inet_ntoa_r()'.

* rs232.[ch] change: Made the `trace2com()' a var-arg function.
  Function `trace2com()' now returns an int (!= 0 is okay).


******************* Changes version 2.2 dev.rel.1 *******************

* timer.c change: Added functions `init_userSuppliedTimerTick()' and
  `userTimerTick()'. These are typically used when timer interrupt is
  taken over by some program (i.e. Allegro). Contributed by Gundolf
  von Bachhaus <GBachhaus@gmx.net>.

* pcarp.c/pcconfig.c changes: WATTCP.CFG config variables "ARP_TO"
  renamed to "ARP.TIMEOUT" and "ARP_ALIVE" to "ARP.ALIVE".

* New files rs232.[ch] implements a simple trace of execution via the
  serial port. Enabled by config.h define `USE_RS232_DBG'. Contributed
  by Gundolf von Bachhaus <GBachhaus@gmx.net>.

* pcarp.[ch] change: A totally rewritten ARP module contributed by
  Gundolf von Bachhaus <GBachhaus@gmx.net>.

* config.h / sock_ini.c change: `USE_EXCHANDLER' removed. It's now on
  by default.

* pcping.c change: Made ping-cache an array. Old `ping_hcache' could
  only hold one entry. Hence flood ping (ping -f) would overwrite cache
  entry.

* pcsed.c change: DOS4GW targets use transmit buffer in DOS memory (not
  outbuf). Function `pkt_tx_buf()' returns pointer to this buffer. Hence
  we save a memcpy() in `pkt_send()'.

* sock_ini.c change: Restores signal-handlers in `tcp_shutdown()' after
  `_eth_release()' is called.

* pcpkt.c change: Read config-file and search for "PKT.VECTOR = 0xNN"
  specifying packet-driver vector to use. Function `get_config_vector()'.
  Old method with using env-var "WATTCP.VEC" is removed.

* pcconfig.c change: New function `tcp_config_name()' returns full
  patch of "WATTCP.CFG" file.

* sockopt.c change: Fixed bug when setting `IP_TTL'. TTL was always set
  to 1.

* pctcp.c change: Removed printing of "discarding.." in `udp_handler()'.

* pcconfig.[ch] change: Added handling of `ARG_STRCPY' type.

* gethost2.c rewritten and integrated into gethost.c

* wattcp.h change: Renamed some UDP_TCP_COMMON fields for clarity:
  `datalen' -> `tx_datalen', `data' -> `tx_data'.
  `rdatalen' -> `rx_datalen', `maxrdatalen' -> `max_rx_data',
  `rdata' -> `rx_data' and `rddata' -> `rx_buf'.

* bsddbg.c change: Removed first parameter to `_sock_debugf()'.

* pcigmp.[ch] merged into pcmult.[ch]

* pctcp.h change: `DAEMON_PERIOD' set to 500 msec (increased from 55 msec).
  Files .\src\wattcpd.[ch] no longer needed; removed.

* pcdbug.c change: print buffer no longer on stack. Uses buffer
  `dbg_buf' malloced in `dbug_init()'.

* Added support for Digital Mars C compiler. small/large 16-bit, 32-bit
  small model with DOS4GW, WDOSX or X32VM extender.

* asmpkt.asm change: Local stack is now setup in .DATA segment.

* The support for the DOS-extender WDOSX is removed since it WDOSX is
  compatible with other DOS4GW-style extenders. Allthough WDOSX has
  more DPMI 0.9 features (e.g. real-mode callbacks), those features
  wasn't needed in Watt-32. PKTDRVR upcalls are not via RMCBs, but use
  the DOS4GW method (see asmpkt4.asm). This is much faster and reduces the
  number of buffer copyies. A single transfer from PKTDRVR to ring-buffer.

* wattcp.h change: Added `locflags' bit `LF_NOCLOSE'. This bit is
  checked in `_ip_delay0/1' before closing socket. Required in tftp.c
  while retrying after timeouts.

* neterr.c change: "#define DATA_MOD _WCDATA" required for Watcom 11.0C.
  "define DATA_MOD _near" required for MSC v8 or older.

* wdpmi.c change: Added function `dpmi_get_ds_limit()' for Borland 32-
  bit compiler.

* pcsed.c change: protocol debugging is now done in `_eth_send()' (macro
  `DEBUG_TX()' is no longer needed).

* udp_dom.c change: Added variable `dom_ttl' for storing TTL of last
  name/ip resolution. Used in `gethostbyname()/gethostbyaddr()' to
  set `h_timeout'.

* pcpkt.c changes: `pkt_set_access()' simplified to receive *any*
  protocol.  This was needed because some PKTDRVRs could not assign
  more than 3 handles. With introduction of PPPoE, fetching handle
  for PPPoE discovery failed. The downside of this is that more upcalls
  are generated. The benefit is that only one receive queue is maintained.

* Added simple PPP protocol (ppp.c); James Carlson's minimal-ppp.c adapted
  for Watt-32.

* pcdbug.c changes: added decoders for PPPoE; `pppoe_head_dump()',
  `pppoe_disc_dump()' and `pppoe_sess_dump()'. PPPoE Session dumper also
  decodes IPCP, LCP and IP-packets.

* wattcp.h fix: `RARP_TYPE', `PPPOE_DISC_TYPE' and `PPPOE_SESS_TYPE' was
  on wrong endian format.

* pcdhcp.c changes: Function `DHCP_read_config()' reads previous configured
  values from file (`$(TEMP)\W32DHCP.TMP') to avoid doing DHCP-boot for every
  program to be run.

* pcstat.c change: New functions `print_pppoe_stats()' prints PPPoE
  count of session/discovery packets. New function `print_vjc_stats()'
  polls DOS-PPP and prints VJ-compression statistics.

* pcpkt.c change: New function `get_rmode_data()' reduces ifdef-clutter.
  New function `pkt_get_vjstats()' returns VJ-compression info from
  PKTDRVR (only DOS-PPP 0.6+ supports this function). New variable
  `_pktdrvrname' set in `pkt_drvr_info()'.

* ioctl.c change: handler for `SIOCGIFBRDADDR' now returns IP-broadcast
  address (not ether broadcast address).


******************* Changes version 2.1 dev.rel.5 *******************

* PPP-over-Ethernet: Preliminary support for PPPoE encapsulation
  for Ethernet. Still requires full PPP implementation.

* pcconfig.c change: Added check for env-var `WATTCP_CFG' before
  checking `WATTCP.CFG'. This is to allow bash (the Unix shell) to
  work (it reportedly doesn't allow `.' in env-vars).

* timer.c changes: `set_timeout()' now uses `gettimeofday()' and
  `microsec_clock()' to get an absolute timestamp. This hopefully
  fixes the problem with timeouts around midnight.

* new files profile.[ch]: Used to measure execution speed. Activated
  by "PROFILE = 1" in wattcp.cfg. Only for djgpp and Watcom 32-bit
  targets running on Pentium (uses RDTSC instruction). Currently only
  `pkt_send()' uses profiling.

* neterr.c changes: `net_errno', `net_strerror' and `net_perror' renamed
  to `errno_s', `strerror_s' and `perror_s' (to be consistent with write_s
  etc.)

* ip_out.c change: Implemented `ip_do_fragment()' and `ip_free_fragment()'.
  These does not yet support IP-options.

* pctcp.[ch] changes: made some TCP-timer values configurable through
  new keywords in `WATTCP.CFG' file:
    "TCP.TIMER.OPEN_TO"   -> tcp_OPEN_TO      default 1 sec
    "TCP.TIMER.CLOSE_TO"  -> tcp_CLOSE_TO     default 1 sec
    "TCP.TIMER.RTO_ADD"   -> tcp_RTO_ADD      default 100 msec
    "TCP.TIMER.RTO_BASE"  -> tcp_RTO_BASE     default 10 msec
    "TCP.TIMER.RESET_TO"  -> tcp_RST_TIME     default 1 sec
    "TCP.TIMER.RETRAN_TO" -> tcp_RETRAN_TIME  default 50 msec

  Parser for these (and some others) moved to sock_ini.c; function
  `tcp_parse_config()'. Added argument `force' to `tcp_Retransmitter()'
  to force a retransmission check from receive.c and transmit.c
  functions.

* wattcp.h etc. change: Renamed struct member `sock_mode' to `sockmode'
  due to warning from linker; `sock_mode()' vs. `.sock_mode'.

* pcconfig.c change: Added `ARG_ATOB' and `ARG_ATOW' for storing bytes
  and words respectively.

* pcpkt.c change: `_pktretries' changed to BYTE. `tx_cnt' in `pkt_send()'
  modified to use range [1.._pktretries].

* ioctl.c change: Added command `SIOCGIFHWADDR' for Linux(?) compatibility.

* makefile.all / target.h changes for compiling with `cl32.exe' from
  MS Visual C 4.0. The only target currently is Pharlap DOSX. Not
  finished yet!

* pctcp.c change: `udp_open()' now only sets `ip = 255.255.255.255' if
  called with ip == 0. This change allows sending to limited broadcast
  addresses. E.g. `a.b.255.255' should no longer be mapped to
  `255.255.255.255'.

* pcdbug.c change: Rewritten decoding of IGMP packets in `igmp_dump()'.
  Only if `USE_MULTICAST' is defined.

* ioctl.c change: command `SIOCGIFADDR' didn't check for address family.
  Now returns local IP-address for `AF_INET' family. Otherwise MAC-
  address. Similarily for command `SIOCSIFADDR'. What should `SIOCDIFADDR'
  and `SIOCAIFADDR' do ?

* select.c change: selecting for exceptions (in `_sock_exc_select()')
  shall only (according to authoritative sources) count the arrival of
  "Out-Of-Band" data i.e. TCP-segments with URG flag set. Watt-32 does
  not yet support OOB data, so selecting for exceptions will never count.

* pcsed.c change: New hook pointers `_eth_xmit_hook' and `_eth_recv_hook'.
  These are meant to be used by libpcap (the promiscous mode network
  library).

* ioctl.c changes: debug printing name of commands. Set flag `IFF_RUNNING'
  for `SIOCGIFFLAGS' command.

* chksum.h / config.h changes: `USE_FAST_CKSUM' define removed. Default
  for all 32-bit targets is to use `inchksum_fast()'. 16-bit targets
  uses `inchksum()' in chksum.c.

* pcpkt.c changes: This module is now completely independant of the various
  link-layers. All MAC-header encoding and decoding is now done in pcsed.c.

* pcsed.[ch] changes: Removed `_pkttoken' variable. Uses `_pktdevclass
  == PD_TOKEN' instead. Fixed zero-padding problem in `eth_mac_xmit()'.
  `_eth_formatpacket()' now clears only the IP-header portion of the
  transmit buffer.

* pcpkt.[ch] changes: Preliminary support for FDDI with IEEE 802.2 headers
  (class 12 driver). New structures `fddi_Header' and `fddi_Packet' added
  to wattcp.h.

* pcpkt.c change: `PKT_TMP' area increased to 30 bytes because of Token-
  Ring type arrays may be 24 bytes (3 types, 8 bytes each).

* pcdbug.c change: Updated `link_head_dump()' function for printing
  Token-Ring header.

* pcpkt.c / pcsed.c changes: Simplified access to MAC-headers through
  new `union link_Packet' and new functions `_eth_mac_xxx()' for easier
  access to various fields in the MAC-header given an IP-packet.
  New function `_eth_get_hwtype()' used to fill ARP, RARP, BOOTP and
  DHCP headers.

* pcpkt.c / pcsed.c etc: Support for IEEE 802.5 Token-Ring contributed by
  Robert Gentz <rgentz@asdis.de>. Updated by me to support all targets.
  `check_tok_header()' is now done when polling queues and not when
  enqueueing (to save time copying packet twice).

* pcrarp.c fix: Polled link-layer packet from `_eth_arrived()' was not
  freed in function `_dorarp()'.


******************* Changes version 2.1 dev.rel.4 *******************

* timer.c change: New function `get_timediff()' returns difference
  between two timers compensating for any day rollover.

* socket.c change: In `_sock_dos_fd()' use `isatty()' instead of
  `_dos_getftime()' to check if file-handle is a valid DOS handle.

* listen.c bugfix: The `backlog' was not limited to range `1..SOMAXCONN'.

* socket.[ch] change: New `Socket' members `send_lowat' and `recv_lowat'
  for setting "low water marks". `socket->send_lowat' is used to determine
  if non-blocking sockets are writable (in `check_non_block_tx()').
  `socket->send_lowat' is also used in `_sock_write_select()'.
  `socket->recv_lowat' is used in `receive()' and `_sock_read_select()'.
  Initial size of both is 0 (controllable by socket options `SO_SNDLOWAT'
  and `SO_RCVLOWAT').

* connect.c change: Sets `errno = ECONNRESET' on failed returned from
  `_ip_delay0()'.  I'm unsure when to use `ECONNREFUSED' and when to use
  `ECONNRESET'.

* select.c change: `sock_signalled()' is now simplified for non-blocking
  sockets; it always returns 0 if `mask' argument not satisfied.

* receive.c / transmit.c change: When socket-state bit `SS_CONN_REFUSED'
  is set return either `ECONNRESET' or `ECONNREFUSED' in `errno'. This
  depends on whether we got a RST or an "ICMP Unreachable" message.

* pctcp.c changes: In `_tcp_sockreset()', sets `so_error = ECONNRESET'
  and not `ECONNREFUSED'.

* shutdown.c change: Don't call `close_s()' on `SHUT_WR'. Only close on
  `SHUT_RDWR' (2).

* select.c change: `read_signalled()' and `write_signalled()' merged
  into one function `sock_signalled()' with different masks. Non-blocking
  listen sockets (both `SS_NBIO' and `SO_ACCEPTCONN' set) shall not count
  as a readable socket in `sock_signalled()'.

* getname.c change: Verify read/write of arguments in `getsockname()'
  and `getpeername()'. Using macro `VERIFY_RW()' on name.

* pcpkt.c bug-fix: When `WATTCP.VEC' was specified only that vector
  should be checked in `find_vector()'. But the search loop was called
  with wrong first/last range. Modified to search [x..(x+num)>.

  `find_vector()' also modified so it never checks a real-mode NULL-
  vector for a matching "PKT DRVR" signature.

* pcconfig.c change: New keyword "DOMAIN_RECURSE" for assigning value to
  `dns_recurse' (see below).

* udp_dom.c change: New variable `dns_recurse' controlling recursive
  resolution of "dot-less" hostnames. Default is 1.

* socket.c change: In `socket()' check that a `SOCK_RAW' protocol is
  in range 0 - 255.

* socket.h change: Needed to call `kbhit()' in `SOCK_YIELD()' for all
  targets except djgpp.  This may cause performance drop in e.g. DOS4GW
  applications, but cannot be helped.  Applications MUST be able to
  break out of e.g. `select_s()' loops with very long timeouts (e.g.
  a server application),

* getserv.c change: Use a small hash-table for speeding up `getservbyport()'.
  (mainly to benefit tcpdump).

* fortify.c change: Use `inchksum_fast()' in `st_ChecksumHeader()' if
  `USE_FAST_CKSUM' is defined. `FORTIFY_CHECKSUM_VALUE' is then 0xFFFF.

* misc.c change: `inchksum()' moved to new module `chksum.c'. Other new
  files `chksum0.s' (for djgpp) and `chksum0.asm' (other DOSX-targets)
  implements `inchksum_fast()'. Anybody care to write a 16-bit version?

  Approx. speed increase, asm-version `inchksum_fast()' vs. C-version
  `inchksum()':

  AMD K6-2I    4:1    GNU gcc 2.95.2
  AMD K6-2I    2:1    Watcom 11.0 wcc386
  Pentium-II  12:1    GNU gcc 2.95.2
  Pentium-II  10:1    Watcom 11.0 wcc386

  The gain is significant because the `checksum()' macro is used 3 times
  when processing a received/sent tcp segment.

* gethost.c change: Made it possible to grow list of host/addresses by
  calling `ReadHostFile()' multiple times. We close previous file if
  called 2nd time.

* fragment.c bug-fix: `setup_first_frag()' potentially copied 20 bytes
  to little into fragment bucket which caused checksum error on higher
  level protocols. Solution was to replace `MAX_IP_DATA' with
  `mtu' in `min()' macro.

* tcp.h / pctcp.h changes: Redefined macros `sock_wait_established()',
  `sock_wait_input()', `sock_wait_closed()' and `sock_tick()' to allow
  using them in a "if () .. else" statement.

* tftp.[ch] changes: Modified to use header `<arpa/tftp.h>' instead.

* pctcp.c bug-fix: Enabling the TimeStamp option ("tcp.opt.ts = 1")
  caused some segments to be sent with MSS worth of rubbish data.
  This was caused by an overflow in the `min()' macro after calling
  `tcp_do_options()'.

* signal.c change (NOT YET): Terminate application on unhandled (not
  trapped) signal `SIGQUIT' assuming it's stuck due to recursive `alarm()'
  handler etc. For this reason we don't chain to previous owner of `SIGALRM'.
  In djgpp the `SIGQUIT' signal is normally mapped to <Ctrl>-<\> key. Can
  be changed by `__djgpp_set_sigquit_key()'


******************* Changes version 2.1 dev.rel.3 *******************

* sock_ini.c changes: Added variable `_watt_no_config' to support diskless
  (embedded) machines running with fixed IP configuration. Look at test
  program in `.\src\tftp.c' for an example. Similarily debug variables
  `dbg_mode_all', `dbg_print_stat' and `dbg_dns_details' are made public
  so an application may set these before calling `dbug_init()' and
  `sock_init()'. The debug file `WATTCP.DBG' will be created in current
  directory (provided the diskless machine have some filesystem).
  New public variables `_watt_environ_name' and `_watt_config_name' to
  override default configuration path and file.

* tftp.c changes: TFTP now works with PumpKIN tftp server
  (http://www.klever.net/kin/index.html). A simple test program is
  included in `tftp.c'.

* pcdhcp.c / tftp.c changes: `tcp_boot_load()' is moved to end of
  `sock_init()'. Thus TFTP is decoupled from DHCP. To actually enable
  the boot process, an application must supply a writer function through
  `tftp_writer' function pointer.

* pcstat.c change: Count and print of all possible ICMP message types.
  Added TCP count for retransmit timeouts (tcps_rexmttimeo) and delayed
  ACKs (tcps_delack) in `tcp_Retransmitter()'.

* pcdbug.c / pcicmp.c change: Check for and handle truncated (too short)
  ICMP messages. Must be at least 8 bytes.

* pcpkt.c change: A hack for building Perl 5.6 (djgpp) with sockets.
  To build Perl, we would normally need DOS memory for approx. 20
  levels of nesting (Perl calls itself recursively).

  If `__bss_count > 0' and environment variable "PERL_BUILD_HACK" is
  present don't allocate around 40kB of DOS memory in `setup_rmode_callback'.
  We simply pretend the packet-driver has been initialised properly.


******************* Changes version 2.1 dev.rel.2 *******************

* pctcp.c / pcconfig.c changes: New variables and WATTCP.CFG keywords
  for controlling (future) advanced TCP options:
   `tcp_opt_timstmp' = "TCP.OPT.TS"      Enable Timestamp option.
   `tcp_opt_sackok'  = "TCP.OPT.SACK"    Enable Selective ACK (not yet).
   `tcp_opt_wscale'  = "TCP.OPT.WSCALE"  Enable Window scale (not yet).

  Default values for all is 0 (off).

* sock_ini.c change: Removed call to `signal(SIGFPE,..)' for Watcom +
  Borland 32-bit targets. If handler was installed, then `SIGFPE' gets
  raised somewhere in the BSD-socket API (in select_s() ??). I've no
  idea why.

* pcdbug.c bug-fix: The parsing of tcp SACK option was wrong.

* pcdbug.c change: Added config-file keyword "debug.dns" for controlling
  detailed printing of DNS records. Defaults to 1.

* pcpkt.h + asmpkt4.asm change: Added 2 bytes to `ARP_SIZE' to make it
  multiple of dwords. asmpkt4.asm now uses dword fill (`rep stosd').

* pctcp.c change: New `tcp_Socket' members `ts_sent', `ts_recent' and
  `ts_echo'. Add TCP TimeStamp option to opening SYN packet (`_tcp_send').
  `tcp_ProcessData()' sets `ts_echo' from ACK packets. And sets `ts_recent'
  from SYN only packets. New `locflags' bit `LF_RCVD_TSTMP' controls when
  to send the TS echo value back to peer; `_tcp_send()' does this in a
  non-SYN (and non-RST) packet.

  IMPORTANT NOTE:
  ---------------
  This change have caused `tcp_Socket' in <tcp.h> to increase by 12 bytes.
  Hence one need to recompile applications that use `tcp_Socket'.

* wdpmi.c change: Added function `_fatal_runtime_error()' to print
  information and release packet-driver when stack overflows occurs.
  Printing e.g. "Stack overflow (400000 bytes) detected at CS:12AE0"
  means that function at 0x12AE0 (where __CHK was called) requested a
  stack-size of 400000 bytes. Stack overflow could also indicate other
  bugs. `_fatal_runtime_error()' also sets a new stack-low value to
  prevent further stack overflows.

* pcarp.c bug-fix: ping.exe and pcping.c revealed a bug in `_arp_handler()'
  An ARP Request/Response with a call to `_arp_search()' caused the old
  MAC address to be replaced by source MAC address in the ARP Request/
  Response message! `_arp_handler()' now requires "arp->ip == ip".

* pcarp.c change: In `_arp_handler()' check if requesting address is
  multicast. Class-D addresses don't use ARP, so don't do an ARP-reply.

* .\bin\finger.c change: Moved `sock_close()' call down after while-loop.
  There are problems with successfully receiving data after closing the
  sending side. Seems the generation of ACKs stops in the FINWT2 state.

* sock_in.c change: Added condition for breaking the loop in `_ip_delay1()'
  (used in macro `sock_wait_input'). When `s->locflags & LF_GOT_FIN' is
  TRUE this indicated we either got a FIN or we cannot receive more data.
  This is not used in `_ip_delay2()' (macro `sock_wait_closed'). Thus
  here we wait until connection is fully closed (entered CLOSED state).

* pctcp.c change: Function `_tcp_sendsoon()' increases the time for issuing
  retransmissions to 500msec while in `CLOSEWT' (or higher) states. This
  was done to relax retransmissions while having unACK'ed data when calling
  `sock_close()'. Refer the `.\bin\finger' program.

* tcp_fsm.c change: sets `LF_GOT_FIN' in `s->locflags' also when entering
  FINWT2 state (only from FINWT1 state) indicating we'll never receive more
  data.

* getprot.c change: call `netdb_init()' in start on all function.
  This function calls `sock_init()' in case it wasn't called beforehand.

* receive.c change: In `raw_receive()', drop raw-packet incase user
  suplied a too small buffer ( < sizeof(struct ip)). Still doesn't handle
  IP-options !.

* pcconfig.c change: New table-driven config-file parser
  `parse_config_table()'. Can also be used by applications (added to
  ../inc/tcp.h).  Parser can store integers (ARG_ATOI), network addresses
  (ARG_ATON), hex byte/words (ARG_ATOX_B/ARG_ATOX_W), duplicate a string
  (ARG_STRDUP), resolve a value to an address (ARG_RESOLVE) or call a
  specified function (ARG_FUNC) for finer control of parsing.

* pcdbug.c changes: Added decoding of PTR records in `dns_resource()'.
  Simplified printing of "class"; dropped "(Internet)" for class 1.
  Renamed record names to official names ("IP address" -> "A",
  "Name Server" -> "NS", "Canonical Name" -> "CNAME" etc. Uses
  `__p_type()' from res_debu.c if compiled with `USE_BIND'.

* config.h change: New flag `USE_BIND' for compiling res*.c files.
  `USE_BSD_FUNC' flag is now independant of resolver functions.

* ../inc/tcp.h change: Added define `WATTCP_DEVEL_REL' to enumerate
  developement releases. Value is also returned in `wattcpVersion()'.

* pctcp.c change: size of `hostname' changed to `MAX_HOSTLEN+1'.

* syslog.c / printk.c change: Argument for `%I' format is now in network
  order (previously in host order).

* pcconfig.change: new keyword `ETHERS = <file>' emulate Unix /etc/ethers
  feature. Read file of ether-address and host-names. Since this feature
  is hardly needed, it's only active if compiled with `config.h' option
  `USE_ETHERS' and `USE_BSD_FUNC'.

* pcconfig.c bug-fix: `netdb_init()' didn't preserve value of
  `_watt_do_exit' causing `sock_init()' *not* to exit when it should.

* pcconfig.c / gethost.c / sock_ini.c changes: when using PPP with dynamic
  IP-address, get FQDN by reverse lookup of assigned IP-address. New
  WATTCP.CFG keyword `DYNAMIC_HOST = 1' causes new function
  `reverse_lookup_myip()' to be called and do the reverse lookup. If
  successfull, replace `hostname' and `def_domain' with result. Otherwise
  print warning and exit.

* version.c bug-fix: The first part of "Watt-32 -" was overwritten by
  string specifying compiler options.

* socket.c change: For non-djgpp targets, let first socket start at 3
  in order not to confuse a socket with stdin/stdout/stderr handles.
  E.g. (Unix) code like:
    if (FD_ISSET(0, &readfd))
       read_keyboard();
    else if (FD_ISSET(s, &readfd))
       read_network();

  blindly assumes handle 0 is always stdin. Thus a real socket handle
  with value 0 will not work in such programs. Socket handles in djgpp
  will always be >3.

* pcstat.c change: added new IP-counter `ips_idropped' to differentiate
  dropped packets on input from packets on output (`ips_odropped').
  Changed `struct ipstat' in <netinet\ip_var.h> accordingly.

* pctcp.c change: New function pointer `_tcp_find_hook' set to
  `sock_find_tcp()' in socket.c when at least one SOCK_STREAM socket
  is allocated. To prevent pulling in too much code for simple non-BSD
  programs.

* pctcp.c change: New function pointer `_tcp_syn_hook' set to
  `_sock_append()' in accept.c when at least one listening SOCK_STREAM
  socket is allocated. To prevent pulling in too much code for simple
  non-BSD programs.

* pctcp.c change: New function pointer `_raw_ip_hook' set to
  `sock_raw_recv()' in socket.c when at least one SOCK_RAW socket is
  allocated. To prevent pulling in too much code for simple non-BSD
  programs.

* socket.c changes: `_sock_debug_exit()', `_sock_debug_on()' and
  `_sock_debug_off()' moved to new module bsddbug.c to prevent
  pulling in too much code for simple non-BSD programs.


******************* Changes version 2.1 dev.rel.1 *******************

* Version 2.1 dev.rel.1 released Apr 21, 2000.

* sock_dat.c merged with pcbuf.c

* pctcp.c had to split up in smaller chunks to prevent TurboC 2.01
  from running out of memory;  watt_largecheck() moved to misc.c.
  tcp_init(), tcp_shutdown() and tcp_post_init() are now static and
  moved to sock_ini.c.  New file ports.c handles local-ports.

* Revisited most sources for use of `const' pointers. `const' is now
  used to signal to reader that object pointed to is not modified.
  Some rewrite was needed to accomplish this. E.g. `resolve()' called
  `rip()' that potentially modified the input argument. It now store
  argument in local buffer.

* wattcp.h changes: Removed macros `in_GetTos', `in_GetTTL',
  `in_GetProtocol', `in_GetVersion' and `in_GetHdrlenBytes'. Macro
  `in_GetHdrLen' (previously called `in_GetHdrlen') now returns IP-
  header size in *bytes*.

* transmit.c changes: Major rewrite of `setup_non_stream()' (previously
  `setup_remote'). Only connectionless protocols (SOCK_DGRAM/SOCK_RAW)
  may transmit without calling `connect()' first and they may transmit
  to different host/port than on last transmission. Thus a reconnect to
  another address must preserve the receive buffer and local-port after
  `connect()' returns.

* wdpmi.c change: new function `dpmi_dos_yield()' for DOS4GW/WDOSX targets.
  Called in connect(), select_s() and accept() loops to reduce CPU-loading.
  Calling `kbhit()' doesn't seem to yield under Windows-NT.

* pcpkt.c change: new functions `pkt_get_params()' and `pkt_get_mtu()'
  (enhanced drivers only). Used to determine correct MTU and MAC-address
  length of driver. If no enhanced driver found, the MTU is taken from
  config-file.

* socket.c change: For sockets of type `SOCK_RAW', specifying protocol
  `IPPROTO_RAW' maps to `IPPROTO_IP' internally.

* receive.c change: Return size/data from `ip_receive()' (SOCK_RAW)
  shall always include IP-header and data.  Flag `INP_HDRINCL' is
  only used in `ip_transmit()' to specify that IP-header is part of
  user's buffer.

* sockopt.c change: Added handling of multicast options `IP_ADD_MEMBERSHIP'
  and `IP_DROP_MEMBERSHIP'. Contributed by Vlad Erochine <vlad@paragon.ru>

* sock_ini.c change: Simplified signal handlers for djgpp. Doesn't
  trap `SIGQUIT'. New define `USE_EXCHANDLER' defined for all targets
  by default. Only `SIGFPE' is trapped for real-mode targets.

* socket.c change: Return 1 in `_sock_dos_fd()' if socket is "stdin..
  stderr". `_sock_debugf()' changed to macro `SOCK_DEBUGF()' incase
  compiling without `USE_DEBUG'.

* loopback.c change: `loopback_device()' is given pointer to IP-header.
  Link-layer header is enqueued to IP-queue (dst/src swapped) after
  `loopback_device()' returns.

* All makefiles for Watcom targets now uses case-sensitive linking;
  "option caseexact".

* To ease compiling for embedded targets, "#include <stdio.h>" is put
  first in all source files and socket.h/resolver.h. This may also
  speed-up generation and parsing of precompiled headers.

* timer.c change: New function `set_timediff()' should be called by
  user just after changing the DOS-time via some function;
  `_dos_settime()', `settime()' or `settimeofday()'. The argument to
  `set_timediff()' is number of milli-seconds added (>0) or subtracted (<0).

* getserv.c, gethost.c change: remove calls to `uninit_warn()' and
  instead call new function `netdb_init()' (in pcbsd.c). This function
  calls `sock_init()' in case it wasn't called beforehand.

* More variables are renamed by prefixing them with `_w32_':
    `_mtu'              -> `_w32_mtu'
    `_mss'              -> `_w32_mss'
    `my_ip_addr'        -> `_w32_my_ip_addr'
    `sin_mask  '        -> `_w32_sin_mask  '
    `_block_tcp '       -> `_w32_block_tcp '
    `_block_udp '       -> `_w32_block_udp '
    `_block_ip  '       -> `_w32_block_ip  '
    `_block_icmp'       -> `_w32_block_icmp'
    `_hostname'         -> `_w32_hostname'
    `_sock_inactive'    -> `_w32_sock_inactive'
    `_sock_datatimeout' -> `_w32_sock_datatimeout'
    `_sock_delay'       -> `_w32_sock_delay'
    `_multihomes'       -> `_w32_multihomes'
    `_usr_init'         -> `_w32_usr_init'
    `_mtu_discover '    -> `_w32_mtu_discover '
    `_tcp_nagle    '    -> `_w32_tcp_nagle    '
    `_tcp_keepalive'    -> `_w32_tcp_keepalive'
    `_ctrace_on'        -> `_w32_ctrace_on'
    `_arp_cache_data'   -> `_w32_arp_cache_data'
    `_arp_gate_list'    -> `_w32_arp_gate_list'
    `_arp_last_gateway' -> `_w32_arp_last_gateway'
    `_arp_timeout'      -> `_w32_arp_timeout'
    `_arp_alive'        -> `_w32_arp_alive'
    `_defaultdomain'    -> `_w32_defaultdomain'
    `_def_domain'       -> `_w32_def_domain'
    `_loc_domain'       -> `_w32_loc_domain'
    `_def_nameservers'  -> `_w32_def_nameservers'
    `_dns_timeout'      -> `_w32_dns_timeout'
    `_last_nameserver'  -> `_w32_last_nameserver'
    `last_cookie'       -> `_w32_last_cookie'
    `cookie'            -> `_w32_cookies'
    `cpu_type'          -> `_w32_cpu_type'
    `init_misc'         -> `_w32_init_misc'
    `inchksum'          -> `_w32_inchksum'
    `Random'            -> `_w32_Random'
    `valid_addr'        -> `_w32_valid_addr'
    `hex_chars'         -> `_w32_hex_chars'
    `hex_CHARS'         -> `_w32_hex_CHARS'
    `has_8254'          -> `_w32_has_8254'
    `init_timers'       -> `_w32_init_timers'
    `set_timeout'       -> `_w32_set_timeout'
    `chk_timeout'       -> `_w32_chk_timeout'
    `cmp_timeout'       -> `_w32_cmp_timeout'
    `hires_timer'       -> `_w32_hires_timer'
    `set_timediff'      -> `_w32_set_timediff'
    `time_str'          -> `_w32_time_str'
    `timer_set'         -> `_w32_timer_set'
    `timer_clr'         -> `_w32_timer_clr'
    `timer_chk'         -> `_w32_timer_chk'
    `calltimeout'       -> `_w32_calltimeout'


  The reason for this naming is to prevent name clashing with other
  libraries and forcing user to include <tcp.h> to get the correct
  name for symbols. Drawback is that most applications using Watt-32
  libs MUST be recompiled.

* connect.c change: set keepalive timer on DGRAM/STREAM socket after
  succesful connection.

* pcarp.c change: ARP-request is sent with ether destination address
  of 00:00:00:00:00:00 (not the link-layer broadcast address).

* pctcp.c change: calls to `reuse_localport()' changed to new function
  `maybe_reuse_localport()'. If tcp/udp-socket is owned by a STREAM/
  DGRAM socket, let `sock_deamon()' free the local port when linger
  period is over.

* receive.c change: Rewritten tcp_receive() loop to shorten the wait
  after FIN is received.  It previously introduced a 2sec delay. Now
  returns 0 when `tcp.locflags & LF_GOT_FIN' is non-zero, i.e. when FIN
  received *and* no un-ACK'ed data detected.

* tcp_fsm.c bug-fix: In `tcp_estab_state()' the ACK-number *after*
  `tcp_ProcessData()' was used in comparision with SEQ-number. It
  should be compared with ACK-number *before* it gets modified.

* tcp_fsm.c change: added local-flag-bit `LF_GOT_FIN' to `tcp.locflags'.
  Set when `FIN' received in `tcp_estab_state()', `tcp_finwt1_state()',
  `tcp_finwt2_state()' or `tcp_lastack_state()'. Used to determine when
  no more data is expected.

* signal.c change: Added `SIGQUIT' to signals to handle (djgpp).

* getprot.c bug-fix: `getprotobyname("tcp")' returned protocol entry
  for "udp".

* socket.c changes: A bit more robust checks for valid `protocol'.
  SOCK_STREAM accepts only `0' or `IPPROTO_TCP'.
  SOCK_DGRAM accepts only `0' or `IPPROTO_UDP'.

* pcstat.c change: Don't print statistics for zero-events.

* crit.c change: Turn off stack-check code generation.

* New file `.\inc\sys\swap.h' defines `intel()', `ntohl()' etc. as
  inline functions for GNU and Watcom compilers (all models).

* New files:
   `linkaddr.c' for functions in <net/if_dl.h>.
   `adr2asc.c' and `asc2adr.c' for functions in recent <arpa/inet.h>.

* misc.c changes: timer handling stuff moved to new module `timer.c'
  Cleaned up the namespace by prefixing several "internal" functions with
  `_w32_'.

* pcbuf.c changes: `sock_rbused()' etc. handles raw-sockets also (VALID_IP).
  Used by `ip_receive()' etc. to check for raw-socket data.

* wattcp.h change: New type `raw_Socket' added to `union sock_type'. This
  is for receiving raw IP-packets in the BSD-socket API.

* makefile.all/dos4gw.mak/common.mak changes: Use option `-zm' for Watcom
  targets. Thus causes each function to be put in a separate code-segment.
  Using `wlink' linker option `option eliminate' causes unused code to be
  removed.

* receive.c changes: Check for `SS_CONN_REFUSED' errors resulting from
  "ICMP Unreachable" messages while looping in `tcp_receive()' and
  `udp_receive()'.

* tcp_fsm.c change: In `tcp_finwt1_state()' simply unthread socket and
  enter `CLOSED' state if `LF_DONTLINGER' flag set.

* config.h changes: New defines for future additions:
    USE_LIBPCAP - Handle sockets of type `SOCK_PACKET' for receiving
                  all network traffic.
    USE_TTCP    - Support T/TCP (Transaction TCP) protocol.

* tcp_fsm.c change: Silently discard incoming `SYN' when listen-queue
  becomes full.

* pcconfig.c changes: Use buffered I/O (`fopen()', `fread()') for DOSX-
  targets when reading `WATTCP.CFG' config-file. Use `open()'/`read()'
  for non-DOSX (small/large) targets to conserve code and data.

* pcdbug.c changes: Fixed some bugs in address matching logic in
  `MatchEthAddr()', `MatchArpRarp()' and `MatchIpAddr()'.
  Rearranged for inlining some functions (GNU-C).

* signal.c change: djgpp 2.03 seems to support `SIGALRM' properly.
  Thus needs to rethink the signal catching logic.

* receive.c/transmit.c/accept.c/connect.c/select.c changes:
  Print signal-number when `setjmp()' catches a signal. djgpp might
  catch `SIGALRM' in these loops. Should we restart the functions?

* fsext.c change: Forgot to clear fd_sets before calling `select_s()'
  at `case __FSEXT_ready'.

* misc.c change: Removed "#ifdef" for BorlandC/TurboC in `_w32_time()'.
  Still don't know what the problem is.


******************* Changes version 2.1 *****************************

* misc.c changes: All timer routines now takes milli-seconds as argument.
  The `set_ttimeout()' routine is gone. This change affects all files that
  calls `set_timeout()'. Timer resolution falls back to 55msec if a 8254
  timer chip isn't found.
  In `_w32_time()' BorlandC/TurboC seems to require "lf" for arguments of
  "double" type.

* Removed file `ffs.asm'. `ffs()' is now included in misc.c for all targets.
  Even djgpp which had a buggy `ffs()' in djgpp <= 2.01.

* signal change.c: Handle also `SIGALRM' for those who have that (djgpp).

* select.c bug-fix: `timeval_diff()' did wrong calculation. Changed to
  return micro-second difference.

* connect.c change: `_nblk_connect()' sets/resets `socket->so_error' so
  that `getsockopt(..SO_ERROR..)' will return proper error when non-blocking
  connection fails. If non-blocking, `_tcp_connect()' sets `socket->so_error'
  to `EALREADY' in case user calls `getsockopt()' before calling `connect()'
  the 2nd time.

* version.c change: `wattcpVersion' changed to a function returning version-
  string.

* pctcp.h / wattcp.h changes: Removed `procref' typedef and made proper
  typedefs for protocol-handler and user-handler respectively. MS Quick-C
  v6.0 didn't handle function-pointers with undefined argument list.
  `ProtoHandler' is for handling udp and tcp-packets from `tcp_tick()'.
  `UserHandler' is for calling user-functions called from wait-loops in
  _ip_delay{0-2}. <tcp.h> updated accordingly.

* select.c changes: Reorganised and simplified. The criterias for a readable
  or writable socket is taken from BSD 4.4; This counts errors as valid
  events for read/write. Hence next recv() or send() will return the proper
  `errno'.

* receive.c change: In `tcp_receive()', don't set `SS_CANTRECVMORE' if
  socket is a listening socket (`SO_ACCEPTCONN').

* sys/socket.h change: `SOMAXCONN' increased from 5 to 32.

* Several changes regarding the listen-queue: listen() no longer allocates
  the listen-queue, it only remembers the backlog count in a new `Socket'
  structure variable.

  When a tcp-packet with SYN-flag set is received on the TCB of this listening
  socket (`SO_ACCEPTCONN' is set in `so_option'), then this TCB is first
  duplicated and if allocation and room in listen-queue, appended to a vacant
  slot in the listen-queue.  The `tcp_listen_state()' then continues to work
  with the copy of this TCB.  The original TCB is unchanged and accepts further
  SYNs on the same port.  The `accept()' loops over the listen-queue and
  creates a new socket (clone) from the first connected TCB.

* sock_ini.c change: Don't install exception handlers for 32-bit targets
  if environment variable "WATT32-NOEXC" is defined.

* config.h changes:  Because some preprocessors (Borland's among others)
  have problems with "#if (W_OPT & O_xx)" where `W_OPT' is > 16bit, all
  of these constructions have been changed to "#if (USE_xx)".
  New define `USE_LOOPBACK' to exclude loopback device for small-model
  targets.

* receive.c + transmit.c changes: Added macro `VERIFY_RW()' to start of
  functions.

* config.h change: New option `O_UDP_ONLY' for making more compact (small
  model) applications supporting only UDP (and IP+ICMP).

* pcsed.c change: Number of transmit retries (`_pktretries') reduced to
  2. The meaning of this variable is changed so that total number of
  transmit attempts in `_pkt_send()' is "_pktretries + 1".

* select.c change: Calling `_sock_start_crit()' and `_sock_stop_crit()'
  prevents `tcp_tick()' and hence `sock_daemon()' from deleting a socket
  from `sk_list' while we're in read/write/exc select functions.

* socket.c changes:
    - Return NULL in `_socklist_add()' on failed protocol allocations
      (`sock->tcp_sock' etc.). Prevents memory leaks and frees `sock'
      also. Tidy up also when djgpp's `__FSEXT_set_data()' fails.
    - New functions `_sock_start_crit()' and `_sock_stop_crit()' controls
      running `sock_daemon()' while in critical regions like in `select_s()'.
    - `tcp_sock_daemon()' "lingers" even when socket was reset or aborted.
      This is to prevent destroying sockets in loop where `sk_list' should
      be contant.

* accept.c changes:
    - Whole `accept()' function is defined as a critical region. Work now
      done in `_accept()' wrapped inside critical region.
    - `_sock_dup_bind()' clones the connection created by the listening
      socket. It's state is similar to it's parent, but defined as a normal
      `SS_CONNECTED' socket and not `SS_LISTENING'. Any data in the listen
      socket is moved over to the clone socket.
    - After cloning the listening socket in `_sock_dup_bind()', it must
      still be listening for further connections on the same port. Undo
      what `tcp_handler()' and `tcp_listen_state()' did to the listening
      socket.

* pcpkt.c changes:
    - Forgot to set Carry flag in `pkt_api_entry()' for non-debug version.
    - Support for WDOSX with any supported compiler (wcc386,bcc32,cl).
      DOSX4GW variable defined as (4|WDOSX).
    - Turn off/on stack-checking for bcc32 also.
    - `pkt_poll_arp()' didn't check for `_pktserial' and Ether protocol
      in non-debug version.
    - `pkt_poll_arp()' now tests for RARP protocol only in RARP version.

* New DOSX combination; WDOSX 0.96+ and Borland's BCC32. Hence renamed
  `watcom.[ch]' to `wdpmi.[ch]'.

* pcarp.[ch] change: Max number of gateways (`MAX_GATE_DATA') reduced
  to 5. `_arp_add_gateway()' now uses `qsort()' after adding gateway to list.

* close.c change: Added `sock_flush()' in `close_stream()' before
  closing socket.

* transmit.c change: Requirement for allowing to send in `tcp_transmit()'
  is now more liberal. Don't send if:
   - TCB-state is <  `ESTAB'.   i.e. not connected or listening.
   - TCP-state is >= `LASTACK'. i.e. FIN received and FIN sent.

* bind.c change: disallow binding `STREAM_SOCK' sockets to a multicast
  address.

* connect.c change: disallow connecting `STREAM_SOCK' sockets to a
  multicast address.

* transmit.c change: removed test on `MSG_WAITALL' in `tcp_transmit()'.
  Always send using `sock_write()' is more efficient and kept Nagle's
  algorithm in effect.

* wattcp.h change: `vj_sa' and `vj_sd' (Van Jacobson's RT algorithm)
  changed to DWORDs because of new milli-second timers. Adds 4 bytes
  to `tcp_Socket' in <tcp.h> also.

* misc.c change: new functions for milli-second timers taken from Phil
  Karn's KA9Q; `set_ms_timeout()' and `chk_ms_timeout()' works similar
  to `set_timeout()' and `chk_timeout()'. Only works with a 8254 PIT so
  only DOSX targets use these for RTT calculations. (PC/XT's may have
  an older 8253 PIT).

* config.h change: option `O_RARP' removed from `W_OPT' (i.e. added to
  `W_EXCLUDE'). I've never heard anybody using a RARP server and hence
  dropped it. Remember to "make clean" after upgrading to this version.

* pctcp.c + sock_ini.c changes: new function `tcp_post_init()' does
  various things after config-file has been read.

* .\bin\ changes: Added file `djcommon,mak' which is included in all
  `makefile.dj' files in sub-directories under `.\bin\'. djgpp users
  are now no longer required to have Borland's maker.exe to compile
  any binaries. Only free tools are used in the process.

* pcpkt.h + asmpkt4.asm change: `IP_BUFS' increased to 20 for DOSX
  targets. This seems to reduce dropped packets (`pkt_dropped()')
  experienced with the Netio test program.  But the Rx rate didn't
  increase noticably. Still some troubles with delayed ACKs in
  `tcp_Retransmitter()' I think.

* receive.c change: Replaced `kbhit()' with `__dpmi_yield()' for djgpp.
  This reduces CPU-loading under e.g. Win-NT.  Under plain DOS there's
  no problem catching SIGINT anyway.

* accept.c change: Replaced `kbhit()' with `__dpmi_yield()' at end of
  while-loop. This drastically reduces CPU-loading under e.g. Win-NT.
  It also makes it safe to interrupt a program (^C/^Break) without
  killing the DOS-box.

* select.c change: function `read_select()' will return 1 for a socket
  which is listening and which have sent ACK/SYN. Thus an `accept()'
  will block until the 3-way handshake is complete.

* pctcp.c and tcp_fsm.c changes: Integrated changes from Steve Lawson's
  `wat9909' RC5 package (October 1999);
  - Some fixes for `missed_seg' logic.

* pcmulti.c/pctcp.c changes: `is_multicast()' moved to pcconfig.c.
  Used in `tcp_handler()' to silentlt discard packets with Multicast
  source address.

* Makefile.all changed for Watcom-386 compilation to use register based
  calls (default). i.e. option `-3s' replaced with `-3r'. Also updated
  `.\bin\dos4gw.mak'.

* pcdbug.c changes: Dropped last SEQ/ACK from debug-file. It now prints
  changes in SEQ/ACK values ("dSEQ" and "dACK").  Last SEQ/ACKs sent and
  received are stored in tcp_Socket at `last_acknum' and `last_seqnum'.

* pctcp.c change: New function `tcp_upd_wind()' sends a receive window
  update to peer.

* Some djgpp programs in `.\bin\' assumed a math coprocessor was present.
  Therefore distributing the emulator `emu387.dxe' is required. I'm also
  looking into using `wemu387.dxe' instead.

* select.c changes:
   - select for exception condition set when state `SS_CONN_REFUSED' is
     set on socket.
   - Condition for setting `EPIPE' in `read_select()' changed to failed
     `tcp_tick()' AND no more data in receive buffer. This causes `EPIPE'
     to be set AFTER all expected data has been read.
   - `usec' and `elapsed' changed to use milli-sec in order to handle long
     timeouts (`long' overflow if `timeout->tv_sec' > 2147 seconds).

* socket.c change: `_TCP_listen()' sets a larger 16kB receive-window
  (`DEFAULT_RCV_WIN'). `_socklist_add()' sets `sock->so_state' to
  `SS_UNCONNECTED'.

* misc.c changes: New function `_watt_valid_addr()' for DOSX targets
  returns TRUE if address is within DS (data segment) limit. Used by
  BSD-socket API to return `EFAULT' (ref. macro `VERIFY_RW()').

* transmit.c changes:
   - Since transmission may take long time, call `SOCK_SIG_SETUP()'
     before transmit routines.

   - In `tcp_transmit()', use `sock_write()' if not enough room in
     tx-buffer. `sock_write()' will loop until all data is sent.

* sockopt.c changes:
   - Added handling of `getsockopt (s,SOL_SOCKET,SO_SNDBUF,..)' and
     `getsockopt (s,SOL_SOCKET,SO_RCVBUF,..)'. SOCK_DGRAM and SOCK_RAW
     does not have transmit buffers, so will return zero for these.

   - Handling `setsockopt (s,SOL_SOCKET,SO_SNDBUF,..)' copies any remaining
     data over to newly allocated buffer. Also clear rest of buffer.

   - Don't allow setting zero buffer size for SO_RCVBUF. Although allowed in
     BSD, the meaning to Watt-32 is unclear.

* pctcp.c changes:
   - `sock_write()' now tests for "if (written < 0)" (was "<=").
     This causes transmit error in `_eth_send()' to `return (0)' from
     `sock_write()',

   - Was wrong calculation of free space (room) in transmit buffer.
     It tested against `s->maxrdatalen'. Now changed to:
     `room = tcp_MaxTxBufSize - s->datalen'.  Thanks to Andreas Fisher
     <a.fischer@aicoss.de> for addressing these bugs.

* pctcp.c change: `udp_handler()' and `tcp_handler()' now returns matched
  socket for IP-packet.  Used to determine if peer allows IP-fragments to
  be sent.

* fcntl.c change: handles command `F_GETFL'; returns `O_NONBLOCK' if
  socket is non-blocking.

* accept.c changes: Contributed fixes from Claus Oberste-Brandenburg.
  New function `_sock_dup_bind()' to be used in creating listen-queued
  backlog in `listen()'.

* Reintroduced the config-option `O_USE_FSEXT' for djgpp. It may be
  desired to disable this for performance reasons etc.

* receive.c change: Extra test for timeout. Timeout only when no new
  data received AND no segments received within time limit.

* pctcp.c and tcp_fsm.c changes: Integrated several changes from Steve
  Lawson's upcoming `wat9909' package (Sept 1999);
   - Handling of missed segments. A new member in `tcp_Socket' remembers
     `missed_seg[2]'.


******************* Changes version 2.0 dev.rel.6 *******************

* pcdhcp.c changes: Added handling of option 52 (option overload) where
  options are present in `dh_file' and/or `dh_sname' fields.
  Parsing TFTP-server name and BOOT-file options for tftp.c module.

* New module tftp.c. Not finished because I didn't have access to a
  server with tftp-extensions. The idea is to be able to load *any*
  file from a TFTP-server after DHCP/BOOTP module have done their things.
  The function pointer `tftp_writer' must be set in order to store the
  file.

* pcpkt.c changes: The ARP-queue receives all non-IP packets.
  `pkt_poll_arp()' drops all if using serial-driver or packets who's
  Ether-type is not ARP or RARP.
  Allocating RARP-handle for receiving RARP-replies if compiling with
  `(W_OPT & O_RARP)'. This is default.
  ARP_SIZE (in pcpkt.h) is now set to (ETH_MIN+10). setup_pkt_inf()
  checks that ARP_SIZE could fit an ARP/RARP packet (plus margin).

* More changes for Watcom+DOS4GW extender;

   - bugfixes in asmpkt4.asm; pkt_enqueue() was buggy. And is now
     simplified. asmpkt.asm is now compiled as 16-bit `USE16' segment.
     Hope this doesn't produces fixup overflows. Segment `ASMPKT4_TEXT'
     should now be linked after `BEGTEXT' (in the AUTO group) to prevent
     this from happening.
   - `buf_size' for the ARP-queue was too small. Minimum ethernet size is
     60 which caused to buffers to be destroyed. `buf_size' is now set to
     `ETH_MIN + PKT_MARGIN'.

   - bugfixes in pcpkt.c; `asmpkt_inf' and `queue->buf_start' was in wrong
     format. Should be on `SEG:OFS' format. `queue->dos_ofs' is only used
     by real-mode asmpkt4.asm to calculate head pointer.

* wattcp.h change: added extra `safetytcp' field at end of `tcp_Socket'.
  tcp_handler()' checks both `safetysig' and `safetytcp'. Always print
  warning if markers destroyed.

* New files poll.[ch].  Function poll() is Linux-specific (to aid
  porting Linux applications to Watt-32). Taken from HTTP-tunnel,
  GPL'ed copyright Lars Brinkhoff <lars@nocrew.org>.

* pcbsd.c change: `_inet_addr()' updated to support dotless IP-address.

* udp_nds.c additions: added functions `isaddr_dotless()' and
  `aton_dotless()' to accept dotless IP-addresses;
  a.b.c.d = X = ((a * 256 + b) * 256 + c) * 256 + d.
  Functions requires that `a' and `d' must be non-zero.

* fcntl.c change: `fcntlsocket()' chains to `ioctlsocket()' for unknown
  commands so that calls like `fcntl (sock,FIONREAD,&length)' may
  succeed.

* signal.c change: don't set `wathndlcbrk' in `_sock_sig_setup()'.
  This hopefully prevents "Interrupting" from beeing printed while
  in BSD-function loops.

* transmit.c change: allow calling `udp_transmit()' without a local
  address. Only `SOCK_STREAM' requires `sock->local_addr' set.

* receive.c change: `udp_receiver()' sets up `socket->local_addr' if
  not done in `bind()'.

* sock_ini.c change: `ExcHandler()' for djgpp target calls `dbug_exit()'
  and `_sock_dbug_exit()' after `_eth_release()' has released PKTDRVR.

* Bugfix in pcdhcp.c, `arp_add_server()'. It was storing the Ethernet
  broadcast address to the ARP-cache for DHCP-server's IP-address.

* misc.c change: I don't trust gcc's handling of `register' variables
  in inchksum(). Hence will let gcc optimize use of local variables.

* pcpkt.c, pcarp.c, pcrarp.c changes for preliminary Token-Ring support.
  New HW-type `arp_TypeToken 0x600' in wattcp.h is used if `_pkttoken'
  is set in pcpkt.c. Never tried a Token-Ring driver so I don't know
  how this works in real-life..

* pctcp.c change: Added `s->err_msg = _LANG("Tx Error")' when `tcp_write'
  or `udp_write' fails in `sock_write()'. Also for UDP in `sock_enqueue()'.

* wattcp.h change: `tcp_Header' changed to use:
        BYTE   unused : 4;
        BYTE   offset : 4;
        BYTE   flags;
  instead of fumbling with:
        WORD   flags;
  Change affects tcp_fsm.c, pctcp.c, pcdbug.c and pcstat.c.

* pcsed.c change: Clear whole `outbuf.data' in _eth_formatpacket().
  Seems that when using serial-drivers (PPP,SLIP) we often cause
  TCP check-sum errors at peer's receiving side because small packets
  (< 60bytes) are not zero-padded.

* udp_dom.c change: dropped `num' argument from `send_dom()'. Put a
  random identifier in `q->h.ident'.

* sock_ini.c change: in `sock_exit()' don't call `dbug_exit()' if
  `watcbroke' is non-zero. I found out it's not a good idea to use DOS
  functions (in dbug_exit) after ^C/^Break is pressed. This may cause
  `_eth_release()' and `pkt_release()' never to be called. Hence will
  cause a hang on next pkt-driver upcall.

* pc_cbrk.c change: save original ^Break state. Restore state on exit.
  Increment `watcbroke' before calling `sock_exit()'.

* pcintr.c changes: updated for Watcom-386 + DOS4GW. Never tested though.

* Removed Borland C flag `-RT-' from `.\bin\common.mak' and `.\bin\makefile'.
  It's not understood by BC <= 3.1 and doesn't make a difference in BC >= 4.0.

* pcstat.c change: in `update_out_stat(), only count higher level
  protocols when IP is not fragmented or when fragment with offset 0
  is sent.

* pcpkt.c/asmpkt4.asm change: receive buffer length (_pkt_inf->rx_len)
  no longer needed. Now using CX value on 1st and 2nd upcall.

* pcdhcp.c change: Any configure DNS nameserver or gateways are deleted
  when `DNS_SRV' or `ROUTERS_ON_SNET' options are received from DHCP-
  server. Better to trust DHCP-server for correct network configuration
  than illegal `wattcp.cfg' data.

* loopback.c change: First call `_chk_ip_header()', then check if packet
  is fragmented. Return if fragmented and let `_ip_defragment()' handle
  it on next poll in `_pkt_poll_ip()'.  Last, check for ICMP "Echo Request"
  and return an "Echo Reply" to sender.

* sock_ini change: set default value for `_survivebootp' to 1 if
  O_DHCP is set.  set default value for `_survivedhcp' to 1 if
  O_RARP is set. Hence BOOTP, DHCP and RARP may be tried until an
  IP-address is obtained.

* pcbootp.c/pcdhcp.c changes: added parsing of option 7 (log-server).
  If syslog-host not specified in config-file, this host is used.

* syslog.c changes: added support for sending messages to log-host
  via UDP. New module `syslog2.c' contains config-parser and data.
  That way `syslog.c' isn't linked in by default.

* pcdbug.c change: Added keyword "DEBUG.STAT" to enable printing
  statistics counters to debug-file at program exit.

* pcpkt.c change: `pkt_enqueue()' will zero-pad remaining of buffer
  after copying to ring-buffer. This seemed to fix the tcp-checksum
  errors.

* sockopt.c change: The local-port fix below allowed socket option
  SO_REUSEADDR to be handled. calls `reuse_localport()' for UDP/TCP.

* pctcp.c changes: `findfreeport()' only tested for ports in use by
  UDP/TCP socket that where open. Since WatTCP goes to CLOSED state
  so quickly, the local port was reused too early. Thanks to Lynx
  which opens sockets all the time, I noted the local/remote ports
  where 1025/80 all the time. New routine `reuse_localport()' clears
  the inuse bit.

* pctcp.c changes: Rearranged some input checks in tcp_handler;
  tcp_chksum() moved after test for RST. Inactivity timer restarted
  before checking for RST.


******************* Changes version 2.0 dev.rel.5 *******************

* Fixed bug in gethost.c / `reverse_lookup()'. Didn't break loop on good
  result. Also in `resolve_ip()', the loop was broken on first fail; it
  didn't try next name-server.

* fragment change: Added TOS and IP-version in fragment matching.
  These must me same on all fragments. TTL and header length may differ
  for each fragment (IP-options).

* transmit.c change: `ip_transmit()' didn't use same IP-identifier if
  sending IP-fragments. New function `_get_this_ip_id()' (in ip_out.c)
  fixes that.

* New module fcntl.c contributed by Claus Oberste-Brandenburg.
  Integrated with djgpp's FS-extension feature (fsext.c).

* sockopt.c change: A bit more testing in setsockopt(). User may not
  set MSS less than 1 or larger than MAX_WINDOW (32767).

* pctcp.c change: Initial SEQ-number changed to use low-word from
  system timer. Previous version used high-word that caused problems
  with ISN reuse.

* misc.c change: Random() didn't work. Now uses mod operations and
  added more checks.

* pctcp.c change: in `udp_handler(): Don't send "ICMP Port Unreachable"
  when receiving "late" responses from DNS on UDP-port 53. Reason being
  that we closed UDP-socket in `lookup_domain()'.

* pcdbug.c change: New `atexit()' function `dbug_exit()' writes statistics
  counters to Watt-debug file before closing it.

* More changes for Watcom+DOS4GW extender;
   - added `dpmi_real_interrupt()' to watcom.c. `intr()' cannot
     be used to issue real-mode interrupt.
   - new module asmpkt4.asm for buffer enqueueing on packet-driver
     upcalls. This module implements the equivalents of `pkt_receiver_pm()'
     and `pkt_enqueue()'.
   - But there's still problems with DOS4GW port. Random crashes
     experienced !

* socket.c change: New function `_sock_dos_fd()' is used to determine
  if EBADF or ENOTSOCK should be set. If socket is a valid DOS-handle,
  then errno is set to ENOTSOCK, else errno = EBADF. Refer new macro
  `SOCK_PROLOGUE()'.

* socket.c change: failing `_sock_get_fd()' is no longer fatal.
  `errno' is not set when returning -1. Caller sets either ENFILE or
  ENOMEM.

* pcsed.c change: Watcom/DOS4GW target used a DOS-allocated buffer
  for transmission (outbuf). Now uses same static buffer as other
  targets. This improves reliability (cannot overwrite DOS-memory).
  The overhead of copying to DOS-memory (PKT_TMP in pcpkt.c) is
  neglible.

* Compiling with `gcc -Winline', revealed some functions in select.c
  and sockopt.c that couldn't be inlined. Thus removing `__inline'.

* pctcp.c change: new function `_get_machine_name()' called from
  `tcp_init()' tries to get host-name from a DOS network extension
  (NetBIOS, LANtastic etc) before `tcp_config()' parses `wattcp.cfg'.

* bsdname.c changes for better conformance to BSD:
    `gethostname()' returns the FQDN (Fully Qualified Domain Name)
    by concatenating `_hostname' + `.' + `def_domain'.

    `sethostname()' now expects a FQDN name. `_hostname' and
    `def_domain' are extracted from this name.

     `getdomainname()' and `setdomainname()' also changed. Doesn't
     touch `_hostname'

* buffer `buf' in sock_prn.c changed from static to auto.

* Compiled the djgpp version (libwatt.a) with gcc 2.9.5. This caused
  only one change; the linker map-file for .\bin\ programs is now
  printed to `stderr' and not to `stdout'. See `.\bin\common.mak' for
  use of `redir' command.

* Added support for "ICMP Address Mask Rquest/Reply" from RFC950.
  The value `sin_mask' (obtained from config-file or DHCP/BOOTP) is
  optionally checked with a "ICMP Address Mask Request".  A warning
  is given when the `sin_mask' and "ICMP Address Mask Reply" differs
  in value.

* Adapted `makefile.all' to accept option `W_OPT=0x????' be put on the
  make command line. If not specified, `W_OPT' is set to default value
  in `.\src\config.h'.

* Preliminary support for builing embedded targets. .\src\config.h
  specifies `O_EMBEDDED' for adding to the `W_OPT' variable. It's
  users responsibility to decide what code should be disabled for
  embedded targets. Sprinkle the code with "#if (W_OPT & O_EMBEDDED)"
  to include special embedded features; like making outch() send a
  character to a RS-232 port. Insert "#if !(W_OPT & O_EMBEDDED)"
  wherever you need to exclude things; like prevent calling file/disk
  related DOS-functions.

* Some C-files under .\bin\ had public function `Abort()' which clashes
  with same in Watcom's clib. Renamed to `Exit()'.

* Watcom large model now works. All .\bin\*.c programs compiled okay.
  But if compiling with `-s' (no stack checking), the programs all
  behave strange. Might be a register that should be saved.

* wattcp.h change of `in_Header': I discovered that Watcom handles
  bit-fields differently from others (GNU,HighC,Borland). The
  following caused `tos' to align at offset 2. Other aligned at 1:
      WORD  hdrlen: 4;
      WORD  ver   : 4;
      BYTE  tos;

  Now changed to:
      BYTE  hdrlen: 4;
      BYTE  ver   : 4;
      BYTE  tos;

  Which is what <netinet/ip.h> also does.

* pcicmp.c change: call `_udp_cancel()' or `_tcp_cancel()' on receiving
  `ICMP_PARAMPROB'. This is usually caused by error in the IP-header.

* pctcp.c changes:
    1) ensure correct structure packing on "struct _pkt" in _tcp_send()
       and udp_write().
    2) update of VJ algorithm, Karn count, RTT and cwin/wwin moved from
       `tcp_handler()' to new routine `tcp_rtt_win()'.

* asmpkt.asm change: Because Watcom assumes SS==DS in `pkt_enqueue()',
  we switch to a small work stack before calling.

* bug in pcsed.c caused ip-header not to be properly cleared.
  Was:
    BYTE *ip = SET_TX (&outbuf,data[0]);
    memset (ip,0,sizeof(*ip));

  Now:
    BYTE *ip = SET_TX (&outbuf,data[0]);
    memset (ip,0,sizeof(in_Header));

* socket.c change for djgpp: `_sock_get_fd()' calls `__FSEXT_alloc_fd()'
  to allocate a DOS-handle.  This is required if socket is to be used
  with e.g. `fdopen()' and normal stdio calls.  Checks are made to ensure
  the handle is < FD_SETSIZE.

* .\src\makefile.all updates for Watcom and Microsoft C compilers.

* pc_cbrk.c change: For djgpp; `set_ctrl_break()' simply calls
  `setcbrk (mode ? 1 : 0)' (D.Kaufman). Don't know if this works under
  Windows-NT; The NTVDM behaves different from plain DOS (or QEMM/EMM386).

* watcom.c change: added function `dpmi_cpu_type()'. Used by `init_misc()'
  before patching `intel()' and `intel16()' to use `bswap' instruction.

* pcpkt.c changes: DOSX targets didn't unlock the pages locked
  during init. Function `unlock_code_and_data()' now called last
  in `pkt_release()'.

* Rearranged pctcp.c: moved TCP state-machine, `tcp_ProcessData()'
  and `_tcp_reset()' to new module tcp_fsm.c.

* Preliminary LADsoft C v1.8 support; .\inc\sys\pack*.h updated.

* wattcp.h + pcdbug.c: removed `tcp_StateCLOSEMSL' (never used).

* Deleted .\src\pack*.h. Source/header files now includes
  "..\inc\sys\pack*.h"

* .\src\neterr.c change: forgot to include "borland\syserr.c" for
  Turbo-C <= 3.1

* Updated <netinet/tcp*.h> for BSD patches from PSC. (Pittsburg
  Supercomputing Centre).  These tcp modifications are for SACK
  (Selective ACK), FACK (Forward ACK) and TCP Auto-tuning. These
  features are not yet implemented though.

* sock_ini.c change: Give warning if `sin_mask' is zero. (caused
  by bad cfg-file).

* pcconfig.c change: Use `sin_mask = aton (value)' and not
  `sin_mask = resolve (value)'. Netmask should never be a name.

* .\src\tests\makefile and test programs rewritten for djgpp only.

* sockopt.c and pctcp.c changes: Added support for `SO_LINGER' option.

* socket.c changes: Added `udp->locflags |= LF_BROADCAST' after calling
  `sock_recv_init()'.

* pctcp.c changes: bitwise constructions like "foo &= ~bar" written
  as "foo ^= bar". I think this is more effective.

* Changed .\src\makefile.all for djgpp: replaced `-mpentium' with
  `-m486' in hope that everybody with djgpp now have at least a
  80486 CPU.

* fsext.c changes (djgpp only): handle reference counting for dup()
  and close(). Handle FS-extension for `fcntl (fd,F_SETFL, O_NONBLOCK)'
  and `fcntl (fd,F_DUPFD)'. Any else needed ?

* Removed files .\src\dgram.? (no longer used)

* syslog.c + printk.c added for syslog() API. Currentrly only prints to
  file. Later will print to log-server (cfg-file or DHCP/BOOTP log-srv
  option). These modules really belongs to the application layer, but is
  included in Watt-32 for convenience.

* `.\src\build.bat' renamed to `configur.bat' (to immitate Unix).

* Various updates to `makefile.all' to improve Watcom support.
  Rudimentary support for Watcom386 + WDOSX extender.

* language.l: fixed `lang_init()' to support beeing called multiple
  times to extend language entries from more than 1 file.
  E.g. application may also add language entries.

* sock_ini.c: removed macro `rand_seed()' and use `peekw(0,0x46C)'
  instead.

* socket.[ch]: New member `bcast_pool' in `struct Socket';
  for queueing UDP-packets for `INADDR_ANY' sockets (SS_PRIV state
  set). Used by `_recvdaemon()' when beeing called by `udp_handler()'.

* fsext.c: replaced `_sock_get_last()' with `fd+1'.
  socket.c: removed `_sock_get_last()'.

* sockopt.c changes: fixed handling of SO_RCVTIMEO/SO_SNDTIMEO:
  User cannot specify timeouts using `setsockopt()'. Only to get,
  e.g:
    struct timeval tv;
    getsockopt (sock,SOL_SOCKET,SO_RCVTIMEO,&tv,sizeof(tv));

* socket.c: In `socklist_add()' don't set `sock->timeout' for UDP
  and raw sockets. This causes `UDP_DGRAM' sockets to never timeout
  on inactivity.

* Added `uninit_warn()' to gethost.c to help application developer to
  remember calling `sock_init()' before using critical functions.
  Especially `gethostbyname()' etc. are often called during init and
  hence these assert the `_watt_is_init' flag and call `uninit_warn()'.
  Maybe `sock_init()' should be called also?

* Changes to keep Watcom C happy: in pcdbug.c and sock_prn.c use `va_list'
  and `va_start' instead of the `(&format)+1' trick as last argument to
  _vbprintf/vsprintf.

* Changes to keep Watcom C happy: in transmit.c and misc.c, rewrite to
  not use cast on `lvalue'.

* Define `rand_seed()' macro for DOS4GW: `(*(WORD*)0x46C)'

* transmit.c, ip_transmit() change: added `tx_len += o_len' if socket
  has IP-options.

* receive.c change: In `udp_receive()' for `socket->so_state == SS_PRIV';
  condition for reception of broadcast packets is changed to:

    if (ret != 0 && peer.s_addr)
    {
      ..
      if (ret < 0)   /* 0-byte probe */
         return (0);
      return (ret);
    }

* bind.c/receive.c changes: Return -1 when `_UDP_listen()' fails.
  `errno = ENOMEM' already set.


******************* Changes version 2.0 dev.rel.4 *******************

* New utility tools in .\util: ERRNOS.C must be compiled with compiler
  of each vendor to produce a list of errno's and sys_errlist[] which
  also includes network related errno's. These lists are produced by
  .\src\build.bat and included in .\src\neterr.c and .\inc\sys\werrno.h

* .\util\mkdep tool now only searches for ".h" files.

* djgpp's FS-extensions for sockets moved to new module fsext.c

* Added call to kbhit() in select_s().

* gethost.c changes: Return `struct hostent' with `my_ip_addr' when
  gethostbyname ("my-host-name") is requested.

* ioctl.c changes: Added SIOCGIFMTU/SIOCGIFFLAGS support.
  Fixed SIOCGIFADDR/SIOCGIFCONF handling.

* Handle special situation when UDP sockets (SOCK_DGRAM) is bound
  to an INADDR_ANY address. Wattcp's `udp_handler()' doesn't store
  address information for broadcast.

  Fix _UDP_listen() to call `sock_recv_init()' which makes sure
  SOCK_DGRAM messages received as broadcast are queued.

  In `receive()', we poll this queue using `sock_recv_from()' or in
  `select_s()' using `sock_recv_used()'.  Thus the `*from' address in
  `receive()' will be correctly set to peer's address ip/port.

* Cleaned out all tabs from .c/.h files. Tabs are evil :-)

* select_s() now terminates the poll-loop if timeout expires
  before we had time to poll all requested sockets. This makes
  the logic for `cnt > 0' AND timed-out much easier.

* Allow bogus IP-packets in `_ip_raw_peek()'.

* Allow SOCK_RAW sockets to call `send()', `sendto()' and `write_s()'
  withhout a `socket->local_addr' filled in.

* gethost.c changes: Added expiry of cached values stored in
  `gethostbyaddr()' and `gethostbyname()'. Configurable timeout
  (default is 15min).

* Moved all build options defined in W_OPT to new file config.h.
  config.h is included in wattcp.h.

* New module nettime.c. Implements net_times() to return "user"
  and "system" time. System time is time-ticks used in BSD-sockets
  calls.

* Added check for "addrlen < sizeof(struct sockaddr_in)" in some
  places. Set `errno = EADDRNOTAVAIL' if fails.

* Added timer for SOCK_STREAM sockets before they are deleted from
  linked list. Times out after `sock_delay' (30) seconds.

* pcconfig.c changes: Added `is_ip_brdcast()' function.

* New module ip_out.c. Routine `_ip_output()' builds the IP-header
  and transmits it.
  Notes:
    Contrary to most Wattcp function, arguments `srp_ip' and
    `dst_ip' are on network-order (big-endian). Arguments `sock',
    `file' and `line' are only used for packet-debugger (in pcdbug.c).

* receive.c changes: store AF_INET in `from->sin_family'.
  Added routine `udp_raw_fill_from()'.


******************* Changes version 2.0 dev.rel.3 *******************

* transmit.c change: Sets ENOMEM if alloca() fails in writev_s().

* bind.c change: Don't change `sin_addr' to our IP-address when
  binding locally.

* connect() sets errno = EHOSTUNREACH when ARP fails.
  Not ENETUNREACH as previously.

* recv(), recvfrom() and read_s() returns -1 and errno = ENOTCONN when
  socket-state SS_CANTRCVMORE is set.

* select_s() now returns when all sockets (s < num_fd) are checked.
  Not when first count gets set.

* select_s() didn't do FD_SET on output. Set correct bit for socket
  when read, write or exception event fullfilled.  Under djgpp,
  call _dpmi_yield() in select loop.

* tcp_receive() refinement: return 0 when FIN received.
  Don't set errno.

* pkt_send() and _eth_send() returns length of data sent.
  sock_write(), sock_enqueue() returns 0 immediately if
  transmission fails (pkt_send() returns 0).

* TCP-debugger changes: ACK/SEQ-numbers written as decimal.
  This makes it easier to look for retransmissions.

* Didn't stop RTT-timer in tcp_Retransmitter(). This caused aggressive
  retransmissions (which caused congestion).
  Uses `sock_delay' for `tcp_LONGTIMEOUT' when opening a connection.

* gethostbyaddr() returns my_ip_adr and hostname for INADDR_ANY (0.0.0.0)
  gethostbyaddr() returns "broadcast" for INADDR_BROADCAST or limited
  broadcasts adresses.

* Fixed __ffs() function (in ffs.asm).
  Added __ffs() (in misc.c) for djgpp 2.01 or older.

* Added handling of SO_KEEPALIVE in tcp_sock_daemon().


******************* Changes version 2.0 dev.rel.2 *******************

* socket() returns -1 with errno = ENETDOWN when no network-driver
  (pktdrvr) is found. Previous action was to exit the program.  -GV

* Changed sock_init(), tcp_init(), _eth_init() and pkt_init() to return
  non-zero if they fails. (to support above change). Error codes (WERR_x)
  are in sock_ini.h.  -GV

* 'sock_setdebug(FILE*)' removed. Instead controlled by WATTCP.CFG keyword
  SK_DEBUG.DEVICE and 'sockopt(s,SO_DEBUG,..)';


*******************  version 2.0 dev.rel.1 *******************

- - -
General Changes                    (12/12/1998)

    Version 2.0 dev release 1.

    Changes for Watt-32 are too numerous to list in detail here.

    Watt-32 supports these compiler environments:

      GNU C/C++ 2.7 (or later) with djgpp2 DOS-extender.
      Metaware HighC 3.x with PharLap DOS-extenders.
      Borland C/C++ 4.x (or later), small/large model, real-mode.

    Provision for Watcom-386, MS Visual C 1.52 and MS Quick-C is included,
    but mostly untested.

    These are some of the new functions of Watt-32:

    DHCP-client: An RFC-1541/2131 compliant DHCP-client allocates
      an IP for you, sets the netmask and gateways etc. User doesn't need to
      configure wattcp.cfg.

    RARP-client: Dan Kegel contributed a RARP-client which tranlates your
      EtherNet address into a usable IP-address.

    ICMP-redirect: Watt-32 automatically switches gateway if an ICMP-redirect
      is received.

    PPP-support: Watt-32 supports both types of PPP-drivers;
      i.e. types that emulate EtherNet frames and those who don't.
      Antonio Lopez Molero has written the excellent DOS-PPP driver that
      works very well with Watt-32. Get
      ftp://ftp.gui.uva.es/.1/pc/freedos/files/internet/dosppp/dosppp06.zip

    Protocol debugger: A much improved protocol debugger/tracer
      analyses IP (ICMP, UDP and TCP) and ARP/RARP packets to/from your host
      (or broadcast). Various headers can be filtered. DNS-records and IP/TCP
      options are also shown.

    BIND Resolver: A port of the Unix resolver library. This was
      added mainly to implement the getmxbyname() function.

    File based lookup: User may specify fixed IP/names in a hosts
      file.  All the getXbyY() functions from <netdb.h> are
      supported.

    BSD-Sockets: Watt-32 tries to mimic the BSD-socket API with
      support for SOCK_DGRAM, SOCK_STREAM, SOCK_RAW, blocking and non-
      blocking I/O. Most header files required to port Unix network programs
      to WatTCP/DOS is provided. This API needs some work to improve transfer
      rate, compliance to the man-pages etc. But it is currently used to
      built the Lynx Web-browser (see http://sol.slcc.edu/lynx/current/)


    1. I've tried to keep the original names on most appliciation-specific
       function, but a few presented too much trouble when porting BSD-Unix
       applications to DOS:

         Old name:          New name:
         getsockname()      _getsockname()
         getpeername()      _getpeername()
         inet_ntoa()        _inet_ntoa()
         inet_addr()        _inet_addr()

       The BSD versions getsockname() and getpeername() are implemented in
       netaddr.c

       Remember: Most (all?) BSD-style network functions use network order
         (i.e. big-endian) quantities as opposed to WatTCP which use
         host order (little-endian) as parameters to all functions.
         Take great care when mixing generic WatTCP functions and
         BSD-style functions.

    2. chk_timeout() returns 0 if argument (timeout) is 0. This is to
       update the 'date' variable more often. Since 'set_timer()' and
       'set_ttimer()' can never return 0 for active timeouts, I regard
       this as safe.

    See readme.too for additional changes.

    -GV, Gisle Vanem <giva@gnett.no>

- - -
General Changes                     (7/16/93)
    I did a lot of cleaning up to make this compile more nicely and
    more than a year's worth of bugs have been fixed.

    Several areas underwent protocol optimization to significantly
    improve performance under certain circumstances.  Noticable
    enhancements include SLIP support and fragments reassembly, but
    the latter is currently disabled as I introduced a bug.

- - -
General Changes                     (3/31/92)
    This update has a lot of little bug fixes, optimizations and
    general improvements thanks to a lot of people's input.  In
    particular, Jason Dent and Graham Robinson (author of PKTMUX10).

1. Push bit handling is improved.  This is mostly necessary for 3270
   protocols, most others treat tcp as a simple binary stream.

2. Zero window probing has been fixed.  This will keep things rolling
   even when the remote machine is swamped and the network becomes lossy
   around the same time.

3. A bug in the ASCII tcp stuff was introduced on my site this month
   and has been fixed.  I don't know if the bug was on my old distribution.

4. Significant changes were made to the internal handling of acknowledgements
   and handling data within the receive window.

5. A bug used to annoy SCO and possibly other system consoles - fixed.
   When WATTCP wished to refuse unwanted sessions from remote systems, it
   would be missing a small flag.  Most tcp's didn't notice this flaw.

6. Type of Service flag now RFC compliant - currently unused in non-military
   installations, this flag could be used to set priorities for TELNET
   sessions versus bulk data transfers like FTP, particularly over slow
   lines.  Phil Karn (Mr. KA9Q) is currently researching this area and
   so this upgrade should make WATTCP code react properly (unlike SunOS, BSD,
   etc.) in sites which use his TCPs.

Erick

- - -
Speed/Performance               (1/04/1992)

    The tcp code has undergone some mods to make it much faster, with
    reads up to 120 kilobytes/s and writes up to 42 kilobytes/s on the
    same subnet as my Sun.

    These speed were great, but my pc is usually on a subnet.  There, the
    speeds were about 26 kB/s in writes and 70 kB/s in reads.

    For read's I was able to use good old sock_fastread.  For writes,
    sock_fastwrite / sock_write just don't cut it because they are limited
    to the small buffer size located in the tcp_Socket structure.

    I've added a new call which let's you get around that limitation,
    sock_enqueue().  This new routine let's you specify a buffer of data
    you wish to enqueue for transmission.  WATTCP records the address of
    that buffer and its length, and starts to transmit it according to
    the TCP rules.  You are not allowed to touch that buffer until all
    the data is fully transmitted, something you can tell by using the
    sock_tbused( s ) until it returns zero.  You must also keep calling
    tcp_tick() or sock_tick() as those routines schedule transmissions.


    Here is some sample code which writes out a disk file:

    tcp_open...
    f->dhanle = open( ....
    ...
    while ( 1 ) {
        /* check connection and do background stuff */
        if (tcp_tick( s ) == 0) break;

        /* see if we can schedule more data */
        if ( sock_tbused( s ) == 0 ){
            printf("disk reading %u bytes\n", ftpdbufferlen );
            if ((diff = read( f->dhandle, ftpdbuffer, ftpdbufferlen )) <= 0 ) {
                /* eof or possibly error condition */
                break;
            } else {
                /* data ready to send */
                sock_enqueue( s, ftpdbuffer, diff );
            }
        }
    }

    close( f->dhandle );
    sock_close( s );
- - -
SMTPSERV  (in separate file: SMTPSERV.ZIP)

    This program accepts inbound mail and places it into mail spool files
    almost identically to the way Phil Karn's NOS does.  You can download the
    executable in pub/wattcp/smtpserv.zip.  If you find it useful or wish
    to have it changed, let me know.

-----------------------------------------------------------------------------

Large Model                     (9/13/1991)
    You can compile large or small model applications.  Check out the
    MAKEFILE in the .\APPS subdirectory to see how easy it is to switch.

    The fullsrc.zip collection automatically produces large and small
    model libraries.

    There is a potential problem when you compile applications because
    you make the same mistake I did and place tcp_Socket on the stack
    by declaring it an automatic variable.  The 'C' stack is normally
    only four K, slightly less than the tcp_Socket structure.

    I didn't figure this one out very quickly, so tcp_open, udp_open,
    and tcp_listen have code to warn you immediately and exit in case
    you forget.

-----------------------------------------------------------------------------

TCP Fixes                       (9/13/1991)
     The TCP portion of WATTCP has had numerous improvements.  I've managed
     to significantly reduce the packet count while improving performance
     and reliability.

-----------------------------------------------------------------------------

New Wattcp Programs
     The latest release of MS-Kermit includes the WATTCP kernel, letting you
     use it as a TELNET program.  I do not know where the ftp site is,
     but it will probably be announced soon on Comp.protocols.tcp-ip.ibmpc
     in the near future.

     LPD is a line printer server which will let a PC accept jobs from UNIX.
     It offers some simple device restriction capabilities.  You can spool
     jobs out any DOS file or device.  It requires a little few lines
     of work to be used at any site other than mine.  It is available

     COMD.EXE is a simple program can be used to allow network access to
     RS232 devices.  With a little work it could be converted into a modem
     pool.  It is available from [129.97.128.196] pub/wattcp/comd.zip.

     If you have any improvements or new applications, please let me know.
     I will gladly distribute them for you.

-----------------------------------------------------------------------------

Nested Config Files             (7/16/91)
    Wattcp config files may be easily nested to allow for centralized
    control of most parameters with local overrides, or user specific
    extensions.

    To include a nested config file, use the following line in the
    main config file:

        include = filename
    eg. include = c:\local.cfg

    If the local file could not be found, a warning message is displayed.
    You may wish to use a local file if it exists, but not display a message
    if it does not.  To do that, simply prepend the filename with a question
    mark.

    eg. include = ?c:\local.cfg

    When the nested file is complete it will return to the main file.

    The nesting limit is dependant upon the number of unused file handles
    and the stack size.

-----------------------------------------------------------------------------

TCP/UDP Packet Dumps            (7/10/1991)
    TCP/UDP packet dumping features have been added and may prove useful
    for testing and debugging your applications.

    The debugger dumps packets, which gives you a feel for what the
    kernal and the other end are trying to do.

    It's my job to try to make things go as fast as possible with as
    few packets as possible (least load).  Actually, when you use the
    dumping feature you usually INCREASE the packet count because the
    dumper takes time which times out the scheduler and causes
    retransmits.

    To include the debugging features in your program, add the line
        dbuginit();
    to your program *before* you call sock_init();

    To enable/disable the debugger, include the following lines in your
    WATTCP.CFG file:
        DEBUG.FILE=somename     # otherwise it will open a file called
                                # WATTCP.DBG in the current subdirectory
                                # somename could be con which will dump
                                # to the screen
        DEBUG.MODE=DUMP         # to dump TCP/UDP data, looks a bit like
                                # DEBUG.COM
   or   DEBUG.MODE=HEADERS      # to dump TCP/UDP headers
   or   DEBUG.MODE=ALL          # to dump everything, headers and data

   You may write some textual data directly to the file.  Remember, you
   must send a 'C' string ending with a 0, and you must include your
   own CRLFs.

        db_write( char *msg );

   NOTE: If you use this feature and you also use usr_init, you
         must chain usr_init as described in the programmers manual,
         and as show in TCPINFO.C.

-----------------------------------------------------------------------------
Good UDP Support                (6/5/1991)
   Initially, only standard socket calls could be used for UDP.  That was kind
   of shabby because UDP tends to be higher traffic, has no flow control, and
   you wish to know record boundaries.

   The new code allows you to declare a big buffer into which the incomming
   UDP packets will be bufferred.  Once initialized with sock_recv_init, the
   buffer is used until the socket is closed.  NOTE: sock_recv... and the
   regular socket input routines are MUTUALLY EXCLUSIVE, you can not use
   one and the other at the same time.

        byte bigbuf[ 8192 ];
        byte smallbuf[ 512 ];
        int templen;

        if ( !udp_open( &data, localport, remote, remoteport, NULL) ) {
            printf("Error opening UDP channel");
            exit( 3 );
        }
        /* set the big buffer */
        if ( sock_recv_init( &data, bigbuf, sizeof( bigbuf )) == -1 ) {
            printf("Error setting the receive buffers");
            exit( 3 );
        }
        while ( 1 ) {
            tcp_tick( NULL );           /* got to do this or sock_tick */

            /* check for incomming udp data */
            if ( templen = sock_recv( &data, smallbuf, sizeof( smallbuf ))) {
                /* something received and it was templen bytes long */
            }
        }
        sock_Close( &data );

   sock_recv... adds extra code, so it need not be used for simple UDP sockets
   such as BOOTP which expects only a single packet.

   See sock_mode checksums below for more interesting notes.

-----------------------------------------------------------------------------
UDP Checksums                   (6/5/1991)
   sock_mode can be used to enable or disable checksums for udp sessions
   using the following calls:

        sock_mode( &socket, UDP_MODE_CHK );
        sock_mode( &socket, UDP_MODE_NOCHK );

   Unlike *some* systems, Waterloo TCP correctly assumes checksums are active
   and allows an application to disable them on the fly as they consider
   appropriate.

   Either or both sides may disable or re-enable checksums.

-----------------------------------------------------------------------------
TCP Nagle Algorithm             (6/5/1991)
   The Nagle algorithm is now used to collect data.  Nagle is ideally suited
   to programs like TELNET (TCPPORT), etc. which send a lot of small chunks
   of data.  Some programs, like X-Windows, real-time data collection, etc.,
   should turn of the Nagle feature.  Nagle is on by default and should not
   be disabled unless a true problem is experienced.

        sock_mode( &socket, TCP_MODE_NONAGLE ); /* turns it off */
        sock_mode( &socket, TCP_MODE_NAGLE );   /* re-enables it */

-----------------------------------------------------------------------------
getdomainname Changes           (6/5/1991)
   getdomainname always took a string and length parameter, just like UNIX.
   Now, if the length is zero, getdomainname just returns the pointer to
   a system copy of the domainstring.

-----------------------------------------------------------------------------
gethostname sethostname Changes (6/5/1991)
   gethostname and sethostname are now available.  They work identically to
   get/setdomainname() (as enhanced above).  The host name can either be set
   via the WATTCP.CFG file or via bootp.
-----------------------------------------------------------------------------

sock_PreRead addition           (4/26/1991)

   int sock_PreRead( void *s, byte *dp, int len );

   Some situations arise where it would be nice to read data without causing
   it to disappear from the socket's buffer.  Usually that means double
   buffering.  sock_PreRead works exactly like sock_FastRead, except it does
   not remove the read data from the data buffers.  The returned value is the
   number of bytes transferred, 0 for no data waiting, or -1 on a socket
   error.

   This function is intended for special cases which are not easily performed
   using other methods.

-----------------------------------------------------------------------------

sethostid addition              (4/26/1991)

   longword sethostid( longword ip );

   This function sets the system's default ip address.  Changing the ip address
   will destroy existing TCP and UDP sessions.  You should close all sockets
   before calling this function.  The passed ip address is always returned.

   This function is low level and rarely useful to an application programmer.

   main()
   {
       longword ip = 0x80010101;   /* 128.1.1.1 */
       char buffer[ 512 ];

       sock_init();
       sethostid( ip );
       printf("IP address has been set to %s\n\r",
           inet_ntoa( buffer, getipaddr() );
   }

-----------------------------------------------------------------------------

setdomainname addition          (4/26/1991)

   char *setdomainname( char *string);

   The domain name returned by getdomainname and used for resolve() is set to
   the value in the string passed to setdomainname().  Note that changing the
   contents of the string after a setdomainname() call may or may not change
   the value of the system domain string and is not recommended.  You are
   recommended to dedicate a static location which will permanently hold that
   name.

   setdomainname( NULL ) is an acceptable way to totally remove any domain name
   and subsequently resolves will not attempt to append a domain name.

   The passed string is always returned, as demonstrated below.

   This function is low level and rarely useful to an application programmer.

   #include <stdio.h>
   #include <tcp.h>
   char buffer[ 512 ];  /* use a static or a calloc, do not place the name
                           in a local variable on the stack, it may get lost! */
   main()
   {
       sock_init();
       puts("Enter a new domain");
       gets( buffer );
       printf("Was using %s\n\r", getdomainname());
       printf("Now using %s\n\r", setdomainname( buffer ));

       setdomainname( NULL );
       puts("Now using no domain name");
   }

-----------------------------------------------------------------------------

_arp_resolve addition           (4/26/1991)

   _arp_resolve( longword ina, void *ethap)

   Given an ip address (ina), find the hardware address.  If ethap is non-NULL,
   place the hardware address in the buffer pointed to by ethap.

   Each call to _arp_resolve checks a local cache to see if we already know
   the hardware address.  If no entry exists for that IP address, steps
   are taken to find a hardware address.  If the ip node is on our subnet,
   an ARP request is broadcast, otherwise _arp_resolve is called recursively
   to find the address to the gateway.

   Socket opens intrinsically call _arp_resolve and place the hardware address
   in the socket structure so they are no longer dependant upon existance in
   the cache.  This means existing tcp and udp sessions do not automatically
   reconfigure if a new route is found to the remote host, but this is typical
   of pc implementations and is quite reasonable.

   Programs which wish to force the hardware address to be in the arp cache
   need only specify the ip address and NULL for the ethap buffer.

   Returns 1 on success or 0 if the ip address could not be resolved.

   This is a special use function and is rarely necessary for user
   applications.

-----------------------------------------------------------------------------

