All kernel-level input and output under STREAMS is based on messages. STREAMS messages are built in sets of three: a message header (msgb(9S)) that contains information pertinent to the message instance; a data block (datab(9S)) that contains information describing the data; and the data itself. Each data block and data pair can be referenced by one or more message headers. The objects passed between STREAMS modules are pointers to messages.
STREAMS messages use two data structures (msgb- the message header, and datab- the data block) to describe the message data. These data structures identify the type of message and point to the data of the message, plus other information. Messages are sent through a stream by successive calls to the put procedure of each module or driver in the stream. Messages can exist as independent units, or on a linked list of messages called a message queue. STREAMS utility routines let developers manipulate messages and message queues.
All STREAMS messages are assigned message types to indicate how they will be used by modules and drivers and how they will be handled by the stream head. Message types are assigned by the stream head, driver, or module when the message is created. The stream head converts the system, calls read, write, putmsg, and putpmsg into specified message types, and sends them downstream. It responds to other calls by copying the contents of certain message types that were sent upstream.