Who sent the message?

Often a server will need to know who sent it a message. There are a number of reasons for this:

It would be cumbersome (and a security hole) to have the client provide this information with each and every message sent. Therefore, there's a structure filled in by the kernel whenever the MsgReceive() function unblocks because it got a message. This structure is of type struct _msg_info, and contains the following:

struct _msg_info
    int     nd;
    int     srcnd;
    pid_t   pid;
    int32_t chid;
    int32_t scoid;
    int32_t coid;
    int32_t msglen;
    int32_t tid;
    int16_t priority;
    int16_t flags;
    int32_t srcmsglen;
    int32_t dstmsglen;

You pass it to the MsgReceive() function as the last argument. If you pass a NULL, then nothing happens. (The information can be retrieved later via the MsgInfo() call, so it's not gone forever!)

Let's look at the fields:

nd, srcnd, pid, and tid
Node Descriptors, process ID, and thread ID of the client. (Note that nd is the receiving node's node descriptor for the transmitting node; srcnd is the transmitting node's node descriptor for the receiving node. There's a very good reason for this :-), which we'll see below in "Some notes on NDs.")
The priority of the sending thread.
chid, coid
Channel ID that the message was sent to, and the connection ID used.
Server Connection ID. This is an internal identifier used by the kernel to route the message from the server back to the client. You don't need to know about it, except for the interesting fact that it will be a small integer that uniquely represents the client.
Contains a variety of flag bits, _NTO_MI_ENDIAN_BIG, _NTO_MI_ENDIAN_DIFF, _NTO_MI_NET_CRED_DIRTY, and _NTO_MI_UNBLOCK_REQ. The _NTO_MI_ENDIAN_BIG and _NTO_MI_ENDIAN_DIFF tell you about the endian-ness of the sending machine (in case the message came over the network from a machine with a different endian-ness), _NTO_MI_NET_CRED_DIRTY is used internally; we'll look at _NTO_MI_UNBLOCK_REQ in the section "Using the _NTO_MI_UNBLOCK_REQ," below.
Number of bytes received.
The length of the source message, in bytes, as sent by the client. This may be greater than the value in msglen, as would be the case when receiving less data than what was sent. Note that this member is valid only if _NTO_CHF_SENDER_LEN was set in the flags argument to ChannelCreate() for the channel that the message was received on.
The length of the client's reply buffer, in bytes. This field is only valid if the _NTO_CHF_REPLY_LEN flag is set in the argument to ChannelCreate() for the channel that the message was received on.