home *** CD-ROM | disk | FTP | other *** search
- ; LANTEST.TXT -- Documentation for LANTEST
- ; Copyright (c) 1994 by Allen Brunson version 1.00 06/30/94
-
-
- ******************************************************************************
- * *
- *** Trademarks ***
- * *
- ******************************************************************************
-
- Borland is a registered trademark of Borland International, Inc.
-
- Microsoft and MS-DOS are registered trademarks and Windows is a trademark
- of Microsoft Corporation.
-
- Netware and Novell are registered trademarks and IPX is a trademark
- of Novell, Inc.
-
-
-
- ******************************************************************************
- * *
- *** Introduction ***
- * *
- ******************************************************************************
-
- LANTEST is a fairly basic program that nonetheless demonstrates all the
- procedures necessary to make LANLIB work effectively. It allows up to 30
- users at PCs on a network to exchange messages in real-time (but could be
- made to support a more or less unlimited number by changing the define
- USERTOTAL in LANTEST.H). It displays a large quantity of messages about its
- operation so as to give the potential NETLIB user a feel for what is going
- on. It is far from bulletproof; a great many optimizations and "sanity
- checks" that would have gone into a production program have been omitted to
- keep the source code relatively simple.
-
-
-
- ******************************************************************************
- * *
- *** Compiling LANTEST ***
- * *
- ******************************************************************************
-
- The following source files pertain solely to LANTEST:
-
- LANTEST.C Main LANTEST source file
- LANTEST.H Defines for LANTEST
- INPUT.C Keyboard input and input processing routines
- NETWORK.C High-level IPX routines
- PROCESS.C Miscellaneous processing routines
- VIDEO.C Rudimentary screen functions
-
- Like any other LANLIB-using program, LANTEST uses the following files:
-
- LANLIBSC.LIB LANLIB routines for the Small and Compact memory models
- LANLIB.H Defines for LANLIB
- LANCFG.H Configuration parameters for LANLIB
- LANUTIL.C Optional routines for dealing with IPXADDRFULL structures
-
- Create a project or make file that includes all the .C files and the proper
- .LIB file. LANTEST was designed as a small model program, but can be made to
- work in any memory model (well, almost any memory model -- see below) by
- including a different .LIB file and changing the memory model check near the
- top of LANTEST.H.
-
- LANLIB and LANTEST have been tested with Borland's Turbo C++ v1.0 and v3.0
- and Microsoft's C++ v8.0. They work fine with all of these, except that the
- Tiny model doesn't work with Microsoft C; its linker says that far segment
- accesses are not allowed in that model.
-
- While tweaking the program to work with Microsoft C, I couldn't find library
- functions to do certain things I wanted to do, so rather than writing my
- own functions, I just left those parts out. Specifically, when compiled
- with a Microsoft compiler, LANTEST will not be able to scroll the upper
- part of the screen (it simply erases it instead), it won't wait a variable
- length of time before sending ping responses, and it is not able to set
- screen colors.
-
- An already compiled version of the demo is given as LANTEST.EXE.
-
-
-
- ******************************************************************************
- * *
- *** Running LANTEST ***
- * *
- ******************************************************************************
-
- LANTEST should be run on two or more PCs, but will minimally function on only
- one. If you have the full version of LANLIB, the PCs involved can be on
- any network segments in an internetwork; if you have the shareware version,
- then the PCs must be on the same segment.
-
- Each PC must at minimum have the IPX TSRs loaded; it doesn't matter whether
- NETX or VLM is loaded or not. If you do have a "full" network, including a
- NetWare server, it might be easiest to copy LANTEST.EXE into a subdirectory
- on the server and run it from there. On the other hand, you might wish to
- copy LANTEST.EXE to each individual PC's hard disk and unload NETX or VLM,
- just to convince yourself that LANLIB really does work without a server.
-
- When started, LANTEST draws a box around most of the screen, leaving a single
- line free at the bottom for entering commands. If your display is in a text
- mode that has more than 25 lines, LANTEST will adjust itself accordingly;
- since it can display up to several lines of information for each packet
- transaction, it needs all the lines it can get. The utility LINE50.COM is
- included to put VGA displays into 50-line mode (or EGAs into 43-line mode);
- you can run this before LANTEST if you wish.
-
- LANTEST initializes LANLIB with a call to ipxStart(). If the IPX driver
- isn't loaded, you'll get an error message to that effect; the program can't
- continue. If the IPX driver was located in memory, LANTEST will display the
- local PC's network address, a reminder that F1 will produce a help screen,
- and instructions to use the NAME and PING commands to get started (or NAME,
- ROUTE, and PING, if you've got the full-blown version).
-
- You can press F1 or enter the command HELP (or H) at any time to get a list
- of commands and keys recognized.
-
- Enter "NAME Allen" (without the quotes), replacing my name with yours.
- The program will tell you that it has set your name.
-
- If you've got a registered version of LANLIB that includes the router-finder,
- next type ROUTE to update the program's network table. This might take
- awhile; you can press Esc to abort. After the route-find is complete, you
- can type NET to get a list of all networks that were discovered. If you
- enter a filename after NET, then it will also write the information to a
- file.
-
- Next enter PING, which will cause LANTEST to broadcast an "are you there?"
- request to all potential users. (If you do the PING before ROUTE, then
- LANTEST will only know about its own network segment at that point and
- therefore will only ping locally.) Other copies of LANTEST will respond with
- "Yes, I'm here" packets, sending the name of the person along with the
- message. LANTEST waits for a random amount of time up to one second before
- sending "Yes, I'm here" responses to keep the copy of the program doing the
- asking from being deluged with replies all arriving at the exact same
- instant.
-
- You should get messages onscreen indicating received ping responses. Wait
- at least a second for the activity to die down. Then enter DISPLAY to
- show a list of all users that were found and the IPX addresses of their PCs.
- The numbers in the "Rcv" and "Snd" columns indicate the maximum number of
- receive and send ECBs that each machine has ever used up to this point.
- The number in the "Time" column is the estimated time it takes to send a
- packet to that user, in IBM PC clock ticks (about 1/18th of a second); this
- information is returned by the ipxAddrImmed() procedure. The machine you are
- using is always first in the list and indicated by an asterisk.
-
- The simplest command you can use is BROADCAST [message], which sends a
- message to all users that the program knows about. (Despite the name, it
- does NOT broadcast the message to address FFFFFFFFFFFFh; this is considered
- a sloppy programming technique.) Note that this has the effect of updating
- all receivers' user lists with your name and ECB usage statistics, if their
- information is out of date.
-
- The MESSAGE [usernum] [message] command will send a message to only one user.
- You must enter the user's number from the list generated by DISPLAY.
-
- An interesting feature of LANTEST is that it will try to interpret the text
- of a received broadcast message or directed message as if it were a command.
- If it's not a valid command, no error will be displayed; it is assumed the
- message was only informational. If the message is a valid command, then
- the receiving copy of LANTEST will act on it. Therefore, all running copies
- of LANTEST can be controlled from any one copy.
-
- The FLURRY command is used to send out flurries of packets. FLURRY ON will
- begin the packet flurry. If at least one copy of LANTEST is sending
- flurries, then all PCs that it knows about will receive the flurries and
- will display the total number of flurry packets received every time that
- 1,000 of them have arrived. Try issuing the command BROADCAST FLURRY ON,
- which will send the command to all PCs running LANTEST, and see how badly
- your network bogs down. FLURRY OFF turns off the flurry packets;
- BROADCAST FLURRY OFF will instruct all PCs to stop. FLURRY RESET resets
- the number of received flurry packets to zero.
-
- STAT displays the maximum number and total number of send and receive ECBs.
- (The maximums are also displayed in the DISPLAY listing.) You can reset
- these values to zeroes with STAT RESET.
-
- If one user exits LANTEST, it doesn't send any kind of notification to other
- users that it has left, so their user tables will be out of date. Issuing
- another PING will clear things up. This could have been taken care of by
- the program itself, but this is only a demo, after all.
-
- When you're finished playing with LANTEST, enter QUIT to return to DOS.
-
-
-
- ******************************************************************************
- * *
- *** Dissecting LANTEST ***
- * *
- ******************************************************************************
-
- There are several source files necessary for LANTEST, but almost all of them
- involve typical program tasks like printing text to the screen, managing
- and processing user input, and so on, and can be safely ignored by the
- reader who merely wants to learn how to use LANLIB.
-
- LANTEST.H contains defines for LANTEST, including the definition of the
- USER structure that holds information on all known users, and struct
- LANTESTPKT, which is the structure for the data in all packets that LANTEST
- sends and receives.
-
- VIDEO.C contains rudimentary screen functions. It has routines to do tedious
- video tasks like drawing the box around the main window, scrolling the top
- portion of the screen, and so on. All video output to the top window is done
- via calls to message().
-
- INPUT.C is responsible for reading keyboard input and processing command
- lines once the user has finished entering them. Two of its procedures,
- getKeys() and cmdProcess(), are in the program's main loop.
-
- PROCESS.C contains miscellaneous procedures not very interesting to the
- potential LANLIB user. demoStart() checks to make sure that the DOS version
- is at least 3.0, the minimum required for LANLIB. The one IPX-related
- procedure it contains is err(), a routine that will display a message
- onscreen for each possible LANLIB error code.
-
- NETWORK.C is the real heart of LANTEST. For the reader interested in
- learning how to use LANLIB, this is the file that deserves closest scrutiny.
- It is initialized with a call to nStart(), which calls ipxStart() to start
- up LANLIB. If the define DEBUG in LANTEST.H is un-commented, then nStart()
- passes the address of an IPXDATA structure, ipxData, to ipxStart() to use as
- the communication data. This is useful for debugging, as you can inspect the
- many fields of the IPX structures to see what is going on. If DEBUG is not
- defined, then nStart() instead calls malloc() to allocate a block of memory
- to use for communication data.
-
- Next nStart() calls ipxAddrLocal() to get the address of the PC it is running
- on and saves the address as the first entry in its user structure. Then it
- copies its address to ipxAddrBroad, an IPXADDRFULL, and uses the utility
- routine ipxAddrBrd() to set the node and immediate address fields to
- FFFFFFFFFFFFh, which makes the address suitable for broadcasting on its local
- segment. (This step is technically only necessary for single-segment
- programs, but even the router-finding version of LANTEST is restricted to
- a single segment until ipxRouteFind() is called.)
-
- Here is LANTEST's main() procedure, from LANTEST.C:
-
- byte main(void) // Begin main()
- {
- demoStart(); // Start up subsystems
-
- while (!endProgram) // Main program loop
- {
- getKeys(); // Get input keys
- cmdProcess(); // Process commands
- while (ipxRecvChk()) recvPacket(); // Process packets
- sendFlurry(); // Send flurry packets
- sendErr(); // Check for send errors
- }
-
- demoStop(); // Stop subsystems
-
- return FALSE; // Return errorlevel 0
- } // End main()
-
- It merely calls demoStart(), then calls six major procedures in a loop until
- endProgram is TRUE, then calls demoStop().
-
- The procedure getKeys() processes no more than one key at a time. This
- allows other tasks to run while the user is entering command lines. The
- procedure cmdProcess() will return immediately unless the user has just
- pressed Enter, ending a command line, or unless there is a message to be
- interpreted as a command. If a command line is ready, cmdProcess() will
- parse it and call the procedure necessary to execute it.
-
- The procedure recvPacket(), in NETWORK.C, processes one received packet.
- Note that the main loop is written so as to call recvPacket() as many
- times as necessary to clear out all received packets. This slows down
- other processes somewhat but ensures that the receive ECBs should almost
- never completely fill up.
-
- recvPacket() checks the first word in the packet's data, looking for
- LANTEST's signature. If it doesn't find it, it displays an error message and
- does nothing further with the packet.
-
- If the signature is okay, it checks the packet type (the second word in the
- packet) to see if it's a flurry packet. If it is, it increments the count
- of flurry packets. If the count is evenly divisible by 1,000, it displays
- the flurry packet total.
-
- If it's not a flurry packet, it displays a message saying that it got the
- packet, along with the address of the sender.
-
- Since the signature in the packet was correct, the sender has now been
- verified as a bona-fide LANTEST user, so userSave() is called to add this
- user to the user table (or to update existing information). The user's
- address, name, and statistics are saved.
-
- LANTEST uses only five types of packets: ping, ping response, broadcast,
- message, and flurry. A number indicating the packet type is stored in
- the packet as its second word-sized variable. Based on this information,
- recvPacket() calls one of four routines to process the packet in some way
- (flurry packets will have already been dealt with).
-
- If the packet was a broadcast or message, then recvBroadcast() or
- recvMessage() is called, respectively. These packets are quite easy to deal
- with; these procedures simply print "Broadcast from <name>:" or "Message from
- <name>:" and then the text of the message, which is stored as the fourth and
- final field in the data packet. Then the text of the message is copied to
- cmdStr, the command string, and inputFlag is set to 2, which means "remote
- input received." The next time through the main loop cmdProcess() will
- notice this and try to interpret the message as a command.
-
- Receiving a ping packet requires the most processing and is done by
- recvPing(). Since the ping will be received by possibly a great many other
- copies of LANTEST, all of which are going to send back a ping response, the
- sender could be deluged with packets, its receive buffers might fill up
- before it could process all the replies, and so some replies might be lost.
- To keep this from happening, recvPing() waits for a random amount of time, up
- to a second, before calling ipxSendPkt() to send a reply to the address that
- the ping was received from. Note that when LANTEST sends a ping, it receives
- a copy just the same as everybody else, so this procedure checks to see if
- the sending address is the same as this PC; if so, it doesn't send a ping
- response.
-
- If the packet received is a ping response, recvPingResponse() is called.
- The purpose of a ping response is to make note of the sender in the user
- table, and recvPacket() has already done this, so recvPingResponse() does
- nothing but print a message onscreen.
-
- routeFind() is called when the user enters the ROUTE command. It calls
- ipxRouteFind() to find networks, and uses routeWait() as its procedure to
- be called while waiting for ipxRouteFind() to complete. If DEBUG is defined,
- it uses a static structure for the network info; if not, it uses malloc() to
- get a block of memory instead. The information that it gathers is only
- used by sendPing(), described below.
-
- The procedure sendFlurry() is called in the main loop. If flurry mode isn't
- turned on, it does nothing. If flurry mode IS on, it sends one (but ONLY
- one) flurry packet to a user in the user table. Then it increments its
- user number for the next call. If the current user number points to a
- slot in the user table that is unused, sendFlurry() does nothing; given
- that most of the slots in the 30-user table will be probably be free,
- sendFlurry() wastes a lot of time. This was done intentionally.
-
- The procedure sendErr() is called repeatedly in LANTEST's main loop. It
- checks for send errors with ipxSendChk(); if there is one, it uses
- ipxSendErr() to retrieve the packet that couldn't be sent and the address it
- should have been sent to. If there's an error, sendErr() does nothing
- but print a message; a "real" program should either retry the send or take
- other action as necessary.
-
- sendBroadcast() is used to broadcast messages to all users. It does NOT
- do so by sending the message to node address FFFFFFFFFFFFh, as you might
- guess; it sends the message to each user in its user table instead. This
- is more work -- it has to do a send for every user in the table, instead of
- just one send to its "broadcast" address (or a send to all of its broadcast
- addresses, if the router finder has been called) -- but this is the proper
- way to go about it. IPX broadcasts are received by every PC on the network,
- whether they're running your program or not. Therefore, each and every IPX
- driver on every machine on the network will receive a broadcast and have to
- spend precious CPU cycles determining that there isn't a program running at
- that machine that wants it. Therefore, you should only use broadcasts when
- absolutely necessary, which is normally only while you're looking for other
- PCs running your program. If you fail to follow this rule, the network
- managers at large sites where your program is run will be very unhappy with
- you.
-
- Since sendBroadcast() does a bunch of sends in quick succession, it really
- should be written so that it checks the return value from ipxSendPkt() to
- see if all available send ECB/packet pairs are in use, and if so, it should
- wait a short period of time, say 20 milliseconds, perhaps using the time
- to call ipxSendErr() to clear out any errors, and then try again. It doesn't
- do this as written.
-
- sendMessage() is pretty much like sendBroadcast(). It's a little simpler
- in that it only has to send to one user, and a little more complicated in
- that it has to collect a user number and check to make sure that the number
- is valid.
-
- sendPing() is called when the user issues the PING command. It clears its
- user tables of all entries (except the PC it is running on, of course) and
- then broadcasts a ping packet. A "ping packet," for the purposes of this
- program, is nothing but one that has its packet type set to the numeric
- value that means "ping packet." Broadcasts should be avoided wherever
- possible, because every PC on a network segment will receive them, and the
- IPX driver at each PC will have to process them whether that PC has a running
- program that wants the packet or not. In this case a broadcast must be used,
- since at this point it is not known who the other users are, so they can't
- be targeted individually. If the router finder is installed and it has been
- called, then sendPing() will broadcast to all known networks; if not, then
- it will broadcast only on its local network.
-
-
-
- ******************************************************************************
- * *
- *** Thoughts on Robust IPX Programs ***
- * *
- ******************************************************************************
-
- There are a lot of things that can go wrong when using IPX. You really
- should take these things into account when designing an IPX-using program.
-
- Among the most serious of IPX programming issues, and one that LANTEST
- doesn't tackle at all, is the fact that IPX doesn't guarantee delivery.
- In the context of LANTEST, a lost packet could mean that a broadcast message
- doesn't arrive at all users' PCs, or that a ping response might be lost and
- so someone's user table would be incorrect. This isn't very serious in a
- demo, but it could be quite disastrous in some production programs.
-
- To make the process of keeping track of users more bulletproof, it would be a
- good idea to have the program send a message to all users just before it
- terminates. Then they could all take that user out of their user table
- without having to re-ping to clear things up.
-
- When pinging, it would be advisable to broadcast a ping, wait a second or two
- to receive replies, and then broadcast a second and third ping. Given IPX's
- claimed delivery rate of 95 percent, the odds against missing somebody that
- way are quite remote.
-
- To go even further, a ping probably shouldn't first clear out the user table,
- but instead mark everyone as "suspect." When a reply is received from
- someone, that makes them a user in good standing. If one or more PCs in the
- table still haven't been heard from at the end of three pings, it's a good
- bet that the user in some way exited the program without its being able to
- send a message that it was terminating. An error message stating that a
- certain user has been "lost" might be appropriate.
-
- When sending messages, it would be a good idea for the receiver to send back
- a reply saying, "yes, I got it," perhaps also sending a checksum of the
- message. If the sender doesn't get a reply in a reasonable amount of time,
- within a second or so, then it can display an error message stating that
- the message wasn't received or try again. The amount of time to wait before
- timing out depends on the network itself.
-
- Another serious issue is the fact that IPX packets may not arrive in the
- same order you sent them in. They probably will, especially on small
- networks, but in larger networks there may be more than one route between
- any two PCs, and based on network traffic or other criteria, a router might
- send a packet one direction one time and another direction the second time;
- this can certainly lead to out-of-order packets.
-
- Therefore, if you're sending a message that's comprised of more than one
- packet, all packets should contain some kind of sequence number. That way
- the receiver can reconstruct the message as necessary.
-
- Network traffic can vary greatly from network to network and from minute
- to minute. Yours will almost certainly not be the only program running
- on the network. As you are writing your program, if at all possible take
- into account the fact that network throughput will not remain constant, and
- keep network traffic to a minimum as much as possible.
-
- Some sort of handshaking will be necessary to get faster machines to
- properly communicate with slower machines. Chances are excellent that a
- fast '486 will be able to send enough packets to a slow '286 to overrun its
- receive ECBs very quickly.
-
-
-
- ******************************************************************************
- * *
- *** Configuring LANLIB for LANTEST ***
- * *
- ******************************************************************************
-
- LANLIB is configured for a specific program via defines in LANCFG.H. The
- defines were not changed to reflect the needs of LANTEST because I wanted to
- leave them at reasonable values for most programs. However, it will be
- instructional to consider how these values should have been set for this
- program.
-
- The value of IPXSOCKET should of course be set to some semi-random value
- between 4000h and 7FFFh, just as with any other IPX-using program. The user
- wishing to make her program particularly bulletproof would set the socket
- number in a configuration file so it could be changed if there is a conflict.
-
- The value IPXNETCNT should be set to something small, since this is a demo; 6
- would probably be a good value.
-
- IPXDATASIZE is an easy one. The largest packet that LANTEST ever sends
- contains 92 data bytes, when doing a message broadcast or a message send
- (ping packets and responses and flurries are smaller), so IPXDATASIZE
- should be set to 92.
-
- IPXRECVCNT should be set to a fairly large number, since flurries can
- obviously fill up receive ECBs very quickly, especially when fast machines
- send to slower ones. Since the size of each individual packet buffer is very
- small, and there's no performance penalty imposed by having lots of
- ECB/packet pairs, this number should be set very high, probably all the
- way up to the maximum, 250.
-
- LANTEST only generates multiple sends under one circumstance: when
- broadcasting a message to all users. So the program might have to do as
- many as 30 back-to-back sends. But it's a fair bet that most sends will
- complete within microseconds of making the request, so setting IPXSENDCNT
- to 10 should be high enough.
-