static int gwi_sta_cb(struct nl_msg *msg, void *vud) { WirelessInfo *info = vud; struct nlattr *tb[NL80211_ATTR_MAX + 1]; struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1]; struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1]; struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = { [NL80211_STA_INFO_RX_BITRATE] = {.type = NLA_NESTED},
int genlmsg_parse(struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], int maxtype, struct nla_policy *policy) { struct genlmsghdr *ghdr; if (!genlmsg_valid_hdr(nlh, hdrlen)) return nl_errno(EINVAL); ghdr = nlmsg_data(nlh); return nla_parse(tb, maxtype, genlmsg_attrdata(ghdr, hdrlen), genlmsg_attrlen(ghdr, hdrlen), policy); }
static int result_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nlmsghdr *n, struct nl_parser_param *pp) { struct flnl_result *res; struct fib_result_nl *fr; struct nl_addr *addr; int err = -EINVAL; res = flnl_result_alloc(); if (!res) goto errout; res->ce_msgtype = n->nlmsg_type; res->fr_req = flnl_request_alloc(); if (!res->fr_req) goto errout; fr = nlmsg_data(n); addr = nl_addr_build(AF_INET, &fr->fl_addr, 4); if (!addr) goto errout; err = flnl_request_set_addr(res->fr_req, addr); nl_addr_put(addr); if (err < 0) goto errout; flnl_request_set_fwmark(res->fr_req, fr->fl_fwmark); flnl_request_set_tos(res->fr_req, fr->fl_tos); flnl_request_set_scope(res->fr_req, fr->fl_scope); flnl_request_set_table(res->fr_req, fr->tb_id_in); res->fr_table_id = fr->tb_id; res->fr_prefixlen = fr->prefixlen; res->fr_nh_sel = fr->nh_sel; res->fr_type = fr->type; res->fr_scope = fr->scope; res->fr_error = fr->err; err = pp->pp_cb((struct nl_object *) res, pp); if (err < 0) goto errout; /* REAL HACK, fib_lookup doesn't support ACK nor does it * send a DONE message, enforce end of message stream * after just the first message */ err = NL_STOP; errout: flnl_result_put(res); return err; }
void lowpansocket::getAddress(struct ieee802154_addr *ret, const vinterface &iface) { #if defined HAVE_LIBNL || HAVE_LIBNL3 #ifdef HAVE_LIBNL3 struct nl_sock *nl = nl_socket_alloc(); #else struct nl_handle *nl = nl_handle_alloc(); #endif unsigned char *buf = NULL; struct sockaddr_nl nla; struct nlattr *attrs[IEEE802154_ATTR_MAX+1]; struct genlmsghdr *ghdr; struct nlmsghdr *nlh; struct nl_msg *msg; int family; if (!nl) return; genl_connect(nl); /* Build and send message */ msg = nlmsg_alloc(); family = genl_ctrl_resolve(nl, "802.15.4 MAC"); genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_ECHO, IEEE802154_LIST_IFACE, 1); nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, iface.toString().c_str()); nl_send_auto_complete(nl, msg); nlmsg_free(msg); /* Receive and parse answer */ nl_recv(nl, &nla, &buf, NULL); nlh = (struct nlmsghdr*)buf; genlmsg_parse(nlh, 0, attrs, IEEE802154_ATTR_MAX, ieee802154_policy); ghdr = (genlmsghdr*)nlmsg_data(nlh); if (!attrs[IEEE802154_ATTR_SHORT_ADDR] || !attrs[IEEE802154_ATTR_SHORT_ADDR]) return; // We only handle short addresses right now ret->addr_type = IEEE802154_ADDR_SHORT; ret->pan_id = nla_get_u16(attrs[IEEE802154_ATTR_PAN_ID]); ret->short_addr = nla_get_u16(attrs[IEEE802154_ATTR_SHORT_ADDR]); free(buf); nl_close(nl); #ifdef HAVE_LIBNL3 nl_socket_free(nl); #else nl_handle_destroy(nl); #endif #endif }
static void quota2_log(unsigned int hooknum, const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const char *prefix) { ulog_packet_msg_t *pm; struct sk_buff *log_skb; size_t size; struct nlmsghdr *nlh; if (!qlog_nl_event) return; size = NLMSG_SPACE(sizeof(*pm)); size = max(size, (size_t)NLMSG_GOODSIZE); log_skb = alloc_skb(size, GFP_ATOMIC); if (!log_skb) { pr_err("xt_quota2: cannot alloc skb for logging\n"); return; } nlh = nlmsg_put(log_skb, /*pid*/0, /*seq*/0, qlog_nl_event, sizeof(*pm), 0); if (!nlh) { pr_err("xt_quota2: nlmsg_put failed\n"); kfree_skb(log_skb); return; } pm = nlmsg_data(nlh); if (skb->tstamp.tv64 == 0) __net_timestamp((struct sk_buff *)skb); pm->data_len = 0; pm->hook = hooknum; if (prefix != NULL) strlcpy(pm->prefix, prefix, sizeof(pm->prefix)); else *(pm->prefix) = '\0'; if (in) strlcpy(pm->indev_name, in->name, sizeof(pm->indev_name)); else pm->indev_name[0] = '\0'; if (out) strlcpy(pm->outdev_name, out->name, sizeof(pm->outdev_name)); else pm->outdev_name[0] = '\0'; NETLINK_CB(log_skb).dst_group = 1; pr_debug("throwing 1 packets to netlink group 1\n"); netlink_broadcast(nflognl, log_skb, 0, 1, GFP_ATOMIC); }
//scan netlink messages are nested (and may even be multipart) (see nl80211.c line 2591: nl80211_send_bss) int CNL80211::parseNlScanResult(nl_msg * msg) { struct nlattr * attr_buffer[NL80211_ATTR_MAX + 1]; struct nlmsghdr * msg_hdr = nlmsg_hdr(msg); struct genlmsghdr * msg_header = (struct genlmsghdr *) nlmsg_data(msg_hdr); struct nlattr * bss_buffer[NL80211_BSS_MAX + 1]; //bss = basic service set ScanResult scanresult; //This is the struct to check the validity of the attributes. See enum nl80211_bss struct nla_policy bss_policy[NL80211_BSS_MAX + 1]; bss_policy[NL80211_BSS_TSF].type = NLA_U64; bss_policy[NL80211_BSS_FREQUENCY].type = NLA_U32; bss_policy[NL80211_BSS_BEACON_INTERVAL].type = NLA_U16; bss_policy[NL80211_BSS_SIGNAL_MBM].type = NLA_U32; bss_policy[NL80211_BSS_SIGNAL_UNSPEC].type = NLA_U8; if (msg_hdr->nlmsg_flags & NLM_F_MULTI) qDebug() << "netlink: Mutlipart message"; //Parse the complete message nla_parse(attr_buffer, NL80211_ATTR_MAX, genlmsg_attrdata(msg_header, 0), genlmsg_attrlen(msg_header, 0), NULL); if (!attr_buffer[NL80211_ATTR_BSS]) { //Check if BSS return NL_SKIP; } //Parse the nested attributes. this is where the scan results are if (nla_parse_nested(bss_buffer, NL80211_BSS_MAX, attr_buffer[NL80211_ATTR_BSS], bss_policy)) { return NL_SKIP; } if (!bss_buffer[NL80211_BSS_BSSID]) return NL_SKIP; scanresult.bssid = libnutcommon::MacAddress((ether_addr*)(bss_buffer[NL80211_BSS_BSSID])); scanresult.signal.bssid = scanresult.bssid; if (bss_buffer[NL80211_BSS_FREQUENCY]) scanresult.freq = nla_get_u32(bss_buffer[NL80211_BSS_FREQUENCY]); if (bss_buffer[NL80211_BSS_SIGNAL_MBM]) { scanresult.signal.type = WSR_RCPI; scanresult.signal.quality.value = nla_get_u32(bss_buffer[NL80211_BSS_SIGNAL_MBM])/100; } if (bss_buffer[NL80211_BSS_SIGNAL_UNSPEC]) { scanresult.signal.type = WSR_UNKNOWN; scanresult.signal.quality.value = nla_get_u8(bss_buffer[NL80211_BSS_SIGNAL_UNSPEC]); } // if (bss_buffer[NL80211_BSS_INFORMATION_ELEMENTS]) // print_ies(nla_data(bss_buffer[NL80211_BSS_INFORMATION_ELEMENTS]), // nla_len(bss_buffer[NL80211_BSS_INFORMATION_ELEMENTS]), // params->unknown, params->type); m_scanResults.push_back(scanresult); return NL_SKIP; }
static int cb_kmod_create_iface(struct nl_msg* msg, void* data) { struct nlattr* tb_msg[NLSMARTCAPWAP_ATTR_MAX + 1]; struct genlmsghdr* gnlh = nlmsg_data(nlmsg_hdr(msg)); uint32_t* ifindex = (uint32_t*)data; nla_parse(tb_msg, NLSMARTCAPWAP_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); if (tb_msg[NLSMARTCAPWAP_ATTR_IFPHY_INDEX]) { *ifindex = nla_get_u32(tb_msg[NLSMARTCAPWAP_ATTR_IFPHY_INDEX]); } return NL_SKIP; }
/** * Validate Generic Netlink message headers * @arg nlh Pointer to Netlink message header * @arg hdrlen Length of user header * * Verifies the integrity of the Netlink and Generic Netlink headers by * enforcing the following requirements: * - Valid Netlink message header (nlmsg_valid_hdr()) * - Presence of a complete Generic Netlink header * - At least \c hdrlen bytes of payload included after the generic * netlink header. * * @return A positive integer (true) if the headers are valid or * 0 (false) if not. */ int genlmsg_valid_hdr(struct nlmsghdr *nlh, int hdrlen) { struct genlmsghdr *ghdr; if (!nlmsg_valid_hdr(nlh, GENL_HDRLEN)) return 0; ghdr = nlmsg_data(nlh); if (genlmsg_len(ghdr) < NLMSG_ALIGN(hdrlen)) return 0; return 1; }
static int eam_test_response(struct nl_msg *msg, void *arg) { char addr6_str[INET6_ADDRSTRLEN]; void *addr6; char *addr4_str; struct in_addr *addr4; bool *is_ipv6 = arg; if (*is_ipv6) { /* IPv6 address translated into IPv4. */ addr4 = nlmsg_data(nlmsg_hdr(msg)); addr4_str = inet_ntoa(*addr4); printf("%s\n", addr4_str); } else { /* IPv4 address translated into IPv6. */ addr6 = nlmsg_data(nlmsg_hdr(msg)); inet_ntop(AF_INET6, addr6, addr6_str, sizeof(addr6_str)); printf("%s\n", addr6_str); } return 0; }
int ieee802154_nl_mcast(struct sk_buff *msg, unsigned int group) { struct nlmsghdr *nlh = nlmsg_hdr(msg); void *hdr = genlmsg_data(nlmsg_data(nlh)); if (genlmsg_end(msg, hdr) < 0) goto out; return genlmsg_multicast(&nl802154_family, msg, 0, group, GFP_ATOMIC); out: nlmsg_free(msg); return -ENOBUFS; }
static int handle_wiphy(struct mesh_node *mesh, struct nl_msg *msg, void *arg) { struct nlattr *tb[NL80211_ATTR_MAX + 1]; struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1]; struct nlattr *nl_band, *nl_rate; struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); struct ieee80211_supported_band *lband; int rem_band, rem_rate, n_rates = 0; enum ieee80211_band band; uint16_t sup_rates[MAX_SUPP_RATES] = { 0 }; struct nlattr *tb_rate[NL80211_BITRATE_ATTR_MAX + 1]; static struct nla_policy rate_policy[NL80211_BITRATE_ATTR_MAX + 1] = { [NL80211_BITRATE_ATTR_RATE] = { .type = NLA_U32 },
int ieee802154_nl_reply(struct sk_buff *msg, struct genl_info *info) { struct nlmsghdr *nlh = nlmsg_hdr(msg); void *hdr = genlmsg_data(nlmsg_data(nlh)); if (genlmsg_end(msg, hdr) < 0) goto out; return genlmsg_reply(msg, info); out: nlmsg_free(msg); return -ENOBUFS; }
/* * @pid:用户进行id @data:发送数据缓冲区 @data_len:缓冲区长度 */ static int genlnet_msg_send(int pid, char *data, uint32_t data_len) { char buf[MAX_STR_LEN]; void *msg; int ret; size_t size; struct sk_buff *skb; struct genlmsghdr *genlhdr; void *reply; memcpy(buf, data, data_len); size = nla_total_size(data_len) + nla_total_size(0); skb = genlmsg_new(size, GFP_KERNEL); if (skb == NULL) { printk("%s %d\n", __func__, __LINE__); return -1; } msg = genlmsg_put(skb, 0, 0, &genlnet_family, 0, MSG_CMD_NOTIFY); if (msg == NULL) { printk("%s %d\n", __func__, __LINE__); goto err; } ret = nla_put(skb, MSG_CMD, data_len, data); if (ret < 0) { printk("%s %d, ret = %d\n", __func__, __LINE__, ret); goto err; } genlhdr = nlmsg_data(nlmsg_hdr(skb)); reply = genlmsg_data(genlhdr); ret = genlmsg_end(skb, reply); if (ret < 0) { printk("%s %d, ret = %d\n", __func__, __LINE__, ret); goto err; } ret = genlmsg_unicast(&init_net, skb, pid); if (ret < 0) { printk("%s %d, ret = %d\n", __func__, __LINE__, ret); goto err; } return 0; err: //nlmsg_free(skb); return -1; }
/* * Change state of port (ie from forwarding to blocking etc) * Used by spanning tree in user space. */ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { struct net *net = sock_net(skb->sk); struct ifinfomsg *ifm; struct nlattr *protinfo; struct net_device *dev; struct net_bridge_port *p; u8 new_state; if (nlmsg_len(nlh) < sizeof(*ifm)) return -EINVAL; ifm = nlmsg_data(nlh); if (ifm->ifi_family != AF_BRIDGE) return -EPFNOSUPPORT; protinfo = nlmsg_find_attr(nlh, sizeof(*ifm), IFLA_PROTINFO); if (!protinfo || nla_len(protinfo) < sizeof(u8)) return -EINVAL; new_state = nla_get_u8(protinfo); if (new_state > BR_STATE_BLOCKING) return -EINVAL; dev = __dev_get_by_index(net, ifm->ifi_index); if (!dev) return -ENODEV; p = br_port_get_rtnl(dev); if (!p) return -EINVAL; /* if kernel STP is running, don't allow changes */ if (p->br->stp_enabled == BR_KERNEL_STP) return -EBUSY; if (!netif_running(dev) || (!netif_carrier_ok(dev) && new_state != BR_STATE_DISABLED)) return -ENETDOWN; p->state = new_state; br_log_state(p); spin_lock_bh(&p->br->lock); br_port_state_selection(p->br); spin_unlock_bh(&p->br->lock); br_ifinfo_notify(RTM_NEWLINK, p); return 0; }
static int event_handler(struct nl_msg *msg, void *arg) { struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); struct nlattr *tb[NL80211_ATTR_MAX + 1]; int cmd = gnlh->cmd; uint8_t *pos; int i; nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); switch (gnlh->cmd) { case NL80211_CMD_FRAME: if (tb[NL80211_ATTR_FRAME] && nla_len(tb[NL80211_ATTR_FRAME])) { pos = nla_data(tb[NL80211_ATTR_FRAME]); if (*(pos + 24) == 0x20) { switch (*(pos + 25)) { case MPATH_PREQ: printf("Path Request Frame "); break; case MPATH_PREP: printf("Path Reply Frame "); break; case MPATH_PERR: printf("Path Error Frame "); break; } printf("from %02x:%02x:%02x:%02x:%02x:%02x\n", *(pos + 10), *(pos + 11), *(pos + 12), *(pos + 13), *(pos + 14), *(pos + 15)); } printf("----------\n"); printf("frame hexdump: "); for (i=0; i<nla_len(tb[NL80211_ATTR_FRAME]); i++) { if (!(i%20)) printf("\n"); printf("%02x ", *pos++); } printf("\n----------\n\n"); } break; case NL80211_CMD_NEW_STATION: printf("NL80211_CMD_NEW_STATION :)\n"); break; default: printf("Ignored event\n"); break; } return NL_SKIP; }
static void hello_nl_recv_msg(struct sk_buff *skb) { struct nlmsghdr *nlh; int pid; struct sk_buff *skb_out; int msg_size; char *msg = "Hello from kernel"; int res, i; msleep(2); printk(KERN_INFO "Entering: %s\n", __FUNCTION__); msg_size = strlen(msg); if (flag == 1) { flag = 0; nlh = (struct nlmsghdr *)skb->data; printk(KERN_INFO "Netlink received msg payload: %s\n", (char *)nlmsg_data(nlh)); pid = nlh->nlmsg_pid; /*pid of sending process */ skb_out = nlmsg_new(msg_size, 0); if (!skb_out) { printk(KERN_ERR "Failed to allocate new skb\n"); return; } nlh = nlmsg_put(skb_out, 0, 0, NLMSG_DONE, msg_size, 0); NETLINK_CB(skb_out).dst_group = 0; /* not in mcast group */ strncpy(nlmsg_data(nlh), msg, msg_size); res = nlmsg_unicast(nl_sk, skb_out, pid); } if (res < 0) printk(KERN_INFO "Error while sending bak to user\n"); }
static int send_data(struct sk_buff *skb) { struct genlmsghdr *genlhdr = nlmsg_data((struct nlmsghdr *)skb->data); void *data = genlmsg_data(genlhdr); int rv; rv = genlmsg_end(skb, data); if (rv < 0) { nlmsg_free(skb); return rv; } return genlmsg_unicast(&init_net, skb, listener_nlpid); }
static int get_cw(struct nl_msg *msg, void *arg) { struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); struct nlattr *tb_msg[NL80211_ATTR_MAX + 1]; unsigned int *wiphy = arg; printf("atlasd: got message!\n"); nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); print_all_attrs(tb_msg); //nl_msg_dump(msg, stdout); return NL_SKIP; }
static int protocol_feature_handler(struct nl_msg *msg, void *arg) { u32 *feat = arg; struct nlattr *tb_msg[NL80211_ATTR_MAX + 1]; struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); if (tb_msg[NL80211_ATTR_PROTOCOL_FEATURES]) *feat = nla_get_u32(tb_msg[NL80211_ATTR_PROTOCOL_FEATURES]); return NL_SKIP; }
static void selnl_add_payload(struct nlmsghdr *nlh, int len, int msgtype, void *data) { switch (msgtype) { case SELNL_MSG_SETENFORCE: { struct selnl_msg_setenforce *msg = nlmsg_data(nlh); memset(msg, 0, len); msg->val = *((int *)data); break; } case SELNL_MSG_POLICYLOAD: { struct selnl_msg_policyload *msg = nlmsg_data(nlh); memset(msg, 0, len); msg->seqno = *((u32 *)data); break; } default: BUG(); } }
/* * Create one netlink message for one interface * Contains port and master info as well as carrier and bridge state. */ static int br_fill_ifinfo(struct sk_buff *skb, const struct net_bridge_port *port, u32 pid, u32 seq, int event, unsigned int flags) { const struct net_bridge *br = port->br; const struct net_device *dev = port->dev; struct ifinfomsg *hdr; struct nlmsghdr *nlh; u8 operstate = netif_running(dev) ? dev->operstate : IF_OPER_DOWN; br_debug(br, "br_fill_info event %d port %s master %s\n", event, dev->name, br->dev->name); nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags); if (nlh == NULL) return -EMSGSIZE; hdr = nlmsg_data(nlh); hdr->ifi_family = AF_BRIDGE; hdr->__ifi_pad = 0; hdr->ifi_type = dev->type; hdr->ifi_index = dev->ifindex; hdr->ifi_flags = dev_get_flags(dev); hdr->ifi_change = 0; if (nla_put_string(skb, IFLA_IFNAME, dev->name) || nla_put_u32(skb, IFLA_MASTER, br->dev->ifindex) || nla_put_u32(skb, IFLA_MTU, dev->mtu) || nla_put_u8(skb, IFLA_OPERSTATE, operstate) || (dev->addr_len && nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr)) || (dev->ifindex != dev->iflink && nla_put_u32(skb, IFLA_LINK, dev->iflink))) goto nla_put_failure; if (event == RTM_NEWLINK) { struct nlattr *nest = nla_nest_start(skb, IFLA_PROTINFO | NLA_F_NESTED); if (nest == NULL || br_port_fill_attrs(skb, port) < 0) goto nla_put_failure; nla_nest_end(skb, nest); } return nlmsg_end(skb, nlh); nla_put_failure: nlmsg_cancel(skb, nlh); return -EMSGSIZE; }
static void hello_nl_recv_msg(struct sk_buff *skb) { struct nlmsghdr *nlh; int pid; printk(KERN_INFO "Entering: %s\n", __FUNCTION__); nlh = (struct nlmsghdr *)skb->data; pid = nlh->nlmsg_pid; /*pid of sending process */ printk(KERN_INFO "[%d]Netlink received msg payload:%s\n", pid, (char *)nlmsg_data(nlh)); hello_nl_send_msg(pid); }
static int print_reg_handler(struct nl_msg *msg, void *arg) { #define PARSE_FLAG(nl_flag, string_value) do { \ if ((flags & nl_flag)) { \ printf(", %s", string_value); \ } \ } while (0) struct nlattr *tb_msg[NL80211_ATTR_MAX + 1]; struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); char *alpha2; struct nlattr *nl_rule; int rem_rule; enum nl80211_dfs_regions dfs_domain; static struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = { [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
static int usnic_is_nlreply_err(struct nlmsghdr *nlm_hdr) { if (nlm_hdr->nlmsg_type == NLMSG_ERROR) { struct nlmsgerr *e = (struct nlmsgerr *)nlmsg_data(nlm_hdr); if (nlm_hdr->nlmsg_len >= (__u32)NLMSG_SIZE(sizeof(*e))) usnic_strerror(e->error, "Received a netlink error message"); else usnic_err( "Received a truncated netlink error message\n"); return 1; } return 0; }
static int valid_handler(struct nl_msg *msg, void *arg) { struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); struct nlattr *head_attr = genlmsg_attrdata(gnlh, 0); int attr_len = genlmsg_attrlen(gnlh, 0); LOG_DBG_("%s\n", __func__); (void) arg; if (print_ascii) return write_ascii(1, (uint8_t *) head_attr, attr_len); (void) write(1, (uint8_t *) head_attr, attr_len); return NL_OK; }
int kni_nl_unicast(int pid, struct sk_buff *skb_in, struct net_device *dev) { struct sk_buff *skb; struct nlmsghdr *nlh; struct net *net = dev_net(dev); struct kni_net_namespace *kni_net = net_generic(net, kni_net_id); struct rw_kni_mbuf_metadata *meta_data; int size, err; unsigned char *data; size = NLMSG_ALIGN(sizeof(*meta_data) + skb_in->len); skb = nlmsg_new(size, GFP_KERNEL); if (skb == NULL){ return -ENOMEM; } nlh = nlmsg_put(skb, pid, 0, KNI_NETLINK_MSG_TX, 0, 0); if (nlh == NULL){ goto nlmsg_failure; } err = skb_linearize(skb_in); if (unlikely(err)){ goto nlmsg_failure; } meta_data = (struct rw_kni_mbuf_metadata *)nlmsg_data(nlh);; memset(meta_data, 0, sizeof(*meta_data)); data = (unsigned char *)(meta_data +1); RW_KNI_VF_SET_MDATA_ENCAP_TYPE(meta_data, skb_in->protocol); RW_KNI_VF_SET_MDATA_LPORTID(meta_data, dev->ifindex); RW_KNI_VF_SET_MDATA_L3_OFFSET(meta_data, skb_in->len); memcpy(data, skb_in->data, skb_in->len); //akki skb_put(skb, size); nlmsg_end(skb, nlh); return nlmsg_unicast(kni_net->netlink_sock, skb, pid); nlmsg_failure: nlmsg_cancel(skb, nlh); kfree_skb(skb); return -1; }
static int session_display_response(struct nl_msg *msg, void *arg) { struct response_hdr *hdr; struct session_entry_us *entries; __u16 entry_count; __u16 i; char *str4; char str6[INET6_ADDRSTRLEN]; hdr = nlmsg_data(nlmsg_hdr(msg)); if (hdr->result_code != RESPONSE_SUCCESS) { print_code_msg(hdr, "Session table", NULL); return hdr->result_code; } entries = (struct session_entry_us *) (hdr + 1); entry_count = (hdr->length - sizeof(*hdr)) / sizeof(*entries); if (entry_count == 0) { printf(" (empty)\n\n"); return 0; } printf("---------------------------------\n"); for (i = 0; i < entry_count; i++) { struct session_entry_us *entry = &entries[i]; if (entry->is_static) printf("STATIC\n"); else printf("DYNAMIC (expires in %u milliseconds).\n", entry->dying_time); str4 = inet_ntoa(entry->ipv4.remote.address); printf("Remote: %s#%u\t", str4, entry->ipv4.remote.l4_id); inet_ntop(AF_INET6, &entry->ipv6.remote.address, str6, INET6_ADDRSTRLEN); printf("%s#%u\n", str6, entry->ipv6.remote.l4_id); str4 = inet_ntoa(entry->ipv4.local.address); printf("Local: %s#%u\t", str4, entry->ipv4.local.l4_id); inet_ntop(AF_INET6, &entry->ipv6.local.address, str6, INET6_ADDRSTRLEN); printf("%s#%u\n", str6, entry->ipv6.local.l4_id); printf("---------------------------------\n"); } printf("\n"); return 0; }
/* function: get_default_route_cb * finds the default route with the request family and out interface and saves the gateway * msg - netlink message * data - (struct default_route_data) requested filters and response storage */ static int get_default_route_cb(struct nl_msg *msg, void *data) { struct rtmsg *rt_p; struct rtattr *rta_p; int rta_len; struct default_route_data *default_route = data; union anyip *this_gateway = NULL; ssize_t this_gateway_size; int this_interface_id = -1; if(default_route->reply_found_route) { // we already found our route return NL_OK; } rt_p = (struct rtmsg *)nlmsg_data(nlmsg_hdr(msg)); if(rt_p->rtm_dst_len != 0) { // not a default route return NL_OK; } if((rt_p->rtm_family != default_route->request_family) || (rt_p->rtm_table != RT_TABLE_MAIN)) { // not a route we care about return NL_OK; } rta_p = (struct rtattr *)RTM_RTA(rt_p); rta_len = RTM_PAYLOAD(nlmsg_hdr(msg)); for(; RTA_OK(rta_p, rta_len); rta_p = RTA_NEXT(rta_p, rta_len)) { switch(rta_p->rta_type) { case RTA_GATEWAY: this_gateway = RTA_DATA(rta_p); this_gateway_size = RTA_PAYLOAD(rta_p); break; case RTA_OIF: this_interface_id = *(int *)RTA_DATA(rta_p); break; default: break; } } if(this_interface_id == default_route->request_interface_id) { default_route->reply_found_route = 1; if(this_gateway != NULL) { memcpy(&default_route->reply_gateway, this_gateway, this_gateway_size); default_route->reply_has_gateway = 1; } else { default_route->reply_has_gateway = 0; } } return NL_OK; }
static int tipc_nl_compat_recv(struct sk_buff *skb, struct genl_info *info) { int err; int len; struct tipc_nl_compat_msg msg; struct nlmsghdr *req_nlh; struct nlmsghdr *rep_nlh; struct tipc_genlmsghdr *req_userhdr = info->userhdr; struct net *net = genl_info_net(info); memset(&msg, 0, sizeof(msg)); req_nlh = (struct nlmsghdr *)skb->data; msg.req = nlmsg_data(req_nlh) + GENL_HDRLEN + TIPC_GENL_HDRLEN; msg.cmd = req_userhdr->cmd; msg.dst_sk = info->dst_sk; if ((msg.cmd & 0xC000) && (!netlink_net_capable(skb, CAP_NET_ADMIN))) { msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_NET_ADMIN); err = -EACCES; goto send; } len = nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN); if (TLV_GET_LEN(msg.req) && !TLV_OK(msg.req, len)) { msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_SUPPORTED); err = -EOPNOTSUPP; goto send; } err = tipc_nl_compat_handle(&msg); if (err == -EOPNOTSUPP) msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_SUPPORTED); else if (err == -EINVAL) msg.rep = tipc_get_err_tlv(TIPC_CFG_TLV_ERROR); send: if (!msg.rep) return err; len = nlmsg_total_size(GENL_HDRLEN + TIPC_GENL_HDRLEN); skb_push(msg.rep, len); rep_nlh = nlmsg_hdr(msg.rep); memcpy(rep_nlh, info->nlhdr, len); rep_nlh->nlmsg_len = msg.rep->len; genlmsg_unicast(net, msg.rep, NETLINK_CB(skb).portid); return err; }
static int pool4_display_response(struct nl_msg *msg, void *arg) { struct nlmsghdr *hdr; struct in_addr *addresses; __u16 addr_count, i; hdr = nlmsg_hdr(msg); addresses = nlmsg_data(hdr); addr_count = nlmsg_datalen(hdr) / sizeof(*addresses); for (i = 0; i < addr_count; i++) printf("%s\n", inet_ntoa(addresses[i])); *((int *) arg) += addr_count; return 0; }