static int handle_incoming_message(struct nl_msg *msg) { struct nlmsghdr *nl_hdr; int is_genl_msg; int res = 0; is_genl_msg = 1; nl_hdr = nlmsg_hdr(msg); if ( nl_hdr->nlmsg_type == NLMSG_ERROR ) { struct nlmsgerr* nl_err = (struct nlmsgerr*)nlmsg_data(nlmsg_hdr(msg)); res = nl_err->error; if ( res != 0 ) /* Else we got just ACK message, no special handling of those */ printf("Error message response code: %d!!\n", nl_err->error); is_genl_msg = 0; } else if ( nl_hdr->nlmsg_type != state.gnl_fid ) { printf("Ignore unknown message type: %d!!\n", nl_hdr->nlmsg_type); is_genl_msg = 0; } if ( is_genl_msg ) { //printf("Handling generic netlink msg: Tx id: %d\n", nlmsg_hdr(msg)->nlmsg_seq); if ( res = genl_cmd_dispatch(msg) ) { printf("Handling generic netlink msg error %d\n", res); process_handle_error(res, msg); } } nlmsg_free(msg); return res; }
int handle_immigration_request(struct nl_msg *req_msg) { struct nl_msg *msg = NULL; struct nlattr *nla; int ret = 0; int seq; struct internal_state* state = get_current_state(); // In params int uid; int slot_index; char* name; // Out params int accept = 1; seq = nlmsg_hdr(req_msg)->nlmsg_seq; nla = nlmsg_find_attr(nlmsg_hdr(req_msg), sizeof(struct genlmsghdr), DIRECTOR_A_UID); if (nla == NULL) return -EBADMSG; uid = nla_get_u32(nla); nla = nlmsg_find_attr(nlmsg_hdr(req_msg), sizeof(struct genlmsghdr), DIRECTOR_A_INDEX); if (nla == NULL) return -EBADMSG; slot_index = nla_get_u32(nla); nla = nlmsg_find_attr(nlmsg_hdr(req_msg), sizeof(struct genlmsghdr), DIRECTOR_A_NAME); if (nla == NULL) return -EBADMSG; //name = nl_data_get(nla_get_data(nla)); name = nla_data(nla); //printf("NPM CALLED FOR NAME: %s\n", name); if ( immigration_request_callback ) immigration_request_callback(uid, slot_index, name, &accept); if ( (ret=prepare_response_message(state->handle, DIRECTOR_IMMIGRATION_REQUEST_RESPONSE, state->gnl_fid, seq, &msg) ) != 0 ) { goto done; } ret = nla_put_u32(msg, DIRECTOR_A_DECISION, accept); if (ret != 0) goto error_del_resp; ret = send_request_message(state->handle, msg, 0); goto done; error_del_resp: nlmsg_free(msg); done: return ret; }
static void ind_ovs_handle_packet_miss(struct ind_ovs_upcall_thread *thread, struct ind_ovs_port *port, struct nl_msg *msg, struct nlattr **attrs) { struct nlmsghdr *nlh = nlmsg_hdr(msg); struct genlmsghdr *gnlh = (void *)(nlh + 1); struct nlattr *key = attrs[OVS_PACKET_ATTR_KEY]; struct nlattr *packet = attrs[OVS_PACKET_ATTR_PACKET]; assert(key && packet); struct ind_ovs_parsed_key pkey; ind_ovs_parse_key(key, &pkey); /* Lookup the flow in the userspace flowtable. */ struct ind_ovs_flow *flow; if (ind_ovs_lookup_flow(&pkey, &flow) != 0) { ind_ovs_upcall_request_pktin(pkey.in_port, port, packet, key, OF_PACKET_IN_REASON_NO_MATCH); return; } /* Reuse the incoming message for the packet execute */ gnlh->cmd = OVS_PACKET_CMD_EXECUTE; ind_ovs_translate_actions(&pkey, flow->of_list_action, msg, OVS_PACKET_ATTR_ACTIONS); __sync_fetch_and_add(&flow->packets, 1); __sync_fetch_and_add(&flow->bytes, nla_len(packet)); /* Reuse the translated actions for adding the kflow. */ struct nlattr *actions = nlmsg_find_attr(nlmsg_hdr(msg), sizeof(struct genlmsghdr) + sizeof(struct ovs_header), OVS_PACKET_ATTR_ACTIONS); /* Don't send the packet back out if it would be dropped. */ if (nla_len(actions) > 0) { nlh->nlmsg_pid = 0; nlh->nlmsg_seq = 0; nlh->nlmsg_flags = NLM_F_REQUEST; struct iovec *iovec = &thread->tx_queue[thread->tx_queue_len++]; iovec->iov_base = nlh; iovec->iov_len = nlh->nlmsg_len; if (thread->log_upcalls) { LOG_VERBOSE("Sending upcall reply:"); ind_ovs_dump_msg(nlh); } } /* See the comment for ind_ovs_upcall_seen_key. */ if (ind_ovs_upcall_seen_key(thread, key)) { /* Create a kflow with the given key and actions. */ ind_ovs_bh_request_kflow(key, actions); } }
static struct sk_buff *brc_send_command(struct sk_buff *request, struct nlattr **attrs) { unsigned long int flags; struct sk_buff *reply; int error; mutex_lock(&brc_serial); /* Increment sequence number first, so that we ignore any replies * to stale requests. */ spin_lock_irqsave(&brc_lock, flags); nlmsg_hdr(request)->nlmsg_seq = ++brc_seq; INIT_COMPLETION(brc_done); spin_unlock_irqrestore(&brc_lock, flags); nlmsg_end(request, nlmsg_hdr(request)); /* Send message. */ error = genlmsg_multicast(request, 0, brc_mc_group.id, GFP_KERNEL); if (error < 0) goto error; /* Wait for reply. */ error = -ETIMEDOUT; if (!wait_for_completion_timeout(&brc_done, BRC_TIMEOUT)) { pr_warn("timed out waiting for userspace\n"); goto error; } /* Grab reply. */ spin_lock_irqsave(&brc_lock, flags); reply = brc_reply; brc_reply = NULL; spin_unlock_irqrestore(&brc_lock, flags); mutex_unlock(&brc_serial); /* Re-parse message. Can't fail, since it parsed correctly once * already. */ error = nlmsg_parse(nlmsg_hdr(reply), GENL_HDRLEN, attrs, BRC_GENL_A_MAX, brc_genl_policy); WARN_ON(error); return reply; error: mutex_unlock(&brc_serial); return ERR_PTR(error); }
int handle_task_exitted(struct nl_msg *req_msg) { struct nl_msg *msg = NULL; struct nlattr *nla; int ret = 0; int seq; struct internal_state* state = get_current_state(); struct rusage *rusage; // In params pid_t pid; int exit_code; seq = nlmsg_hdr(req_msg)->nlmsg_seq; nla = nlmsg_find_attr(nlmsg_hdr(req_msg), sizeof(struct genlmsghdr), DIRECTOR_A_PID); if (nla == NULL) return -EBADMSG; pid = nla_get_u32(nla); nla = nlmsg_find_attr(nlmsg_hdr(req_msg), sizeof(struct genlmsghdr), DIRECTOR_A_EXIT_CODE); if (nla == NULL) return -EBADMSG; exit_code = nla_get_u32(nla); nla = nlmsg_find_attr(nlmsg_hdr(req_msg), sizeof(struct genlmsghdr), DIRECTOR_A_RUSAGE); if (nla == NULL) return -EBADMSG; //rusage = nl_data_get(nla_get_data(nla)); rusage = nla_data(nla); if ( task_exitted_callback ) task_exitted_callback(pid, exit_code, rusage); if ( (ret=prepare_response_message(state->sk, DIRECTOR_ACK, state->gnl_fid, seq, &msg) ) != 0 ) { goto done; } if (ret != 0) goto error_del_resp; ret = send_request_message(state->sk, msg, 0); goto done; error_del_resp: nlmsg_free(msg); done: return ret; }
/* 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 show_vport__(struct nl_msg *msg, void *arg) { struct nlmsghdr *nlh = nlmsg_hdr(msg); struct nlattr *attrs[OVS_VPORT_ATTR_MAX+1]; if (genlmsg_parse(nlh, sizeof(struct ovs_header), attrs, OVS_VPORT_ATTR_MAX, NULL) < 0) { abort(); } fprintf(stderr, " %d %s %s\n", nla_get_u32(attrs[OVS_VPORT_ATTR_PORT_NO]), (char *)nla_data(attrs[OVS_VPORT_ATTR_NAME]), vport_type_str__(nla_get_u32(attrs[OVS_VPORT_ATTR_TYPE]))); struct ovs_vport_stats *stats = nla_data(attrs[OVS_VPORT_ATTR_STATS]); fprintf(stderr, " rx: packets=%"PRIu64" bytes=%"PRIu64" errors=%"PRIu64" dropped=%"PRIu64"\n", (uint64_t)stats->rx_packets, (uint64_t)stats->rx_bytes, (uint64_t)stats->rx_errors, (uint64_t)stats->rx_dropped); fprintf(stderr, " tx: packets=%"PRIu64" bytes=%"PRIu64" errors=%"PRIu64" dropped=%"PRIu64"\n", (uint64_t)stats->tx_packets, (uint64_t)stats->tx_bytes, (uint64_t)stats->tx_errors, (uint64_t)stats->tx_dropped); return NL_OK; }
static int ipvs_daemon_parse_cb(struct nl_msg *msg, void *arg) { struct nlmsghdr *nlh = nlmsg_hdr(msg); struct nlattr *attrs[IPVS_CMD_ATTR_MAX + 1]; struct nlattr *daemon_attrs[IPVS_DAEMON_ATTR_MAX + 1]; ipvs_daemon_t *u = (ipvs_daemon_t *)arg; int i = 0; /* We may get two daemons. If we've already got one, this is the second */ if (u[0].state) i = 1; if (genlmsg_parse(nlh, 0, attrs, IPVS_CMD_ATTR_MAX, ipvs_cmd_policy) != 0) return -1; if (nla_parse_nested(daemon_attrs, IPVS_DAEMON_ATTR_MAX, attrs[IPVS_CMD_ATTR_DAEMON], ipvs_daemon_policy)) return -1; if (!(daemon_attrs[IPVS_DAEMON_ATTR_STATE] && daemon_attrs[IPVS_DAEMON_ATTR_MCAST_IFN] && daemon_attrs[IPVS_DAEMON_ATTR_SYNC_ID])) return -1; u[i].state = nla_get_u32(daemon_attrs[IPVS_DAEMON_ATTR_STATE]); strncpy(u[i].mcast_ifn, nla_get_string(daemon_attrs[IPVS_DAEMON_ATTR_MCAST_IFN]), IP_VS_IFNAME_MAXLEN); u[i].syncid = nla_get_u32(daemon_attrs[IPVS_DAEMON_ATTR_SYNC_ID]); return NL_OK; }
static void audit_set_pid(struct audit_buffer *ab, pid_t pid) { if (ab) { struct nlmsghdr *nlh = nlmsg_hdr(ab->skb); nlh->nlmsg_pid = pid; } }
static int nl80211_iface_info_handler (struct nl_msg *msg, void *arg) { struct nl80211_iface_info *info = arg; struct genlmsghdr *gnlh = nlmsg_data (nlmsg_hdr (msg)); struct nlattr *tb[NL80211_ATTR_MAX + 1]; if (nla_parse (tb, NL80211_ATTR_MAX, genlmsg_attrdata (gnlh, 0), genlmsg_attrlen (gnlh, 0), NULL) < 0) return NL_SKIP; if (!tb[NL80211_ATTR_IFTYPE]) return NL_SKIP; switch (nla_get_u32 (tb[NL80211_ATTR_IFTYPE])) { case NL80211_IFTYPE_ADHOC: info->mode = NM_802_11_MODE_ADHOC; break; case NL80211_IFTYPE_AP: info->mode = NM_802_11_MODE_AP; break; case NL80211_IFTYPE_STATION: info->mode = NM_802_11_MODE_INFRA; break; } return NL_SKIP; }
/* * Receive events from netlink socket and generate events. */ static int __ni_rtevent_process_cb(struct nl_msg *msg, void *ptr) { const struct sockaddr_nl *sender = nlmsg_get_src(msg); struct nlmsghdr *nlh; ni_netconfig_t *nc; if ((nc = ni_global_state_handle(0)) == NULL) return NL_SKIP; if (sender->nl_pid != 0) { ni_error("ignoring rtnetlink event message from PID %u", sender->nl_pid); return NL_SKIP; } nlh = nlmsg_hdr(msg); if (__ni_rtevent_process(nc, sender, nlh) < 0) { ni_debug_events("ignoring %s rtnetlink event", ni_rtnl_msg_type_to_name(nlh->nlmsg_type, "unknown")); return NL_SKIP; } return NL_OK; }
static int dump_mgmt_frame(struct nl_msg *msg, void *arg) { struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); struct nlattr *tb_msg[NL80211_ATTR_MAX + 1]; nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); if (tb_msg[NL80211_ATTR_WIPHY_FREQ]) { uint32_t freq = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_FREQ]); printf("freq %u MHz\n", freq); } if (tb_msg[NL80211_ATTR_RX_SIGNAL_DBM]) { /* nl80211_send_mgmt sends signed dBm value as u32 */ int dbm = nla_get_u32(tb_msg[NL80211_ATTR_RX_SIGNAL_DBM]); printf("rssi %d dBm\n", dbm); } if (tb_msg[NL80211_ATTR_FRAME]) { int len = nla_len(tb_msg[NL80211_ATTR_FRAME]); uint8_t *data = nla_data(tb_msg[NL80211_ATTR_FRAME]); iw_hexdump("mgmt", data, len); } return 0; }
static int _list(struct nl_msg *nl_msg, void *arg) { struct nlmsghdr *nlh = nlmsg_hdr(nl_msg); struct nlattr *info[TIPC_NLA_MAX + 1]; struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1]; genlmsg_parse(nlh, 0, info, TIPC_NLA_MAX, NULL); if (!info[TIPC_NLA_BEARER]) { log_err("no bearer received from kernel\n"); return NL_STOP; } if (nla_parse_nested(attrs, TIPC_NLA_BEARER_MAX, info[TIPC_NLA_BEARER], NULL)) { log_err("parsing nested bearer properties\n"); return NL_STOP; } if (!attrs[TIPC_NLA_BEARER_NAME]) { log_err("no bearer name received from kernel\n"); return NL_STOP; } printf("%s\n", nla_get_string(attrs[TIPC_NLA_BEARER_NAME])); return NL_OK; }
// valid interface callback handler static int iface_handler(struct nl_msg *msg, void *arg) { struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); struct nlattr *tb_msg[NL80211_ATTR_MAX + 1]; nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); if (tb_msg[NL80211_ATTR_WIPHY]) { char wiphy[IFNAMSIZ]; sprintf(wiphy, "phy%d", nla_get_u32(tb_msg[NL80211_ATTR_WIPHY])); // If selected physical interface matches the result, search for a monitor interface and copy the name if(strcmp(phy_name, wiphy) == 0) { if (tb_msg[NL80211_ATTR_IFTYPE] && tb_msg[NL80211_ATTR_IFNAME]) { // If the interface type is monitor if(nla_get_u32(tb_msg[NL80211_ATTR_IFTYPE]) == 6) strcpy(IF_name, nla_get_string(tb_msg[NL80211_ATTR_IFNAME])); } } } return NL_SKIP; }
void kernel_receive(struct sk_buff *__skb) //内核从用户空间接收数据 { struct sk_buff *skb; struct nlmsghdr *nlh = NULL; char *data = "This is eric's test message from kernel"; printk( "[kernel recv] begin kernel_receive\n"); skb = skb_get(__skb); if(skb->len >= sizeof(struct nlmsghdr)){ nlh = (struct nlmsghdr *)skb->data; if((nlh->nlmsg_len >= sizeof(struct nlmsghdr)) && (__skb->len >= nlh->nlmsg_len)){ user_process.pid = nlh->nlmsg_pid; printk( "[kernel recv] data receive from user are:%s\n", (char *)NLMSG_DATA(nlh)); printk( "[kernel recv] user_pid:%d\n", user_process.pid); // send_to_user(data); } }else{ printk( "[kernel recv] data receive from user are:%s\n",(char *)NLMSG_DATA(nlmsg_hdr(__skb))); // send_to_user(data); } kfree_skb(skb); }
static int get_devices_handler(struct nl_msg *n, void *arg) { struct nlmsghdr *nlh = nlmsg_hdr(n); struct nlattr *attrs[NFC_ATTR_MAX + 1]; char *name; uint32_t idx, protocols; bool powered; DBG(""); genlmsg_parse(nlh, 0, attrs, NFC_ATTR_MAX, NULL); if (!attrs[NFC_ATTR_DEVICE_INDEX] || !attrs[NFC_ATTR_DEVICE_NAME] || !attrs[NFC_ATTR_PROTOCOLS]) { nl_perror(NLE_MISSING_ATTR, "NFC_CMD_GET_DEVICE"); return NL_STOP; } idx = nla_get_u32(attrs[NFC_ATTR_DEVICE_INDEX]); name = nla_get_string(attrs[NFC_ATTR_DEVICE_NAME]); protocols = nla_get_u32(attrs[NFC_ATTR_PROTOCOLS]); if (!attrs[NFC_ATTR_DEVICE_POWERED]) powered = false; else powered = nla_get_u8(attrs[NFC_ATTR_DEVICE_POWERED]); __near_manager_adapter_add(idx, name, protocols, powered); return NL_SKIP; }
static int show_datapath__(struct nl_msg *msg, void *arg) { struct nlmsghdr *nlh = nlmsg_hdr(msg); struct genlmsghdr *gnlh = nlmsg_data(nlh); struct ovs_header *hdr = (void *)(gnlh + 1); struct nlattr *attrs[OVS_DP_ATTR_MAX+1]; if (genlmsg_parse(nlh, sizeof(struct ovs_header), attrs, OVS_DP_ATTR_MAX, NULL) < 0) { abort(); } struct ovs_dp_stats *stats = nla_data(attrs[OVS_DP_ATTR_STATS]); fprintf(stderr, "%s:\n", (char *)nla_data(attrs[OVS_DP_ATTR_NAME])); fprintf(stderr, " kernel lookups: hit=%"PRIu64" missed=%"PRIu64" lost=%"PRIu64"\n", (uint64_t)stats->n_hit, (uint64_t)stats->n_missed, (uint64_t)stats->n_lost); fprintf(stderr, " kernel flows=%"PRIu64"\n", (uint64_t)stats->n_flows); fprintf(stderr, " ports:\n"); show_vports__(hdr->dp_ifindex); return NL_OK; }
static void kernel_receive(struct sk_buff *skb) { struct nlmsghdr *nlh = NULL; int len; nlh = nlmsg_hdr(skb); len = skb->len; while(nlmsg_ok(nlh, len)) { if (down_trylock(&receive_sem)) { return; } if (nlh->nlmsg_type == NL_U_PID) { write_lock_bh(&user_proc.lock); user_proc.pid = nlh->nlmsg_pid; write_unlock_bh(&user_proc.lock); } else if (nlh->nlmsg_type == NL_CLOSE) { write_lock_bh(&user_proc.lock); if (nlh->nlmsg_pid == user_proc.pid) { user_proc.pid = 0; } write_unlock_bh(&user_proc.lock); } up(&receive_sem); nlh = nlmsg_next(nlh, &len); } }
int mac80211_get_coverageclass(char *interface) { struct nlattr *tb[NL80211_ATTR_MAX + 1]; struct nl_msg *msg; struct genlmsghdr *gnlh; int phy; unsigned char coverage=0; phy = mac80211_get_phyidx_by_vifname(interface); if (phy == -1) return 0; msg = unl_genl_msg(&unl, NL80211_CMD_GET_WIPHY, false); NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, phy); if (unl_genl_request_single(&unl, msg, &msg) < 0) return 0; if (!msg) return 0; gnlh=nlmsg_data(nlmsg_hdr(msg)); nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); if (tb[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) { coverage = nla_get_u8(tb[NL80211_ATTR_WIPHY_COVERAGE_CLASS]); /* See handle_distance() for an explanation where the '450' comes from */ // printf("\tCoverage class: %d (up to %dm)\n", coverage, 450 * coverage); } // printf ("%d\n", coverage); nlmsg_free(msg); return coverage; nla_put_failure: nlmsg_free(msg); return 0; }
static int handle_cmd(struct sk_buff *skb, struct genl_info *info) { struct sk_buff *rep_buf; struct nlmsghdr *rep_nlh; struct nlmsghdr *req_nlh = info->nlhdr; struct tipc_genlmsghdr *req_userhdr = info->userhdr; int hdr_space = nlmsg_total_size(GENL_HDRLEN + TIPC_GENL_HDRLEN); u16 cmd; if ((req_userhdr->cmd & 0xC000) && (!capable(CAP_NET_ADMIN))) cmd = TIPC_CMD_NOT_NET_ADMIN; else cmd = req_userhdr->cmd; rep_buf = tipc_cfg_do_cmd(req_userhdr->dest, cmd, nlmsg_data(req_nlh) + GENL_HDRLEN + TIPC_GENL_HDRLEN, nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN), hdr_space); if (rep_buf) { skb_push(rep_buf, hdr_space); rep_nlh = nlmsg_hdr(rep_buf); memcpy(rep_nlh, req_nlh, hdr_space); rep_nlh->nlmsg_len = rep_buf->len; genlmsg_unicast(&init_net, rep_buf, NETLINK_CB(skb).portid); } return 0; }
static int get_noise_for_scan_results(struct nl_msg *msg, void *arg) { struct nlattr *tb[NL80211_ATTR_MAX + 1]; struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1]; static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = { [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
int nl_send_auto_complete_apda(struct nl_handle *handle,struct nl_msg *msg) { struct nlmsghdr *nlh; struct nl_cb *cb = handle->h_cb; int ret = 0; nlh = nlmsg_hdr(msg); if (nlh->nlmsg_pid == 0) nlh->nlmsg_pid = handle->h_local.nl_pid; if (nlh->nlmsg_seq == 0) nlh->nlmsg_seq = handle->h_seq_next++; if (msg->nm_protocol == -1) msg->nm_protocol = handle->h_proto; //msg->nm_flags |= (NLM_F_REQUEST | NLM_F_ACK); if (cb->cb_send_ow) return cb->cb_send_ow(handle, msg); else { int ret1; ret1 = adapter_socket_init(); if(ret1 < 0) { printf("adapter_socket_init fail\n"); close(listenfd); return -1; } char sendbuf[2048]; pduFormat(sendbuf,msg); ret = send(listenfd,sendbuf,2048,0); if (ret < 0){ printf("nl80211: NL_SEND_AUTO_COMPLETE failed\n"); close(listenfd); } return ret ; } }
static int usnic_nl_send_query(struct usnic_nl_sk *unlsk, struct nl_msg *msg, int protocol, int flag) { int ret, retry; struct nlmsghdr *nlhdr; nlhdr = nlmsg_hdr(msg); while (1) { nlhdr->nlmsg_pid = nl_socket_get_local_port(unlsk->nlh); nlhdr->nlmsg_seq = ++unlsk->seq; nlmsg_set_proto(msg, protocol); nlhdr->nlmsg_flags = flag; /* Sometimes nl_send() can fail simply because the * kernel is temporarily out of resources, and we * should just try again. libnl1 and libnl3 handle * this case a little differently, so use the * USD_NL_SEND() macro to hide the differences. If * retry comes back as true, then sleep a little and * try again. */ USD_NL_SEND(unlsk->nlh, msg, ret, retry); if (retry) { usleep(5); continue; } break; } return ret; }
int pool6_display(void) { struct request_hdr request = { .length = sizeof(request), .mode = MODE_POOL6, .operation = OP_DISPLAY, }; int row_count = 0; int error; error = netlink_request(&request, request.length, pool6_display_response, &row_count); if (!error) { if (row_count > 0) log_info(" (Fetched %u prefixes.)", row_count); else log_info(" (empty)"); } return error; } static int pool6_count_response(struct nl_msg *msg, void *arg) { __u64 *conf = nlmsg_data(nlmsg_hdr(msg)); printf("%llu\n", *conf); return 0; }
int connection_process(struct connection *conn, struct sk_buff *skb) { int ret = 0; do { if (mutex_lock_interruptible(&(conn->data_lock))) { MCDRV_DBG_ERROR("Interrupted getting data semaphore!"); ret = -1; break; } kfree_skb(conn->skb); /* Get a reference to the incomming skb */ conn->skb = skb_get(skb); if (conn->skb) { conn->data_msg = nlmsg_hdr(conn->skb); conn->data_len = NLMSG_PAYLOAD(conn->data_msg, 0); conn->data_start = NLMSG_DATA(conn->data_msg); up(&(conn->data_available_sem)); } mutex_unlock(&(conn->data_lock)); ret = 0; } while (0); return ret; }
static int sample_nl_cb(struct nl_msg *msg, void *arg) { struct nlmsghdr *nlh = nlmsg_hdr(msg); struct nlattr *attrs_echo[SAMPLE_ECHO_ATTR_MAX + 1]; struct nlattr *attrs_info[SAMPLE_INFO_ATTR_MAX + 1]; struct sample_nla sn; if (genlmsg_parse(nlh, 0, attrs_echo, SAMPLE_ECHO_ATTR_MAX, sample_echo_policy) != 0){ return -1; } if (!attrs_echo[SAMPLE_ECHO_ATTR_INFO] || !attrs_echo[SAMPLE_ECHO_ATTR_DATA]){ elog("attrs null\n"); return -1; } strncpy(sn.data, nla_get_string(attrs_echo[SAMPLE_ECHO_ATTR_DATA]), sizeof(sn.data)); if(nla_parse_nested(attrs_info, SAMPLE_INFO_ATTR_MAX, attrs_echo[SAMPLE_ECHO_ATTR_INFO], sample_info_policy)) return -1; sn.info.x = nla_get_u32(attrs_info[SAMPLE_INFO_ATTR_X]); sn.info.y = nla_get_u32(attrs_info[SAMPLE_INFO_ATTR_Y]); sample_nl_dump(&sn); return NL_OK; }
static int eam_display_response(struct nl_msg *msg, void *arg) { struct nlmsghdr *hdr; struct eamt_entry *entries; struct display_params *params = arg; __u16 entry_count, i; hdr = nlmsg_hdr(msg); entries = nlmsg_data(hdr); entry_count = nlmsg_datalen(hdr) / sizeof(*entries); if (params->csv_format) { for (i = 0; i < entry_count; i++) { print_eamt_entry(&entries[i], ","); } } else { for (i = 0; i < entry_count; i++) { print_eamt_entry(&entries[i], " - "); } } params->row_count += entry_count; params->req_payload->display.prefix4_set = hdr->nlmsg_flags & NLM_F_MULTI; if (entry_count > 0) params->req_payload->display.prefix4 = entries[entry_count - 1].prefix4; return 0; }
static void netlink_notification (NMNetlinkMonitor *monitor, struct nl_msg *msg, gpointer user_data) { NMIP6Manager *manager = (NMIP6Manager *) user_data; NMIP6Device *device; struct nlmsghdr *hdr; hdr = nlmsg_hdr (msg); nm_log_dbg (LOGD_HW, "netlink event type %d", hdr->nlmsg_type); switch (hdr->nlmsg_type) { case RTM_NEWADDR: case RTM_DELADDR: device = process_address_change (manager, msg); break; case RTM_NEWROUTE: case RTM_DELROUTE: device = process_route_change (manager, msg); break; case RTM_NEWNDUSEROPT: device = process_nduseropt (manager, msg); break; case RTM_NEWLINK: device = process_newlink (manager, msg); break; default: return; } if (device) { nm_ip6_device_sync_from_netlink (device); } }
/* Callback for sequence number check */ static int iz_cb_seq_check(struct nl_msg *msg, void *arg) { uint32_t seq; if(nlmsg_get_src(msg)->nl_groups) return NL_OK; seq = nlmsg_hdr(msg)->nlmsg_seq; if (seq == iz_seq) { if (!(nlmsg_hdr(msg)->nlmsg_flags & NLM_F_MULTI)) iz_seq ++; return NL_OK; } printf("Sequence number mismatch (%i, %i)!", seq, iz_seq); return NL_SKIP; }
static NMIP6Device * process_address_change (NMIP6Manager *manager, struct nl_msg *msg) { NMIP6ManagerPrivate *priv = NM_IP6_MANAGER_GET_PRIVATE (manager); NMIP6Device *device; struct nlmsghdr *hdr; struct rtnl_addr *rtnladdr; int old_size; hdr = nlmsg_hdr (msg); rtnladdr = NULL; nl_msg_parse (msg, ref_object, &rtnladdr); if (!rtnladdr) { nm_log_dbg (LOGD_IP6, "error processing netlink new/del address message"); return NULL; } device = nm_ip6_manager_get_device (manager, rtnl_addr_get_ifindex (rtnladdr)); old_size = nl_cache_nitems (priv->addr_cache); nl_cache_include (priv->addr_cache, (struct nl_object *)rtnladdr, NULL, NULL); /* The kernel will re-notify us of automatically-added addresses * every time it gets another router advertisement. We only want * to notify higher levels if we actually changed something. */ nm_log_dbg (LOGD_IP6, "(%s): address cache size: %d -> %d:", device_get_iface (device), old_size, nl_cache_nitems (priv->addr_cache)); dump_address_change (device, hdr, rtnladdr); rtnl_addr_put (rtnladdr); if (nl_cache_nitems (priv->addr_cache) == old_size) return NULL; return device; }