{Begin SubSec Support for Other Level One Protocols} {Title Support for Other Level One Protocols} {Text Raw packets other than of type PUP or NS can also be sent and received. This section describes facilities to support such protocols. Many of these functions have a {lisp \} in their names to designate that they are system internal, not to be dealt with as casually as user-level functions. {FnDef {Name RESTART.ETHER} {Text This function is intended to be invoked from the executive on those rare occasions when the Ethernet appears completely unresponsive, due to Lisp having gotten into a bad state. {fn RESTART.ETHER} reinitializes Lisp's Ethernet driver(s), just as when the Lisp system is started up following a {fn LOGOUT}, {fn SYSOUT}, etc. This aborts any Ethernet activity and clears several internal caches, including the routing table. }} {indexX {Name ALLOCATE.ETHERPACKET} {Type Function} {Text {lisp (\ALLOCATE.ETHERPACKET)}} } {FnDef {Name \ALLOCATE.ETHERPACKET} {Args} {Text Returns an {lisp ETHERPACKET} datum. Enough of the packet is cleared so that if the packet represents a {lisp PUP} or {lisp NS} packet, that its header is all zeros; no guarantee is made about the remainder of the packet. }} {indexX {Name RELEASE.ETHERPACKET} {Type Function} {Text {lisp (\RELEASE.ETHERPACKET {arg EPKT})}} } {FnDef {Name \RELEASE.ETHERPACKET} {Args EPKT} {Text Returns {arg EPKT} to the pool of free packets. This operation is dangerous if the caller actually is still holding on to {arg EPKT}, e.g., in some queue, since this packet could be returned to someone else (via {fn \ALLOCATE.ETHERPACKET}) and suffer the resulting contention. From a logical standpoint, programs need never call {fn \RELEASE.ETHERPACKET}, since the packets are eventually garbage-collected after all pointers to them drop. However, since the packets are so large, normal garbage collections tend not to occur frequently enough. Thus, for best performance, a well-disciplined program should explicitly release packets when it knows it is finished with them. }} A locally-connected network for the transmission and receipt of Ether packets is specified by a {it network descriptor block}, an object of type {lisp NDB}. There is one {lisp NDB} for each directly-connected network; ordinarily there is only one. The {lisp NDB} contains information specific to the network, e.g., its {lisp PUP} and {lisp NS} network numbers, and information about how to send and receive packets on it. {indexX {Name LOCALNDBS} {Type Variable} {Text {lisp \LOCALNDBS}} } {vardef {Name \LOCALNDBS} {Text The first {lisp NDB} connected to this machine, or {lisp NIL} if there is no network. Any other {lisp NDB}s are linked to this first one via the {lisp NDBNEXT} field of the {lisp NDB}. }} In order to transmit an Ether packet, a program must specify the packet's type and its immediate destination. The type is a 16-bit integer identifying the packet's protocol. There are preassigned types for {lisp PUP} and {lisp NS}. The destination is a host address on the local network, in whatever form the local network uses for addressing; it is not necessarily related to the logical ultimate destination of the packet. Determining the immediate destination of a packet is the task of {it routing}. The functions {fn SENDPUP} and {fn SENDXIP} take care of this for the {lisp PUP} and {lisp NS} protocols, routing a packet directly to its destination if that host is on the local network, or routing it to a gateway if the host is on some other network accessible via the gateway. Of course, a gateway must know about the type (protocol) of a packet in order to be able to forward it. {FnDef {Name ENCAPSULATE.ETHERPACKET} {Args NDB PACKET PDH NBYTES ETYPE} {Text Encapsulates {arg PACKET} for transmission on network {arg NDB}. {arg PDH} is the physical destination host (e.g., an 8-bit pup host number or a 48-bit NS host number); {arg NBYTES} is the length of the packet in bytes; {arg ETYPE} is the packet's encapsulation type (an integer). }} {FnDef {Name TRANSMIT.ETHERPACKET} {Args NDB PACKET} {Text Transmits {arg PACKET}, which must already have been encapsulated, on network {arg NDB}. Disposition of the packet after transmission is complete is determined by the value of {arg PACKET}'s {lisp EPREQUEUE} field. }} In order to receive Ether packets of type other than {lisp PUP} or {lisp NS}, the programmer must specify what to do with incoming packets. Lisp maintains a set of {it packet filters}, functions whose job it is to appropriately dispose of incoming packets of the kind they want. When a packet arrives, the Ethernet driver calls each filter function in turn until it finds one that accepts the packet. The filter function is called with two arguments: ({arg PACKET} {arg TYPE}), where {arg PACKET} is the actual packet, and {arg TYPE} is its Ethernet encapsulation type (a number). If a filter function accepts the packet, it should do what it wants to with it, and return {lisp T}; else it should return {lisp NIL}, allowing other packet filters to see the packet. Since the filter function is run at interrupt level, it should keep its computation to a minimum. For example, if there is a lot to be done with the packet, the filter function can place it on a queue and notify another process of its arrival. The system already supplies packet filters for packets of type {lisp PUP} and {lisp NS}; these filters enqueue the incoming packet on the input queue of the socket to which the packet is addressed, after checking that the packet is well-formed and indeed addressed to an existing socket on this machine. Incoming packets have their {lisp EPNETWORK} field filled in with the {lisp NDB} of the network on which the packet arrived. {indexX {Name ADD.PACKET.FILTER} {Type Function} {Text {lisp (\ADD.PACKET.FILTER {arg FILTER})}} } {FnDef {Name \ADD.PACKET.FILTER} {Args FILTER} {Text Adds function {arg FILTER} to the list of packet filters if it is not already there. }} {indexX {Name DEL.PACKET.FILTER} {Type Function} {Text {lisp (\DEL.PACKET.FILTER {arg FILTER})}} } {FnDef {Name \DEL.PACKET.FILTER} {Args FILTER} {Text Removes {arg FILTER} from the list of packet filters. }} {indexX {Name CHECKSUM} {Type Function} {Text {lisp (\CHECKSUM {arg BASE} {arg NWORDS} {arg INITSUM})}} } {FnDef {Name \CHECKSUM} {Args BASE NWORDS INITSUM} {Text Computes the one's complement add and cycle checksum for the {arg NWORDS} words starting at address {arg BASE}. If {arg INITSUM} is supplied, it is treated as the accumulated checksum for some set of words preceding {arg BASE}; normally {arg INITSUM} is omitted (and thus treated as zero). }} {FnDef {Name PRINTPACKET} {Args PACKET CALLER FILE PRE.NOTE DOFILTER} {Text Prints {arg PACKET} by invoking a function appropriate to {arg PACKET}'s type. See {fn PRINTPUP} for the intended meaning of the other arguments. In order for {fn PRINTPACKET} to work on a non-standard packet, there must be information on the list {var \PACKET.PRINTERS}. }} {indexX {Name PACKET.PRINTERS} {Type Variable} {Text {lisp \PACKET.PRINTERS}} } {VarDef {Name \PACKET.PRINTERS} {Text An association list mapping packet type into the name of a function for printing that type of packet. }} }{End SubSec Support for Other Level One Protocols} {Begin SubSec The SYSQUEUE mechanism} {Title The SYSQUEUE mechanism} {Text The {lisp SYSQUEUE} facility provides a low-level queueing facility. The functions described herein are all system internal: they can cause much confusion if misused. A {lisp SYSQUEUE} is a datum containing a pointer to the first element of the queue and a pointer to the last; each item in the queue points to the next via a pointer field located at offset 0 in the item (its {lisp QLINK} field in the {lisp QABLEITEM} record). A {lisp SYSQUEUE} can be created by calling {lisp (NCREATE 'SYSQUEUE)}. {indexX {Name ENQUEUE} {Type Function} {Text {lisp (\ENQUEUE {arg Q} {arg ITEM})}} } {FnDef {Name \ENQUEUE} {Args Q ITEM} {Text Enqueues {arg ITEM} on {arg Q}, i.e., links it to the tail of the queue, updating {arg Q}'s tail pointer appropriately. }} {indexX {Name DEQUEUE} {Type Function} {Text {lisp (\DEQUEUE {arg Q})}} } {FnDef {Name \DEQUEUE} {Args Q} {Text Removes the first item from {arg Q} and returns it, or returns {lisp NIL} if {arg Q} is empty. }} {indexX {Name UNQUEUE} {Type Function} {Text {lisp (\UNQUEUE {arg Q} {arg ITEM} {arg NOERRORFLG})}} } {FnDef {Name \UNQUEUE} {Args Q ITEM NOERRORFLG} {Text Removes the {arg ITEM} from {arg Q}, wherever it is located in the queue, and returns it. If {arg ITEM} is not in {arg Q}, causes an error, unless {arg NOERRORFLG} is true, in which case it returns {lisp NIL}. }} {indexX {Name QUEUELENGTH} {Type Function} {Text {lisp (\QUEUELENGTH {arg Q})}} } {FnDef {Name \QUEUELENGTH} {Args Q} {Text Returns the number of elements in {arg Q}. }} {indexX {Name ONQUEUE} {Type Function} {Text {lisp (\ONQUEUE {arg ITEM} {arg Q})}} } {FnDef {Name \ONQUEUE} {Args ITEM Q} {Text True if {arg ITEM} is an element of {arg Q}. }} }{End SubSec The SYSQUEUE mechanism} ?1(DEFAULTFONT 1 (GACHA 10) (GACHA 8) (TERMINAL 8)) ?1(DEFAULTFONT 1 (GACHA 10) (GACHA 8) (TERMINAL 8)) öª#°zº