Пример #1
0
static int tipc_nl_compat_link_reset_stats(struct tipc_nl_compat_cmd_doit *cmd,
					   struct sk_buff *skb,
					   struct tipc_nl_compat_msg *msg)
{
	char *name;
	struct nlattr *link;

	name = (char *)TLV_DATA(msg->req);

	link = nla_nest_start(skb, TIPC_NLA_LINK);
	if (!link)
		return -EMSGSIZE;

	if (nla_put_string(skb, TIPC_NLA_LINK_NAME, name))
		return -EMSGSIZE;

	nla_nest_end(skb, link);

	return 0;
}
Пример #2
0
static int tipc_nl_compat_bearer_disable(struct tipc_nl_compat_cmd_doit *cmd,
					 struct sk_buff *skb,
					 struct tipc_nl_compat_msg *msg)
{
	char *name;
	struct nlattr *bearer;

	name = (char *)TLV_DATA(msg->req);

	bearer = nla_nest_start(skb, TIPC_NLA_BEARER);
	if (!bearer)
		return -EMSGSIZE;

	if (nla_put_string(skb, TIPC_NLA_BEARER_NAME, name))
		return -EMSGSIZE;

	nla_nest_end(skb, bearer);

	return 0;
}
Пример #3
0
static struct sk_buff *cfg_set_own_addr(void)
{
	u32 addr;

	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR))
		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);

	addr = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
	if (addr == tipc_own_addr)
		return tipc_cfg_reply_none();
	if (!tipc_addr_node_valid(addr))
		return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
						   " (node address)");
	if (tipc_own_addr)
		return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
						   " (cannot change node address once assigned)");
	if (!tipc_net_start(addr))
		return tipc_cfg_reply_none();

	return tipc_cfg_reply_error_string("cannot change to network mode");
}
Пример #4
0
static int tipc_nl_compat_net_set(struct sk_buff *skb,
				  struct tipc_nl_compat_msg *msg)
{
	u32 val;
	struct nlattr *net;

	val = ntohl(*(__be32 *)TLV_DATA(msg->req));

	net = nla_nest_start(skb, TIPC_NLA_NET);
	if (!net)
		return -EMSGSIZE;

	if (msg->cmd == TIPC_CMD_SET_NODE_ADDR) {
		if (nla_put_u32(skb, TIPC_NLA_NET_ADDR, val))
			return -EMSGSIZE;
	} else if (msg->cmd == TIPC_CMD_SET_NETID) {
		if (nla_put_u32(skb, TIPC_NLA_NET_ID, val))
			return -EMSGSIZE;
	}
	nla_nest_end(skb, net);

	return 0;
}
Пример #5
0
static int
prestlv_print(netdissect_options *ndo,
              register const u_char * pptr, register u_int len,
              u_int16_t op_msk _U_, int indent)
{
	const struct forces_tlv *tlv = (struct forces_tlv *)pptr;
	register const u_char *tdp = (u_char *) TLV_DATA(tlv);
	struct res_val *r = (struct res_val *)tdp;
	u_int dlen;

	/*
	 * pdatacnt_print() has ensured that len (the TLV length)
	 * >= TLV_HDRL.
	 */
	dlen = len - TLV_HDRL;
	if (dlen != RESLEN) {
		ND_PRINT((ndo, "illegal RESULT-TLV: %d bytes!\n", dlen));
		return -1;
	}

	ND_TCHECK(*r);
	if (r->result >= 0x18 && r->result <= 0xFE) {
		ND_PRINT((ndo, "illegal reserved result code: 0x%x!\n", r->result));
		return -1;
	}

	if (ndo->ndo_vflag >= 3) {
		char *ib = indent_pr(indent, 0);
		ND_PRINT((ndo, "%s  Result: %s (code 0x%x)\n", ib,
		       tok2str(ForCES_errs, NULL, r->result), r->result));
	}
	return 0;

trunc:
	ND_PRINT((ndo, "%s", tstr));
	return -1;
}
Пример #6
0
static int tipc_nl_compat_name_table_dump_header(struct tipc_nl_compat_msg *msg)
{
	int i;
	u32 depth;
	struct tipc_name_table_query *ntq;
	static const char * const header[] = {
		"Type       ",
		"Lower      Upper      ",
		"Port Identity              ",
		"Publication Scope"
	};

	ntq = (struct tipc_name_table_query *)TLV_DATA(msg->req);

	depth = ntohl(ntq->depth);

	if (depth > 4)
		depth = 4;
	for (i = 0; i < depth; i++)
		tipc_tlv_sprintf(msg->rep, header[i]);
	tipc_tlv_sprintf(msg->rep, "\n");

	return 0;
}
Пример #7
0
static int tipc_nl_compat_link_set(struct sk_buff *skb,
				   struct tipc_nl_compat_msg *msg)
{
	struct nlattr *link;
	struct nlattr *prop;
	struct tipc_link_config *lc;

	lc = (struct tipc_link_config *)TLV_DATA(msg->req);

	link = nla_nest_start(skb, TIPC_NLA_LINK);
	if (!link)
		return -EMSGSIZE;

	if (nla_put_string(skb, TIPC_NLA_LINK_NAME, lc->name))
		return -EMSGSIZE;

	prop = nla_nest_start(skb, TIPC_NLA_LINK_PROP);
	if (!prop)
		return -EMSGSIZE;

	if (msg->cmd == TIPC_CMD_SET_LINK_PRI) {
		if (nla_put_u32(skb, TIPC_NLA_PROP_PRIO, ntohl(lc->value)))
			return -EMSGSIZE;
	} else if (msg->cmd == TIPC_CMD_SET_LINK_TOL) {
		if (nla_put_u32(skb, TIPC_NLA_PROP_TOL, ntohl(lc->value)))
			return -EMSGSIZE;
	} else if (msg->cmd == TIPC_CMD_SET_LINK_WINDOW) {
		if (nla_put_u32(skb, TIPC_NLA_PROP_WIN, ntohl(lc->value)))
			return -EMSGSIZE;
	}

	nla_nest_end(skb, prop);
	nla_nest_end(skb, link);

	return 0;
}
Пример #8
0
static int tipc_tlv_sprintf(struct sk_buff *skb, const char *fmt, ...)
{
	int n;
	u16 len;
	u32 rem;
	char *buf;
	struct tlv_desc *tlv;
	va_list args;

	rem = tipc_skb_tailroom(skb);

	tlv = (struct tlv_desc *)skb->data;
	len = TLV_GET_LEN(tlv);
	buf = TLV_DATA(tlv) + len;

	va_start(args, fmt);
	n = vscnprintf(buf, rem, fmt, args);
	va_end(args);

	TLV_SET_LEN(tlv, n + len);
	skb_put(skb, n);

	return n;
}
Пример #9
0
static int tipc_nl_compat_link_set(struct tipc_nl_compat_cmd_doit *cmd,
				   struct sk_buff *skb,
				   struct tipc_nl_compat_msg *msg)
{
	struct tipc_link_config *lc;
	struct tipc_bearer *bearer;
	struct tipc_media *media;

	lc = (struct tipc_link_config *)TLV_DATA(msg->req);

	media = tipc_media_find(lc->name);
	if (media) {
		cmd->doit = &tipc_nl_media_set;
		return tipc_nl_compat_media_set(skb, msg);
	}

	bearer = tipc_bearer_find(msg->net, lc->name);
	if (bearer) {
		cmd->doit = &tipc_nl_bearer_set;
		return tipc_nl_compat_bearer_set(skb, msg);
	}

	return __tipc_nl_compat_link_set(skb, msg);
}
Пример #10
0
int
prestlv_print(register const u_char * pptr, register u_int len,
	      u_int16_t op_msk _U_, int indent)
{
	const struct forces_tlv *tlv = (struct forces_tlv *)pptr;
	register const u_char *tdp = (u_char *) TLV_DATA(tlv);
	struct res_val *r = (struct res_val *)tdp;
	u_int dlen;

	/*
	 * pdatacnt_print() has ensured that len (the TLV length)
	 * >= TLV_HDRL.
	 */
	dlen = len - TLV_HDRL;
	if (dlen != RESLEN) {
		printf("illegal RESULT-TLV: %d bytes!\n", dlen);
		return -1;
	}

	TCHECK(*r);
	if (r->result >= 0x18 && r->result <= 0xFE) {
		printf("illegal reserved result code: 0x%x!\n", r->result);
		return -1;
	}

	if (vflag >= 3) {
		char *ib = indent_pr(indent, 0);
		printf("%s  Result: %s (code 0x%x)\n", ib,
		       tok2str(ForCES_errs, NULL, r->result), r->result);
	}
	return 0;

trunc:
	fputs("[|forces]", stdout);
	return -1;
}
Пример #11
0
static int tipc_nl_compat_name_table_dump(struct tipc_nl_compat_msg *msg,
					  struct nlattr **attrs)
{
	char port_str[27];
	struct tipc_name_table_query *ntq;
	struct nlattr *nt[TIPC_NLA_NAME_TABLE_MAX + 1];
	struct nlattr *publ[TIPC_NLA_PUBL_MAX + 1];
	u32 node, depth, type, lowbound, upbound;
	static const char * const scope_str[] = {"", " zone", " cluster",
						 " node"};

	nla_parse_nested(nt, TIPC_NLA_NAME_TABLE_MAX,
			 attrs[TIPC_NLA_NAME_TABLE], NULL);

	nla_parse_nested(publ, TIPC_NLA_PUBL_MAX, nt[TIPC_NLA_NAME_TABLE_PUBL],
			 NULL);

	ntq = (struct tipc_name_table_query *)TLV_DATA(msg->req);

	depth = ntohl(ntq->depth);
	type = ntohl(ntq->type);
	lowbound = ntohl(ntq->lowbound);
	upbound = ntohl(ntq->upbound);

	if (!(depth & TIPC_NTQ_ALLTYPES) &&
	    (type != nla_get_u32(publ[TIPC_NLA_PUBL_TYPE])))
		return 0;
	if (lowbound && (lowbound > nla_get_u32(publ[TIPC_NLA_PUBL_UPPER])))
		return 0;
	if (upbound && (upbound < nla_get_u32(publ[TIPC_NLA_PUBL_LOWER])))
		return 0;

	tipc_tlv_sprintf(msg->rep, "%-10u ",
			 nla_get_u32(publ[TIPC_NLA_PUBL_TYPE]));

	if (depth == 1)
		goto out;

	tipc_tlv_sprintf(msg->rep, "%-10u %-10u ",
			 nla_get_u32(publ[TIPC_NLA_PUBL_LOWER]),
			 nla_get_u32(publ[TIPC_NLA_PUBL_UPPER]));

	if (depth == 2)
		goto out;

	node = nla_get_u32(publ[TIPC_NLA_PUBL_NODE]);
	sprintf(port_str, "<%u.%u.%u:%u>", tipc_zone(node), tipc_cluster(node),
		tipc_node(node), nla_get_u32(publ[TIPC_NLA_PUBL_REF]));
	tipc_tlv_sprintf(msg->rep, "%-26s ", port_str);

	if (depth == 3)
		goto out;

	tipc_tlv_sprintf(msg->rep, "%-10u %s",
			 nla_get_u32(publ[TIPC_NLA_PUBL_REF]),
			 scope_str[nla_get_u32(publ[TIPC_NLA_PUBL_SCOPE])]);
out:
	tipc_tlv_sprintf(msg->rep, "\n");

	return 0;
}
Пример #12
0
static int tipc_nl_compat_link_stat_dump(struct tipc_nl_compat_msg *msg,
					 struct nlattr **attrs)
{
	char *name;
	struct nlattr *link[TIPC_NLA_LINK_MAX + 1];
	struct nlattr *prop[TIPC_NLA_PROP_MAX + 1];
	struct nlattr *stats[TIPC_NLA_STATS_MAX + 1];

	nla_parse_nested(link, TIPC_NLA_LINK_MAX, attrs[TIPC_NLA_LINK], NULL);

	nla_parse_nested(prop, TIPC_NLA_PROP_MAX, link[TIPC_NLA_LINK_PROP],
			 NULL);

	nla_parse_nested(stats, TIPC_NLA_STATS_MAX, link[TIPC_NLA_LINK_STATS],
			 NULL);

	name = (char *)TLV_DATA(msg->req);
	if (strcmp(name, nla_data(link[TIPC_NLA_LINK_NAME])) != 0)
		return 0;

	tipc_tlv_sprintf(msg->rep, "\nLink <%s>\n",
			 nla_data(link[TIPC_NLA_LINK_NAME]));

	if (link[TIPC_NLA_LINK_BROADCAST]) {
		__fill_bc_link_stat(msg, prop, stats);
		return 0;
	}

	if (link[TIPC_NLA_LINK_ACTIVE])
		tipc_tlv_sprintf(msg->rep, "  ACTIVE");
	else if (link[TIPC_NLA_LINK_UP])
		tipc_tlv_sprintf(msg->rep, "  STANDBY");
	else
		tipc_tlv_sprintf(msg->rep, "  DEFUNCT");

	tipc_tlv_sprintf(msg->rep, "  MTU:%u  Priority:%u",
			 nla_get_u32(link[TIPC_NLA_LINK_MTU]),
			 nla_get_u32(prop[TIPC_NLA_PROP_PRIO]));

	tipc_tlv_sprintf(msg->rep, "  Tolerance:%u ms  Window:%u packets\n",
			 nla_get_u32(prop[TIPC_NLA_PROP_TOL]),
			 nla_get_u32(prop[TIPC_NLA_PROP_WIN]));

	tipc_tlv_sprintf(msg->rep,
			 "  RX packets:%u fragments:%u/%u bundles:%u/%u\n",
			 nla_get_u32(link[TIPC_NLA_LINK_RX]) -
			 nla_get_u32(stats[TIPC_NLA_STATS_RX_INFO]),
			 nla_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTS]),
			 nla_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTED]),
			 nla_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLES]),
			 nla_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLED]));

	tipc_tlv_sprintf(msg->rep,
			 "  TX packets:%u fragments:%u/%u bundles:%u/%u\n",
			 nla_get_u32(link[TIPC_NLA_LINK_TX]) -
			 nla_get_u32(stats[TIPC_NLA_STATS_TX_INFO]),
			 nla_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTS]),
			 nla_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTED]),
			 nla_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLES]),
			 nla_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLED]));

	tipc_tlv_sprintf(msg->rep,
			 "  TX profile sample:%u packets  average:%u octets\n",
			 nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_CNT]),
			 nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_TOT]) /
			 nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT]));

	tipc_tlv_sprintf(msg->rep,
			 "  0-64:%u%% -256:%u%% -1024:%u%% -4096:%u%% ",
			 perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P0]),
			      nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT])),
			 perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P1]),
			      nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT])),
			 perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P2]),
			      nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT])),
			 perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P3]),
			      nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT])));

	tipc_tlv_sprintf(msg->rep, "-16384:%u%% -32768:%u%% -66000:%u%%\n",
			 perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P4]),
			      nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT])),
			 perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P5]),
			      nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT])),
			 perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P6]),
			      nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT])));

	tipc_tlv_sprintf(msg->rep,
			 "  RX states:%u probes:%u naks:%u defs:%u dups:%u\n",
			 nla_get_u32(stats[TIPC_NLA_STATS_RX_STATES]),
			 nla_get_u32(stats[TIPC_NLA_STATS_RX_PROBES]),
			 nla_get_u32(stats[TIPC_NLA_STATS_RX_NACKS]),
			 nla_get_u32(stats[TIPC_NLA_STATS_RX_DEFERRED]),
			 nla_get_u32(stats[TIPC_NLA_STATS_DUPLICATES]));

	tipc_tlv_sprintf(msg->rep,
			 "  TX states:%u probes:%u naks:%u acks:%u dups:%u\n",
			 nla_get_u32(stats[TIPC_NLA_STATS_TX_STATES]),
			 nla_get_u32(stats[TIPC_NLA_STATS_TX_PROBES]),
			 nla_get_u32(stats[TIPC_NLA_STATS_TX_NACKS]),
			 nla_get_u32(stats[TIPC_NLA_STATS_TX_ACKS]),
			 nla_get_u32(stats[TIPC_NLA_STATS_RETRANSMITTED]));

	tipc_tlv_sprintf(msg->rep,
			 "  Congestion link:%u  Send queue max:%u avg:%u",
			 nla_get_u32(stats[TIPC_NLA_STATS_LINK_CONGS]),
			 nla_get_u32(stats[TIPC_NLA_STATS_MAX_QUEUE]),
			 nla_get_u32(stats[TIPC_NLA_STATS_AVG_QUEUE]));

	return 0;
}
Пример #13
0
int fcp_to_ts_51011(/*in*/ const char *stream, /*in*/ size_t len,
        /*out*/ struct ts_51011_921_resp *out)
{
    const char *end = &stream[len];
    struct tlv fcp;
    int ret = parseTlv(stream, end, &fcp);
    const char *what = NULL;
#define FCP_CVT_THROW(_ret, _what)  \
    do {                    \
        ret = _ret;         \
        what = _what;       \
        goto except;        \
    } while (0)

    if (ret < 0)
        FCP_CVT_THROW(ret, "ETSI TS 102 221, 11.1.1.3: FCP template TLV structure");
    if (fcp.tag != 0x62)
        FCP_CVT_THROW(-EINVAL, "ETSI TS 102 221, 11.1.1.3: FCP template tag");

    /*
     * NOTE: Following fields do not exist in FCP template:
     * - file_acc
     * - file_status
     */

    memset(out, 0, sizeof(*out));
    while (fcp.data < fcp.end) {
        unsigned char fdbyte;
        size_t property_size;
        struct tlv tlv;
        ret = parseTlv(fcp.data, end, &tlv);
        if (ret < 0)
            FCP_CVT_THROW(ret, "ETSI TS 102 221, 11.1.1.3: FCP property TLV structure");
        property_size = (tlv.end - tlv.data) / 2;

        switch (tlv.tag) {
            case 0x80: /* File size, ETSI TS 102 221, 11.1.1.4.1 */
                /* File size > 0xFFFF is not supported by ts_51011 */
                if (property_size != 2)
                    FCP_CVT_THROW(-ENOTSUP, "3GPP TS 51 011, 9.2.1: Unsupported file size");
                /* be16 on both sides */
                ((char*)&out->file_size)[0] = TLV_DATA(tlv, 0);
                ((char*)&out->file_size)[1] = TLV_DATA(tlv, 1);
                break;
            case 0x83: /* File identifier, ETSI TS 102 221, 11.1.1.4.4 */
                /* Sanity check */
                if (property_size != 2)
                    FCP_CVT_THROW(-EINVAL, "ETSI TS 102 221, 11.1.1.4.4: Invalid file identifier");
                /* be16 on both sides */
                ((char*)&out->file_id)[0] = TLV_DATA(tlv, 0);
                ((char*)&out->file_id)[1] = TLV_DATA(tlv, 1);
                break;
            case 0x82: /* File descriptior, ETSI TS 102 221, 11.1.1.4.3 */
                /* Sanity check */
                if (property_size < 2)
                    FCP_CVT_THROW(-EINVAL, "ETSI TS 102 221, 11.1.1.4.3: Invalid file descriptor");
                fdbyte = TLV_DATA(tlv, 0);
                /* ETSI TS 102 221, Table 11.5 for FCP fields */
                /* 3GPP TS 51 011, 9.2.1 and 9.3 for 'out' fields */
                if ((fdbyte & 0xBF) == 0x38) {
                    out->file_type = 2; /* DF of ADF */
                } else if ((fdbyte & 0xB0) == 0x00) {
                    out->file_type = 4; /* EF */
                    out->file_status = 1; /* Not invalidated */
                    ++out->data_size; /* file_structure field is valid */
                    if ((fdbyte & 0x07) == 0x01) {
                        out->file_structure = 0; /* Transparent */
                    } else {
                        if (property_size < 5)
                            FCP_CVT_THROW(-EINVAL, "ETSI TS 102 221, 11.1.1.4.3: Invalid non-transparent file descriptor");
                        ++out->data_size; /* record_size field is valid */
                        out->record_size = TLV_DATA(tlv, 3);
                        if ((fdbyte & 0x07) == 0x06) {
                            out->file_structure = 3; /* Cyclic */
                        } else if ((fdbyte & 0x07) == 0x02) {
                            out->file_structure = 1; /* Linear fixed */
                        } else {
                            FCP_CVT_THROW(-EINVAL, "ETSI TS 102 221, 11.1.1.4.3: Invalid file structure");
                        }
                    }
                } else {
                    out->file_type = 0; /* RFU */
                }
                break;
        }
        fcp.data = tlv.end;
    }

 finally:
    return ret;

 except:
 #undef FCP_CVT_THROW
    ALOGE("FCP to TS 510 11: Specification violation: %s.", what);
    goto finally;
}