Example #1
0
File: sdes.c Project: soramimi/qSIP
/**
 * Encode one SDES chunk into mbuffer
 *
 * @param mb    Buffer to encode into
 * @param src   First SSRC/CSRC
 * @param itemc Number of SDES items to encode
 *
 * @return 0 if success, otherwise errorcode
 */
int rtcp_sdes_encode(struct mbuf *mb, uint32_t src, uint32_t itemc, ...)
{
	va_list ap;
	size_t start;
	int err = 0;

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

	va_start(ap, itemc);

	start = mb->pos;
	err = mbuf_write_u32(mb, htonl(src));

	/* add all SDES items */
	while (itemc-- && !err) {
		const uint8_t type = va_arg(ap, int);
		const char *v = va_arg(ap, const char *);
		size_t len;
		if (!v)
			continue;

		len = strlen(v); /* note: max 255 chars */
		if (len > 255) {
			err = EINVAL;
			goto out;
		}

		err  = mbuf_write_u8(mb, type);
		err |= mbuf_write_u8(mb, len & 0xff);
		err |= mbuf_write_mem(mb, (uint8_t *)v, len);
	}

	/* END padding */
	err |= mbuf_write_u8(mb, RTCP_SDES_END);
	while ((mb->pos - start) & 0x3)
		err |= mbuf_write_u8(mb, RTCP_SDES_END);

 out:
	va_end(ap);

	return err;
}
Example #2
0
File: cstr.c Project: soramimi/qSIP
/**
 * Encode a DNS character string into a memory buffer
 *
 * @param mb  Memory buffer to encode into
 * @param str Character string
 *
 * @return 0 if success, otherwise errorcode
 */
int dns_cstr_encode(struct mbuf *mb, const char *str)
{
	uint8_t len;
	int err = 0;

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

	len = (uint8_t)strlen(str);

	err |= mbuf_write_u8(mb, len);
	err |= mbuf_write_mem(mb, (const uint8_t *)str, len);

	return err;
}
Example #3
0
static int pcp_map_encode(struct mbuf *mb, const struct pcp_map *map)
{
	int err = 0;

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

	err |= mbuf_write_mem(mb, map->nonce, sizeof(map->nonce));
	err |= mbuf_write_u8(mb, map->proto);
	err |= mbuf_fill(mb, 0x00, 3);
	err |= mbuf_write_u16(mb, htons(map->int_port));
	err |= pcp_write_port(mb, &map->ext_addr);
	err |= pcp_ipaddr_encode(mb, &map->ext_addr);

	return err;
}
Example #4
0
static int editor_input(struct commands *commands, struct mbuf *mb, char key,
			struct re_printf *pf, bool *del, bool is_long)
{
	int err = 0;

	switch (key) {

	case KEYCODE_ESC:
		*del = true;
		return re_hprintf(pf, "\nCancel\n");

	case KEYCODE_NONE:
	case KEYCODE_REL:
		break;

	case '\n':
		*del = true;
		return re_hprintf(pf, "\n");

	case '\b':
	case KEYCODE_DEL:
		if (mb->pos > 0) {
			err |= re_hprintf(pf, "\b ");
			mb->pos = mb->end = (mb->pos - 1);
		}
		break;

	case '\t':
		if (is_long) {
			const struct cmd *cmd = NULL;
			size_t n;

			err = re_hprintf(pf,
					 "TAB completion for \"%b\":\n",
					 mb->buf, mb->end);
			if (err)
				return err;

			/* Find all long commands that matches the N
			 * first characters of the input string.
			 *
			 * If the number of matches is exactly one,
			 * we can regard it as TAB completion.
			 */

			err = cmd_print_all(pf, commands, true, false,
					    (char *)mb->buf, mb->end);
			if (err)
				return err;

			n = get_match(commands, &cmd,
				      (char *)mb->buf, mb->end);
			if (n == 1 && cmd) {

				mb->pos = 0;
				mbuf_write_str(mb, cmd->name);
			}
			else if (n == 0) {
				err = re_hprintf(pf, "(none)\n");
			}
		}
		else {
			err = mbuf_write_u8(mb, key);
		}
		break;

	default:
		err = mbuf_write_u8(mb, key);
		break;
	}

	if (is_long) {
		err |= re_hprintf(pf, "\r/%b",
				  mb->buf, mb->end);
	}
	else
		err |= re_hprintf(pf, "\r> %32b", mb->buf, mb->end);

	return err;
}
Example #5
0
int turnc_send(struct turnc *turnc, const struct sa *dst, struct mbuf *mb)
{
	size_t pos, indlen;
	struct chan *chan;
	int err;

	if (!turnc || !dst || !mb)
		return EINVAL;

	chan = turnc_chan_find_peer(turnc, dst);
	if (chan) {
		struct chan_hdr hdr;

		if (mb->pos < CHAN_HDR_SIZE)
			return EINVAL;

		hdr.nr  = turnc_chan_numb(chan);
		hdr.len = mbuf_get_left(mb);

		mb->pos -= CHAN_HDR_SIZE;
		pos = mb->pos;

		err = turnc_chan_hdr_encode(&hdr, mb);
		if (err)
			return err;

		if (turnc->proto == IPPROTO_TCP) {

			mb->pos = mb->end;

			/* padding */
			while (hdr.len++ & 0x03) {
				err = mbuf_write_u8(mb, 0x00);
				if (err)
					return err;
			}
		}

		mb->pos = pos;
	}
	else {
		indlen = stun_indlen(dst);

		if (mb->pos < indlen)
			return EINVAL;

		mb->pos -= indlen;
		pos = mb->pos;

		err = stun_msg_encode(mb, STUN_METHOD_SEND,
				      STUN_CLASS_INDICATION, sendind_tid,
				      NULL, NULL, 0, false, 0x00, 2,
				      STUN_ATTR_XOR_PEER_ADDR, dst,
				      STUN_ATTR_DATA, mb);
		if (err)
			return err;

		mb->pos = pos;
	}

	switch (turnc->proto) {

	case IPPROTO_UDP:
		err = udp_send(turnc->sock, &turnc->srv, mb);
		break;

	case IPPROTO_TCP:
		err = tcp_send(turnc->sock, mb);
		break;

#ifdef USE_DTLS
	case STUN_TRANSP_DTLS:
		err = dtls_send(turnc->sock, mb);
		break;
#endif

	default:
		err = EPROTONOSUPPORT;
		break;
	}

	return err;
}
Example #6
0
int stun_attr_encode(struct mbuf *mb, uint16_t type, const void *v,
		     const uint8_t *tid, uint8_t padding)
{
	const struct stun_change_req *ch_req = v;
	const struct stun_errcode *err_code = v;
	const struct stun_unknown_attr *ua = v;
	const unsigned int *num = v;
	const struct mbuf *mbd = v;
	size_t start, len;
	uint32_t i, n;
	int err = 0;

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

	mb->pos += 4;
	start = mb->pos;

	switch (type) {

	case STUN_ATTR_MAPPED_ADDR:
	case STUN_ATTR_ALT_SERVER:
	case STUN_ATTR_RESP_ORIGIN:
	case STUN_ATTR_OTHER_ADDR:
		tid = NULL;
		/*@fallthrough@*/
	case STUN_ATTR_XOR_PEER_ADDR:
	case STUN_ATTR_XOR_RELAY_ADDR:
	case STUN_ATTR_XOR_MAPPED_ADDR:
		err |= stun_addr_encode(mb, v, tid);
		break;

	case STUN_ATTR_CHANGE_REQ:
		n = (uint32_t)ch_req->ip << 2 | (uint32_t)ch_req->port << 1;
		err |= mbuf_write_u32(mb, htonl(n));
		break;

	case STUN_ATTR_USERNAME:
	case STUN_ATTR_REALM:
	case STUN_ATTR_NONCE:
	case STUN_ATTR_SOFTWARE:
		err |= mbuf_write_str(mb, v);
		break;

	case STUN_ATTR_MSG_INTEGRITY:
		err |= mbuf_write_mem(mb, v, 20);
		break;

	case STUN_ATTR_ERR_CODE:
		err |= mbuf_write_u16(mb, 0x00);
		err |= mbuf_write_u8(mb,  err_code->code/100);
		err |= mbuf_write_u8(mb,  err_code->code%100);
		err |= mbuf_write_str(mb, err_code->reason);
		break;

	case STUN_ATTR_UNKNOWN_ATTR:
		for (i=0; i<ua->typec; i++)
			err |= mbuf_write_u16(mb, htons(ua->typev[i]));
		break;

	case STUN_ATTR_CHANNEL_NUMBER:
	case STUN_ATTR_RESP_PORT:
		err |= mbuf_write_u16(mb, htons(*num));
		err |= mbuf_write_u16(mb, 0x0000);
		break;

	case STUN_ATTR_LIFETIME:
	case STUN_ATTR_PRIORITY:
	case STUN_ATTR_FINGERPRINT:
		err |= mbuf_write_u32(mb, htonl(*num));
		break;

	case STUN_ATTR_DATA:
	case STUN_ATTR_PADDING:
		if (mb == mbd) {
			mb->pos = mb->end;
			break;
		}
		err |= mbuf_write_mem(mb, mbuf_buf(mbd), mbuf_get_left(mbd));
		break;

	case STUN_ATTR_REQ_ADDR_FAMILY:
	case STUN_ATTR_REQ_TRANSPORT:
		err |= mbuf_write_u8(mb, *num);
		err |= mbuf_write_u8(mb, 0x00);
		err |= mbuf_write_u16(mb, 0x0000);
		break;

	case STUN_ATTR_EVEN_PORT:
		err |= mbuf_write_u8(mb, ((struct stun_even_port *)v)->r << 7);
		break;

	case STUN_ATTR_DONT_FRAGMENT:
	case STUN_ATTR_USE_CAND:
		 /* no value */
		break;

	case STUN_ATTR_RSV_TOKEN:
	case STUN_ATTR_CONTROLLED:
	case STUN_ATTR_CONTROLLING:
		err |= mbuf_write_u64(mb, sys_htonll(*(uint64_t *)v));
		break;

	default:
		err = EINVAL;
		break;
	}

	/* header */
	len = mb->pos - start;

	mb->pos = start - 4;
	err |= mbuf_write_u16(mb, htons(type));
	err |= mbuf_write_u16(mb, htons(len));
	mb->pos += len;

	/* padding */
	while ((mb->pos - start) & 0x03)
		err |= mbuf_write_u8(mb, padding);

	return err;
}
Example #7
0
File: option.c Project: alfredh/rew
int pcp_option_encode(struct mbuf *mb, enum pcp_option_code code,
		      const void *v)
{
	const struct sa *sa = v;
	const struct pcp_option_filter *filt = v;
	size_t start, len;
	int err = 0;

	if (!mb)
		return EINVAL;

	mb->pos += 4;
	start = mb->pos;

	switch (code) {

	case PCP_OPTION_THIRD_PARTY:
		if (!sa)
			return EINVAL;
		err |= pcp_ipaddr_encode(mb, sa);
		break;

	case PCP_OPTION_PREFER_FAILURE:
		/* no payload */
		break;

	case PCP_OPTION_FILTER:
		if (!filt)
			return EINVAL;
		err |= mbuf_write_u8(mb, 0x00);
		err |= mbuf_write_u8(mb, filt->prefix_length);
		err |= mbuf_write_u16(mb, htons(sa_port(&filt->remote_peer)));
		err |= pcp_ipaddr_encode(mb, &filt->remote_peer);
		break;

	case PCP_OPTION_DESCRIPTION:
		if (!v)
			return EINVAL;
		err |= mbuf_write_str(mb, v);
		break;

	default:
		(void)re_fprintf(stderr,
				 "pcp: unsupported option %d\n", code);
		return EINVAL;
	}

	/* header */
	len = mb->pos - start;

	mb->pos = start - 4;
	err |= mbuf_write_u8(mb, code);
	err |= mbuf_write_u8(mb, 0x00);
	err |= mbuf_write_u16(mb, htons(len));
	mb->pos += len;

	/* padding */
	while ((mb->pos - start) & 0x03)
		err |= mbuf_write_u8(mb, 0x00);

	return err;
}
Example #8
0
File: pkt.c Project: kaija/libre
int rtcp_vencode(struct mbuf *mb, enum rtcp_type type, uint32_t count,
		 va_list ap)
{
	size_t i, pos;
	uint16_t len;
	const uint8_t *data;
	size_t data_len;
	const uint32_t *srcv;
	const char *reason;
	rtcp_encode_h *ench;
	void *arg;
	int err = 0;

	if (!mb)
		return EINVAL;

	pos = mb->pos;

	/* Skip header - encoded last */
	mb->pos = mb->end = (mb->pos + RTCP_HDR_SIZE);

	switch (type) {

	case RTCP_SR:
		for (i=0; i<6; i++)
			err |= mbuf_write_u32(mb, htonl(va_arg(ap, uint32_t)));
		ench = va_arg(ap, rtcp_encode_h *);
		arg = va_arg(ap, void *);
		if (ench)
			err |= ench(mb, arg);
		break;

	case RTCP_RR:
		err = mbuf_write_u32(mb, htonl(va_arg(ap, uint32_t)));
		ench = va_arg(ap, rtcp_encode_h *);
		arg = va_arg(ap, void *);
		if (ench)
			err |= ench(mb, arg);
		break;

	case RTCP_SDES:
		ench = va_arg(ap, rtcp_encode_h *);
		arg = va_arg(ap, void *);
		if (ench)
			err |= ench(mb, arg);
		break;

	case RTCP_BYE:
		srcv   = va_arg(ap, uint32_t *);
		reason = va_arg(ap, char *);
		for (i=0; i<count && !err; i++) {
			err = mbuf_write_u32(mb, htonl(srcv[i]));
		}
		if (reason) {
			err |= mbuf_write_u8(mb, strlen(reason));
			err |= mbuf_write_str(mb, reason);
		}
		break;

	case RTCP_APP:
		err  = mbuf_write_u32(mb, htonl(va_arg(ap, uint32_t)));
		err |= mbuf_write_mem(mb, va_arg(ap, uint8_t *), 4);
		data = va_arg(ap, const uint8_t *);
		data_len = va_arg(ap, size_t);
		if (data) {
			if (data_len % 4) {
				DEBUG_WARNING("not a multiple of 32bits\n");
				return EBADMSG;
			}
			err |= mbuf_write_mem(mb, data, data_len);
		}
		break;

	case RTCP_FIR:
		err  = mbuf_write_u32(mb, htonl(va_arg(ap, uint32_t)));
		break;

	case RTCP_NACK:
		err  = mbuf_write_u32(mb, htonl(va_arg(ap, uint32_t)));
		err |= mbuf_write_u16(mb, htons(va_arg(ap, uint32_t)));
		err |= mbuf_write_u16(mb, htons(va_arg(ap, uint32_t)));
		break;

	case RTCP_RTPFB:
	case RTCP_PSFB:
		err  = mbuf_write_u32(mb, htonl(va_arg(ap, uint32_t)));
		err |= mbuf_write_u32(mb, htonl(va_arg(ap, uint32_t)));
		ench = va_arg(ap, rtcp_encode_h *);
		arg = va_arg(ap, void *);
		if (ench)
			err |= ench(mb, arg);
		break;

	default:
		return EINVAL;
	}
	if (err)
		return err;

	/* padding to 32 bits */
	while ((mb->end - pos) & 0x3)
		err |= mbuf_write_u8(mb, 0x00);
	if (err)
		return err;

	/* Encode RTCP Header */
	mb->pos = pos;
	len = (mb->end - pos - RTCP_HDR_SIZE)/sizeof(uint32_t);
	err = rtcp_hdr_encode(mb, count, type, len);
	if (err)
		return err;

	mb->pos = mb->end;

	return 0;
}