Beispiel #1
0
static int str_decode(struct mbuf *mb, char **str, size_t len)
{
	if (mbuf_get_left(mb) < len)
		return EBADMSG;

	return mbuf_strdup(mb, str, len);
}
Beispiel #2
0
/**
 * Decode a DNS character string from a memory buffer
 *
 * @param mb  Memory buffer to decode from
 * @param str Pointer to allocated character string
 *
 * @return 0 if success, otherwise errorcode
 */
int dns_cstr_decode(struct mbuf *mb, char **str)
{
	uint8_t len;

	if (!mb || !str || (mbuf_get_left(mb) < 1))
		return EINVAL;

	len = mbuf_read_u8(mb);

	if (mbuf_get_left(mb) < len)
		return EBADMSG;

	return mbuf_strdup(mb, str, len);
}
Beispiel #3
0
static int cmd_report(const struct cmd *cmd, struct re_printf *pf,
		      struct mbuf *mb, void *data)
{
	struct cmd_arg arg;
	int err;

	memset(&arg, 0, sizeof(arg));

	mb->pos = 0;
	err = mbuf_strdup(mb, &arg.prm, mb->end);
	if (err)
		return err;

	arg.key      = cmd->key;
	arg.data     = data;

	err = cmd->h(pf, &arg);

	mem_deref(arg.prm);

	return err;
}
Beispiel #4
0
int pcp_option_decode(struct pcp_option **optp, struct mbuf *mb)
{
	struct pcp_option *opt;
	size_t start, len;
	uint16_t port;
	int err = 0;

	if (!optp || !mb)
		return EINVAL;

	if (mbuf_get_left(mb) < 4)
		return EBADMSG;

	opt = mem_zalloc(sizeof(*opt), destructor);
	if (!opt)
		return ENOMEM;

	opt->code = mbuf_read_u8(mb);
	(void)mbuf_read_u8(mb);
	len = ntohs(mbuf_read_u16(mb));

	if (mbuf_get_left(mb) < len)
		goto badmsg;

	start = mb->pos;

	switch (opt->code) {

	case PCP_OPTION_THIRD_PARTY:
		if (len < 16)
			goto badmsg;
		err = pcp_ipaddr_decode(mb, &opt->u.third_party);
		break;

	case PCP_OPTION_PREFER_FAILURE:
		/* no payload */
		break;

	case PCP_OPTION_FILTER:
		if (len < 20)
			goto badmsg;
		(void)mbuf_read_u8(mb);
		opt->u.filter.prefix_length = mbuf_read_u8(mb);
		port = ntohs(mbuf_read_u16(mb));
		err = pcp_ipaddr_decode(mb, &opt->u.filter.remote_peer);
		sa_set_port(&opt->u.filter.remote_peer, port);
		break;

	case PCP_OPTION_DESCRIPTION:
		err = mbuf_strdup(mb, &opt->u.description, len);
		break;

	default:
		mb->pos += len;

		(void)re_printf("pcp: ignore option code %d (len=%zu)\n",
				opt->code, len);
		break;
	}

	if (err)
		goto error;

	/* padding */
	while (((mb->pos - start) & 0x03) && mbuf_get_left(mb))
		++mb->pos;

	*optp = opt;

	return 0;

 badmsg:
	err = EBADMSG;
 error:
	mem_deref(opt);

	return err;
}
Beispiel #5
0
Datei: pkt.c Projekt: kaija/libre
/**
 * Decode one RTCP message from a buffer
 *
 * @param msgp Pointer to allocated RTCP Message
 * @param mb   Buffer to decode from
 *
 * @return 0 for success, otherwise errorcode
 */
int rtcp_decode(struct rtcp_msg **msgp, struct mbuf *mb)
{
	struct rtcp_msg *msg = NULL;
	size_t start, i, sz, count, rem;
	int err;

	if (!msgp)
		return EINVAL;
	if (mbuf_get_left(mb) < RTCP_HDR_SIZE)
		return EBADMSG;

	msg = mem_zalloc(sizeof(*msg), rtcp_destructor);
	if (!msg)
		return ENOMEM;

	start = mb->pos;

	/* decode and check header */
	err = rtcp_hdr_decode(mb, &msg->hdr);
	if (err)
		goto out;

	if (msg->hdr.version != RTCP_VERSION)
		goto badmsg;

	/* check length and remaining */
	rem = msg->hdr.length * sizeof(uint32_t);
	if (mbuf_get_left(mb) < rem)
		goto badmsg;

	count = msg->hdr.count;

	switch (msg->hdr.pt) {

	case RTCP_SR:
		if (mbuf_get_left(mb) < (RTCP_SRC_SIZE + RTCP_SR_SIZE))
			goto badmsg;
		msg->r.sr.ssrc     = ntohl(mbuf_read_u32(mb));
		msg->r.sr.ntp_sec  = ntohl(mbuf_read_u32(mb));
		msg->r.sr.ntp_frac = ntohl(mbuf_read_u32(mb));
		msg->r.sr.rtp_ts   = ntohl(mbuf_read_u32(mb));
		msg->r.sr.psent    = ntohl(mbuf_read_u32(mb));
		msg->r.sr.osent    = ntohl(mbuf_read_u32(mb));

		err = rtcp_rr_alloc(&msg->r.sr.rrv, count);
		if (err)
			goto out;
		for (i=0; i<count && !err; i++)
			err = rtcp_rr_decode(mb, &msg->r.sr.rrv[i]);
		break;

	case RTCP_RR:
		if (mbuf_get_left(mb) < RTCP_SRC_SIZE)
			goto badmsg;
		msg->r.rr.ssrc = ntohl(mbuf_read_u32(mb));

		err = rtcp_rr_alloc(&msg->r.rr.rrv, count);
		if (err)
			goto out;
		for (i=0; i<count && !err; i++)
			err = rtcp_rr_decode(mb, &msg->r.rr.rrv[i]);
		break;

	case RTCP_SDES:
		if (count == 0)
			break;

		sz = count * sizeof(*msg->r.sdesv);
		msg->r.sdesv = mem_zalloc(sz, NULL);
		if (!msg->r.sdesv) {
			err = ENOMEM;
			goto out;
		}

		for (i=0; i<msg->hdr.count && !err; i++)
			err = rtcp_sdes_decode(mb, &msg->r.sdesv[i]);
		break;

	case RTCP_BYE:
		sz = count * sizeof(*msg->r.bye.srcv);
		msg->r.bye.srcv = mem_alloc(sz, NULL);
		if (!msg->r.bye.srcv) {
			err = ENOMEM;
			goto out;
		}
		if (mbuf_get_left(mb) < sz)
			goto badmsg;
		for (i=0; i<count; i++)
			msg->r.bye.srcv[i] = ntohl(mbuf_read_u32(mb));

		/* decode reason (optional) */
		if (rem > count*sizeof(uint32_t)) {
			const size_t len = mbuf_read_u8(mb);
			if (mbuf_get_left(mb) < len)
				goto badmsg;

			err = mbuf_strdup(mb, &msg->r.bye.reason, len);
		}
		break;

	case RTCP_APP:
		if (mbuf_get_left(mb) < RTCP_APP_SIZE)
			goto badmsg;
		msg->r.app.src = ntohl(mbuf_read_u32(mb));
		(void)mbuf_read_mem(mb, (uint8_t *)msg->r.app.name,
				    sizeof(msg->r.app.name));
		if (rem > RTCP_APP_SIZE) {
			msg->r.app.data_len = rem - RTCP_APP_SIZE;
			msg->r.app.data = mem_alloc(msg->r.app.data_len, NULL);
			if (!msg->r.app.data) {
				err = ENOMEM;
				goto out;
			}
			if (mbuf_get_left(mb) < msg->r.app.data_len)
				goto badmsg;
			(void)mbuf_read_mem(mb, msg->r.app.data,
					    msg->r.app.data_len);
		}
		break;

	case RTCP_FIR:
		if (mbuf_get_left(mb) < RTCP_FIR_SIZE)
			goto badmsg;
		msg->r.fir.ssrc = ntohl(mbuf_read_u32(mb));
		break;

	case RTCP_NACK:
		if (mbuf_get_left(mb) < RTCP_NACK_SIZE)
			goto badmsg;
		msg->r.nack.ssrc = ntohl(mbuf_read_u32(mb));
		msg->r.nack.fsn  = ntohs(mbuf_read_u16(mb));
		msg->r.nack.blp  = ntohs(mbuf_read_u16(mb));
		break;

	case RTCP_RTPFB:
		if (mbuf_get_left(mb) < RTCP_FB_SIZE)
			goto badmsg;
		msg->r.fb.ssrc_packet = ntohl(mbuf_read_u32(mb));
		msg->r.fb.ssrc_media = ntohl(mbuf_read_u32(mb));
		msg->r.fb.n = msg->hdr.length - 2;

		err = rtcp_rtpfb_decode(mb, msg);
		break;

	case RTCP_PSFB:
		if (mbuf_get_left(mb) < RTCP_FB_SIZE)
			goto badmsg;
		msg->r.fb.ssrc_packet = ntohl(mbuf_read_u32(mb));
		msg->r.fb.ssrc_media = ntohl(mbuf_read_u32(mb));
		msg->r.fb.n = msg->hdr.length - 2;

		err = rtcp_psfb_decode(mb, msg);
		break;

	default:
		/* unknown message type */
		mbuf_advance(mb, rem);
		break;
	}
	if (err)
		goto out;

	/* slurp padding */
	while ((mb->pos - start) & 0x3 && mbuf_get_left(mb))
		++mb->pos;

 out:
	if (err)
		mem_deref(msg);
	else
		*msgp = msg;

	return err;

 badmsg:
	mem_deref(msg);
	return EBADMSG;
}