cnet's Physical LayerThe Physical Layer (either the internal default version or one provided with the -R option) has the responsibility of delivering data frames between nodes. Frames are delivered along either point-to-point links or Ethernet segments. Each physical link is numbered within each node from 1 to its total number of links. As a special case, link 0 represents a loopback link, and is provided to simply copy a frame immediately from a node's output to input. In general, the Physical Layer will randomly corrupt and drop data frames on all point-to-point links, but not on the loopback link or Ethernet segments.
When your protocols wish to transmit a data frame along a link, they write that frame to the Physical Layer. On calling the CNET_write_physical function, you indicate the length of the frame to be written and on return CNET_write_physical indicates how many bytes were accepted. A typical sequence for a network of just 2 nodes, connected by a single point-to-point link is:
Each link is also constrained in how many bytes may be written to it in each call to CNET_write_physical. This limit may be specified in the topology file, using the link attribute transmitbufsize, and may be detemined at run-time from the C variable linkinfo[linkno].transmitbufsize. Setting transmitbufsize to a small value, say 1KB, will require your protocols to fragment large messages before sending them. The default value of transmitbufsize (9KB), is sufficient to handle the largest message generated by the Application Layer (8KB), and so fragmentation is not required in elementary protocols.
When cnet informs the destination node that a frame has arrived, the handler for EV_PHYSICALREADY should read that frame. On return from a successful call to CNET_read_physical, your protocol is informed on which link the frame arrived and how long it was.
Of course, in a simple network with just one point-to-point link or one Ethernet segment, all frames will be transmitted and will arrive on link number 1. Point-to-point links impose no particular format on the frames written to it; unless corrupted or lost, whatever is written to a point-to-point link will arrive unmodified, and without interpretation, at the other end of the link.
As an aid to debugging protocols, the function CNET_write_physical() will 'trap' the situation when a large number of frames have been written to the Physical Layer, and when the receiving node has not read any of them off. This trap is currently set at the large value of 1000, which surely indicates an error in a protocol. An errant protocol may have some unbounded loop, or a very short timeout-and-retransmission sequence, resulting in many calls to CNET_write_physical() at the sender, before any EV_PHYSICALREADY events are handled at the receiver. If the frame limit is exceeded, CNET_write_physical() will return -1 and set cnet_errno to ER_TOOBUSY.
To provide some sense of realism, frames (or packets) written to Ethernet links are expected to carry the address of their destination Network Interface Card (NIC) at the very beginning of the frame. cnet provides the data type CnetNicaddr to represent the addresses of its NICs, as an array of LEN_NICADDR (=6) unsigned characters. cnet interprets the leading LEN_NICADDR bytes of each frame on an Ethernet segment to be an address. The special address, whose string representation is ff:ff:ff:ff:ff:ff, is interpreted as the Ethernet broadcast address. Any frame carrying the broadcast address as its destination address will be delivered to all NICs on the Ethernet segment, except the sender. cnet does not support multicast or group addressing.
Consider the following example function, used to write data to an Ethernet segment:
This function assumes that the data's length is not too long for Ethernet (<= ETH_MAXDATA (=1500) bytes). The required destination's NIC address is first copied to the destination address field, and then the address of the local NIC used copied to the source address field. Notice that because the CnetNicaddr type is actually an array of characters, we do not use the & operator in the calls to memcpy. The data's true length is copied into the packet's two-byte type field, the provided data copied to the packet's data. After ensuring that the packet to be written is at least ETH_MINPACKET (=64) bytes long, the packet is written to the link. Again, cnet does not enforce (nor understand) the use of our ETHERPACKET data type, but does assume that the first LEN_NICADDR bytes of each packet provides the destination NIC address.
Two additional Physical Layer functions are provided to assist in the debugging of multi-layered protocols. CNET_write_physical_reliable is identical to CNET_write_physical except that frames sent using it will not be subject to frame corruption or loss. It can be considered as a ``perfect'' Data Link Layer if you just want to implement higher-layered protocols. The function CNET_write_direct also bypasses all Physical Layer errors and instructs a message to be sent directly to the node whose address is specified as a parameter. It thus provides perfect a Data Link Layer and Network Layer.
|cnet was written and is maintained by Chris McDonald (firstname.lastname@example.org)|