static void vlan_print_map(FILE *f, const char *name_json, const char *name_fp, struct rtattr *attr) { struct ifla_vlan_qos_mapping *m; struct rtattr *i; int rem; open_json_array(PRINT_JSON, name_json); print_string(PRINT_FP, NULL, "\n %s { ", name_fp); rem = RTA_PAYLOAD(attr); for (i = RTA_DATA(attr); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) { m = RTA_DATA(i); if (is_json_context()) { open_json_object(NULL); print_uint(PRINT_JSON, "from", NULL, m->from); print_uint(PRINT_JSON, "to", NULL, m->to); close_json_object(); } else { fprintf(f, "%u:%u ", m->from, m->to); } } close_json_array(PRINT_JSON, NULL); print_string(PRINT_FP, NULL, "%s ", "}"); }
static int link_mon_summary_cb(const struct nlmsghdr *nlh, void *data) { struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); struct nlattr *info[TIPC_NLA_MAX + 1] = {}; struct nlattr *attrs[TIPC_NLA_MON_MAX + 1] = {}; mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info); if (!info[TIPC_NLA_MON]) return MNL_CB_ERROR; mnl_attr_parse_nested(info[TIPC_NLA_MON], parse_attrs, attrs); open_json_object(NULL); print_string(PRINT_ANY, "bearer", "\nbearer %s\n", mnl_attr_get_str(attrs[TIPC_NLA_MON_BEARER_NAME])); print_uint(PRINT_ANY, "table_generation", " table_generation %u\n", mnl_attr_get_u32(attrs[TIPC_NLA_MON_LISTGEN])); print_uint(PRINT_ANY, "cluster_size", " cluster_size %u\n", mnl_attr_get_u32(attrs[TIPC_NLA_MON_PEERCNT])); print_string(PRINT_ANY, "algorithm", " algorithm %s\n", attrs[TIPC_NLA_MON_ACTIVE] ? "overlapping-ring" : "full-mesh"); close_json_object(); return MNL_CB_OK; }
void PrintNewMessages(void) { unsigned int i; int first = 1; for (i = 1; i < MAX_MESSAGES; i++) { if (USERS[CURRENT_USER].messages[i][0] == '\0') { continue; } if (USERS[CURRENT_USER].msg_read[i] == 1) { continue; } if (first) { print("Unread messages:\n"); first = 0; } print("***********************************\n"); print_uint(i); print(": "); print(USERS[CURRENT_USER].messages[i]); print("\n"); print("***********************************\n"); USERS[CURRENT_USER].msg_read[i] = 1; } return; }
int fill_arg(int i, va_list *valist, const char *str) { char c; t_spec_flags opts; ft_bzero(&opts, sizeof(t_spec_flags)); i += fill_flags(str + i + 1, &opts) + 1; i += fill_width(str + i, &opts); i += fill_precision(str + i, &opts); i += fill_lenght(str + i, &opts); if ((c = str[i]) == 'S' || c == 'C' || c == 'D' || c == 'U' || c == 'O') opts.len_mod = LM_L; if (c == 'd' || c == 'i' || c == 'D') print_int(valist, &opts); else if (c == 'u' || c == 'U') print_uint(valist, &opts); else if (c == 's' || c == 'S') print_str(valist, &opts); else if (c == 'c' || c == 'C') print_char(valist, &opts); else if (c == 'p' || c == 'x' || c == 'X') print_hex(valist, &opts, c); else if (c == 'o' || c == 'O') print_octal(valist, &opts); else if (c == '%') ft_putchar(c); return (i); }
int convert_binary(t_tag *tag, va_list *args) { uintmax_t nbr; nbr = va_arg(*args, int); nbr = get_unsigned_length(nbr, tag); return (print_uint(tag, nbr, "01", "0b")); }
static void print_tx_sc(const char *prefix, __u64 sci, __u8 encoding_sa, struct rtattr *txsc_stats, struct rtattr *secy_stats, struct rtattr *sa) { struct rtattr *sa_attr[MACSEC_SA_ATTR_MAX + 1]; struct rtattr *a; int rem; print_string(PRINT_FP, NULL, "%s", prefix); print_0xhex(PRINT_ANY, "sci", "TXSC: %016llx", ntohll(sci)); print_uint(PRINT_ANY, "encoding_sa", " on SA %d\n", encoding_sa); print_secy_stats(prefix, secy_stats); print_txsc_stats(prefix, txsc_stats); open_json_array(PRINT_JSON, "sa_list"); rem = RTA_PAYLOAD(sa); for (a = RTA_DATA(sa); RTA_OK(a, rem); a = RTA_NEXT(a, rem)) { bool state; open_json_object(NULL); parse_rtattr_nested(sa_attr, MACSEC_SA_ATTR_MAX + 1, a); state = rta_getattr_u8(sa_attr[MACSEC_SA_ATTR_ACTIVE]); print_string(PRINT_FP, NULL, "%s", prefix); print_string(PRINT_FP, NULL, "%s", prefix); print_uint(PRINT_ANY, "an", "%d:", rta_getattr_u8(sa_attr[MACSEC_SA_ATTR_AN])); print_uint(PRINT_ANY, "pn", " PN %u,", rta_getattr_u32(sa_attr[MACSEC_SA_ATTR_PN])); print_bool(PRINT_JSON, "active", NULL, state); print_string(PRINT_FP, NULL, " state %s,", state ? "on" : "off"); print_key(sa_attr[MACSEC_SA_ATTR_KEYID]); print_txsa_stats(prefix, sa_attr[MACSEC_SA_ATTR_STATS]); close_json_object(); } close_json_array(PRINT_JSON, NULL); }
static void print_attrs(struct rtattr *attrs[]) { print_flag(attrs, "protect", MACSEC_SECY_ATTR_PROTECT); if (attrs[MACSEC_SECY_ATTR_VALIDATE]) { __u8 val = rta_getattr_u8(attrs[MACSEC_SECY_ATTR_VALIDATE]); print_string(PRINT_ANY, "validate", "validate %s ", validate_str[val]); } print_flag(attrs, "sc", MACSEC_RXSC_ATTR_ACTIVE); print_flag(attrs, "sa", MACSEC_SA_ATTR_ACTIVE); print_flag(attrs, "encrypt", MACSEC_SECY_ATTR_ENCRYPT); print_flag(attrs, "send_sci", MACSEC_SECY_ATTR_INC_SCI); print_flag(attrs, "end_station", MACSEC_SECY_ATTR_ES); print_flag(attrs, "scb", MACSEC_SECY_ATTR_SCB); print_flag(attrs, "replay", MACSEC_SECY_ATTR_REPLAY); if (attrs[MACSEC_SECY_ATTR_WINDOW]) { __u32 win = rta_getattr_u32(attrs[MACSEC_SECY_ATTR_WINDOW]); print_uint(PRINT_ANY, "window", "window %u ", win); } if (attrs[MACSEC_SECY_ATTR_CIPHER_SUITE]) { __u64 cid = rta_getattr_u64(attrs[MACSEC_SECY_ATTR_CIPHER_SUITE]); print_string(PRINT_FP, NULL, "%s", _SL_); print_string(PRINT_ANY, "cipher_suite", " cipher suite: %s,", cs_id_to_name(cid)); } if (attrs[MACSEC_SECY_ATTR_ICV_LEN]) { __u8 icv_len = rta_getattr_u8(attrs[MACSEC_SECY_ATTR_ICV_LEN]); print_uint(PRINT_ANY, "icv_length", " using ICV length %u\n", icv_len); } }
int convert_octal(t_tag *tag, va_list *args) { uintmax_t output_arg; output_arg = va_arg(*args, uintmax_t); output_arg = get_unsigned_length(output_arg, tag); if (output_arg == 0 && tag->has_precision && !tag->flag_sharp && (tag->precision == 1 || tag->precision == 0)) { if (!tag->has_width) return (tag->precision = 0); else { print_width_pad(0, tag->width, ' '); return (tag->width); } } if (tag->has_precision == 1) return (print_uint(tag, output_arg, "01234567", NULL)); else return (print_uint(tag, output_arg, "01234567", "0")); }
int convert_hexa(t_tag *tag, va_list *args) { uintmax_t output_arg; output_arg = va_arg(*args, uintmax_t); output_arg = get_unsigned_length(output_arg, tag); if (output_arg == 0 && tag->has_precision && (tag->precision == 1 || tag->precision == 0)) { if (!tag->has_width) return (tag->precision = 0); else { print_width_pad(0, tag->width, ' '); return (tag->width); } } if (tag->specifier == 'x') return (print_uint(tag, output_arg, "0123456789abcdef", "0x")); else return (print_uint(tag, output_arg, "0123456789ABCDEF", "0X")); }
int print_int(int64_t x, char **buffer, size_t *len) { if (x == LLONG_MIN) { return puts_in("-9223372036854775808", buffer, len); } int res = 0; if (x < 0) { if (putc_s('-', buffer, len)) { ++res; } x = -x; } return res + print_uint(x, 10, buffer, len); }
static int link_get_cb(const struct nlmsghdr *nlh, void *data) { int *prop = data; struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); struct nlattr *info[TIPC_NLA_MAX + 1] = {}; struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1] = {}; struct nlattr *props[TIPC_NLA_PROP_MAX + 1] = {}; mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info); if (!info[TIPC_NLA_LINK]) return MNL_CB_ERROR; mnl_attr_parse_nested(info[TIPC_NLA_LINK], parse_attrs, attrs); if (!attrs[TIPC_NLA_LINK_PROP]) return MNL_CB_ERROR; mnl_attr_parse_nested(attrs[TIPC_NLA_LINK_PROP], parse_attrs, props); if (!props[*prop]) return MNL_CB_ERROR; new_json_obj(json); open_json_object(NULL); switch (*prop) { case TIPC_NLA_PROP_PRIO: print_uint(PRINT_ANY, PRIORITY_STR, "%u\n", mnl_attr_get_u32(props[*prop])); break; case TIPC_NLA_PROP_TOL: print_uint(PRINT_ANY, TOLERANCE_STR, "%u\n", mnl_attr_get_u32(props[*prop])); break; case TIPC_NLA_PROP_WIN: print_uint(PRINT_ANY, WINDOW_STR, "%u\n", mnl_attr_get_u32(props[*prop])); break; default: break; } close_json_object(); delete_json_obj(); return MNL_CB_OK; }
static int print_connmark(struct action_util *au, FILE *f, struct rtattr *arg) { struct rtattr *tb[TCA_CONNMARK_MAX + 1]; struct tc_connmark *ci; if (arg == NULL) return -1; parse_rtattr_nested(tb, TCA_CONNMARK_MAX, arg); if (tb[TCA_CONNMARK_PARMS] == NULL) { print_string(PRINT_FP, NULL, "%s", "[NULL connmark parameters]"); return -1; } ci = RTA_DATA(tb[TCA_CONNMARK_PARMS]); print_string(PRINT_ANY, "kind", "%s ", "connmark"); print_uint(PRINT_ANY, "zone", "zone %u", ci->zone); print_action_control(f, " ", ci->action, ""); print_string(PRINT_FP, NULL, "%s", _SL_); print_uint(PRINT_ANY, "index", "\t index %u", ci->index); print_int(PRINT_ANY, "ref", " ref %d", ci->refcnt); print_int(PRINT_ANY, "bind", " bind %d", ci->bindcnt); if (show_stats) { if (tb[TCA_CONNMARK_TM]) { struct tcf_t *tm = RTA_DATA(tb[TCA_CONNMARK_TM]); print_tm(f, tm); } } print_string(PRINT_FP, NULL, "%s", _SL_); return 0; }
static void vlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) { struct ifla_vlan_flags *flags; SPRINT_BUF(b1); if (!tb) return; if (tb[IFLA_VLAN_PROTOCOL] && RTA_PAYLOAD(tb[IFLA_VLAN_PROTOCOL]) < sizeof(__u16)) return; if (!tb[IFLA_VLAN_ID] || RTA_PAYLOAD(tb[IFLA_VLAN_ID]) < sizeof(__u16)) return; if (tb[IFLA_VLAN_PROTOCOL]) print_string(PRINT_ANY, "protocol", "protocol %s ", ll_proto_n2a( rta_getattr_u16(tb[IFLA_VLAN_PROTOCOL]), b1, sizeof(b1))); else print_string(PRINT_ANY, "protocol", "protocol %s ", "802.1q"); print_uint(PRINT_ANY, "id", "id %u ", rta_getattr_u16(tb[IFLA_VLAN_ID])); if (tb[IFLA_VLAN_FLAGS]) { if (RTA_PAYLOAD(tb[IFLA_VLAN_FLAGS]) < sizeof(*flags)) return; flags = RTA_DATA(tb[IFLA_VLAN_FLAGS]); vlan_print_flags(f, flags->flags); } if (tb[IFLA_VLAN_INGRESS_QOS]) vlan_print_map(f, "ingress_qos", "ingress-qos-map", tb[IFLA_VLAN_INGRESS_QOS]); if (tb[IFLA_VLAN_EGRESS_QOS]) vlan_print_map(f, "egress_qos", "egress-qos-map", tb[IFLA_VLAN_EGRESS_QOS]); }
static int print_mirred(struct action_util *au, FILE *f, struct rtattr *arg) { struct tc_mirred *p; struct rtattr *tb[TCA_MIRRED_MAX + 1]; const char *dev; if (arg == NULL) return -1; parse_rtattr_nested(tb, TCA_MIRRED_MAX, arg); if (tb[TCA_MIRRED_PARMS] == NULL) { print_string(PRINT_FP, NULL, "%s", "[NULL mirred parameters]"); return -1; } p = RTA_DATA(tb[TCA_MIRRED_PARMS]); dev = ll_index_to_name(p->ifindex); if (dev == 0) { fprintf(stderr, "Cannot find device %d\n", p->ifindex); return -1; } print_string(PRINT_ANY, "kind", "%s ", "mirred"); print_string(PRINT_FP, NULL, "(%s", mirred_n2a(p->eaction)); print_string(PRINT_JSON, "mirred_action", NULL, mirred_action(p->eaction)); print_string(PRINT_JSON, "direction", NULL, mirred_direction(p->eaction)); print_string(PRINT_ANY, "to_dev", " to device %s)", dev); print_action_control(f, " ", p->action, ""); print_uint(PRINT_ANY, "index", "\n \tindex %u", p->index); print_int(PRINT_ANY, "ref", " ref %d", p->refcnt); print_int(PRINT_ANY, "bind", " bind %d", p->bindcnt); if (show_stats) { if (tb[TCA_MIRRED_TM]) { struct tcf_t *tm = RTA_DATA(tb[TCA_MIRRED_TM]); print_tm(f, tm); } } print_string(PRINT_FP, NULL, "%s", "\n "); return 0; }
void ListMessages(void) { unsigned int i; for (i = 1; i <= USERS[CURRENT_USER].top_message; i++) { if (USERS[CURRENT_USER].messages[i][0] == '\0') { continue; } print("***********************************\n"); print_uint(i); print(": "); print(USERS[CURRENT_USER].messages[i]); print("\n"); print("***********************************\n"); } return; }
static void link_mon_print_peer_state(const uint32_t addr, const char *status, const char *monitored, const uint32_t dom_gen) { char addr_str[16]; sprintf(addr_str, "%u.%u.%u", tipc_zone(addr), tipc_cluster(addr), tipc_node(addr)); if (is_json_context()) { print_string(PRINT_JSON, "node", NULL, addr_str); print_string(PRINT_JSON, "status", NULL, status); print_string(PRINT_JSON, "monitored", NULL, monitored); print_uint(PRINT_JSON, "generation", NULL, dom_gen); } else { printf("%-*s", MAX_NODE_WIDTH, addr_str); printf("%-*s", STATUS_WIDTH, status); printf("%-*s", DIRECTLY_MON_WIDTH, monitored); printf("%-*u", MAX_DOM_GEN_WIDTH, dom_gen); } }
unsigned int print_it(t_tmp_arg *tmp, t_params *params, char c, unsigned int chars_to_save) { unsigned int wt; wt = 0; (c == 'd') ? (wt = print_int(tmp, params, 0, 0)) : (0); (c == 'i') ? (wt = print_int(tmp, params, 0, 0)) : (0); (c == 'u') ? (wt = print_uint(tmp, params, 0, 0)) : (0); (c == 'x') ? (wt = print_little_hexa(tmp, params, 0, 0)) : (0); (c == 'X') ? (wt = print_large_hexa(tmp, params, 0, 0)) : (0); (c == 'n') ? (wt = save_chars(tmp, chars_to_save)) : (0); (c == 'o') ? (wt = print_octal(tmp, params, 0, 0)) : (0); (c == 'c') ? (wt = print_char(tmp, params, 0, 0)) : (0); (c == 's') ? (wt = print_str(tmp, params, 0, 0)) : (0); (c == '%') ? (wt = print_percent()) : (0); (c == 'S') ? (wt = print_all_str(tmp, params, 0, 0)) : (0); (c == 'p') ? (wt = print_ptr(tmp, params, 0, 0)) : (0); (c == 'b') ? (wt = print_binary(tmp, params, 0, 0)) : (0); return (wt); }
static int link_mon_get_cb(const struct nlmsghdr *nlh, void *data) { struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); struct nlattr *info[TIPC_NLA_MAX + 1] = {}; struct nlattr *attrs[TIPC_NLA_MON_MAX + 1] = {}; mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info); if (!info[TIPC_NLA_MON]) return MNL_CB_ERROR; mnl_attr_parse_nested(info[TIPC_NLA_MON], parse_attrs, attrs); if (!attrs[TIPC_NLA_MON_ACTIVATION_THRESHOLD]) return MNL_CB_ERROR; new_json_obj(json); print_uint(PRINT_ANY, "threshold", "%u\n", mnl_attr_get_u32(attrs[TIPC_NLA_MON_ACTIVATION_THRESHOLD])); delete_json_obj(); return MNL_CB_OK; }
int vsnprintf_internal(char **s, size_t *len, const char *fmt, va_list args) { if (len != NULL && *len == 0) { return 0; } if (len != NULL) --*len; int count = 0; for (int i = 0; fmt[i] != 0; ++i) { if (len != NULL && *len == 0) { break; } if (fmt[i] == '%') { ++i; int cntl = 0, cnth = 0, cntz = 0; while (fmt[i] == 'l') { ++cntl; ++i; } while (fmt[i] == 'h') { ++cnth; ++i; } while (fmt[i] == 'z') { ++cntz; ++i; } if (fmt[i] == 'd' || fmt[i] == 'i') { int64_t x; GET_SIZED_INT(signed, ssize_t); count += print_int(x, s, len); continue; } else if (fmt[i] == 'p') { void *x = va_arg(args, void*); count += puts_in("0x", s, len); count += print_uint((uint64_t) x, 16, s, len); continue; } else if (fmt[i] == 'u') {
static int vti_parse_opt(struct link_util *lu, int argc, char **argv, struct nlmsghdr *n) { struct ifinfomsg *ifi = (struct ifinfomsg *)(n + 1); struct { struct nlmsghdr n; struct ifinfomsg i; char buf[1024]; } req = { .n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi)), .n.nlmsg_flags = NLM_F_REQUEST, .n.nlmsg_type = RTM_GETLINK, .i.ifi_family = preferred_family, .i.ifi_index = ifi->ifi_index, }; struct rtattr *tb[IFLA_MAX + 1]; struct rtattr *linkinfo[IFLA_INFO_MAX+1]; struct rtattr *vtiinfo[IFLA_VTI_MAX + 1]; unsigned int ikey = 0; unsigned int okey = 0; unsigned int saddr = 0; unsigned int daddr = 0; unsigned int link = 0; unsigned int fwmark = 0; int len; if (!(n->nlmsg_flags & NLM_F_CREATE)) { if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0) { get_failed: fprintf(stderr, "Failed to get existing tunnel info.\n"); return -1; } len = req.n.nlmsg_len; len -= NLMSG_LENGTH(sizeof(*ifi)); if (len < 0) goto get_failed; parse_rtattr(tb, IFLA_MAX, IFLA_RTA(&req.i), len); if (!tb[IFLA_LINKINFO]) goto get_failed; parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb[IFLA_LINKINFO]); if (!linkinfo[IFLA_INFO_DATA]) goto get_failed; parse_rtattr_nested(vtiinfo, IFLA_VTI_MAX, linkinfo[IFLA_INFO_DATA]); if (vtiinfo[IFLA_VTI_IKEY]) ikey = rta_getattr_u32(vtiinfo[IFLA_VTI_IKEY]); if (vtiinfo[IFLA_VTI_OKEY]) okey = rta_getattr_u32(vtiinfo[IFLA_VTI_OKEY]); if (vtiinfo[IFLA_VTI_LOCAL]) saddr = rta_getattr_u32(vtiinfo[IFLA_VTI_LOCAL]); if (vtiinfo[IFLA_VTI_REMOTE]) daddr = rta_getattr_u32(vtiinfo[IFLA_VTI_REMOTE]); if (vtiinfo[IFLA_VTI_LINK]) link = rta_getattr_u8(vtiinfo[IFLA_VTI_LINK]); if (vtiinfo[IFLA_VTI_FWMARK]) fwmark = rta_getattr_u32(vtiinfo[IFLA_VTI_FWMARK]); } while (argc > 0) { if (!matches(*argv, "key")) { unsigned int uval; NEXT_ARG(); if (strchr(*argv, '.')) uval = get_addr32(*argv); else { if (get_unsigned(&uval, *argv, 0) < 0) { fprintf(stderr, "Invalid value for \"key\": \"%s\"; it should be an unsigned integer\n", *argv); exit(-1); } uval = htonl(uval); } ikey = okey = uval; } else if (!matches(*argv, "ikey")) { unsigned int uval; NEXT_ARG(); if (strchr(*argv, '.')) uval = get_addr32(*argv); else { if (get_unsigned(&uval, *argv, 0) < 0) { fprintf(stderr, "invalid value for \"ikey\": \"%s\"; it should be an unsigned integer\n", *argv); exit(-1); } uval = htonl(uval); } ikey = uval; } else if (!matches(*argv, "okey")) { unsigned int uval; NEXT_ARG(); if (strchr(*argv, '.')) uval = get_addr32(*argv); else { if (get_unsigned(&uval, *argv, 0) < 0) { fprintf(stderr, "invalid value for \"okey\": \"%s\"; it should be an unsigned integer\n", *argv); exit(-1); } uval = htonl(uval); } okey = uval; } else if (!matches(*argv, "remote")) { NEXT_ARG(); if (!strcmp(*argv, "any")) { fprintf(stderr, "invalid value for \"remote\": \"%s\"\n", *argv); exit(-1); } else { daddr = get_addr32(*argv); } } else if (!matches(*argv, "local")) { NEXT_ARG(); if (!strcmp(*argv, "any")) { fprintf(stderr, "invalid value for \"local\": \"%s\"\n", *argv); exit(-1); } else { saddr = get_addr32(*argv); } } else if (!matches(*argv, "dev")) { NEXT_ARG(); link = if_nametoindex(*argv); if (link == 0) { fprintf(stderr, "Cannot find device \"%s\"\n", *argv); exit(-1); } } else if (strcmp(*argv, "fwmark") == 0) { NEXT_ARG(); if (get_u32(&fwmark, *argv, 0)) invarg("invalid fwmark\n", *argv); } else usage(); argc--; argv++; } addattr32(n, 1024, IFLA_VTI_IKEY, ikey); addattr32(n, 1024, IFLA_VTI_OKEY, okey); addattr_l(n, 1024, IFLA_VTI_LOCAL, &saddr, 4); addattr_l(n, 1024, IFLA_VTI_REMOTE, &daddr, 4); addattr32(n, 1024, IFLA_VTI_FWMARK, fwmark); if (link) addattr32(n, 1024, IFLA_VTI_LINK, link); return 0; } static void vti_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) { const char *local = "any"; const char *remote = "any"; __u32 key; unsigned int link; char s2[IFNAMSIZ]; if (!tb) return; if (tb[IFLA_VTI_REMOTE]) { unsigned int addr = rta_getattr_u32(tb[IFLA_VTI_REMOTE]); if (addr) remote = format_host(AF_INET, 4, &addr); } print_string(PRINT_ANY, "remote", "remote %s ", remote); if (tb[IFLA_VTI_LOCAL]) { unsigned int addr = rta_getattr_u32(tb[IFLA_VTI_LOCAL]); if (addr) local = format_host(AF_INET, 4, &addr); } print_string(PRINT_ANY, "local", "local %s ", local); if (tb[IFLA_VTI_LINK] && (link = rta_getattr_u32(tb[IFLA_VTI_LINK]))) { const char *n = if_indextoname(link, s2); if (n) print_string(PRINT_ANY, "link", "dev %s ", n); else print_uint(PRINT_ANY, "link_index", "dev %u ", link); } if (tb[IFLA_VTI_IKEY] && (key = rta_getattr_u32(tb[IFLA_VTI_IKEY]))) print_0xhex(PRINT_ANY, "ikey", "ikey %#x ", ntohl(key)); if (tb[IFLA_VTI_OKEY] && (key = rta_getattr_u32(tb[IFLA_VTI_OKEY]))) print_0xhex(PRINT_ANY, "okey", "okey %#x ", ntohl(key)); if (tb[IFLA_VTI_FWMARK]) { __u32 fwmark = rta_getattr_u32(tb[IFLA_VTI_FWMARK]); if (fwmark) { SPRINT_BUF(b1); snprintf(b1, sizeof(b1), "0x%x", fwmark); print_string(PRINT_ANY, "fwmark", "fwmark %s ", s2); } } } static void vti_print_help(struct link_util *lu, int argc, char **argv, FILE *f) { print_usage(f); }
static int vxnprintf(char *buf, int size, const char *fmt, va_list ap, int flags) { int written = 0, w, moremods; int width, prec; char ch, *s; unsigned int uarg; int arg; if (size <= 0) return 0; while (written < size) { ch = *fmt++; if (ch == '\0') break; /* normal character => just output it */ if (ch != '%') { printc(buf++, ch, flags); written++; continue; } /* to get here, ch == '%' */ ch = *fmt++; if (ch == '\0') break; flags &= FLAG_TTY; /* preserve only the TTY flag */ width = prec = -1; moremods = 1; /* read flags and modifiers (width+precision): */ do { switch(ch) { case '#': /* alternative output */ flags |= FLAG_ALT; break; case '0': /* zero padding */ flags |= FLAG_ZEROPAD; break; case ' ': /* space in place of '-' */ flags |= FLAG_SPACE; break; case '+': /* '+' in place of '-' */ flags |= FLAG_SIGN; break; case '-': /* left align the field */ flags |= FLAG_LEFT; break; case '.': /* value precision */ prec = scan_int(fmt, &fmt); break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* field width */ width = scan_int(fmt-1, &fmt); break; default: /* no more modifiers to scan */ moremods = 0; } if (moremods) ch = *fmt++; } while (moremods && ch != '\0'); if (ch == '\0') break; /* read the type of the argument : */ switch(ch) { case 'i': /* signed integer */ case 'd': arg = va_arg(ap, int); if (arg < 0) { /* negative value, print '-' and negate */ printc(buf++, '-', flags); written++; arg = -arg; } if (flags & FLAG_SIGN) { /* '+' in place of '-' */ printc(buf++, '+', flags); written++; } else if (flags & FLAG_SPACE) { /* ' ' in place of '-' */ printc(buf++, ' ', flags); written++; } w = print_uint(buf, size-written, arg, 10, flags, 0, 0); buf += w; written += w; break; case 'o': /* octal integer */ if (prec < width && (flags & FLAG_ZEROPAD)) prec = width; uarg = va_arg(ap, unsigned int); w = print_uint(buf, size-written, uarg, 8, flags, prec, width); buf += w; written += w; break; case 'u': /* unsigned integer */ if (prec < width && (flags & FLAG_ZEROPAD)) prec = width; uarg = va_arg(ap, unsigned int); w = print_uint(buf, size-written, uarg, 10, flags, prec, width); buf += w; written += w; break; case 'p': /* memory pointer */ flags |= FLAG_ALT; case 'x': /* hexadecimal integer, noncapitals */ flags |= FLAG_SMALLS; case 'X': /* hexadecimal integer, capitals */ if (flags & FLAG_ALT) { /* alt form begins with '0x' */ printc(buf++, '0', flags); written++; if (written < size) { printc(buf++, 'x', flags); written++; } width -= 2; } if (prec < width && (flags & FLAG_ZEROPAD)) prec = width; uarg = va_arg(ap, unsigned int); w = print_uint(buf, size-written, uarg, 16, flags, prec, width); buf += w; written += w; break; case 'c': /* character */ arg = va_arg(ap, int); printc(buf++, (char)arg, flags); written++; break; case 's': /* string */ s = va_arg(ap, char*); w = size; if (prec != -1 && written+prec < size) w = written+prec; while (written < w && *s != '\0') { printc(buf++, *s++, flags); written++; } break; default: /* unknown type, just output */ printc(buf++, ch, flags); written++; } } /* the string was truncated */ if (written == size) { buf--; written = -1; } printc(buf, '\0', flags); /* terminating zero */ return written; }
int print_neigh(struct nlmsghdr *n, void *arg) { FILE *fp = (FILE *)arg; struct ndmsg *r = NLMSG_DATA(n); int len = n->nlmsg_len; struct rtattr *tb[NDA_MAX+1]; static int logit = 1; __u8 protocol = 0; if (n->nlmsg_type != RTM_NEWNEIGH && n->nlmsg_type != RTM_DELNEIGH && n->nlmsg_type != RTM_GETNEIGH) { fprintf(stderr, "Not RTM_NEWNEIGH: %08x %08x %08x\n", n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); return 0; } len -= NLMSG_LENGTH(sizeof(*r)); if (len < 0) { fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); return -1; } if (filter.flushb && n->nlmsg_type != RTM_NEWNEIGH) return 0; if (filter.family && filter.family != r->ndm_family) return 0; if (filter.index && filter.index != r->ndm_ifindex) return 0; if (!(filter.state&r->ndm_state) && !(r->ndm_flags & NTF_PROXY) && !(r->ndm_flags & NTF_EXT_LEARNED) && (r->ndm_state || !(filter.state&0x100)) && (r->ndm_family != AF_DECnet)) return 0; if (filter.master && !(n->nlmsg_flags & NLM_F_DUMP_FILTERED)) { if (logit) { logit = 0; fprintf(fp, "\nWARNING: Kernel does not support filtering by master device\n\n"); } } parse_rtattr(tb, NDA_MAX, NDA_RTA(r), n->nlmsg_len - NLMSG_LENGTH(sizeof(*r))); if (inet_addr_match_rta(&filter.pfx, tb[NDA_DST])) return 0; if (tb[NDA_PROTOCOL]) protocol = rta_getattr_u8(tb[NDA_PROTOCOL]); if (filter.protocol && filter.protocol != protocol) return 0; if (filter.unused_only && tb[NDA_CACHEINFO]) { struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]); if (ci->ndm_refcnt) return 0; } if (filter.flushb) { struct nlmsghdr *fn; if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) { if (flush_update()) return -1; } fn = (struct nlmsghdr *)(filter.flushb + NLMSG_ALIGN(filter.flushp)); memcpy(fn, n, n->nlmsg_len); fn->nlmsg_type = RTM_DELNEIGH; fn->nlmsg_flags = NLM_F_REQUEST; fn->nlmsg_seq = ++rth.seq; filter.flushp = (((char *)fn) + n->nlmsg_len) - filter.flushb; filter.flushed++; if (show_stats < 2) return 0; } open_json_object(NULL); if (n->nlmsg_type == RTM_DELNEIGH) print_bool(PRINT_ANY, "deleted", "Deleted ", true); else if (n->nlmsg_type == RTM_GETNEIGH) print_null(PRINT_ANY, "miss", "%s ", "miss"); if (tb[NDA_DST]) { const char *dst; int family = r->ndm_family; if (family == AF_BRIDGE) { if (RTA_PAYLOAD(tb[NDA_DST]) == sizeof(struct in6_addr)) family = AF_INET6; else family = AF_INET; } dst = format_host_rta(family, tb[NDA_DST]); print_color_string(PRINT_ANY, ifa_family_color(family), "dst", "%s ", dst); } if (!filter.index && r->ndm_ifindex) { if (!is_json_context()) fprintf(fp, "dev "); print_color_string(PRINT_ANY, COLOR_IFNAME, "dev", "%s ", ll_index_to_name(r->ndm_ifindex)); } if (tb[NDA_LLADDR]) { const char *lladdr; SPRINT_BUF(b1); lladdr = ll_addr_n2a(RTA_DATA(tb[NDA_LLADDR]), RTA_PAYLOAD(tb[NDA_LLADDR]), ll_index_to_type(r->ndm_ifindex), b1, sizeof(b1)); if (!is_json_context()) fprintf(fp, "lladdr "); print_color_string(PRINT_ANY, COLOR_MAC, "lladdr", "%s", lladdr); } if (r->ndm_flags & NTF_ROUTER) print_null(PRINT_ANY, "router", " %s", "router"); if (r->ndm_flags & NTF_PROXY) print_null(PRINT_ANY, "proxy", " %s", "proxy"); if (r->ndm_flags & NTF_EXT_LEARNED) print_null(PRINT_ANY, "extern_learn", " %s ", "extern_learn"); if (show_stats) { if (tb[NDA_CACHEINFO]) print_cacheinfo(RTA_DATA(tb[NDA_CACHEINFO])); if (tb[NDA_PROBES]) print_uint(PRINT_ANY, "probes", " probes %u", rta_getattr_u32(tb[NDA_PROBES])); } if (r->ndm_state) print_neigh_state(r->ndm_state); if (protocol) { SPRINT_BUF(b1); print_string(PRINT_ANY, "protocol", " proto %s ", rtnl_rtprot_n2a(protocol, b1, sizeof(b1))); } print_string(PRINT_FP, NULL, "\n", ""); close_json_object(); fflush(stdout); return 0; }
static int ipneigh_modify(int cmd, int flags, int argc, char **argv) { struct { struct nlmsghdr n; struct ndmsg ndm; char buf[256]; } req = { .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg)), .n.nlmsg_flags = NLM_F_REQUEST | flags, .n.nlmsg_type = cmd, .ndm.ndm_family = preferred_family, .ndm.ndm_state = NUD_PERMANENT, }; char *dev = NULL; int dst_ok = 0; int dev_ok = 0; int lladdr_ok = 0; char *lla = NULL; inet_prefix dst; while (argc > 0) { if (matches(*argv, "lladdr") == 0) { NEXT_ARG(); if (lladdr_ok) duparg("lladdr", *argv); lla = *argv; lladdr_ok = 1; } else if (strcmp(*argv, "nud") == 0) { unsigned int state; NEXT_ARG(); if (nud_state_a2n(&state, *argv)) invarg("nud state is bad", *argv); req.ndm.ndm_state = state; } else if (matches(*argv, "proxy") == 0) { NEXT_ARG(); if (matches(*argv, "help") == 0) usage(); if (dst_ok) duparg("address", *argv); get_addr(&dst, *argv, preferred_family); dst_ok = 1; dev_ok = 1; req.ndm.ndm_flags |= NTF_PROXY; } else if (strcmp(*argv, "router") == 0) { req.ndm.ndm_flags |= NTF_ROUTER; } else if (matches(*argv, "extern_learn") == 0) { req.ndm.ndm_flags |= NTF_EXT_LEARNED; } else if (strcmp(*argv, "dev") == 0) { NEXT_ARG(); dev = *argv; dev_ok = 1; } else if (matches(*argv, "protocol") == 0) { __u32 proto; NEXT_ARG(); if (rtnl_rtprot_a2n(&proto, *argv)) invarg("\"protocol\" value is invalid\n", *argv); if (addattr8(&req.n, sizeof(req), NDA_PROTOCOL, proto)) return -1; } else { if (strcmp(*argv, "to") == 0) { NEXT_ARG(); } if (matches(*argv, "help") == 0) { NEXT_ARG(); } if (dst_ok) duparg2("to", *argv); get_addr(&dst, *argv, preferred_family); dst_ok = 1; } argc--; argv++; } if (!dev_ok || !dst_ok || dst.family == AF_UNSPEC) { fprintf(stderr, "Device and destination are required arguments.\n"); exit(-1); } req.ndm.ndm_family = dst.family; if (addattr_l(&req.n, sizeof(req), NDA_DST, &dst.data, dst.bytelen) < 0) return -1; if (lla && strcmp(lla, "null")) { char llabuf[20]; int l; l = ll_addr_a2n(llabuf, sizeof(llabuf), lla); if (l < 0) return -1; if (addattr_l(&req.n, sizeof(req), NDA_LLADDR, llabuf, l) < 0) return -1; } ll_init_map(&rth); if (dev) { req.ndm.ndm_ifindex = ll_name_to_index(dev); if (!req.ndm.ndm_ifindex) return nodev(dev); } if (rtnl_talk(&rth, &req.n, NULL) < 0) exit(2); return 0; } static void print_cacheinfo(const struct nda_cacheinfo *ci) { static int hz; if (!hz) hz = get_user_hz(); if (ci->ndm_refcnt) print_uint(PRINT_ANY, "refcnt", " ref %u", ci->ndm_refcnt); print_uint(PRINT_ANY, "used", " used %u", ci->ndm_used / hz); print_uint(PRINT_ANY, "confirmed", "/%u", ci->ndm_confirmed / hz); print_uint(PRINT_ANY, "updated", "/%u", ci->ndm_updated / hz); } static void print_neigh_state(unsigned int nud) { open_json_array(PRINT_JSON, is_json_context() ? "state" : ""); #define PRINT_FLAG(f) \ if (nud & NUD_##f) { \ nud &= ~NUD_##f; \ print_string(PRINT_ANY, NULL, " %s", #f); \ } PRINT_FLAG(INCOMPLETE); PRINT_FLAG(REACHABLE); PRINT_FLAG(STALE); PRINT_FLAG(DELAY); PRINT_FLAG(PROBE); PRINT_FLAG(FAILED); PRINT_FLAG(NOARP); PRINT_FLAG(PERMANENT); #undef PRINT_FLAG close_json_array(PRINT_JSON, NULL); }
static int print_ntable(struct nlmsghdr *n, void *arg) { FILE *fp = (FILE *)arg; struct ndtmsg *ndtm = NLMSG_DATA(n); int len = n->nlmsg_len; struct rtattr *tb[NDTA_MAX+1]; struct rtattr *tpb[NDTPA_MAX+1]; int ret; if (n->nlmsg_type != RTM_NEWNEIGHTBL) { fprintf(stderr, "Not NEIGHTBL: %08x %08x %08x\n", n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); return 0; } len -= NLMSG_LENGTH(sizeof(*ndtm)); if (len < 0) { fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); return -1; } if (preferred_family && preferred_family != ndtm->ndtm_family) return 0; parse_rtattr(tb, NDTA_MAX, NDTA_RTA(ndtm), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ndtm))); if (tb[NDTA_NAME]) { const char *name = rta_getattr_str(tb[NDTA_NAME]); if (filter.name && strcmp(filter.name, name)) return 0; } if (tb[NDTA_PARMS]) { parse_rtattr(tpb, NDTPA_MAX, RTA_DATA(tb[NDTA_PARMS]), RTA_PAYLOAD(tb[NDTA_PARMS])); if (tpb[NDTPA_IFINDEX]) { __u32 ifindex = rta_getattr_u32(tpb[NDTPA_IFINDEX]); if (filter.index && filter.index != ifindex) return 0; } else { if (filter.index && filter.index != NONE_DEV) return 0; } } open_json_object(NULL); print_string(PRINT_ANY, "family", "%s ", family_name(ndtm->ndtm_family)); if (tb[NDTA_NAME]) { const char *name = rta_getattr_str(tb[NDTA_NAME]); print_string(PRINT_ANY, "name", "%s ", name); } print_nl(); ret = (tb[NDTA_THRESH1] || tb[NDTA_THRESH2] || tb[NDTA_THRESH3] || tb[NDTA_GC_INTERVAL]); if (ret) print_string(PRINT_FP, NULL, " ", NULL); if (tb[NDTA_THRESH1]) { __u32 thresh1 = rta_getattr_u32(tb[NDTA_THRESH1]); print_uint(PRINT_ANY, "thresh1", "thresh1 %u ", thresh1); } if (tb[NDTA_THRESH2]) { __u32 thresh2 = rta_getattr_u32(tb[NDTA_THRESH2]); print_uint(PRINT_ANY, "thresh2", "thresh2 %u ", thresh2); } if (tb[NDTA_THRESH3]) { __u32 thresh3 = rta_getattr_u32(tb[NDTA_THRESH3]); print_uint(PRINT_ANY, "thresh3", "thresh3 %u ", thresh3); } if (tb[NDTA_GC_INTERVAL]) { __u64 gc_int = rta_getattr_u64(tb[NDTA_GC_INTERVAL]); print_u64(PRINT_ANY, "gc_interval", "gc_int %llu ", gc_int); } if (ret) print_nl(); if (tb[NDTA_CONFIG] && show_stats) print_ndtconfig(RTA_DATA(tb[NDTA_CONFIG])); if (tb[NDTA_PARMS]) print_ndtparams(tpb); if (tb[NDTA_STATS] && show_stats) print_ndtstats(RTA_DATA(tb[NDTA_STATS])); print_string(PRINT_FP, NULL, "\n", ""); close_json_object(); fflush(fp); return 0; }
static int gre_parse_opt(struct link_util *lu, int argc, char **argv, struct nlmsghdr *n) { struct ifinfomsg *ifi = (struct ifinfomsg *)(n + 1); struct { struct nlmsghdr n; struct ifinfomsg i; } req = { .n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi)), .n.nlmsg_flags = NLM_F_REQUEST, .n.nlmsg_type = RTM_GETLINK, .i.ifi_family = preferred_family, .i.ifi_index = ifi->ifi_index, }; struct nlmsghdr *answer; struct rtattr *tb[IFLA_MAX + 1]; struct rtattr *linkinfo[IFLA_INFO_MAX+1]; struct rtattr *greinfo[IFLA_GRE_MAX + 1]; __u16 iflags = 0; __u16 oflags = 0; __be32 ikey = 0; __be32 okey = 0; struct in6_addr raddr = IN6ADDR_ANY_INIT; struct in6_addr laddr = IN6ADDR_ANY_INIT; unsigned int link = 0; unsigned int flowinfo = 0; unsigned int flags = 0; __u8 hop_limit = DEFAULT_TNL_HOP_LIMIT; __u8 encap_limit = IPV6_DEFAULT_TNL_ENCAP_LIMIT; __u16 encaptype = 0; __u16 encapflags = TUNNEL_ENCAP_FLAG_CSUM6; __u16 encapsport = 0; __u16 encapdport = 0; int len; __u32 fwmark = 0; __u32 erspan_idx = 0; if (!(n->nlmsg_flags & NLM_F_CREATE)) { if (rtnl_talk(&rth, &req.n, &answer) < 0) { get_failed: fprintf(stderr, "Failed to get existing tunnel info.\n"); return -1; } len = answer->nlmsg_len; len -= NLMSG_LENGTH(sizeof(*ifi)); if (len < 0) goto get_failed; parse_rtattr(tb, IFLA_MAX, IFLA_RTA(NLMSG_DATA(answer)), len); if (!tb[IFLA_LINKINFO]) goto get_failed; parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb[IFLA_LINKINFO]); if (!linkinfo[IFLA_INFO_DATA]) goto get_failed; parse_rtattr_nested(greinfo, IFLA_GRE_MAX, linkinfo[IFLA_INFO_DATA]); if (greinfo[IFLA_GRE_IKEY]) ikey = rta_getattr_u32(greinfo[IFLA_GRE_IKEY]); if (greinfo[IFLA_GRE_OKEY]) okey = rta_getattr_u32(greinfo[IFLA_GRE_OKEY]); if (greinfo[IFLA_GRE_IFLAGS]) iflags = rta_getattr_u16(greinfo[IFLA_GRE_IFLAGS]); if (greinfo[IFLA_GRE_OFLAGS]) oflags = rta_getattr_u16(greinfo[IFLA_GRE_OFLAGS]); if (greinfo[IFLA_GRE_LOCAL]) memcpy(&laddr, RTA_DATA(greinfo[IFLA_GRE_LOCAL]), sizeof(laddr)); if (greinfo[IFLA_GRE_REMOTE]) memcpy(&raddr, RTA_DATA(greinfo[IFLA_GRE_REMOTE]), sizeof(raddr)); if (greinfo[IFLA_GRE_TTL]) hop_limit = rta_getattr_u8(greinfo[IFLA_GRE_TTL]); if (greinfo[IFLA_GRE_LINK]) link = rta_getattr_u32(greinfo[IFLA_GRE_LINK]); if (greinfo[IFLA_GRE_ENCAP_LIMIT]) encap_limit = rta_getattr_u8(greinfo[IFLA_GRE_ENCAP_LIMIT]); if (greinfo[IFLA_GRE_FLOWINFO]) flowinfo = rta_getattr_u32(greinfo[IFLA_GRE_FLOWINFO]); if (greinfo[IFLA_GRE_FLAGS]) flags = rta_getattr_u32(greinfo[IFLA_GRE_FLAGS]); if (greinfo[IFLA_GRE_ENCAP_TYPE]) encaptype = rta_getattr_u16(greinfo[IFLA_GRE_ENCAP_TYPE]); if (greinfo[IFLA_GRE_ENCAP_FLAGS]) encapflags = rta_getattr_u16(greinfo[IFLA_GRE_ENCAP_FLAGS]); if (greinfo[IFLA_GRE_ENCAP_SPORT]) encapsport = rta_getattr_u16(greinfo[IFLA_GRE_ENCAP_SPORT]); if (greinfo[IFLA_GRE_ENCAP_DPORT]) encapdport = rta_getattr_u16(greinfo[IFLA_GRE_ENCAP_DPORT]); if (greinfo[IFLA_GRE_FWMARK]) fwmark = rta_getattr_u32(greinfo[IFLA_GRE_FWMARK]); if (greinfo[IFLA_GRE_ERSPAN_INDEX]) erspan_idx = rta_getattr_u32(greinfo[IFLA_GRE_ERSPAN_INDEX]); free(answer); } while (argc > 0) { if (!matches(*argv, "key")) { NEXT_ARG(); iflags |= GRE_KEY; oflags |= GRE_KEY; ikey = okey = tnl_parse_key("key", *argv); } else if (!matches(*argv, "ikey")) { NEXT_ARG(); iflags |= GRE_KEY; ikey = tnl_parse_key("ikey", *argv); } else if (!matches(*argv, "okey")) { NEXT_ARG(); oflags |= GRE_KEY; okey = tnl_parse_key("okey", *argv); } else if (!matches(*argv, "seq")) { iflags |= GRE_SEQ; oflags |= GRE_SEQ; } else if (!matches(*argv, "iseq")) { iflags |= GRE_SEQ; } else if (!matches(*argv, "oseq")) { oflags |= GRE_SEQ; } else if (!matches(*argv, "csum")) { iflags |= GRE_CSUM; oflags |= GRE_CSUM; } else if (!matches(*argv, "icsum")) { iflags |= GRE_CSUM; } else if (!matches(*argv, "ocsum")) { oflags |= GRE_CSUM; } else if (!matches(*argv, "remote")) { inet_prefix addr; NEXT_ARG(); get_addr(&addr, *argv, AF_INET6); memcpy(&raddr, &addr.data, sizeof(raddr)); } else if (!matches(*argv, "local")) { inet_prefix addr; NEXT_ARG(); get_addr(&addr, *argv, AF_INET6); memcpy(&laddr, &addr.data, sizeof(laddr)); } else if (!matches(*argv, "dev")) { NEXT_ARG(); link = if_nametoindex(*argv); if (link == 0) { fprintf(stderr, "Cannot find device \"%s\"\n", *argv); exit(-1); } } else if (!matches(*argv, "ttl") || !matches(*argv, "hoplimit")) { __u8 uval; NEXT_ARG(); if (get_u8(&uval, *argv, 0)) invarg("invalid TTL", *argv); hop_limit = uval; } else if (!matches(*argv, "tos") || !matches(*argv, "tclass") || !matches(*argv, "dsfield")) { __u8 uval; NEXT_ARG(); flowinfo &= ~IP6_FLOWINFO_TCLASS; if (strcmp(*argv, "inherit") == 0) flags |= IP6_TNL_F_USE_ORIG_TCLASS; else { if (get_u8(&uval, *argv, 16)) invarg("invalid TClass", *argv); flowinfo |= htonl((__u32)uval << 20) & IP6_FLOWINFO_TCLASS; flags &= ~IP6_TNL_F_USE_ORIG_TCLASS; } } else if (strcmp(*argv, "flowlabel") == 0 || strcmp(*argv, "fl") == 0) { __u32 uval; NEXT_ARG(); flowinfo &= ~IP6_FLOWINFO_FLOWLABEL; if (strcmp(*argv, "inherit") == 0) flags |= IP6_TNL_F_USE_ORIG_FLOWLABEL; else { if (get_u32(&uval, *argv, 16)) invarg("invalid Flowlabel", *argv); if (uval > 0xFFFFF) invarg("invalid Flowlabel", *argv); flowinfo |= htonl(uval) & IP6_FLOWINFO_FLOWLABEL; flags &= ~IP6_TNL_F_USE_ORIG_FLOWLABEL; } } else if (strcmp(*argv, "dscp") == 0) { NEXT_ARG(); if (strcmp(*argv, "inherit") != 0) invarg("not inherit", *argv); flags |= IP6_TNL_F_RCV_DSCP_COPY; } else if (strcmp(*argv, "noencap") == 0) { encaptype = TUNNEL_ENCAP_NONE; } else if (strcmp(*argv, "encap") == 0) { NEXT_ARG(); if (strcmp(*argv, "fou") == 0) encaptype = TUNNEL_ENCAP_FOU; else if (strcmp(*argv, "gue") == 0) encaptype = TUNNEL_ENCAP_GUE; else if (strcmp(*argv, "none") == 0) encaptype = TUNNEL_ENCAP_NONE; else invarg("Invalid encap type.", *argv); } else if (strcmp(*argv, "encap-sport") == 0) { NEXT_ARG(); if (strcmp(*argv, "auto") == 0) encapsport = 0; else if (get_u16(&encapsport, *argv, 0)) invarg("Invalid source port.", *argv); } else if (strcmp(*argv, "encap-dport") == 0) { NEXT_ARG(); if (get_u16(&encapdport, *argv, 0)) invarg("Invalid destination port.", *argv); } else if (strcmp(*argv, "encap-csum") == 0) { encapflags |= TUNNEL_ENCAP_FLAG_CSUM; } else if (strcmp(*argv, "noencap-csum") == 0) { encapflags &= ~TUNNEL_ENCAP_FLAG_CSUM; } else if (strcmp(*argv, "encap-udp6-csum") == 0) { encapflags |= TUNNEL_ENCAP_FLAG_CSUM6; } else if (strcmp(*argv, "noencap-udp6-csum") == 0) { encapflags &= ~TUNNEL_ENCAP_FLAG_CSUM6; } else if (strcmp(*argv, "encap-remcsum") == 0) { encapflags |= TUNNEL_ENCAP_FLAG_REMCSUM; } else if (strcmp(*argv, "noencap-remcsum") == 0) { encapflags &= ~TUNNEL_ENCAP_FLAG_REMCSUM; } else if (strcmp(*argv, "fwmark") == 0) { NEXT_ARG(); if (strcmp(*argv, "inherit") == 0) { flags |= IP6_TNL_F_USE_ORIG_FWMARK; fwmark = 0; } else { if (get_u32(&fwmark, *argv, 0)) invarg("invalid fwmark\n", *argv); flags &= ~IP6_TNL_F_USE_ORIG_FWMARK; } } else if (strcmp(*argv, "encaplimit") == 0) { NEXT_ARG(); if (strcmp(*argv, "none") == 0) { flags |= IP6_TNL_F_IGN_ENCAP_LIMIT; } else { __u8 uval; if (get_u8(&uval, *argv, 0)) invarg("invalid ELIM", *argv); encap_limit = uval; flags &= ~IP6_TNL_F_IGN_ENCAP_LIMIT; } } else if (strcmp(*argv, "erspan") == 0) { NEXT_ARG(); if (get_u32(&erspan_idx, *argv, 0)) invarg("invalid erspan index\n", *argv); if (erspan_idx & ~((1<<20) - 1) || erspan_idx == 0) invarg("erspan index must be > 0 and <= 20-bit\n", *argv); } else usage(); argc--; argv++; } addattr32(n, 1024, IFLA_GRE_IKEY, ikey); addattr32(n, 1024, IFLA_GRE_OKEY, okey); addattr_l(n, 1024, IFLA_GRE_IFLAGS, &iflags, 2); addattr_l(n, 1024, IFLA_GRE_OFLAGS, &oflags, 2); addattr_l(n, 1024, IFLA_GRE_LOCAL, &laddr, sizeof(laddr)); addattr_l(n, 1024, IFLA_GRE_REMOTE, &raddr, sizeof(raddr)); if (link) addattr32(n, 1024, IFLA_GRE_LINK, link); addattr_l(n, 1024, IFLA_GRE_TTL, &hop_limit, 1); addattr_l(n, 1024, IFLA_GRE_ENCAP_LIMIT, &encap_limit, 1); addattr_l(n, 1024, IFLA_GRE_FLOWINFO, &flowinfo, 4); addattr32(n, 1024, IFLA_GRE_FLAGS, flags); addattr32(n, 1024, IFLA_GRE_FWMARK, fwmark); if (erspan_idx != 0) addattr32(n, 1024, IFLA_GRE_ERSPAN_INDEX, erspan_idx); addattr16(n, 1024, IFLA_GRE_ENCAP_TYPE, encaptype); addattr16(n, 1024, IFLA_GRE_ENCAP_FLAGS, encapflags); addattr16(n, 1024, IFLA_GRE_ENCAP_SPORT, htons(encapsport)); addattr16(n, 1024, IFLA_GRE_ENCAP_DPORT, htons(encapdport)); return 0; } static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) { char s2[64]; const char *local = "any"; const char *remote = "any"; unsigned int iflags = 0; unsigned int oflags = 0; unsigned int flags = 0; unsigned int flowinfo = 0; struct in6_addr in6_addr_any = IN6ADDR_ANY_INIT; if (!tb) return; if (tb[IFLA_GRE_FLAGS]) flags = rta_getattr_u32(tb[IFLA_GRE_FLAGS]); if (tb[IFLA_GRE_FLOWINFO]) flowinfo = rta_getattr_u32(tb[IFLA_GRE_FLOWINFO]); if (tb[IFLA_GRE_REMOTE]) { struct in6_addr addr; memcpy(&addr, RTA_DATA(tb[IFLA_GRE_REMOTE]), sizeof(addr)); if (memcmp(&addr, &in6_addr_any, sizeof(addr))) remote = format_host(AF_INET6, sizeof(addr), &addr); } print_string(PRINT_ANY, "remote", "remote %s ", remote); if (tb[IFLA_GRE_LOCAL]) { struct in6_addr addr; memcpy(&addr, RTA_DATA(tb[IFLA_GRE_LOCAL]), sizeof(addr)); if (memcmp(&addr, &in6_addr_any, sizeof(addr))) local = format_host(AF_INET6, sizeof(addr), &addr); } print_string(PRINT_ANY, "local", "local %s ", local); if (tb[IFLA_GRE_LINK] && rta_getattr_u32(tb[IFLA_GRE_LINK])) { unsigned int link = rta_getattr_u32(tb[IFLA_GRE_LINK]); const char *n = if_indextoname(link, s2); if (n) print_string(PRINT_ANY, "link", "dev %s ", n); else print_uint(PRINT_ANY, "link_index", "dev %u ", link); } if (tb[IFLA_GRE_TTL]) { __u8 ttl = rta_getattr_u8(tb[IFLA_GRE_TTL]); if (ttl) print_int(PRINT_ANY, "ttl", "hoplimit %d ", ttl); else print_int(PRINT_JSON, "ttl", NULL, ttl); } if (flags & IP6_TNL_F_IGN_ENCAP_LIMIT) print_bool(PRINT_ANY, "ip6_tnl_f_ign_encap_limit", "encaplimit none ", true); else if (tb[IFLA_GRE_ENCAP_LIMIT]) { int encap_limit = rta_getattr_u8(tb[IFLA_GRE_ENCAP_LIMIT]); print_int(PRINT_ANY, "encap_limit", "encaplimit %d ", encap_limit); } if (flags & IP6_TNL_F_USE_ORIG_FLOWLABEL) { print_bool(PRINT_ANY, "ip6_tnl_f_use_orig_flowlabel", "flowlabel inherit ", true); } else { if (is_json_context()) { SPRINT_BUF(b1); snprintf(b1, sizeof(b1), "0x%05x", ntohl(flowinfo & IP6_FLOWINFO_FLOWLABEL)); print_string(PRINT_JSON, "flowlabel", NULL, b1); } else { fprintf(f, "flowlabel 0x%05x ", ntohl(flowinfo & IP6_FLOWINFO_FLOWLABEL)); } } if (flags & IP6_TNL_F_USE_ORIG_TCLASS) { print_bool(PRINT_ANY, "ip6_tnl_f_use_orig_tclass", "tclass inherit ", true); } else { if (is_json_context()) { SPRINT_BUF(b1); snprintf(b1, sizeof(b1), "0x%05x", ntohl(flowinfo & IP6_FLOWINFO_TCLASS) >> 20); print_string(PRINT_JSON, "tclass", NULL, b1); } else { fprintf(f, "tclass 0x%02x ", ntohl(flowinfo & IP6_FLOWINFO_TCLASS) >> 20); } }
static int _show_bc_link_stat(const char *name, struct nlattr *prop[], struct nlattr *stats[]) { open_json_object(NULL); print_string(PRINT_ANY, "link", "Link <%s>\n", name); print_uint(PRINT_ANY, WINDOW_STR, " Window:%u packets\n", mnl_attr_get_u32(prop[TIPC_NLA_PROP_WIN])); open_json_object("rx packets"); print_uint(PRINT_ANY, "rx packets", " RX packets:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_INFO])); print_uint(PRINT_ANY, "fragments", " fragments:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTS])); print_uint(PRINT_ANY, "fragmented", "/%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTED])); print_uint(PRINT_ANY, "bundles", " bundles:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLES])); print_uint(PRINT_ANY, "bundled", "/%u\n", mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLED])); close_json_object(); open_json_object("tx packets"); print_uint(PRINT_ANY, "tx packets", " TX packets:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_INFO])); print_uint(PRINT_ANY, "fragments", " fragments:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTS])); print_uint(PRINT_ANY, "fragmented", "/%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTED])); print_uint(PRINT_ANY, "bundles", " bundles:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLES])); print_uint(PRINT_ANY, "bundled", "/%u\n", mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLED])); close_json_object(); open_json_object("rx naks"); print_uint(PRINT_ANY, "rx naks", " RX naks:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_NACKS])); print_uint(PRINT_ANY, "defs", " defs:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_DEFERRED])); print_uint(PRINT_ANY, "dups", " dups:%u\n", mnl_attr_get_u32(stats[TIPC_NLA_STATS_DUPLICATES])); close_json_object(); open_json_object("tx naks"); print_uint(PRINT_ANY, "tx naks", " TX naks:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_NACKS])); print_uint(PRINT_ANY, "acks", " acks:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_ACKS])); print_uint(PRINT_ANY, "retrans", " retrans:%u\n", mnl_attr_get_u32(stats[TIPC_NLA_STATS_RETRANSMITTED])); close_json_object(); print_uint(PRINT_ANY, "congestion link", " Congestion link:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_LINK_CONGS])); print_uint(PRINT_ANY, "send queue max", " Send queue max:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_MAX_QUEUE])); print_uint(PRINT_ANY, "avg", " avg:%u\n", mnl_attr_get_u32(stats[TIPC_NLA_STATS_AVG_QUEUE])); close_json_object(); return MNL_CB_OK; }
/* device creation */ static void macsec_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) { if (!tb) return; if (tb[IFLA_MACSEC_SCI]) { if (is_json_context()) { SPRINT_BUF(b1); snprintf(b1, sizeof(b1), "%016llx", ntohll(rta_getattr_u64(tb[IFLA_MACSEC_SCI]))); print_string(PRINT_JSON, "sci", NULL, b1); } else { fprintf(f, "sci %016llx ", ntohll(rta_getattr_u64(tb[IFLA_MACSEC_SCI]))); } } print_flag(tb, "protect", IFLA_MACSEC_PROTECT); if (tb[IFLA_MACSEC_CIPHER_SUITE]) { __u64 csid = rta_getattr_u64(tb[IFLA_MACSEC_CIPHER_SUITE]); print_string(PRINT_ANY, "cipher_suite", "cipher %s ", cs_id_to_name(csid)); } if (tb[IFLA_MACSEC_ICV_LEN]) { if (is_json_context()) { char b2[4]; snprintf(b2, sizeof(b2), "%hhu", rta_getattr_u8(tb[IFLA_MACSEC_ICV_LEN])); print_uint(PRINT_JSON, "icv_len", NULL, atoi(b2)); } else { fprintf(f, "icvlen %hhu ", rta_getattr_u8(tb[IFLA_MACSEC_ICV_LEN])); } } if (tb[IFLA_MACSEC_ENCODING_SA]) { if (is_json_context()) { char b2[4]; snprintf(b2, sizeof(b2), "%hhu", rta_getattr_u8(tb[IFLA_MACSEC_ENCODING_SA])); print_uint(PRINT_JSON, "encoding_sa", NULL, atoi(b2)); } else { fprintf(f, "encodingsa %hhu ", rta_getattr_u8(tb[IFLA_MACSEC_ENCODING_SA])); } } if (tb[IFLA_MACSEC_VALIDATION]) { __u8 val = rta_getattr_u8(tb[IFLA_MACSEC_VALIDATION]); print_string(PRINT_ANY, "validation", "validate %s ", validate_str[val]); } const char *inc_sci, *es, *replay; if (is_json_context()) { inc_sci = "inc_sci"; replay = "replay_protect"; es = "es"; } else { inc_sci = "send_sci"; es = "end_station"; replay = "replay"; } print_flag(tb, "encrypt", IFLA_MACSEC_ENCRYPT); print_flag(tb, inc_sci, IFLA_MACSEC_INC_SCI); print_flag(tb, es, IFLA_MACSEC_ES); print_flag(tb, "scb", IFLA_MACSEC_SCB); print_flag(tb, replay, IFLA_MACSEC_REPLAY_PROTECT); if (tb[IFLA_MACSEC_WINDOW]) print_int(PRINT_ANY, "window", "window %d ", rta_getattr_u32(tb[IFLA_MACSEC_WINDOW])); }
static int ipntable_modify(int cmd, int flags, int argc, char **argv) { struct { struct nlmsghdr n; struct ndtmsg ndtm; char buf[1024]; } req = { .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndtmsg)), .n.nlmsg_flags = NLM_F_REQUEST | flags, .n.nlmsg_type = cmd, .ndtm.ndtm_family = preferred_family, }; char *namep = NULL; char *threshsp = NULL; char *gc_intp = NULL; char parms_buf[1024] = {}; struct rtattr *parms_rta = (struct rtattr *)parms_buf; int parms_change = 0; parms_rta->rta_type = NDTA_PARMS; parms_rta->rta_len = RTA_LENGTH(0); while (argc > 0) { if (strcmp(*argv, "name") == 0) { int len; NEXT_ARG(); if (namep) duparg("NAME", *argv); namep = *argv; len = strlen(namep) + 1; addattr_l(&req.n, sizeof(req), NDTA_NAME, namep, len); } else if (strcmp(*argv, "thresh1") == 0) { __u32 thresh1; NEXT_ARG(); threshsp = *argv; if (get_u32(&thresh1, *argv, 0)) invarg("\"thresh1\" value is invalid", *argv); addattr32(&req.n, sizeof(req), NDTA_THRESH1, thresh1); } else if (strcmp(*argv, "thresh2") == 0) { __u32 thresh2; NEXT_ARG(); threshsp = *argv; if (get_u32(&thresh2, *argv, 0)) invarg("\"thresh2\" value is invalid", *argv); addattr32(&req.n, sizeof(req), NDTA_THRESH2, thresh2); } else if (strcmp(*argv, "thresh3") == 0) { __u32 thresh3; NEXT_ARG(); threshsp = *argv; if (get_u32(&thresh3, *argv, 0)) invarg("\"thresh3\" value is invalid", *argv); addattr32(&req.n, sizeof(req), NDTA_THRESH3, thresh3); } else if (strcmp(*argv, "gc_int") == 0) { __u64 gc_int; NEXT_ARG(); gc_intp = *argv; if (get_u64(&gc_int, *argv, 0)) invarg("\"gc_int\" value is invalid", *argv); addattr_l(&req.n, sizeof(req), NDTA_GC_INTERVAL, &gc_int, sizeof(gc_int)); } else if (strcmp(*argv, "dev") == 0) { __u32 ifindex; NEXT_ARG(); ifindex = ll_name_to_index(*argv); if (!ifindex) return nodev(*argv); rta_addattr32(parms_rta, sizeof(parms_buf), NDTPA_IFINDEX, ifindex); } else if (strcmp(*argv, "base_reachable") == 0) { __u64 breachable; NEXT_ARG(); if (get_u64(&breachable, *argv, 0)) invarg("\"base_reachable\" value is invalid", *argv); rta_addattr_l(parms_rta, sizeof(parms_buf), NDTPA_BASE_REACHABLE_TIME, &breachable, sizeof(breachable)); parms_change = 1; } else if (strcmp(*argv, "retrans") == 0) { __u64 retrans; NEXT_ARG(); if (get_u64(&retrans, *argv, 0)) invarg("\"retrans\" value is invalid", *argv); rta_addattr_l(parms_rta, sizeof(parms_buf), NDTPA_RETRANS_TIME, &retrans, sizeof(retrans)); parms_change = 1; } else if (strcmp(*argv, "gc_stale") == 0) { __u64 gc_stale; NEXT_ARG(); if (get_u64(&gc_stale, *argv, 0)) invarg("\"gc_stale\" value is invalid", *argv); rta_addattr_l(parms_rta, sizeof(parms_buf), NDTPA_GC_STALETIME, &gc_stale, sizeof(gc_stale)); parms_change = 1; } else if (strcmp(*argv, "delay_probe") == 0) { __u64 delay_probe; NEXT_ARG(); if (get_u64(&delay_probe, *argv, 0)) invarg("\"delay_probe\" value is invalid", *argv); rta_addattr_l(parms_rta, sizeof(parms_buf), NDTPA_DELAY_PROBE_TIME, &delay_probe, sizeof(delay_probe)); parms_change = 1; } else if (strcmp(*argv, "queue") == 0) { __u32 queue; NEXT_ARG(); if (get_u32(&queue, *argv, 0)) invarg("\"queue\" value is invalid", *argv); rta_addattr32(parms_rta, sizeof(parms_buf), NDTPA_QUEUE_LEN, queue); parms_change = 1; } else if (strcmp(*argv, "app_probes") == 0) { __u32 aprobe; NEXT_ARG(); if (get_u32(&aprobe, *argv, 0)) invarg("\"app_probes\" value is invalid", *argv); rta_addattr32(parms_rta, sizeof(parms_buf), NDTPA_APP_PROBES, aprobe); parms_change = 1; } else if (strcmp(*argv, "ucast_probes") == 0) { __u32 uprobe; NEXT_ARG(); if (get_u32(&uprobe, *argv, 0)) invarg("\"ucast_probes\" value is invalid", *argv); rta_addattr32(parms_rta, sizeof(parms_buf), NDTPA_UCAST_PROBES, uprobe); parms_change = 1; } else if (strcmp(*argv, "mcast_probes") == 0) { __u32 mprobe; NEXT_ARG(); if (get_u32(&mprobe, *argv, 0)) invarg("\"mcast_probes\" value is invalid", *argv); rta_addattr32(parms_rta, sizeof(parms_buf), NDTPA_MCAST_PROBES, mprobe); parms_change = 1; } else if (strcmp(*argv, "anycast_delay") == 0) { __u64 anycast_delay; NEXT_ARG(); if (get_u64(&anycast_delay, *argv, 0)) invarg("\"anycast_delay\" value is invalid", *argv); rta_addattr_l(parms_rta, sizeof(parms_buf), NDTPA_ANYCAST_DELAY, &anycast_delay, sizeof(anycast_delay)); parms_change = 1; } else if (strcmp(*argv, "proxy_delay") == 0) { __u64 proxy_delay; NEXT_ARG(); if (get_u64(&proxy_delay, *argv, 0)) invarg("\"proxy_delay\" value is invalid", *argv); rta_addattr_l(parms_rta, sizeof(parms_buf), NDTPA_PROXY_DELAY, &proxy_delay, sizeof(proxy_delay)); parms_change = 1; } else if (strcmp(*argv, "proxy_queue") == 0) { __u32 pqueue; NEXT_ARG(); if (get_u32(&pqueue, *argv, 0)) invarg("\"proxy_queue\" value is invalid", *argv); rta_addattr32(parms_rta, sizeof(parms_buf), NDTPA_PROXY_QLEN, pqueue); parms_change = 1; } else if (strcmp(*argv, "locktime") == 0) { __u64 locktime; NEXT_ARG(); if (get_u64(&locktime, *argv, 0)) invarg("\"locktime\" value is invalid", *argv); rta_addattr_l(parms_rta, sizeof(parms_buf), NDTPA_LOCKTIME, &locktime, sizeof(locktime)); parms_change = 1; } else { invarg("unknown", *argv); } argc--; argv++; } if (!namep) missarg("NAME"); if (!threshsp && !gc_intp && !parms_change) { fprintf(stderr, "Not enough information: changeable attributes required.\n"); exit(-1); } if (parms_rta->rta_len > RTA_LENGTH(0)) { addattr_l(&req.n, sizeof(req), NDTA_PARMS, RTA_DATA(parms_rta), RTA_PAYLOAD(parms_rta)); } if (rtnl_talk(&rth, &req.n, NULL) < 0) exit(2); return 0; } static const char *ntable_strtime_delta(__u32 msec) { static char str[32]; struct timeval now = {}; time_t t; struct tm *tp; if (msec == 0) goto error; if (gettimeofday(&now, NULL) < 0) { perror("gettimeofday"); goto error; } t = now.tv_sec - (msec / 1000); tp = localtime(&t); if (!tp) goto error; strftime(str, sizeof(str), "%Y-%m-%d %T", tp); return str; error: strcpy(str, "(error)"); return str; } static void print_ndtconfig(const struct ndt_config *ndtc) { print_uint(PRINT_ANY, "key_length", " config key_len %u ", ndtc->ndtc_key_len); print_uint(PRINT_ANY, "entry_size", "entry_size %u ", ndtc->ndtc_entry_size); print_uint(PRINT_ANY, "entries", "entries %u ", ndtc->ndtc_entries); print_nl(); print_string(PRINT_ANY, "last_flush", " last_flush %s ", ntable_strtime_delta(ndtc->ndtc_last_flush)); print_string(PRINT_ANY, "last_rand", "last_rand %s ", ntable_strtime_delta(ndtc->ndtc_last_rand)); print_nl(); print_uint(PRINT_ANY, "hash_rnd", " hash_rnd %u ", ndtc->ndtc_hash_rnd); print_0xhex(PRINT_ANY, "hash_mask", "hash_mask %08llx ", ndtc->ndtc_hash_mask); print_uint(PRINT_ANY, "hash_chain_gc", "hash_chain_gc %u ", ndtc->ndtc_hash_chain_gc); print_uint(PRINT_ANY, "proxy_qlen", "proxy_qlen %u ", ndtc->ndtc_proxy_qlen); print_nl(); }
static int process(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { struct genlmsghdr *ghdr; struct rtattr *attrs[MACSEC_ATTR_MAX + 1]; struct rtattr *attrs_secy[MACSEC_SECY_ATTR_MAX + 1]; int len = n->nlmsg_len; int ifindex; __u64 sci; __u8 encoding_sa; if (n->nlmsg_type != genl_family) return -1; len -= NLMSG_LENGTH(GENL_HDRLEN); if (len < 0) return -1; ghdr = NLMSG_DATA(n); if (ghdr->cmd != MACSEC_CMD_GET_TXSC) return 0; parse_rtattr(attrs, MACSEC_ATTR_MAX, (void *) ghdr + GENL_HDRLEN, len); if (!validate_dump(attrs)) { fprintf(stderr, "incomplete dump message\n"); return -1; } ifindex = rta_getattr_u32(attrs[MACSEC_ATTR_IFINDEX]); parse_rtattr_nested(attrs_secy, MACSEC_SECY_ATTR_MAX + 1, attrs[MACSEC_ATTR_SECY]); if (!validate_secy_dump(attrs_secy)) { fprintf(stderr, "incomplete dump message\n"); return -1; } sci = rta_getattr_u64(attrs_secy[MACSEC_SECY_ATTR_SCI]); encoding_sa = rta_getattr_u8(attrs_secy[MACSEC_SECY_ATTR_ENCODING_SA]); if (filter.ifindex && ifindex != filter.ifindex) return 0; if (filter.sci && sci != filter.sci) return 0; open_json_object(NULL); print_uint(PRINT_ANY, "ifindex", "%u: ", ifindex); print_color_string(PRINT_ANY, COLOR_IFNAME, "ifname", "%s: ", ll_index_to_name(ifindex)); print_attrs(attrs_secy); print_tx_sc(" ", sci, encoding_sa, attrs[MACSEC_ATTR_TXSC_STATS], attrs[MACSEC_ATTR_SECY_STATS], attrs[MACSEC_ATTR_TXSA_LIST]); if (attrs[MACSEC_ATTR_RXSC_LIST]) print_rxsc_list(attrs[MACSEC_ATTR_RXSC_LIST]); close_json_object(); return 0; }
static int _show_link_stat(const char *name, struct nlattr *attrs[], struct nlattr *prop[], struct nlattr *stats[]) { uint32_t proft; open_json_object(NULL); print_string(PRINT_ANY, "link", "\nLink <%s>\n", name); print_string(PRINT_JSON, "state", "", NULL); open_json_array(PRINT_JSON, NULL); if (attrs[TIPC_NLA_LINK_ACTIVE]) print_string(PRINT_ANY, NULL, " %s", "ACTIVE"); else if (attrs[TIPC_NLA_LINK_UP]) print_string(PRINT_ANY, NULL, " %s", "STANDBY"); else print_string(PRINT_ANY, NULL, " %s", "DEFUNCT"); close_json_array(PRINT_JSON, NULL); print_uint(PRINT_ANY, "mtu", " MTU:%u", mnl_attr_get_u32(attrs[TIPC_NLA_LINK_MTU])); print_uint(PRINT_ANY, PRIORITY_STR, " Priority:%u", mnl_attr_get_u32(prop[TIPC_NLA_PROP_PRIO])); print_uint(PRINT_ANY, TOLERANCE_STR, " Tolerance:%u ms", mnl_attr_get_u32(prop[TIPC_NLA_PROP_TOL])); print_uint(PRINT_ANY, WINDOW_STR, " Window:%u packets\n", mnl_attr_get_u32(prop[TIPC_NLA_PROP_WIN])); open_json_object("rx packets"); print_uint(PRINT_ANY, "rx packets", " RX packets:%u", mnl_attr_get_u32(attrs[TIPC_NLA_LINK_RX]) - mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_INFO])); print_uint(PRINT_ANY, "fragments", " fragments:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTS])); print_uint(PRINT_ANY, "fragmented", "/%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTED])); print_uint(PRINT_ANY, "bundles", " bundles:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLES])); print_uint(PRINT_ANY, "bundled", "/%u\n", mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLED])); close_json_object(); open_json_object("tx packets"); print_uint(PRINT_ANY, "tx packets", " TX packets:%u", mnl_attr_get_u32(attrs[TIPC_NLA_LINK_TX]) - mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_INFO])); print_uint(PRINT_ANY, "fragments", " fragments:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTS])); print_uint(PRINT_ANY, "fragmented", "/%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTED])); print_uint(PRINT_ANY, "bundles", " bundles:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLES])); print_uint(PRINT_ANY, "bundled", "/%u\n", mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLED])); close_json_object(); proft = mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT]); print_uint(PRINT_ANY, "tx profile sample", " TX profile sample:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_CNT])); print_uint(PRINT_ANY, "packets average", " packets average:%u octets\n", mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_TOT]) / proft); print_uint(PRINT_ANY, "0-64", " 0-64:%u%%", perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P0]), proft)); print_uint(PRINT_ANY, "-256", " -256:%u%%", perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P1]), proft)); print_uint(PRINT_ANY, "-1024", " -1024:%u%%", perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P2]), proft)); print_uint(PRINT_ANY, "-4096", " -4096:%u%%", perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P3]), proft)); print_uint(PRINT_ANY, "-16384", " -16384:%u%%", perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P4]), proft)); print_uint(PRINT_ANY, "-32768", " -32768:%u%%", perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P5]), proft)); print_uint(PRINT_ANY, "-66000", " -66000:%u%%\n", perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P6]), proft)); open_json_object("rx states"); print_uint(PRINT_ANY, "rx states", " RX states:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_STATES])); print_uint(PRINT_ANY, "probes", " probes:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_PROBES])); print_uint(PRINT_ANY, "naks", " naks:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_NACKS])); print_uint(PRINT_ANY, "defs", " defs:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_DEFERRED])); print_uint(PRINT_ANY, "dups", " dups:%u\n", mnl_attr_get_u32(stats[TIPC_NLA_STATS_DUPLICATES])); close_json_object(); open_json_object("tx states"); print_uint(PRINT_ANY, "tx states", " TX states:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_STATES])); print_uint(PRINT_ANY, "probes", " probes:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_PROBES])); print_uint(PRINT_ANY, "naks", " naks:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_NACKS])); print_uint(PRINT_ANY, "acks", " acks:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_ACKS])); print_uint(PRINT_ANY, "retrans", " retrans:%u\n", mnl_attr_get_u32(stats[TIPC_NLA_STATS_RETRANSMITTED])); close_json_object(); print_uint(PRINT_ANY, "congestion link", " Congestion link:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_LINK_CONGS])); print_uint(PRINT_ANY, "send queue max", " Send queue max:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_MAX_QUEUE])); print_uint(PRINT_ANY, "avg", " avg:%u\n", mnl_attr_get_u32(stats[TIPC_NLA_STATS_AVG_QUEUE])); close_json_object(); return MNL_CB_OK; }