Talk and Ntalk

The only "official" documentation of the talk protocol is in talkd.h:
The talk server acts a repository of invitations, responding to requests by clients wishing to rendezvous for the purpose of holding a conversation. In normal operation, a client, the caller, initiates a rendezvous by sending a CTL_MSG to the server of type LOOK_UP. This causes the server to search its invitation tables to check if an invitation currently exists for the caller (to speak to the callee specified in the message). If the lookup fails, the caller then sends an ANNOUNCE message causing the server to broadcast an announcement on the callee's login ports requesting contact. When the callee responds, the local server uses the recorded invitation to respond with the appropriate rendezvous address and the caller and callee client programs establish a stream connection through which the conversation takes place.
/*
 * Client->server request message format.
 */
typedef struct {
	u_char	vers;		/* protocol version */
	u_char	type;		/* request type, see below */
	u_char	answer;		/* not used */
	u_char	pad;
	u_long	id_num;		/* message id */
	struct	osockaddr addr;		/* old (4.3) style */
	struct	osockaddr ctl_addr;	/* old (4.3) style */
	long	pid;		/* caller's process id */
#define	NAME_SIZE	12
	char	l_name[NAME_SIZE];/* caller's name */
	char	r_name[NAME_SIZE];/* callee's name */
#define	TTY_SIZE	16
	char	r_tty[TTY_SIZE];/* callee's tty name */
} CTL_MSG;

/*
 * Server->client response message format.
 */
typedef struct {
	u_char	vers;		/* protocol version */
	u_char	type;		/* type of request message, see below */
	u_char	answer;		/* respose to request message, see below */
	u_char	pad;
	u_long	id_num;		/* message id */
	struct	osockaddr addr;	/* address for establishing conversation */
} CTL_RESPONSE;

#define	TALK_VERSION	1		/* protocol version */

/* message type values */
#define LEAVE_INVITE	0	/* leave invitation with server */
#define LOOK_UP		1	/* check for invitation by callee */
#define DELETE		2	/* delete invitation by caller */
#define ANNOUNCE	3	/* announce invitation by caller */
talk is byte-order dependent, ntalk is not. Sources can be found, for example, in the NetBSD distribution:
/src/BSD/NetBSD-current/src/usr.bin/talk/
/src/BSD/NetBSD-current/src/libexec/talkd/
  1. The daemon listens for UDP packets on port 518.
  2. The talk application creates a TCP socket with a random incoming port. This allows several concurrent talk connections on the same machine.
  3. The talk application first checks the remote daemon for invitations via the LOOK_UP command. If found, it connects the TCP socket created in the previous step to that address.
  4. If none are found, it sends an invitation to the remote daemon (ANNOUNCE) and leaves an invitation on the local daemon (LEAVE_INVITE). The remote daemon writes a message to the user's terminal requesting that the other side connect.
  5. The invitation is deleted (DELETE) once the TCP connection has been established.
Mac talk
Last modified: 1997-04-30 by Henning Schulzrinne