/*
 * Copyright (c) 2013 The TCPDUMP project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/* \summary: ZeroMQ Message Transport Protocol (ZMTP) printer */
/* specification: https://rfc.zeromq.org/spec/13/ */

#include <config.h>

#include "netdissect-stdinc.h"

#include "netdissect.h"
#include "extract.h"


/* Maximum number of ZMTP/1.0 frame body bytes (without the flags) to dump in
 * hex and ASCII under a single "-v" flag.
 */
#define VBYTES 128

static const struct tok flags_bm[] = {
	{ 0x01, "MORE"  },
	{ 0x02, "R1" },
	{ 0x04, "R2" },
	{ 0x08, "R3" },
	{ 0x10, "R4" },
	{ 0x20, "R5" },
	{ 0x40, "R6" },
	{ 0x80, "R7" },
	{ 0, NULL }
};

/*
 * Below is an excerpt from the "13/ZMTP" specification:
 *
 * A ZMTP message consists of 1 or more frames.
 *
 * A ZMTP frame consists of a length, followed by a flags field and a frame
 * body of (length - 1) octets. Note: the length includes the flags field, so
 * an empty frame has a length of 1.
 *
 * For frames with a length of 1 to 254 octets, the length SHOULD BE encoded
 * as a single octet. The minimum valid length of a frame is 1 octet, thus a
 * length of 0 is invalid and such frames SHOULD be discarded silently.
 *
 * For frames with lengths of 255 and greater, the length SHALL BE encoded as
 * a single octet with the value 255, followed by the length encoded as a
 * 64-bit unsigned integer in network byte order. For frames with lengths of
 * 1 to 254 octets this encoding MAY be also used.
 *
 * The flags field consists of a single octet containing various control
 * flags. Bit 0 is the least significant bit.
 *
 * - Bit 0 (MORE): More frames to follow. A value of 0 indicates that there
 *   are no more frames to follow. A value of 1 indicates that more frames
 *   will follow. On messages consisting of a single frame the MORE flag MUST
 *   be 0.
 *
 * - Bits 1-7: Reserved. Bits 1-7 are reserved for future use and SHOULD be
 *   zero.
 */

static const u_char *
zmtp1_print_frame(netdissect_options *ndo, const u_char *cp, const u_char *ep)
{
	uint64_t body_len_declared, body_len_captured, header_len;
	uint8_t flags;

	ND_PRINT("\n\t");

	if (GET_U_1(cp) != 0xFF) {	/* length/0xFF */
		header_len = 1; /* length */
		body_len_declared = GET_U_1(cp);
		ND_PRINT(" frame flags+body  (8-bit) length %" PRIu64, body_len_declared);
	} else {
		header_len = 1 + 8; /* 0xFF, length */
		ND_PRINT(" frame flags+body (64-bit) length");
		ND_TCHECK_LEN(cp, header_len); /* 0xFF, length */
		body_len_declared = GET_BE_U_8(cp + 1);
		ND_PRINT(" %" PRIu64, body_len_declared);
	}
	if (body_len_declared == 0)
		return cp + header_len; /* skip to the next frame */
	ND_TCHECK_LEN(cp, header_len + 1); /* ..., flags */
	flags = GET_U_1(cp + header_len);

	body_len_captured = ep - cp - header_len;
	if (body_len_declared > body_len_captured)
		ND_PRINT(" (%" PRIu64 " captured)", body_len_captured);
	ND_PRINT(", flags 0x%02x", flags);

	if (ndo->ndo_vflag) {
		uint64_t body_len_printed = ND_MIN(body_len_captured, body_len_declared);

		ND_PRINT(" (%s)", bittok2str(flags_bm, "none", flags));
		if (ndo->ndo_vflag == 1)
			body_len_printed = ND_MIN(VBYTES + 1, body_len_printed);
		if (body_len_printed > 1) {
			ND_PRINT(", first %" PRIu64 " byte(s) of body:", body_len_printed - 1);
			hex_and_ascii_print(ndo, "\n\t ", cp + header_len + 1, body_len_printed - 1);
		}
	}

	/*
	 * Do not advance cp by the sum of header_len and body_len_declared
	 * before each offset has successfully passed ND_TCHECK_LEN() as the
	 * sum can roll over (9 + 0xfffffffffffffff7 = 0) and cause an
	 * infinite loop.
	 */
	cp += header_len;
	ND_TCHECK_LEN(cp, body_len_declared); /* Next frame within the buffer ? */
	return cp + body_len_declared;

trunc:
	nd_trunc_longjmp(ndo);
}

void
zmtp1_print(netdissect_options *ndo, const u_char *cp, u_int len)
{
	const u_char *ep = ND_MIN(ndo->ndo_snapend, cp + len);

	ndo->ndo_protocol = "zmtp1";
	ND_PRINT(": ZMTP/1.0");
	while (cp < ep)
		cp = zmtp1_print_frame(ndo, cp, ep);
}

/* The functions below decode a ZeroMQ datagram, supposedly stored in the "Data"
 * field of an ODATA/RDATA [E]PGM packet. An excerpt from zmq_pgm(7) man page
 * follows.
 *
 * In order for late joining consumers to be able to identify message
 * boundaries, each PGM datagram payload starts with a 16-bit unsigned integer
 * in network byte order specifying either the offset of the first message frame
 * in the datagram or containing the value 0xFFFF if the datagram contains
 * solely an intermediate part of a larger message.
 *
 * Note that offset specifies where the first message begins rather than the
 * first message part. Thus, if there are trailing message parts at the
 * beginning of the packet the offset ignores them and points to first initial
 * message part in the packet.
 */

static const u_char *
zmtp1_print_intermediate_part(netdissect_options *ndo, const u_char *cp, const u_int len)
{
	u_int frame_offset;
	u_int remaining_len;

	frame_offset = GET_BE_U_2(cp);
	ND_PRINT("\n\t frame offset 0x%04x", frame_offset);
	cp += 2;
	remaining_len = ND_BYTES_AVAILABLE_AFTER(cp); /* without the frame length */

	if (frame_offset == 0xFFFF)
		frame_offset = len - 2; /* always within the declared length */
	else if (2 + frame_offset > len) {
		ND_PRINT(" (exceeds datagram declared length)");
		goto trunc;
	}

	/* offset within declared length of the datagram */
	if (frame_offset) {
		ND_PRINT("\n\t frame intermediate part, %u bytes", frame_offset);
		if (frame_offset > remaining_len)
			ND_PRINT(" (%u captured)", remaining_len);
		if (ndo->ndo_vflag) {
			u_int len_printed = ND_MIN(frame_offset, remaining_len);

			if (ndo->ndo_vflag == 1)
				len_printed = ND_MIN(VBYTES, len_printed);
			if (len_printed > 1) {
				ND_PRINT(", first %u byte(s):", len_printed);
				hex_and_ascii_print(ndo, "\n\t ", cp, len_printed);
			}
		}
	}
	return cp + frame_offset;

trunc:
	nd_trunc_longjmp(ndo);
}

void
zmtp1_datagram_print(netdissect_options *ndo, const u_char *cp, const u_int len)
{
	const u_char *ep = ND_MIN(ndo->ndo_snapend, cp + len);

	ndo->ndo_protocol = "zmtp1";
	cp = zmtp1_print_intermediate_part(ndo, cp, len);
	while (cp < ep)
		cp = zmtp1_print_frame(ndo, cp, ep);
}
