int ac_kmod_init(void) { int result; /* */ capwap_lock_init(&g_ac.kmodhandle.msglock); /* Configure netlink callback */ g_ac.kmodhandle.nl_cb = nl_cb_alloc(NL_CB_DEFAULT); if (!g_ac.kmodhandle.nl_cb) { ac_kmod_free(); return -1; } /* Create netlink socket */ g_ac.kmodhandle.nl = nl_create_handle(g_ac.kmodhandle.nl_cb); if (!g_ac.kmodhandle.nl) { ac_kmod_free(); return -1; } g_ac.kmodhandle.nl_fd = nl_socket_get_fd(g_ac.kmodhandle.nl); /* Get nlsmartcapwap netlink family */ g_ac.kmodhandle.nlsmartcapwap_id = genl_ctrl_resolve(g_ac.kmodhandle.nl, NLSMARTCAPWAP_GENL_NAME); if (g_ac.kmodhandle.nlsmartcapwap_id < 0) { log_printf(LOG_WARNING, "Unable to found kernel module"); ac_kmod_free(); return -1; } /* Configure callback function */ nl_cb_set(g_ac.kmodhandle.nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, ac_kmod_no_seq_check, NULL); nl_cb_set(g_ac.kmodhandle.nl_cb, NL_CB_VALID, NL_CB_CUSTOM, ac_kmod_valid_handler, NULL); /* Link to kernel module */ result = ac_kmod_link(); if (result) { ac_kmod_free(); return result; } /* Configure netlink message socket */ g_ac.kmodhandle.nlmsg_cb = nl_cb_alloc(NL_CB_DEFAULT); if (!g_ac.kmodhandle.nlmsg_cb) { ac_kmod_free(); return -1; } /* */ g_ac.kmodhandle.nlmsg = nl_create_handle(g_ac.kmodhandle.nlmsg_cb); if (!g_ac.kmodhandle.nlmsg) { ac_kmod_free(); return -1; } return 0; }
static int go_offchan_freq(struct nl80211_state *state, int devidx, int freq) { struct nl_cb *cb; struct nl_cb *s_cb; struct nl_msg *msg; int err; msg = nlmsg_alloc(); if (!msg) { fprintf(stderr, "failed to allocate netlink message\n"); return 2; } cb = nl_cb_alloc(nl_debug ? NL_CB_DEBUG : NL_CB_DEFAULT); s_cb = nl_cb_alloc(nl_debug ? NL_CB_DEBUG : NL_CB_DEFAULT); if (!cb || !s_cb) { fprintf(stderr, "failed to allocate netlink callbacks\n"); err = 2; goto out_free_msg; } genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0, 0, NL80211_CMD_REMAIN_ON_CHANNEL, 0); NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx); NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); /* 5 seconds is the max allowed, values passed are in ms */ NLA_PUT_U32(msg, NL80211_ATTR_DURATION, 60); nl_socket_set_cb(state->nl_sock, s_cb); err = nl_send_auto_complete(state->nl_sock, msg); if (err < 0) goto out; err = 1; nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err); nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err); while (err > 0) nl_recvmsgs(state->nl_sock, cb); out: nl_cb_put(cb); out_free_msg: nlmsg_free(msg); return err; nla_put_failure: fprintf(stderr, "building message failed\n"); return 2; }
// Retrieve monitor interface for a given physical interface int ret_mon_IF(struct nl80211_state *state) { struct nl_msg *msg; struct nl_cb *cb, *s_cb; int err = 1; msg = nlmsg_alloc(); if (!msg) { fprintf(stderr, "failed to allocate netlink message\n"); return 2; } // Allocate a new callback handle. cb = nl_cb_alloc(NL_CB_DEFAULT); s_cb = nl_cb_alloc(NL_CB_DEFAULT); if (!cb || !s_cb) { fprintf(stderr, "failed to allocate netlink callbacks\n"); err = 2; goto out_free_msg; } // Add Generic Netlink header (i.e. NL80211_CMD_GET_INTERFACE) to Netlink message genlmsg_put(msg, 0, 0, state->nl80211_id, 0, 768, NL80211_CMD_GET_INTERFACE, 0); // Set up a valid callback function if (nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, iface_handler, NULL)) goto out; // Attach the callback function to a netlink socket nl_socket_set_cb(state->nl_sock, s_cb); // Finalize and transmit Netlink message if(nl_send_auto_complete(state->nl_sock, msg) < 0) goto out; // Set up error, finish and acknowledgment callback function nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err); nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err); while (err > 0) nl_recvmsgs(state->nl_sock, cb); out: nl_cb_put(cb); out_free_msg: nlmsg_free(msg); return err; }
static int call_survey_freq(struct nl80211_state *state, int devidx, int freq) { struct nl_cb *cb; struct nl_cb *s_cb; struct nl_msg *msg; int err; msg = nlmsg_alloc(); if (!msg) { fprintf(stderr, "failed to allocate netlink message\n"); return 2; } cb = nl_cb_alloc(nl_debug ? NL_CB_DEBUG : NL_CB_DEFAULT); s_cb = nl_cb_alloc(nl_debug ? NL_CB_DEBUG : NL_CB_DEFAULT); if (!cb || !s_cb) { fprintf(stderr, "failed to allocate netlink callbacks\n"); err = 2; goto out_free_msg; } genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0, NLM_F_DUMP, NL80211_CMD_GET_SURVEY, 0); NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx); nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, handle_survey_dump, (void *) &freq); nl_socket_set_cb(state->nl_sock, s_cb); err = nl_send_auto_complete(state->nl_sock, msg); if (err < 0) goto out; err = 1; nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err); nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err); while (err > 0) nl_recvmsgs(state->nl_sock, cb); out: nl_cb_put(cb); out_free_msg: nlmsg_free(msg); return err; nla_put_failure: fprintf(stderr, "building message failed\n"); return 2; }
int unl_genl_request(struct unl *unl, struct nl_msg *msg, unl_cb handler, void *arg) { struct nlmsghdr *nlh; struct nl_cb *cb; int err; cb = nl_cb_alloc(NL_CB_CUSTOM); nlh = nlmsg_hdr(msg); err = nl_send_auto_complete(unl->sock, msg); if (err < 0) goto out; err = 1; nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err); nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err); if (handler) nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, handler, arg); while (err > 0) nl_recvmsgs(unl->sock, cb); out: nlmsg_free(msg); nl_cb_put(cb); return err; }
int dhd_nl_sock_connect(struct dhd_netlink_info *dhd_nli) { dhd_nli->nl = nl_socket_alloc(); if (dhd_nli->nl == NULL) return -1; if (genl_connect(dhd_nli->nl) < 0) { fprintf(stderr, "netlink connection failed\n"); goto err; } dhd_nli->nl_id = genl_ctrl_resolve(dhd_nli->nl, "nl80211"); if (dhd_nli->nl_id < 0) { fprintf(stderr, "'nl80211' netlink not found\n"); goto err; } dhd_nli->cb = nl_cb_alloc(NL_CB_DEBUG); if (dhd_nli->cb == NULL) goto err; nl_socket_set_cb(dhd_nli->nl, dhd_nli->cb); return 0; err: nl_cb_put(dhd_nli->cb); nl_socket_free(dhd_nli->nl); fprintf(stderr, "nl80211 connection failed\n"); return -1; }
static struct nl80211_msg_conveyor * nl80211_new(struct genl_family *family, int cmd, int flags) { static struct nl80211_msg_conveyor cv; struct nl_msg *req = NULL; struct nl_cb *cb = NULL; req = nlmsg_alloc(); if (!req) goto err; cb = nl_cb_alloc(NL_CB_DEFAULT); if (!cb) goto err; genlmsg_put(req, 0, 0, genl_family_get_id(family), 0, flags, cmd, 0); cv.msg = req; cv.cb = cb; return &cv; err: nla_put_failure: if (cb) nl_cb_put(cb); if (req) nlmsg_free(req); return NULL; }
void ind_ovs_port_init(void) { int nlerr; route_cache_sock = nl_socket_alloc(); if (route_cache_sock == NULL) { LOG_ERROR("nl_socket_alloc failed"); abort(); } if ((nlerr = nl_cache_mngr_alloc(route_cache_sock, NETLINK_ROUTE, 0, &route_cache_mngr)) < 0) { LOG_ERROR("nl_cache_mngr_alloc failed: %s", nl_geterror(nlerr)); abort(); } if ((nlerr = nl_cache_mngr_add(route_cache_mngr, "route/link", link_change_cb, NULL, &link_cache)) < 0) { LOG_ERROR("nl_cache_mngr_add failed: %s", nl_geterror(nlerr)); abort(); } if (ind_soc_socket_register(nl_cache_mngr_get_fd(route_cache_mngr), (ind_soc_socket_ready_callback_f)route_cache_mngr_socket_cb, NULL) < 0) { LOG_ERROR("failed to register socket"); abort(); } netlink_callbacks = nl_cb_alloc(NL_CB_DEFAULT); if (netlink_callbacks == NULL) { LOG_ERROR("failed to allocate netlink callbacks"); abort(); } }
static int wprobe_send_msg(struct nl_msg *msg, void *callback, void *arg) { struct nl_cb *cb; int err = 0; cb = nl_cb_alloc(NL_CB_DEFAULT); if (!cb) goto out_no_cb; if (callback) nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, callback, arg); err = nl_send_auto_complete(handle, msg); if (err < 0) goto out; err = 1; nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err); nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err); while (err > 0) nl_recvmsgs(handle, cb); out: nl_cb_put(cb); out_no_cb: nlmsg_free(msg); return err; }
static int nl80211_add_mon_if(struct nl80211_state *state, const char *device, const char *mondevice) { int ifindex, ret; struct nl_msg *msg; struct nl_cb *cb = NULL; int finished = 0; ifindex = device_ifindex(device); msg = nl80211_nlmsg_xalloc(); genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0, 0, NL80211_CMD_NEW_INTERFACE, 0); NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex); NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, mondevice); NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_MONITOR); ret = nl_send_auto_complete(state->nl_sock, msg); if (ret < 0) { if (ret == -ENFILE) { nlmsg_free(msg); return -EBUSY; } panic("Cannot send_auto_complete!\n"); } cb = nl_cb_alloc(NL_CB_CUSTOM); if (!cb) panic("Cannot alloc nl_cb!\n"); nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, nl80211_wait_handler, &finished); nl_cb_err(cb, NL_CB_CUSTOM, nl80211_error_handler, NULL); nl_recvmsgs(state->nl_sock, cb); if (!finished) { ret = nl_wait_for_ack(state->nl_sock); if (ret < 0) { if (ret == -ENFILE) { nlmsg_free(msg); return -EBUSY; } panic("Waiting for netlink ack failed!\n"); } } nl_cb_put(cb); nlmsg_free(msg); return 0; nla_put_failure: panic("nla put failure!\n"); return -EIO; /* dummy */ }
int SoftapController::executeScanLinkCmd(const char *iface, int *iface_freq) { struct nl_cb *cb; struct nl_msg *msg; int devidx = 0; int err; // initialize to non-valid freq *iface_freq = 0; devidx = if_nametoindex(iface); if (devidx == 0) { LOGE("failed to translate ifname to idx"); return -errno; } msg = nlmsg_alloc(); if (!msg) { LOGE("failed to allocate netlink message"); return 2; } cb = nl_cb_alloc(NL_CB_DEFAULT); if (!cb) { LOGE("failed to allocate netlink callbacks"); err = 2; goto out_free_msg; } genlmsg_put(msg, 0, 0, genl_family_get_id(nl80211), 0, NLM_F_DUMP, NL80211_CMD_GET_SCAN, 0); NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx); // iface_freq will be filled out by the callback nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, linkDumpCbHandler, iface_freq); err = nl_send_auto_complete(nl_soc, msg); if (err < 0) goto out; err = 1; nl_cb_err(cb, NL_CB_CUSTOM, NlErrorHandler, &err); nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, NlFinishHandler, &err); nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, NlAckHandler, &err); while (err > 0) nl_recvmsgs(nl_soc, cb); out: nl_cb_put(cb); out_free_msg: nlmsg_free(msg); return err; nla_put_failure: LOGW("building message failed"); return 2; }
static int handle_mgmt_dump(struct nl80211_state *state, struct nl_msg *msg, int argc, char **argv, enum id_input id) { struct nl_cb *mgmt_cb; char *ndev = argv[0]; int mgmt_argc = 5; char **mgmt_argv; unsigned int count = 0; int err = 0; int i; mgmt_argv = calloc(mgmt_argc, sizeof(char*)); if (!mgmt_argv) return -ENOMEM; mgmt_argv[0] = ndev; mgmt_argv[1] = "mgmt"; mgmt_argv[2] = "reg"; for (i = 3; i < argc; i += 3) { if (strcmp(argv[i], "count") == 0) { count = 1 + atoi(argv[i + 1]); break; } if (strcmp(argv[i], "frame") != 0) { err = 1; goto out; } mgmt_argv[3] = argv[i + 1]; mgmt_argv[4] = argv[i + 2]; err = handle_cmd(state, II_NETDEV, mgmt_argc, mgmt_argv); if (err) goto out; } mgmt_cb = nl_cb_alloc(iw_debug ? NL_CB_DEBUG : NL_CB_DEFAULT); if (!mgmt_cb) { err = 1; goto out; } /* need to turn off sequence number checking */ nl_cb_set(mgmt_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, seq_handler, NULL); nl_cb_set(mgmt_cb, NL_CB_VALID, NL_CB_CUSTOM, dump_mgmt_frame, NULL); while (--count) nl_recvmsgs(state->nl_sock, mgmt_cb); nl_cb_put(mgmt_cb); out: free(mgmt_argv); return err; }
static struct nl80211_msg_conveyor * nl80211_msg(const char *ifname, int cmd, int flags) { static struct nl80211_msg_conveyor cv; int ifidx = -1, phyidx = -1; struct nl_msg *req = NULL; struct nl_cb *cb = NULL; if (nl80211_init() < 0) goto err; if (!strncmp(ifname, "phy", 3)) phyidx = atoi(&ifname[3]); else if (!strncmp(ifname, "radio", 5)) phyidx = atoi(&ifname[5]); else if (!strncmp(ifname, "mon.", 4)) ifidx = if_nametoindex(&ifname[4]); else ifidx = if_nametoindex(ifname); if ((ifidx < 0) && (phyidx < 0)) return NULL; req = nlmsg_alloc(); if (!req) goto err; cb = nl_cb_alloc(NL_CB_DEFAULT); if (!cb) goto err; genlmsg_put(req, 0, 0, genl_family_get_id(nls->nl80211), 0, flags, cmd, 0); if (ifidx > -1) NLA_PUT_U32(req, NL80211_ATTR_IFINDEX, ifidx); if (phyidx > -1) NLA_PUT_U32(req, NL80211_ATTR_WIPHY, phyidx); cv.msg = req; cv.cb = cb; return &cv; err: nla_put_failure: if (cb) nl_cb_put(cb); if (req) nlmsg_free(req); return NULL; }
/* function: alloc_ack_callbacks * allocates a set of netlink callbacks. returns NULL on failure. callbacks will modify retval with <0 meaning failure * retval - shared state between caller and callback functions */ struct nl_cb *alloc_ack_callbacks(int *retval) { struct nl_cb *callbacks; callbacks = nl_cb_alloc(NL_CB_DEFAULT); if(!callbacks) { return NULL; } nl_cb_set(callbacks, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, retval); nl_cb_err(callbacks, NL_CB_CUSTOM, error_handler, retval); return callbacks; }
/** * Clone an existing callback handle * @arg orig original callback handle * @return Newly allocated callback handle being a duplicate of * orig or NULL */ struct nl_cb *nl_cb_clone(struct nl_cb *orig) { struct nl_cb *cb; cb = nl_cb_alloc(NL_CB_DEFAULT); if (!cb) return NULL; memcpy(cb, orig, sizeof(*orig)); cb->cb_refcnt = 1; return cb; }
int main() { struct nl_sock * sk; int cbarg; // nl_debug = 4; // setup netlink socket sk = nl_socket_alloc(); nl_socket_disable_seq_check(sk); // disable sequence number check genl_connect(sk); int id = genl_ctrl_resolve(sk, DEMO_FAMILY_NAME); struct nl_msg * msg; // create a messgae msg = nlmsg_alloc(); genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, id, 0, // hdrlen 0, // flags DEMO_CMD, // numeric command identifier DEMO_VERSION // interface version ); nla_put_string(msg, DEMO_ATTR1_STRING, "hola"); nla_put_u16(msg, DEMO_ATTR2_UINT16, 0xf1); // send it nl_send_auto(sk, msg); // handle reply struct nl_cb * cb = NULL; cb = nl_cb_alloc(NL_CB_CUSTOM); //nl_cb_set_all(cb, NL_CB_DEBUG, NULL, NULL); nl_cb_set_all(cb, NL_CB_CUSTOM, cb_handler, &cbarg); nl_cb_err(cb, NL_CB_DEBUG, NULL, NULL); int nrecv = nl_recvmsgs_report(sk, cb); printf("cbarg %d nrecv %d\n", cbarg, nrecv); // cleanup nlmsg_free(msg); nl_close(sk); nl_socket_free(sk); return 0; }
void unl_genl_loop(struct unl *unl, unl_cb handler, void *arg) { struct nl_cb *cb; cb = nl_cb_alloc(NL_CB_CUSTOM); unl->loop_done = false; nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, handler, arg); while (!unl->loop_done) nl_recvmsgs(unl->sock, cb); nl_cb_put(cb); }
int nlt_get_ifinfo(struct nl_sock *sk, struct nlt_ifinfo *ifinfo) { struct nl_msg *msg = nlmsg_alloc(); if (!msg) return -1; int flags = NLM_F_DUMP; int family_id = genl_ctrl_resolve(sk, "nl80211"); genlmsg_put(msg, 0, NL_AUTO_SEQ, family_id, 0, flags, NL80211_CMD_GET_INTERFACE, 0); // NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, 0); nl_send_auto(sk, msg); int err; struct nl_cb *nl_cb = nl_cb_alloc(NL_CB_CUSTOM); nl_cb_set(nl_cb, NL_CB_VALID, NL_CB_CUSTOM, get_ifinfo_cb, ifinfo); nl_cb_err(nl_cb, NL_CB_CUSTOM, error_handler, &err); int nlr; // do { nlr = nl_recvmsgs(sk, nl_cb); // printf("round %d\n",nlr); // }while(1);; //int nlr = nl_recvmsgs_default(sk); // cw_log(LOG_ERR, "iGet if index: Make if %d - %s", nlr, nl_geterror(nlr)); // nla_put_failure: nlmsg_free(msg); return 0; }
static int __nl_send_msg(struct nl_sock *sock, struct nl_msg *msg, int (*rx_handler)(struct nl_msg *, void *), int (*finish_handler)(struct nl_msg *, void *), void *data) { struct nl_cb *cb; int err, done; struct send_msg_data send_data; DBG(""); cb = nl_cb_alloc(NL_CB_DEFAULT); if (!cb) return -ENOMEM; err = nl_send_auto_complete(sock, msg); if (err < 0) { nl_cb_put(cb); near_error("%s", strerror(err)); return err; } err = done = 0; send_data.done = &done; send_data.data = data; send_data.finish_handler = finish_handler; nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, __finish_handler, &send_data); nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &done); if (rx_handler) nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, rx_handler, data); while (err == 0 && done == 0) nl_recvmsgs(sock, cb); nl_cb_put(cb); return err; }
/* function: getinterface_ip * finds the first global non-privacy IP of the given family for the given interface, or returns NULL. caller frees pointer * interface - interface to look for * family - family */ union anyip *getinterface_ip(const char *interface, int family) { struct ifaddrmsg ifa; struct nl_cb *callbacks = NULL; struct target targ; union anyip *retval = NULL; targ.family = family; targ.foundip = 0; targ.ifindex = if_nametoindex(interface); if(targ.ifindex == 0) { return NULL; // interface not found } memset(&ifa, 0, sizeof(ifa)); ifa.ifa_family = targ.family; callbacks = nl_cb_alloc(NL_CB_DEFAULT); if(!callbacks) { goto cleanup; } nl_cb_set(callbacks, NL_CB_VALID, NL_CB_CUSTOM, getaddr_cb, &targ); nl_cb_err(callbacks, NL_CB_CUSTOM, error_handler, &targ); // sends message and waits for a response send_ifaddrmsg(RTM_GETADDR, NLM_F_REQUEST | NLM_F_ROOT, &ifa, callbacks); if(targ.foundip) { retval = malloc(sizeof(union anyip)); if(!retval) { logmsg(ANDROID_LOG_FATAL,"getinterface_ip/out of memory"); goto cleanup; } memcpy(retval, &targ.ip, sizeof(union anyip)); } cleanup: if(callbacks) nl_cb_put(callbacks); return retval; }
static int do_listen_events(void) { struct nl_cb *cb = nl_cb_alloc((log_level > LOG_WARNING) ? NL_CB_DEBUG : NL_CB_DEFAULT); if (!cb) { LOG_ERR_("failed to allocate netlink callbacks\n"); return -ENOMEM; } /* no sequence checking for multicast messages */ nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, valid_handler, NULL); for (;;) nl_recvmsgs(state.nl_sock, cb); nl_cb_put(cb); return 0; }
static gboolean __nfc_netlink_event(GIOChannel *channel, GIOCondition cond, gpointer data) { struct nl_cb *cb; struct nlnfc_state *state = data; if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) return FALSE; cb = nl_cb_alloc(NL_CB_VERBOSE); if (!cb) return TRUE; nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, nfc_netlink_event, data); nl_recvmsgs(state->event_sock, cb); nl_cb_put(cb); return TRUE; }
/* function: get_default_route * finds the first default route with the given family and interface, returns the gateway (if it exists) in the struct * default_route - requested family and interface, and response storage */ int get_default_route(struct default_route_data *default_route) { struct rtmsg msg; struct nl_cb *callbacks = NULL; struct nl_msg *nlmsg = NULL; int retval = 0; default_route->reply_has_gateway = 0; default_route->reply_found_route = 0; memset(&msg,'\0',sizeof(msg)); msg.rtm_family = default_route->request_family; msg.rtm_table = RT_TABLE_MAIN; msg.rtm_protocol = RTPROT_KERNEL; msg.rtm_scope = RT_SCOPE_UNIVERSE; callbacks = nl_cb_alloc(NL_CB_DEFAULT); if(!callbacks) { retval = -ENOMEM; goto cleanup; } // get_default_route_cb sets the response fields in default_route nl_cb_set(callbacks, NL_CB_VALID, NL_CB_CUSTOM, get_default_route_cb, default_route); nl_cb_err(callbacks, NL_CB_CUSTOM, error_handler, &retval); nlmsg = nlmsg_alloc_rtmsg(RTM_GETROUTE, NLM_F_REQUEST | NLM_F_ROOT, &msg); if(!nlmsg) { retval = -ENOMEM; goto cleanup; } send_netlink_msg(nlmsg, callbacks); cleanup: if(callbacks) nl_cb_put(callbacks); if(nlmsg) nlmsg_free(nlmsg); return retval; }
bool CNL80211::open() { if (m_connected) return true; m_nlCallback = nl_cb_alloc(NL_CB_DEFAULT); m_nlSocket = nl_socket_alloc(); if(!m_nlSocket) { emit message("Could not create netlink socket"); return false; } if (!genl_connect(m_nlSocket)) { emit message("Could not connect to generic netlink interface"); close(); return false; } if (genl_ctrl_alloc_cache(m_nlSocket, &m_nlCache)) { emit message("Could not allocate generic netlink cache."); close(); return false; } m_nlFamily = genl_ctrl_search_by_name(m_nlCache, "nl80211"); if (!m_nlFamily) { emit message("Could not find nl80211"); close(); return false; } m_nlFd = nl_socket_get_fd(m_nlSocket); m_nlSn = new QSocketNotifier(m_nlFd,QSocketNotifier::Read,this); connect(m_nlSn,SIGNAL(activated(int)), this, SLOT(readNlMessage(void))); //Start Signal Quality polling m_sqTimerId = startTimer(m_sqPollrate); m_connected = true; return true; }
static struct nl_cb *gen_cb(){ struct nl_cb *ret = nl_cb_alloc(NL_CB_DEFAULT); if(!ret) flooder_log(FLOODER_DEBUG, "Failed to allocate a callback"); return ret; }
static int send_recv_nlcmd(void *nla, size_t nla_len) { int err, nla_offset = 0; struct nl_cb *cb; struct nl_cb *s_cb; struct nl_msg *msg; if (cur_cmd <= NL80211_CMD_UNSPEC) { LOG_ERR_("Unsupported nl command: %d\n", cur_cmd); return 1; } if (devidx_set) /* Since devidx is a uint32_t the attribute will consume 8 * bytes. The nla input stream must be appended after this * attribute. */ nla_offset = 8; LOG_DBG_("%s: Allocating %d bytes for nlmsg\n", __func__, nla_len + nla_offset + NLMSG_HDRLEN + GENL_HDRLEN); msg = nlmsg_alloc_size(nla_len + nla_offset + NLMSG_HDRLEN + GENL_HDRLEN); if (!msg) { LOG_ERR_("failed to allocate netlink message\n"); return 2; } cb = nl_cb_alloc((log_level > LOG_WARNING) ? NL_CB_DEBUG : NL_CB_DEFAULT); s_cb = nl_cb_alloc((log_level > LOG_WARNING) ? NL_CB_DEBUG : NL_CB_DEFAULT); if (!cb || !s_cb) { LOG_ERR_("failed to allocate netlink callbacks\n"); err = 2; goto out; } genlmsg_put(msg, 0, 0, state.nl80211_id, 0, 0, cur_cmd, 0); if (devidx_set) { LOG_DBG_("%s: Adding devidx %d attribute\n", __func__, devidx); if (dev_by_phy) NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, devidx); else NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx); } add_nla_stream_to_msg(msg, nla, nla_len); nl_socket_set_cb(state.nl_sock, s_cb); err = nl_send_auto_complete(state.nl_sock, msg); if (err < 0) { LOG_ERR_("nl_send_auto_complete %d\n", err); goto out; } err = 1; nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err); nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err); nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, valid_handler, NULL); while (err > 0) nl_recvmsgs(state.nl_sock, cb); out: nl_cb_put(cb); nl_cb_put(s_cb); nlmsg_free(msg); return err; nla_put_failure: LOG_ERR_("building message failed\n"); return 2; }
int main(int argc, char *argv[]) { int opt; while ((opt = getopt(argc, argv, PARAMS)) != -1) { switch (opt) { case 'h': fprintf(stdout, HELP, argv[0]); exit(EXIT_SUCCESS); default: fprintf(stderr, USAGE, argv[0]); exit(EXIT_FAILURE); } } if (optind >= argc - 3) { fprintf(stderr, USAGE, argv[0]); exit(EXIT_FAILURE); } pthread_create(&monthread, NULL, mon_run, NULL); ifacename = argv[optind]; monifname = argv[optind+1]; ssid = argv[optind+2]; int chan = atoi(argv[optind+3]); struct ifreq s; int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); strcpy(s.ifr_name, ifacename); if (ioctl(fd, SIOCGIFHWADDR, &s)) { die("Unable to retrieve hardware address"); } close(fd); memcpy(stamac, s.ifr_addr.sa_data, 6); int iface = if_nametoindex(ifacename); struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT); if(!cb) die("Can't allocate cb"); struct nl_handle *handle; handle = nl_handle_alloc_cb(cb); if(!handle) die("Can't allocate handle"); if(genl_connect(handle)) die("Can't connect to generic netlink"); if ((handle_id = genl_ctrl_resolve(handle, "nl80211")) < 0) die("Can't resolve generic netlink"); usleep(100000); int ret; struct nl_msg* msg; do { msg = gen_msg(iface, ssid, chan); ret = send_and_recv(handle, msg, cb); }while(ret == DEVICE_BUSY); if (ret) printf("Sending failed %s\n", strerror(-ret)); int ctr = 0; while(state != 2) { usleep(100); ctr++; if(ctr == 40000) { die("No probe response within timeout"); } } }
static int execute_nl_interface_cmd(const char *iface, enum nl80211_iftype type, uint8_t cmd) { struct nl_cb *cb; struct nl_msg *msg; int devidx = 0; int err; int add_interface = (cmd == NL80211_CMD_NEW_INTERFACE); if (add_interface) { devidx = phy_lookup(); } else { devidx = if_nametoindex(iface); if (devidx == 0) { ALOGE("failed to translate ifname to idx"); return -errno; } } msg = nlmsg_alloc(); if (!msg) { ALOGE("failed to allocate netlink message"); return 2; } cb = nl_cb_alloc(NL_CB_DEFAULT); if (!cb) { ALOGE("failed to allocate netlink callbacks"); err = 2; goto out_free_msg; } genlmsg_put(msg, 0, 0, genl_family_get_id(nl80211), 0, 0, cmd, 0); if (add_interface) { NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, devidx); } else { NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx); } if (add_interface) { NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, iface); NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, type); } err = nl_send_auto_complete(nl_soc, msg); if (err < 0) goto out; err = 1; nl_cb_err(cb, NL_CB_CUSTOM, nl_error_handler, &err); nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, nl_finish_handler, &err); nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, nl_ack_handler, &err); while (err > 0) nl_recvmsgs(nl_soc, cb); out: nl_cb_put(cb); out_free_msg: nlmsg_free(msg); return err; nla_put_failure: ALOGW("building message failed"); return 2; }
int nl80211_get_chanlist(const char *interface, int *ret_num_chans, int **ret_chan_list, char *errstr) { nl80211_channel_block_t cblock; #ifndef HAVE_LINUX_NETLINK snprintf(errstr, LORCON_STATUS_MAX, "LORCON was not compiled with netlink/nl80211 " "support, check the output of ./configure for why"); return NL80211_CHANLIST_NOT_NL80211; #else void *handle, *cache, *family; struct nl_cb *cb; int err; struct nl_msg *msg; cblock.phyname = nl80211_find_parent(interface); if (strlen(cblock.phyname) == 0) { if (if_nametoindex(interface) <= 0) { snprintf(errstr, LORCON_STATUS_MAX, "Interface %s doesn't exist", interface); return NL80211_CHANLIST_NO_INTERFACE; } snprintf(errstr, LORCON_STATUS_MAX, "LORCON could not find a parent phy device " "for interface %s, it isn't nl80211?", interface); return NL80211_CHANLIST_NOT_NL80211; } if (nl80211_connect(interface, &handle, &cache, &family, errstr) < 0) { return NL80211_CHANLIST_GENERIC; } msg = nlmsg_alloc(); cb = nl_cb_alloc(NL_CB_DEFAULT); err = 1; nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, nl80211_freqlist_cb, &cblock); nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, nl80211_finish_cb, &err); nl_cb_err(cb, NL_CB_CUSTOM, nl80211_error_cb, &err); genlmsg_put(msg, 0, 0, genl_family_get_id((struct genl_family *) family), 0, NLM_F_DUMP, NL80211_CMD_GET_WIPHY, 0); if (nl_send_auto_complete((struct nl_sock *) handle, msg) < 0) { snprintf(errstr, LORCON_STATUS_MAX, "%s: Failed to write nl80211 message", __FUNCTION__); nl80211_disconnect(handle); return NL80211_CHANLIST_GENERIC; } while (err) nl_recvmsgs((struct nl_sock *) handle, cb); nl80211_disconnect(handle); (*ret_num_chans) = cblock.nfreqs; (*ret_chan_list) = (int *) malloc(sizeof(int) * cblock.nfreqs); memcpy(*ret_chan_list, cblock.channel_list, sizeof(int) * cblock.nfreqs); free(cblock.channel_list); free(cblock.phyname); return (*ret_num_chans); #endif }
static int __handle_cmd(struct nl80211_state *state, const char *iface, int get) { struct nl_cb *cb; struct nl_msg *msg; int devidx = 0; int err; devidx = if_nametoindex(iface); if (devidx == 0) devidx = -1; if (devidx < 0) return -errno; msg = nlmsg_alloc(); if (!msg) { fprintf(stderr, "failed to allocate netlink message\n"); return 2; } cb = nl_cb_alloc(NL_CB_DEFAULT); if (!cb) { fprintf(stderr, "failed to allocate netlink callbacks\n"); err = 2; goto out_free_msg; } if (get) genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0, 0, NL80211_CMD_GET_POWER_SAVE, 0); else genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0, 0, NL80211_CMD_SET_POWER_SAVE, 0); NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx); if (get) err = get_power_save(state, cb, msg); else err = set_power_save(state, cb, msg); if (err) goto out; err = nl_send_auto_complete(state->nl_sock, msg); if (err < 0) goto out; err = 1; nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err); nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err); while (err > 0) nl_recvmsgs(state->nl_sock, cb); out: nl_cb_put(cb); out_free_msg: nlmsg_free(msg); return err; nla_put_failure: fprintf(stderr, "building message failed\n"); return 2; }