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; }
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; }
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"); }
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; }
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; }
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; }
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; }
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; }
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); }
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; }
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; }
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; }
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; }