static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags, struct net_device *dev) { void *hdr; struct wpan_phy *phy; pr_debug("%s\n", __func__); hdr = genlmsg_put(msg, 0, seq, &nl802154_family, flags, IEEE802154_LIST_IFACE); if (!hdr) goto out; phy = ieee802154_mlme_ops(dev)->get_phy(dev); BUG_ON(!phy); NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name); NLA_PUT_STRING(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)); NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex); NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN, dev->dev_addr); NLA_PUT_U16(msg, IEEE802154_ATTR_SHORT_ADDR, ieee802154_mlme_ops(dev)->get_short_addr(dev)); NLA_PUT_U16(msg, IEEE802154_ATTR_PAN_ID, ieee802154_mlme_ops(dev)->get_pan_id(dev)); wpan_phy_put(phy); return genlmsg_end(msg, hdr); nla_put_failure: wpan_phy_put(phy); genlmsg_cancel(msg, hdr); out: return -EMSGSIZE; }
static int l2tp_nl_session_send(struct sk_buff *skb, u32 pid, u32 seq, int flags, struct l2tp_session *session) { void *hdr; struct nlattr *nest; struct l2tp_tunnel *tunnel = session->tunnel; struct sock *sk = NULL; sk = tunnel->sock; hdr = genlmsg_put(skb, pid, seq, &l2tp_nl_family, flags, L2TP_CMD_SESSION_GET); if (IS_ERR(hdr)) return PTR_ERR(hdr); NLA_PUT_U32(skb, L2TP_ATTR_CONN_ID, tunnel->tunnel_id); NLA_PUT_U32(skb, L2TP_ATTR_SESSION_ID, session->session_id); NLA_PUT_U32(skb, L2TP_ATTR_PEER_CONN_ID, tunnel->peer_tunnel_id); NLA_PUT_U32(skb, L2TP_ATTR_PEER_SESSION_ID, session->peer_session_id); NLA_PUT_U32(skb, L2TP_ATTR_DEBUG, session->debug); NLA_PUT_U16(skb, L2TP_ATTR_PW_TYPE, session->pwtype); NLA_PUT_U16(skb, L2TP_ATTR_MTU, session->mtu); if (session->mru) NLA_PUT_U16(skb, L2TP_ATTR_MRU, session->mru); if (session->ifname && session->ifname[0]) NLA_PUT_STRING(skb, L2TP_ATTR_IFNAME, session->ifname); if (session->cookie_len) NLA_PUT(skb, L2TP_ATTR_COOKIE, session->cookie_len, &session->cookie[0]); if (session->peer_cookie_len) NLA_PUT(skb, L2TP_ATTR_PEER_COOKIE, session->peer_cookie_len, &session->peer_cookie[0]); NLA_PUT_U8(skb, L2TP_ATTR_RECV_SEQ, session->recv_seq); NLA_PUT_U8(skb, L2TP_ATTR_SEND_SEQ, session->send_seq); NLA_PUT_U8(skb, L2TP_ATTR_LNS_MODE, session->lns_mode); #ifdef CONFIG_XFRM if ((sk) && (sk->sk_policy[0] || sk->sk_policy[1])) NLA_PUT_U8(skb, L2TP_ATTR_USING_IPSEC, 1); #endif if (session->reorder_timeout) NLA_PUT_MSECS(skb, L2TP_ATTR_RECV_TIMEOUT, session->reorder_timeout); nest = nla_nest_start(skb, L2TP_ATTR_STATS); if (nest == NULL) goto nla_put_failure; NLA_PUT_U64(skb, L2TP_ATTR_TX_PACKETS, session->stats.tx_packets); NLA_PUT_U64(skb, L2TP_ATTR_TX_BYTES, session->stats.tx_bytes); NLA_PUT_U64(skb, L2TP_ATTR_TX_ERRORS, session->stats.tx_errors); NLA_PUT_U64(skb, L2TP_ATTR_RX_PACKETS, session->stats.rx_packets); NLA_PUT_U64(skb, L2TP_ATTR_RX_BYTES, session->stats.rx_bytes); NLA_PUT_U64(skb, L2TP_ATTR_RX_SEQ_DISCARDS, session->stats.rx_seq_discards); NLA_PUT_U64(skb, L2TP_ATTR_RX_OOS_PACKETS, session->stats.rx_oos_packets); NLA_PUT_U64(skb, L2TP_ATTR_RX_ERRORS, session->stats.rx_errors); nla_nest_end(skb, nest); return genlmsg_end(skb, hdr); nla_put_failure: genlmsg_cancel(skb, hdr); return -1; }
static int l2tp_nl_tunnel_send(struct sk_buff *skb, u32 pid, u32 seq, int flags, struct l2tp_tunnel *tunnel) { void *hdr; struct nlattr *nest; struct sock *sk = NULL; struct inet_sock *inet; hdr = genlmsg_put(skb, pid, seq, &l2tp_nl_family, flags, L2TP_CMD_TUNNEL_GET); if (IS_ERR(hdr)) return PTR_ERR(hdr); NLA_PUT_U8(skb, L2TP_ATTR_PROTO_VERSION, tunnel->version); NLA_PUT_U32(skb, L2TP_ATTR_CONN_ID, tunnel->tunnel_id); NLA_PUT_U32(skb, L2TP_ATTR_PEER_CONN_ID, tunnel->peer_tunnel_id); NLA_PUT_U32(skb, L2TP_ATTR_DEBUG, tunnel->debug); NLA_PUT_U16(skb, L2TP_ATTR_ENCAP_TYPE, tunnel->encap); nest = nla_nest_start(skb, L2TP_ATTR_STATS); if (nest == NULL) goto nla_put_failure; NLA_PUT_U64(skb, L2TP_ATTR_TX_PACKETS, tunnel->stats.tx_packets); NLA_PUT_U64(skb, L2TP_ATTR_TX_BYTES, tunnel->stats.tx_bytes); NLA_PUT_U64(skb, L2TP_ATTR_TX_ERRORS, tunnel->stats.tx_errors); NLA_PUT_U64(skb, L2TP_ATTR_RX_PACKETS, tunnel->stats.rx_packets); NLA_PUT_U64(skb, L2TP_ATTR_RX_BYTES, tunnel->stats.rx_bytes); NLA_PUT_U64(skb, L2TP_ATTR_RX_SEQ_DISCARDS, tunnel->stats.rx_seq_discards); NLA_PUT_U64(skb, L2TP_ATTR_RX_OOS_PACKETS, tunnel->stats.rx_oos_packets); NLA_PUT_U64(skb, L2TP_ATTR_RX_ERRORS, tunnel->stats.rx_errors); nla_nest_end(skb, nest); sk = tunnel->sock; if (!sk) goto out; inet = inet_sk(sk); switch (tunnel->encap) { case L2TP_ENCAPTYPE_UDP: NLA_PUT_U16(skb, L2TP_ATTR_UDP_SPORT, ntohs(inet->inet_sport)); NLA_PUT_U16(skb, L2TP_ATTR_UDP_DPORT, ntohs(inet->inet_dport)); NLA_PUT_U8(skb, L2TP_ATTR_UDP_CSUM, (sk->sk_no_check != UDP_CSUM_NOXMIT)); /* NOBREAK */ case L2TP_ENCAPTYPE_IP: NLA_PUT_BE32(skb, L2TP_ATTR_IP_SADDR, inet->inet_saddr); NLA_PUT_BE32(skb, L2TP_ATTR_IP_DADDR, inet->inet_daddr); break; } out: return genlmsg_end(skb, hdr); nla_put_failure: genlmsg_cancel(skb, hdr); return -1; }
static int ipvs_nl_fill_service_attr(struct nl_msg *msg, ipvs_service_t *svc) { struct nlattr *nl_service; struct ip_vs_flags flags = { .flags = svc->flags, .mask = ~0 }; nl_service = nla_nest_start(msg, IPVS_CMD_ATTR_SERVICE); if (!nl_service) return -1; NLA_PUT_U16(msg, IPVS_SVC_ATTR_AF, svc->af); if (svc->fwmark) { NLA_PUT_U32(msg, IPVS_SVC_ATTR_FWMARK, svc->fwmark); } else { NLA_PUT_U16(msg, IPVS_SVC_ATTR_PROTOCOL, svc->protocol); NLA_PUT(msg, IPVS_SVC_ATTR_ADDR, sizeof(svc->addr), &(svc->addr)); NLA_PUT_U16(msg, IPVS_SVC_ATTR_PORT, svc->port); } NLA_PUT_STRING(msg, IPVS_SVC_ATTR_SCHED_NAME, svc->sched_name); if (svc->pe_name[0]) NLA_PUT_STRING(msg, IPVS_SVC_ATTR_PE_NAME, svc->pe_name); NLA_PUT(msg, IPVS_SVC_ATTR_FLAGS, sizeof(flags), &flags); NLA_PUT_U32(msg, IPVS_SVC_ATTR_TIMEOUT, svc->timeout); NLA_PUT_U32(msg, IPVS_SVC_ATTR_NETMASK, svc->netmask); nla_nest_end(msg, nl_service); return 0; nla_put_failure: return -1; } #endif int ipvs_add_service(ipvs_service_t *svc) { ipvs_func = ipvs_add_service; #ifdef LIBIPVS_USE_NL if (try_nl) { struct nl_msg *msg = ipvs_nl_message(IPVS_CMD_NEW_SERVICE, 0); if (!msg) return -1; if (ipvs_nl_fill_service_attr(msg, svc)) { nlmsg_free(msg); return -1; } return ipvs_nl_send_message(msg, ipvs_nl_noop_cb, NULL); } #endif CHECK_COMPAT_SVC(svc, -1); return setsockopt(sockfd, IPPROTO_IP, IP_VS_SO_SET_ADD, (char *)svc, sizeof(struct ip_vs_service_kern)); out_err: return -1; }
int ipvs_start_daemon(ipvs_daemon_t *dm) { struct ip_vs_daemon_kern dmk; ipvs_func = ipvs_start_daemon; #ifdef LIBIPVS_USE_NL if (try_nl) { struct nlattr *nl_daemon; struct nl_msg *msg = ipvs_nl_message(IPVS_CMD_NEW_DAEMON, 0); if (!msg) return -1; nl_daemon = nla_nest_start(msg, IPVS_CMD_ATTR_DAEMON); if (!nl_daemon) goto nla_put_failure; NLA_PUT_U32(msg, IPVS_DAEMON_ATTR_STATE, dm->state); NLA_PUT_STRING(msg, IPVS_DAEMON_ATTR_MCAST_IFN, dm->mcast_ifn); NLA_PUT_U32(msg, IPVS_DAEMON_ATTR_SYNC_ID, dm->syncid); if (dm->sync_maxlen) NLA_PUT_U16(msg, IPVS_DAEMON_ATTR_SYNC_MAXLEN, dm->sync_maxlen); if (dm->mcast_port) NLA_PUT_U16(msg, IPVS_DAEMON_ATTR_MCAST_PORT, dm->mcast_port); if (dm->mcast_ttl) NLA_PUT_U8(msg, IPVS_DAEMON_ATTR_MCAST_TTL, dm->mcast_ttl); if (AF_INET6 == dm->mcast_af) NLA_PUT(msg, IPVS_DAEMON_ATTR_MCAST_GROUP6, sizeof(dm->mcast_group.in6), &dm->mcast_group.in6); else if (AF_INET == dm->mcast_af) NLA_PUT_U32(msg, IPVS_DAEMON_ATTR_MCAST_GROUP, dm->mcast_group.ip); nla_nest_end(msg, nl_daemon); return ipvs_nl_send_message(msg, ipvs_nl_noop_cb, NULL); nla_put_failure: nlmsg_free(msg); return -1; } #endif memset(&dmk, 0, sizeof(dmk)); dmk.state = dm->state; strcpy(dmk.mcast_ifn, dm->mcast_ifn); dmk.syncid = dm->syncid; return setsockopt(sockfd, IPPROTO_IP, IP_VS_SO_SET_STARTDAEMON, (char *)&dmk, sizeof(dmk)); }
static iz_res_t set_request(struct iz_cmd *cmd, struct nl_msg *msg) { char *dummy; uint16_t pan_id, short_addr; uint8_t chan; if (!cmd->argv[1]) return IZ_STOP_ERR; NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, cmd->argv[1]); if (!cmd->argv[2]) return IZ_STOP_ERR; pan_id = strtol(cmd->argv[2], &dummy, 16); if (*dummy) { printf("Bad PAN ID!\n"); return IZ_STOP_ERR; } NLA_PUT_U16(msg, IEEE802154_ATTR_COORD_PAN_ID, pan_id); if (!cmd->argv[3]) return IZ_STOP_ERR; short_addr = strtol(cmd->argv[3], &dummy, 16); if (*dummy) { printf("Bad short address!\n"); return IZ_STOP_ERR; } NLA_PUT_U16(msg, IEEE802154_ATTR_COORD_SHORT_ADDR, short_addr); if (!cmd->argv[4]) return IZ_STOP_ERR; chan = strtol(cmd->argv[4], &dummy, 10); if (*dummy) { printf("Bad channel number!\n"); return IZ_STOP_ERR; } NLA_PUT_U8(msg, IEEE802154_ATTR_CHANNEL, chan); /* set all unneeded attributes to 0*/ NLA_PUT_U8(msg, IEEE802154_ATTR_PAN_COORD, 0); NLA_PUT_U8(msg, IEEE802154_ATTR_BCN_ORD, 0); NLA_PUT_U8(msg, IEEE802154_ATTR_SF_ORD, 0); NLA_PUT_U8(msg, IEEE802154_ATTR_BAT_EXT, 0); NLA_PUT_U8(msg, IEEE802154_ATTR_COORD_REALIGN, 0); return IZ_CONT_OK; nla_put_failure: return IZ_STOP_ERR; }
int ieee802154_nl_disassoc_indic(struct net_device *dev, struct ieee802154_addr *addr, u8 reason) { struct sk_buff *msg; pr_debug("%s\n", __func__); msg = ieee802154_nl_create(0, IEEE802154_DISASSOCIATE_INDIC); if (!msg) return -ENOBUFS; NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name); NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex); NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN, dev->dev_addr); if (addr->addr_type == IEEE802154_ADDR_LONG) NLA_PUT(msg, IEEE802154_ATTR_SRC_HW_ADDR, IEEE802154_ADDR_LEN, addr->hwaddr); else NLA_PUT_U16(msg, IEEE802154_ATTR_SRC_SHORT_ADDR, addr->short_addr); NLA_PUT_U8(msg, IEEE802154_ATTR_REASON, reason); return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id); nla_put_failure: nlmsg_free(msg); return -ENOBUFS; }
static int register_mgmt_frame(struct nl80211_state *state, struct nl_msg *msg, int argc, char **argv, enum id_input id) { unsigned int type; unsigned char *match; size_t match_len; int ret; ret = sscanf(argv[0], "%x", &type); if (ret != 1) { printf("invalid frame type: %s\n", argv[0]); return 2; } match = parse_hex(argv[1], &match_len); if (!match) { printf("invalid frame pattern: %s\n", argv[1]); return 2; } NLA_PUT_U16(msg, NL80211_ATTR_FRAME_TYPE, type); NLA_PUT(msg, NL80211_ATTR_FRAME_MATCH, match_len, match); return 0; nla_put_failure: return -ENOBUFS; }
int ieee802154_nl_assoc_confirm(struct net_device *dev, u16 short_addr, u8 status) { struct sk_buff *msg; pr_debug("%s\n", __func__); msg = ieee802154_nl_create(0, IEEE802154_ASSOCIATE_CONF); if (!msg) return -ENOBUFS; NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name); NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex); NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN, dev->dev_addr); NLA_PUT_U16(msg, IEEE802154_ATTR_SHORT_ADDR, short_addr); NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status); return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id); nla_put_failure: nlmsg_free(msg); return -ENOBUFS; }
static int nfc_genl_send_target(struct sk_buff *msg, struct nfc_target *target, struct netlink_callback *cb, int flags) { void *hdr; hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, &nfc_genl_family, flags, NFC_CMD_GET_TARGET); if (!hdr) return -EMSGSIZE; genl_dump_check_consistent(cb, hdr, &nfc_genl_family); NLA_PUT_U32(msg, NFC_ATTR_TARGET_INDEX, target->idx); NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, target->supported_protocols); NLA_PUT_U16(msg, NFC_ATTR_TARGET_SENS_RES, target->sens_res); NLA_PUT_U8(msg, NFC_ATTR_TARGET_SEL_RES, target->sel_res); if (target->nfcid1_len > 0) NLA_PUT(msg, NFC_ATTR_TARGET_NFCID1, target->nfcid1_len, target->nfcid1); if (target->sensb_res_len > 0) NLA_PUT(msg, NFC_ATTR_TARGET_SENSB_RES, target->sensb_res_len, target->sensb_res); if (target->sensf_res_len > 0) NLA_PUT(msg, NFC_ATTR_TARGET_SENSF_RES, target->sensf_res_len, target->sensf_res); return genlmsg_end(msg, hdr); nla_put_failure: genlmsg_cancel(msg, hdr); return -EMSGSIZE; }
static int nfnl_exp_build_message(const struct nfnl_exp *exp, int cmd, int flags, struct nl_msg **result) { struct nl_msg *msg; int err; msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_CTNETLINK_EXP, cmd, flags, nfnl_exp_get_family(exp), 0); if (msg == NULL) return -NLE_NOMEM; if ((err = nfnl_exp_build_tuple(msg, exp, CTA_EXPECT_TUPLE)) < 0) goto err_out; if ((err = nfnl_exp_build_tuple(msg, exp, CTA_EXPECT_MASTER)) < 0) goto err_out; if ((err = nfnl_exp_build_tuple(msg, exp, CTA_EXPECT_MASK)) < 0) goto err_out; if (nfnl_exp_test_src(exp, NFNL_EXP_TUPLE_NAT)) { if ((err = nfnl_exp_build_nat(msg, exp)) < 0) goto err_out; } if (nfnl_exp_test_class(exp)) NLA_PUT_U32(msg, CTA_EXPECT_CLASS, htonl(nfnl_exp_get_class(exp))); if (nfnl_exp_test_fn(exp)) NLA_PUT_STRING(msg, CTA_EXPECT_FN, nfnl_exp_get_fn(exp)); if (nfnl_exp_test_id(exp)) NLA_PUT_U32(msg, CTA_EXPECT_ID, htonl(nfnl_exp_get_id(exp))); if (nfnl_exp_test_timeout(exp)) NLA_PUT_U32(msg, CTA_EXPECT_TIMEOUT, htonl(nfnl_exp_get_timeout(exp))); if (nfnl_exp_test_helper_name(exp)) NLA_PUT_STRING(msg, CTA_EXPECT_HELP_NAME, nfnl_exp_get_helper_name(exp)); if (nfnl_exp_test_zone(exp)) NLA_PUT_U16(msg, CTA_EXPECT_ZONE, htons(nfnl_exp_get_zone(exp))); if (nfnl_exp_test_flags(exp)) NLA_PUT_U32(msg, CTA_EXPECT_FLAGS, htonl(nfnl_exp_get_flags(exp))); *result = msg; return 0; nla_put_failure: err_out: nlmsg_free(msg); return err; }
static int ipvs_nl_fill_dest_attr(struct nl_msg *msg, ipvs_dest_t *dst) { struct nlattr *nl_dest; nl_dest = nla_nest_start(msg, IPVS_CMD_ATTR_DEST); if (!nl_dest) return -1; NLA_PUT_U16(msg, IPVS_DEST_ATTR_ADDR_FAMILY, dst->af); NLA_PUT(msg, IPVS_DEST_ATTR_ADDR, sizeof(dst->addr), &(dst->addr)); NLA_PUT_U16(msg, IPVS_DEST_ATTR_PORT, dst->port); NLA_PUT_U32(msg, IPVS_DEST_ATTR_FWD_METHOD, dst->conn_flags & IP_VS_CONN_F_FWD_MASK); NLA_PUT_U32(msg, IPVS_DEST_ATTR_WEIGHT, dst->weight); NLA_PUT_U32(msg, IPVS_DEST_ATTR_U_THRESH, dst->u_threshold); NLA_PUT_U32(msg, IPVS_DEST_ATTR_L_THRESH, dst->l_threshold); nla_nest_end(msg, nl_dest); return 0; nla_put_failure: return -1; }
static iz_res_t disassoc_request(struct iz_cmd *cmd, struct nl_msg *msg) { char *dummy; uint8_t reason; unsigned char hwa[IEEE802154_ADDR_LEN]; uint16_t short_addr; int ret; if (!cmd->argv[1]) return IZ_STOP_ERR; NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, cmd->argv[1]); if (!cmd->argv[2]) return IZ_STOP_ERR; if (cmd->argv[2][0] == 'H' || cmd->argv[2][0] == 'h') { ret = parse_hw_addr(cmd->argv[2]+1, hwa); if (ret) { printf("Bad destination address!\n"); return IZ_STOP_ERR; } NLA_PUT(msg, IEEE802154_ATTR_DEST_HW_ADDR, IEEE802154_ADDR_LEN, hwa); } else { short_addr = strtol(cmd->argv[2], &dummy, 16); if (*dummy) { printf("Bad destination address!\n"); return IZ_STOP_ERR; } NLA_PUT_U16(msg, IEEE802154_ATTR_DEST_SHORT_ADDR, short_addr); } if (!cmd->argv[3]) return IZ_STOP_ERR; reason = strtol(cmd->argv[3], &dummy, 16); if (*dummy) { printf("Bad disassociation reason!\n"); return IZ_STOP_ERR; } if (cmd->argv[4]) return IZ_STOP_ERR; NLA_PUT_U8(msg, IEEE802154_ATTR_REASON, reason); return IZ_CONT_OK; nla_put_failure: return IZ_STOP_ERR; }
int ieee802154_nl_beacon_indic(struct net_device *dev, u16 panid, u16 coord_addr) { struct sk_buff *msg; pr_debug("%s\n", __func__); msg = ieee802154_nl_create(0, IEEE802154_BEACON_NOTIFY_INDIC); if (!msg) return -ENOBUFS; NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name); NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex); NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN, dev->dev_addr); NLA_PUT_U16(msg, IEEE802154_ATTR_COORD_SHORT_ADDR, coord_addr); NLA_PUT_U16(msg, IEEE802154_ATTR_COORD_PAN_ID, panid); return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id); nla_put_failure: nlmsg_free(msg); return -ENOBUFS; }
static int nfnl_ct_build_message(const struct nfnl_ct *ct, int cmd, int flags, struct nl_msg **result) { struct nl_msg *msg; int err; msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_CTNETLINK, cmd, flags, nfnl_ct_get_family(ct), 0); if (msg == NULL) return -NLE_NOMEM; if ((err = nfnl_ct_build_tuple(msg, ct, 0)) < 0) goto err_out; /* REPLY tuple is optional, dont add unless at least src/dst specified */ if ( nfnl_ct_get_src(ct, 1) && nfnl_ct_get_dst(ct, 1) ) if ((err = nfnl_ct_build_tuple(msg, ct, 1)) < 0) goto err_out; if (nfnl_ct_test_status(ct)) NLA_PUT_U32(msg, CTA_STATUS, htonl(nfnl_ct_get_status(ct))); if (nfnl_ct_test_timeout(ct)) NLA_PUT_U32(msg, CTA_TIMEOUT, htonl(nfnl_ct_get_timeout(ct))); if (nfnl_ct_test_mark(ct)) NLA_PUT_U32(msg, CTA_MARK, htonl(nfnl_ct_get_mark(ct))); if (nfnl_ct_test_id(ct)) NLA_PUT_U32(msg, CTA_ID, htonl(nfnl_ct_get_id(ct))); if (nfnl_ct_test_zone(ct)) NLA_PUT_U16(msg, CTA_ZONE, htons(nfnl_ct_get_zone(ct))); *result = msg; return 0; nla_put_failure: err_out: nlmsg_free(msg); return err; }
static int handle_interface_noack_map(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, enum id_input id) { uint16_t noack_map; char *end; if (argc != 1) return 1; noack_map = strtoul(argv[0], &end, 16); if (*end) return 1; NLA_PUT_U16(msg, NL80211_ATTR_NOACK_MAP, noack_map); return 0; nla_put_failure: return -ENOBUFS; }
static int nfnl_ct_build_tuple(struct nl_msg *msg, const struct nfnl_ct *ct, int repl) { struct nlattr *tuple, *ip, *proto; struct nl_addr *addr; int family; family = nfnl_ct_get_family(ct); tuple = nla_nest_start(msg, repl ? CTA_TUPLE_REPLY : CTA_TUPLE_ORIG); if (!tuple) goto nla_put_failure; ip = nla_nest_start(msg, CTA_TUPLE_IP); if (!ip) goto nla_put_failure; addr = nfnl_ct_get_src(ct, repl); if (addr) NLA_PUT_ADDR(msg, family == AF_INET ? CTA_IP_V4_SRC : CTA_IP_V6_SRC, addr); addr = nfnl_ct_get_dst(ct, repl); if (addr) NLA_PUT_ADDR(msg, family == AF_INET ? CTA_IP_V4_DST : CTA_IP_V6_DST, addr); nla_nest_end(msg, ip); proto = nla_nest_start(msg, CTA_TUPLE_PROTO); if (!proto) goto nla_put_failure; if (nfnl_ct_test_proto(ct)) NLA_PUT_U8(msg, CTA_PROTO_NUM, nfnl_ct_get_proto(ct)); if (nfnl_ct_test_src_port(ct, repl)) NLA_PUT_U16(msg, CTA_PROTO_SRC_PORT, htons(nfnl_ct_get_src_port(ct, repl))); if (nfnl_ct_test_dst_port(ct, repl)) NLA_PUT_U16(msg, CTA_PROTO_DST_PORT, htons(nfnl_ct_get_dst_port(ct, repl))); if (family == AF_INET) { if (nfnl_ct_test_icmp_id(ct, repl)) NLA_PUT_U16(msg, CTA_PROTO_ICMP_ID, htons(nfnl_ct_get_icmp_id(ct, repl))); if (nfnl_ct_test_icmp_type(ct, repl)) NLA_PUT_U8(msg, CTA_PROTO_ICMP_TYPE, nfnl_ct_get_icmp_type(ct, repl)); if (nfnl_ct_test_icmp_code(ct, repl)) NLA_PUT_U8(msg, CTA_PROTO_ICMP_CODE, nfnl_ct_get_icmp_code(ct, repl)); } else if (family == AF_INET6) { if (nfnl_ct_test_icmp_id(ct, repl)) NLA_PUT_U16(msg, CTA_PROTO_ICMPV6_ID, htons(nfnl_ct_get_icmp_id(ct, repl))); if (nfnl_ct_test_icmp_type(ct, repl)) NLA_PUT_U8(msg, CTA_PROTO_ICMPV6_TYPE, nfnl_ct_get_icmp_type(ct, repl)); if (nfnl_ct_test_icmp_code(ct, repl)) NLA_PUT_U8(msg, CTA_PROTO_ICMPV6_CODE, nfnl_ct_get_icmp_code(ct, repl)); } nla_nest_end(msg, proto); nla_nest_end(msg, tuple); return 0; nla_put_failure: return -NLE_MSGSIZE; }
static int nfnl_exp_build_tuple(struct nl_msg *msg, const struct nfnl_exp *exp, int cta) { struct nlattr *tuple, *ip, *proto; struct nl_addr *addr; int family; family = nfnl_exp_get_family(exp); int type = exp_get_tuple_attr(cta); if (cta == CTA_EXPECT_NAT) tuple = nla_nest_start(msg, CTA_EXPECT_NAT_TUPLE); else tuple = nla_nest_start(msg, cta); if (!tuple) goto nla_put_failure; ip = nla_nest_start(msg, CTA_TUPLE_IP); if (!ip) goto nla_put_failure; addr = nfnl_exp_get_src(exp, type); if (addr) NLA_PUT_ADDR(msg, family == AF_INET ? CTA_IP_V4_SRC : CTA_IP_V6_SRC, addr); addr = nfnl_exp_get_dst(exp, type); if (addr) NLA_PUT_ADDR(msg, family == AF_INET ? CTA_IP_V4_DST : CTA_IP_V6_DST, addr); nla_nest_end(msg, ip); proto = nla_nest_start(msg, CTA_TUPLE_PROTO); if (!proto) goto nla_put_failure; if (nfnl_exp_test_l4protonum(exp, type)) NLA_PUT_U8(msg, CTA_PROTO_NUM, nfnl_exp_get_l4protonum(exp, type)); if (nfnl_exp_test_ports(exp, type)) { NLA_PUT_U16(msg, CTA_PROTO_SRC_PORT, htons(nfnl_exp_get_src_port(exp, type))); NLA_PUT_U16(msg, CTA_PROTO_DST_PORT, htons(nfnl_exp_get_dst_port(exp, type))); } if (nfnl_exp_test_icmp(exp, type)) { NLA_PUT_U16(msg, CTA_PROTO_ICMP_ID, htons(nfnl_exp_get_icmp_id(exp, type))); NLA_PUT_U8(msg, CTA_PROTO_ICMP_TYPE, nfnl_exp_get_icmp_type(exp, type)); NLA_PUT_U8(msg, CTA_PROTO_ICMP_CODE, nfnl_exp_get_icmp_code(exp, type)); } nla_nest_end(msg, proto); nla_nest_end(msg, tuple); return 0; nla_put_failure: return -NLE_MSGSIZE; }
static int wowlan_parse_tcp_file(struct nl_msg *msg, const char *fn) { char buf[16768]; int err = 1; FILE *f = fopen(fn, "r"); struct nlattr *tcp; if (!f) return 1; tcp = nla_nest_start(msg, NL80211_WOWLAN_TRIG_TCP_CONNECTION); if (!tcp) goto nla_put_failure; while (!feof(f)) { char *eol; if (!fgets(buf, sizeof(buf), f)) break; eol = strchr(buf + 5, '\r'); if (eol) *eol = 0; eol = strchr(buf + 5, '\n'); if (eol) *eol = 0; if (strncmp(buf, "source=", 7) == 0) { struct in_addr in_addr; char *addr = buf + 7; char *port = strchr(buf + 7, ':'); if (port) { *port = 0; port++; } if (inet_aton(addr, &in_addr) == 0) goto close; NLA_PUT_U32(msg, NL80211_WOWLAN_TCP_SRC_IPV4, in_addr.s_addr); if (port) NLA_PUT_U16(msg, NL80211_WOWLAN_TCP_SRC_PORT, atoi(port)); } else if (strncmp(buf, "dest=", 5) == 0) { struct in_addr in_addr; char *addr = buf + 5; char *port = strchr(buf + 5, ':'); char *mac; unsigned char macbuf[6]; if (!port) goto close; *port = 0; port++; mac = strchr(port, '@'); if (!mac) goto close; *mac = 0; mac++; if (inet_aton(addr, &in_addr) == 0) goto close; NLA_PUT_U32(msg, NL80211_WOWLAN_TCP_DST_IPV4, in_addr.s_addr); NLA_PUT_U16(msg, NL80211_WOWLAN_TCP_DST_PORT, atoi(port)); if (mac_addr_a2n(macbuf, mac)) goto close; NLA_PUT(msg, NL80211_WOWLAN_TCP_DST_MAC, 6, macbuf); } else if (strncmp(buf, "data=", 5) == 0) { size_t len; unsigned char *pkt = parse_hex(buf + 5, &len); if (!pkt) goto close; NLA_PUT(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD, len, pkt); free(pkt); } else if (strncmp(buf, "data.interval=", 14) == 0) { NLA_PUT_U32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL, atoi(buf + 14)); } else if (strncmp(buf, "wake=", 5) == 0) { unsigned char *pat, *mask; size_t patlen; if (parse_hex_mask(buf + 5, &pat, &patlen, &mask)) goto close; NLA_PUT(msg, NL80211_WOWLAN_TCP_WAKE_MASK, DIV_ROUND_UP(patlen, 8), mask); NLA_PUT(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD, patlen, pat); free(mask); free(pat); } else if (strncmp(buf, "data.seq=", 9) == 0) { struct nl80211_wowlan_tcp_data_seq seq = {}; char *len, *offs, *start; len = buf + 9; offs = strchr(len, ','); if (!offs) goto close; *offs = 0; offs++; start = strchr(offs, ','); if (start) { *start = 0; start++; seq.start = atoi(start); } seq.len = atoi(len); seq.offset = atoi(offs); NLA_PUT(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ, sizeof(seq), &seq); } else if (strncmp(buf, "data.tok=", 9) == 0) { struct nl80211_wowlan_tcp_data_token *tok; size_t stream_len; char *len, *offs, *toks; unsigned char *stream; len = buf + 9; offs = strchr(len, ','); if (!offs) goto close; *offs = 0; offs++; toks = strchr(offs, ','); if (!toks) goto close; *toks = 0; toks++; stream = parse_hex(toks, &stream_len); if (!stream) goto close; tok = malloc(sizeof(*tok) + stream_len); if (!tok) { free(stream); err = -ENOMEM; goto close; } tok->len = atoi(len); tok->offset = atoi(offs); memcpy(tok->token_stream, stream, stream_len); NLA_PUT(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN, sizeof(*tok) + stream_len, tok); free(stream); free(tok); } else { if (buf[0] == '#') continue; goto close; } } err = 0; goto close; nla_put_failure: err = -ENOBUFS; close: fclose(f); nla_nest_end(msg, tcp); return err; }
static int vlan_put_attrs(struct nl_msg *msg, struct rtnl_link *link) { struct vlan_info *vi = link->l_info; struct nlattr *data; if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) return -NLE_MSGSIZE; if (vi->vi_mask & VLAN_HAS_ID) NLA_PUT_U16(msg, IFLA_VLAN_ID, vi->vi_vlan_id); if (vi->vi_mask & VLAN_HAS_FLAGS) { struct ifla_vlan_flags flags = { .flags = vi->vi_flags, .mask = vi->vi_flags_mask, }; NLA_PUT(msg, IFLA_VLAN_FLAGS, sizeof(flags), &flags); } if (vi->vi_mask & VLAN_HAS_INGRESS_QOS) { struct ifla_vlan_qos_mapping map; struct nlattr *qos; int i; if (!(qos = nla_nest_start(msg, IFLA_VLAN_INGRESS_QOS))) goto nla_put_failure; for (i = 0; i <= VLAN_PRIO_MAX; i++) { if (vi->vi_ingress_qos[i]) { map.from = i; map.to = vi->vi_ingress_qos[i]; NLA_PUT(msg, i, sizeof(map), &map); } } nla_nest_end(msg, qos); } if (vi->vi_mask & VLAN_HAS_EGRESS_QOS) { struct ifla_vlan_qos_mapping map; struct nlattr *qos; int i; if (!(qos = nla_nest_start(msg, IFLA_VLAN_EGRESS_QOS))) goto nla_put_failure; for (i = 0; i < vi->vi_negress; i++) { map.from = vi->vi_egress_qos[i].vm_from; map.to = vi->vi_egress_qos[i].vm_to; NLA_PUT(msg, i, sizeof(map), &map); } nla_nest_end(msg, qos); } nla_nest_end(msg, data); nla_put_failure: return 0; } static struct rtnl_link_info_ops vlan_info_ops = { .io_name = "vlan", .io_alloc = vlan_alloc, .io_parse = vlan_parse, .io_dump = { [NL_DUMP_LINE] = vlan_dump_line, [NL_DUMP_DETAILS] = vlan_dump_details, }, .io_clone = vlan_clone,
struct ip_vs_get_dests *ipvs_get_dests(ipvs_service_entry_t *svc) { struct ip_vs_get_dests *d; struct ip_vs_get_dests_kern *dk; socklen_t len; int i; len = sizeof(*d) + sizeof(ipvs_dest_entry_t) * svc->num_dests; if (!(d = malloc(len))) return NULL; ipvs_func = ipvs_get_dests; #ifdef LIBIPVS_USE_NL if (try_nl) { struct nl_msg *msg; struct nlattr *nl_service; if (svc->num_dests == 0) d = realloc(d,sizeof(*d) + sizeof(ipvs_dest_entry_t)); d->fwmark = svc->fwmark; d->protocol = svc->protocol; d->addr = svc->addr; d->port = svc->port; d->num_dests = svc->num_dests; d->af = svc->af; msg = ipvs_nl_message(IPVS_CMD_GET_DEST, NLM_F_DUMP); if (!msg) goto ipvs_nl_dest_failure; nl_service = nla_nest_start(msg, IPVS_CMD_ATTR_SERVICE); if (!nl_service) goto nla_put_failure; NLA_PUT_U16(msg, IPVS_SVC_ATTR_AF, svc->af); if (svc->fwmark) { NLA_PUT_U32(msg, IPVS_SVC_ATTR_FWMARK, svc->fwmark); } else { NLA_PUT_U16(msg, IPVS_SVC_ATTR_PROTOCOL, svc->protocol); NLA_PUT(msg, IPVS_SVC_ATTR_ADDR, sizeof(svc->addr), &svc->addr); NLA_PUT_U16(msg, IPVS_SVC_ATTR_PORT, svc->port); } nla_nest_end(msg, nl_service); if (ipvs_nl_send_message(msg, ipvs_dests_parse_cb, &d)) goto ipvs_nl_dest_failure; return d; nla_put_failure: nlmsg_free(msg); ipvs_nl_dest_failure: free(d); return NULL; } #endif if (svc->af != AF_INET) { errno = EAFNOSUPPORT; free(d); return NULL; } len = sizeof(*dk) + sizeof(struct ip_vs_dest_entry_kern) * svc->num_dests; if (!(dk = malloc(len))) { free(d); return NULL; } dk->fwmark = svc->fwmark; dk->protocol = svc->protocol; dk->addr = svc->addr.ip; dk->port = svc->port; dk->num_dests = svc->num_dests; if (getsockopt(sockfd, IPPROTO_IP, IP_VS_SO_GET_DESTS, dk, &len) < 0) { free(d); free(dk); return NULL; } memcpy(d, dk, sizeof(struct ip_vs_get_dests_kern)); d->af = AF_INET; d->addr.ip = d->__addr_v4; for (i = 0; i < dk->num_dests; i++) { memcpy(&d->entrytable[i], &dk->entrytable[i], sizeof(struct ip_vs_dest_entry_kern)); d->entrytable[i].af = AF_INET; d->entrytable[i].addr.ip = d->entrytable[i].__addr_v4; } free(dk); return d; }
static iz_res_t assoc_request(struct iz_cmd *cmd, struct nl_msg *msg) { char *dummy; uint16_t pan_id, coord_short_addr; uint8_t chan; unsigned char hwa[IEEE802154_ADDR_LEN]; int ret; uint8_t cap = 0 | (1 << 1) /* FFD */ | (1 << 3) /* Receiver ON */ /*| (1 << 7) */ /* allocate short */ ; if (!cmd->argv[1]) return IZ_STOP_ERR; NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, cmd->argv[1]); if (!cmd->argv[2]) return IZ_STOP_ERR; pan_id = strtol(cmd->argv[2], &dummy, 16); if (*dummy) { printf("Bad PAN ID!\n"); return IZ_STOP_ERR; } if (!cmd->argv[3]) return IZ_STOP_ERR; if (cmd->argv[3][0] == 'H' || cmd->argv[3][0] == 'h') { ret = parse_hw_addr(cmd->argv[3]+1, hwa); if (ret) { printf("Bad coordinator address!\n"); return IZ_STOP_ERR; } NLA_PUT(msg, IEEE802154_ATTR_COORD_HW_ADDR, IEEE802154_ADDR_LEN, hwa); } else { coord_short_addr = strtol(cmd->argv[3], &dummy, 16); if (*dummy) { printf("Bad coordinator address!\n"); return IZ_STOP_ERR; } NLA_PUT_U16(msg, IEEE802154_ATTR_COORD_SHORT_ADDR, coord_short_addr); } if (!cmd->argv[4]) return IZ_STOP_ERR; chan = strtol(cmd->argv[4], &dummy, 10); if (*dummy) { printf("Bad channel number!\n"); return IZ_STOP_ERR; } if (cmd->argv[5]) { if (strcmp(cmd->argv[5], "short") || cmd->argv[6]) return IZ_STOP_ERR; else cap |= 1 << 7; /* Request short addr */ } NLA_PUT_U8(msg, IEEE802154_ATTR_CHANNEL, chan); NLA_PUT_U16(msg, IEEE802154_ATTR_COORD_PAN_ID, pan_id); NLA_PUT_U8(msg, IEEE802154_ATTR_CAPABILITY, cap); return IZ_CONT_OK; nla_put_failure: return IZ_STOP_ERR; }
static int vlan_put_attrs(struct nl_msg *msg, struct rtnl_link *link) { struct vlan_info *vi = link->l_info; struct nlattr *data; if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) return nl_errno(ENOBUFS); if (vi->vi_mask & VLAN_HAS_ID) NLA_PUT_U16(msg, IFLA_VLAN_ID, vi->vi_vlan_id); if (vi->vi_mask & VLAN_HAS_FLAGS) { struct ifla_vlan_flags flags = { .flags = vi->vi_flags, .mask = vi->vi_flags_mask, }; NLA_PUT(msg, IFLA_VLAN_FLAGS, sizeof(flags), &flags); } if (vi->vi_mask & VLAN_HAS_INGRESS_QOS) { struct ifla_vlan_qos_mapping map; struct nlattr *qos; int i; if (!(qos = nla_nest_start(msg, IFLA_VLAN_INGRESS_QOS))) goto nla_put_failure; for (i = 0; i <= VLAN_PRIO_MAX; i++) { if (vi->vi_ingress_qos[i]) { map.from = i; map.to = vi->vi_ingress_qos[i]; NLA_PUT(msg, i, sizeof(map), &map); } } nla_nest_end(msg, qos); } if (vi->vi_mask & VLAN_HAS_EGRESS_QOS) { struct ifla_vlan_qos_mapping map; struct nlattr *qos; int i; if (!(qos = nla_nest_start(msg, IFLA_VLAN_EGRESS_QOS))) goto nla_put_failure; for (i = 0; i < vi->vi_negress; i++) { map.from = vi->vi_egress_qos[i].vm_from; map.to = vi->vi_egress_qos[i].vm_to; NLA_PUT(msg, i, sizeof(map), &map); } nla_nest_end(msg, qos); } nla_nest_end(msg, data); nla_put_failure: return 0; } static struct rtnl_link_info_ops vlan_info_ops = { .io_name = "vlan", .io_alloc = vlan_alloc, .io_parse = vlan_parse, .io_dump[NL_DUMP_BRIEF] = vlan_dump_brief, .io_dump[NL_DUMP_FULL] = vlan_dump_full, .io_clone = vlan_clone, .io_put_attrs = vlan_put_attrs, .io_free = vlan_free, }; int rtnl_link_vlan_set_id(struct rtnl_link *link, int id) { struct vlan_info *vi = link->l_info; if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops) return nl_error(EOPNOTSUPP, "Not a VLAN link"); vi->vi_vlan_id = id; vi->vi_mask |= VLAN_HAS_ID; return 0; } int rtnl_link_vlan_get_id(struct rtnl_link *link) { struct vlan_info *vi = link->l_info; if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops) return nl_error(EOPNOTSUPP, "Not a VLAN link"); if (vi->vi_mask & VLAN_HAS_ID) return vi->vi_vlan_id; else return 0; } int rtnl_link_vlan_set_flags(struct rtnl_link *link, unsigned int flags) { struct vlan_info *vi = link->l_info; if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops) return nl_error(EOPNOTSUPP, "Not a VLAN link"); vi->vi_flags_mask |= flags; vi->vi_flags |= flags; vi->vi_mask |= VLAN_HAS_FLAGS; return 0; } int rtnl_link_vlan_unset_flags(struct rtnl_link *link, unsigned int flags) { struct vlan_info *vi = link->l_info; if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops) return nl_error(EOPNOTSUPP, "Not a VLAN link"); vi->vi_flags_mask |= flags; vi->vi_flags &= ~flags; vi->vi_mask |= VLAN_HAS_FLAGS; return 0; } unsigned int rtnl_link_vlan_get_flags(struct rtnl_link *link) { struct vlan_info *vi = link->l_info; if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops) return nl_error(EOPNOTSUPP, "Not a VLAN link"); return vi->vi_flags; } int rtnl_link_vlan_set_ingress_map(struct rtnl_link *link, int from, uint32_t to) { struct vlan_info *vi = link->l_info; if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops) return nl_error(EOPNOTSUPP, "Not a VLAN link"); if (from < 0 || from > VLAN_PRIO_MAX) return nl_error(EINVAL, "Invalid vlan prio 0..%d", VLAN_PRIO_MAX); vi->vi_ingress_qos[from] = to; vi->vi_mask |= VLAN_HAS_INGRESS_QOS; return 0; } uint32_t *rtnl_link_vlan_get_ingress_map(struct rtnl_link *link) { struct vlan_info *vi = link->l_info; if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops) { nl_error(EOPNOTSUPP, "Not a VLAN link"); return NULL; } if (vi->vi_mask & VLAN_HAS_INGRESS_QOS) return vi->vi_ingress_qos; else return NULL; } int rtnl_link_vlan_set_egress_map(struct rtnl_link *link, uint32_t from, int to) { struct vlan_info *vi = link->l_info; if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops) return nl_error(EOPNOTSUPP, "Not a VLAN link"); if (to < 0 || to > VLAN_PRIO_MAX) return nl_error(EINVAL, "Invalid vlan prio 0..%d", VLAN_PRIO_MAX); if (vi->vi_negress >= vi->vi_egress_size) { int new_size = vi->vi_egress_size + 32; void *ptr; ptr = realloc(vi->vi_egress_qos, new_size); if (!ptr) return nl_errno(ENOMEM); vi->vi_egress_qos = ptr; vi->vi_egress_size = new_size; } vi->vi_egress_qos[vi->vi_negress].vm_from = from; vi->vi_egress_qos[vi->vi_negress].vm_to = to; vi->vi_negress++; vi->vi_mask |= VLAN_HAS_EGRESS_QOS; return 0; } struct vlan_map *rtnl_link_vlan_get_egress_map(struct rtnl_link *link, int *negress) { struct vlan_info *vi = link->l_info; if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops) { nl_error(EOPNOTSUPP, "Not a VLAN link"); return NULL; } if (negress == NULL) { nl_error(EINVAL, "Require pointer to store negress"); return NULL; } if (vi->vi_mask & VLAN_HAS_EGRESS_QOS) { *negress = vi->vi_negress; return vi->vi_egress_qos; } else { *negress = 0; return NULL; } } static void __init vlan_init(void) { rtnl_link_register_info(&vlan_info_ops); } static void __exit vlan_exit(void) { rtnl_link_unregister_info(&vlan_info_ops); }
int mtk_cfg80211_testmode_get_sta_statistics(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) #define NLA_PUT(skb, attrtype, attrlen, data) \ do { \ if (unlikely(nla_put(skb, attrtype, attrlen, data) < 0)) \ printk("NLA PUT Error!!!!\n"); \ } while (0) #define NLA_PUT_TYPE(skb, type, attrtype, value) \ do { \ type __tmp = value; \ NLA_PUT(skb, attrtype, sizeof(type), &__tmp); \ } while (0) #define NLA_PUT_U8(skb, attrtype, value) \ NLA_PUT_TYPE(skb, u8, attrtype, value) #define NLA_PUT_U16(skb, attrtype, value) \ NLA_PUT_TYPE(skb, u16, attrtype, value) #define NLA_PUT_U32(skb, attrtype, value) \ NLA_PUT_TYPE(skb, u32, attrtype, value) #endif WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; INT_32 i4Status = -EINVAL; UINT_32 u4BufLen; UINT_32 u4LinkScore; UINT_32 u4TotalError; UINT_32 u4TxExceedThresholdCount; UINT_32 u4TxTotalCount; P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS prParams = NULL; PARAM_GET_STA_STA_STATISTICS rQueryStaStatistics; struct sk_buff *skb; ASSERT(wiphy); ASSERT(prGlueInfo); if (data && len) { prParams = (P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS) data; } if (!prParams->aucMacAddr) { DBGLOG(QM, TRACE, ("%s MAC Address is NULL\n", __func__)); i4Status = -EINVAL; goto nla_put_failure; } skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(PARAM_GET_STA_STA_STATISTICS) + 1); if (!skb) { DBGLOG(QM, TRACE, ("%s allocate skb failed:\n", __func__)); i4Status = -ENOMEM; goto nla_put_failure; } DBGLOG(QM, TRACE, ("Get [" MACSTR "] STA statistics\n", MAC2STR(prParams->aucMacAddr))); kalMemZero(&rQueryStaStatistics, sizeof(rQueryStaStatistics)); COPY_MAC_ADDR(rQueryStaStatistics.aucMacAddr, prParams->aucMacAddr); rStatus = kalIoctl(prGlueInfo, wlanoidQueryStaStatistics, &rQueryStaStatistics, sizeof(rQueryStaStatistics), TRUE, FALSE, TRUE, TRUE, &u4BufLen); /* Calcute Link Score */ u4TxExceedThresholdCount = rQueryStaStatistics.u4TxExceedThresholdCount; u4TxTotalCount = rQueryStaStatistics.u4TxTotalCount; u4TotalError = rQueryStaStatistics.u4TxFailCount + rQueryStaStatistics.u4TxLifeTimeoutCount; /* u4LinkScore 10~100 , ExceedThreshold ratio 0~90 only */ /* u4LinkScore 0~9 , Drop packet ratio 0~9 and all packets exceed threshold */ if (u4TxTotalCount) { if (u4TxExceedThresholdCount <= u4TxTotalCount) { u4LinkScore = (90 - ((u4TxExceedThresholdCount * 90) / u4TxTotalCount)); } else { u4LinkScore = 0; } } else { u4LinkScore = 90; } u4LinkScore += 10; if (u4LinkScore == 10) { if (u4TotalError <= u4TxTotalCount) { u4LinkScore = (10 - ((u4TotalError * 10) / u4TxTotalCount)); } else { u4LinkScore = 0; } } if (u4LinkScore > 100) { u4LinkScore = 100; } NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, 0); NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_VERSION, NL80211_DRIVER_TESTMODE_VERSION); NLA_PUT(skb, NL80211_TESTMODE_STA_STATISTICS_MAC, MAC_ADDR_LEN, prParams->aucMacAddr); NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_LINK_SCORE, u4LinkScore); NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_FLAG, rQueryStaStatistics.u4Flag); /* FW part STA link status */ NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_PER, rQueryStaStatistics.ucPer); NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_RSSI, rQueryStaStatistics.ucRcpi); NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_PHY_MODE, rQueryStaStatistics.u4PhyMode); NLA_PUT_U16(skb, NL80211_TESTMODE_STA_STATISTICS_TX_RATE, rQueryStaStatistics.u2LinkSpeed); NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_FAIL_CNT, rQueryStaStatistics.u4TxFailCount); NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_TIMEOUT_CNT, rQueryStaStatistics.u4TxLifeTimeoutCount); NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_AIR_TIME, rQueryStaStatistics.u4TxAverageAirTime); /* Driver part link status */ NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_TOTAL_CNT, rQueryStaStatistics.u4TxTotalCount); NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_THRESHOLD_CNT, rQueryStaStatistics.u4TxExceedThresholdCount); NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_PROCESS_TIME, rQueryStaStatistics.u4TxAverageProcessTime); /* Network counter */ NLA_PUT(skb, NL80211_TESTMODE_STA_STATISTICS_TC_EMPTY_CNT_ARRAY, sizeof(rQueryStaStatistics.au4TcResourceEmptyCount), rQueryStaStatistics.au4TcResourceEmptyCount); /* Sta queue length */ NLA_PUT(skb, NL80211_TESTMODE_STA_STATISTICS_TC_QUE_LEN_ARRAY, sizeof(rQueryStaStatistics.au4TcQueLen), rQueryStaStatistics.au4TcQueLen); /* Global QM counter */ NLA_PUT(skb, NL80211_TESTMODE_STA_STATISTICS_TC_AVG_QUE_LEN_ARRAY, sizeof(rQueryStaStatistics.au4TcAverageQueLen), rQueryStaStatistics.au4TcAverageQueLen); NLA_PUT(skb, NL80211_TESTMODE_STA_STATISTICS_TC_CUR_QUE_LEN_ARRAY, sizeof(rQueryStaStatistics.au4TcCurrentQueLen), rQueryStaStatistics.au4TcCurrentQueLen); /* Reserved field */ NLA_PUT(skb, NL80211_TESTMODE_STA_STATISTICS_RESERVED_ARRAY, sizeof(rQueryStaStatistics.au4Reserved), rQueryStaStatistics.au4Reserved); i4Status = cfg80211_testmode_reply(skb); nla_put_failure: return i4Status; }