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 struct nl80211_msg_conveyor * nl80211_send( struct nl80211_msg_conveyor *cv, int (*cb_func)(struct nl_msg *, void *), void *cb_arg ) { static struct nl80211_msg_conveyor rcv; int err = 1; if (cb_func) nl_cb_set(cv->cb, NL_CB_VALID, NL_CB_CUSTOM, cb_func, cb_arg); else nl_cb_set(cv->cb, NL_CB_VALID, NL_CB_CUSTOM, nl80211_msg_response, &rcv); if (nl_send_auto_complete(nls->nl_sock, cv->msg) < 0) goto err; nl_cb_err(cv->cb, NL_CB_CUSTOM, nl80211_msg_error, &err); nl_cb_set(cv->cb, NL_CB_FINISH, NL_CB_CUSTOM, nl80211_msg_finish, &err); nl_cb_set(cv->cb, NL_CB_ACK, NL_CB_CUSTOM, nl80211_msg_ack, &err); while (err > 0) nl_recvmsgs(nls->nl_sock, cv->cb); return &rcv; err: nl_cb_put(cv->cb); nlmsg_free(cv->msg); return NULL; }
static int nl80211_del_mon_if(struct nl80211_state *state, const char *device, const char *mondevice) { int ifindex, ret; struct nl_msg *msg; ifindex = device_ifindex(mondevice); msg = nl80211_nlmsg_xalloc(); genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0, 0, NL80211_CMD_DEL_INTERFACE, 0); NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex); ret = nl_send_auto_complete(state->nl_sock, msg); if (ret < 0) panic("Cannot send_auto_complete!\n"); ret = nl_wait_for_ack(state->nl_sock); if (ret < 0) panic("Waiting for netlink ack failed!\n"); nlmsg_free(msg); return 0; nla_put_failure: panic("nla put failure!\n"); return -EIO; /* dummy */ }
void send_msg(long int ip, long int puerto, char sentido){ nla_put_u32( msg, ATTR_ADDR, ip); nla_put_u16( msg, ATTR_PORT, puerto); nla_put_u16( msg, ATTR_WAY, sentido); nl_send_auto_complete(sock, msg); printf("Peticion registrada :)"); }
static int send_and_recv(struct nl_sock *nl_sock, struct nl_msg *msg, int (*valid_handler)(struct nl_msg *, void *), void *valid_data) { struct nl_cb *cb; int err = -ENOMEM; cb = nl_cb_clone(nlcfg.nl_cb); if (!cb) goto out; err = nl_send_auto_complete(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); if (valid_handler) nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, valid_handler, valid_data); while (err > 0) nl_recvmsgs(nl_sock, cb); out: nl_cb_put(cb); nlmsg_free(msg); return err; }
int main(int argc, char *argv[]) { struct nl_sock *sock; struct nl_msg *msg; void *hdr; int err; sock = nlt_alloc_socket(); nlt_connect(sock, NETLINK_GENERIC); msg = nlmsg_alloc(); if (msg == NULL) fatal(NLE_NOMEM, "Unable to allocate netlink message"); hdr = genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, GENL_ID_CTRL, 0, 0, CTRL_CMD_GETFAMILY, 1); if (hdr == NULL) fatal(ENOMEM, "Unable to write genl header"); if ((err = nla_put_u32(msg, CTRL_ATTR_FAMILY_ID, GENL_ID_CTRL)) < 0) fatal(err, "Unable to add attribute: %s", nl_geterror(err)); if ((err = nl_send_auto_complete(sock, msg)) < 0) fatal(err, "Unable to send message: %s", nl_geterror(err)); if ((err = nl_recvmsgs_default(sock)) < 0) fatal(err, "Unable to receive message: %s", nl_geterror(err)); nlmsg_free(msg); nl_close(sock); nl_socket_free(sock); return 0; }
void CNL80211::scan() { //Get interface index for device: unsigned int devidx = if_nametoindex(m_ifname.toAscii().constData()); if (devidx == 0) { emit message("Could not get interface index"); return; } //Allocate a new netlink message nl_msg * msg; msg = nlmsg_alloc(); if (!msg) { emit message("Could not allocate netlink message"); return; } //allocate the callback function with default verbosity // nl_cb * cb = nl_cb_alloc(NL_CB_DEFAULT); // if (!cb) { // emit message("Could not allocate netlink callback"); // nlmsg_free(msg); // return; // } nl_socket_modify_cb(m_nlSocket, NL_CB_VALID, NL_CB_CUSTOM, &cbForScanResults, this); genlmsg_put(msg, 0, 0, genl_family_get_id(m_nlFamily), 0, (NLM_F_REQUEST | NLM_F_DUMP), NL80211_CMD_GET_SCAN, 0); //Set the interface we want to operate on nla_put_u32(msg, NL80211_ATTR_IFNAME,devidx); //hier kommt noch was rein //Send the message nl_send_auto_complete(m_nlSocket,msg); nlmsg_free(msg); }
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 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 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 */ }
/* NOTE: this function consumes 'msg' */ static int _nl80211_send_and_recv (struct nl_sock *nl_sock, struct nl_cb *nl_cb, struct nl_msg *msg, int (*valid_handler) (struct nl_msg *, void *), void *valid_data) { struct nl_cb *cb; int err, done; g_return_val_if_fail (msg != NULL, -ENOMEM); cb = nl_cb_clone (nl_cb); if (!cb) { err = -ENOMEM; goto out; } err = nl_send_auto_complete (nl_sock, msg); if (err < 0) goto out; done = 0; nl_cb_err (cb, NL_CB_CUSTOM, error_handler, &done); nl_cb_set (cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &done); nl_cb_set (cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &done); if (valid_handler) nl_cb_set (cb, NL_CB_VALID, NL_CB_CUSTOM, valid_handler, valid_data); /* Loop until one of our NL callbacks says we're done; on success * done will be 1, on error it will be < 0. */ while (!done) { err = nl_recvmsgs (nl_sock, cb); if (err && err != -NLE_AGAIN) { /* Kernel scan list can change while we are dumping it, as new scan * results from H/W can arrive. BSS info is assured to be consistent * and we don't need consistent view of whole scan list. Hence do * not warn on DUMP_INTR error for get scan command. */ if (err == -NLE_DUMP_INTR && genlmsg_hdr(nlmsg_hdr(msg))->cmd == NL80211_CMD_GET_SCAN) break; nm_log_warn (LOGD_WIFI, "nl_recvmsgs() error: (%d) %s", err, nl_geterror (err)); break; } } if (err == 0 && done < 0) err = done; out: nl_cb_put (cb); nlmsg_free (msg); return err; }
int nl80211_createvap(const char *interface, const char *newinterface, char *errstr) { #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 -1; #else struct nl_sock *nl_handle; struct nl_cache *nl_cache; struct genl_family *nl80211; struct nl_msg *msg; if (if_nametoindex(newinterface) > 0) return 1; if (nl80211_connect(interface, (void **) &nl_handle, (void **) &nl_cache, (void **) &nl80211, errstr) < 0) return -1; if ((msg = nlmsg_alloc()) == NULL) { snprintf(errstr, LORCON_STATUS_MAX, "nl80211_createvap() failed to allocate " "message"); nl80211_disconnect(nl_handle); return -1; } genlmsg_put(msg, 0, 0, genl_family_get_id(nl80211), 0, 0, NL80211_CMD_NEW_INTERFACE, 0); NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(interface)); NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, newinterface); NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_MONITOR); if (nl_send_auto_complete(nl_handle, msg) < 0 || nl_wait_for_ack(nl_handle) < 0) { nla_put_failure: snprintf(errstr, LORCON_STATUS_MAX, "nl80211_createvap() failed to create " "interface '%s'", newinterface); nlmsg_free(msg); nl80211_disconnect(nl_handle); return -1; } nlmsg_free(msg); nl80211_disconnect(nl_handle); if (if_nametoindex(newinterface) <= 0) { snprintf(errstr, LORCON_STATUS_MAX, "nl80211_createvap() thought we made a " "vap, but it wasn't there when we looked"); return -1; } return 0; #endif }
static int send_log_msg(struct nl_handle *handle, struct nl_msg *msg) { int err; err = nl_send_auto_complete(handle, msg); nlmsg_free(msg); if (err < 0) return err; return nl_wait_for_ack(handle); }
/** * Delete a neighbour * @arg handle netlink handle * @arg neigh neighbour to delete * * Builds a netlink message by calling rtnl_neigh_build_delete_request(), * sends the request to the kernel and waits for the next ACK to be * received and thus blocks until the request has been fullfilled. * * @return 0 on sucess or a negative error if an error occured. */ int rtnl_neigh_delete(struct nl_handle *handle, struct rtnl_neigh *neigh) { int err; struct nl_msg *m = rtnl_neigh_build_delete_request(neigh); if ((err = nl_send_auto_complete(handle, nl_msg_get(m))) < 0) return err; nl_msg_free(m); return nl_wait_for_ack(handle); }
/** * Add a new rule * @arg handle netlink handle * @arg tmpl template with requested changes * * Builds a netlink message by calling rtnl_rule_build_add_request(), * sends the request to the kernel and waits for the next ACK to be * received and thus blocks until the request has been fullfilled. * * @return 0 on sucess or a negative error if an error occured. */ int rtnl_rule_add(struct nl_handle *handle, struct rtnl_rule *tmpl) { int err; struct nl_msg *m = rtnl_rule_build_add_request(tmpl); if ((err = nl_send_auto_complete(handle, nl_msg_get(m))) < 0) return err; nl_msg_free(m); return nl_wait_for_ack(handle); }
static int send_log_request(struct nl_sock *sk, struct nl_msg *msg) { int err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return wait_for_ack(sk); }
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; }
int nl80211_setchannel_cache(const char *interface, void *handle, void *family, int channel, unsigned int chmode, char *errstr) { #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 the same error as we get if the device doesn't support nlfreq return -22; #else struct nl_sock *nl_handle = (struct nl_sock *) handle; struct genl_family *nl80211 = (struct genl_family *) family; struct nl_msg *msg; int ret = 0; int chanmode[] = { NL80211_CHAN_NO_HT, NL80211_CHAN_HT20, NL80211_CHAN_HT40PLUS, NL80211_CHAN_HT40MINUS }; if (chmode > 4) { snprintf(errstr, LORCON_STATUS_MAX, "Invalid channel mode\n"); return -1; } if ((msg = nlmsg_alloc()) == NULL) { snprintf(errstr, LORCON_STATUS_MAX, "nl80211_setchannel() failed to allocate " "message"); return -1; } genlmsg_put(msg, 0, 0, genl_family_get_id(nl80211), 0, 0, NL80211_CMD_SET_WIPHY, 0); NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(interface)); NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, ChanToFreq(channel)); NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, chanmode[chmode]); if ((ret = nl_send_auto_complete(nl_handle, msg)) >= 0) { if ((ret = nl_wait_for_ack(nl_handle)) < 0) goto nla_put_failure; } nlmsg_free(msg); return 0; nla_put_failure: snprintf(errstr, LORCON_STATUS_MAX, "nl80211_setchannel() could not set channel " "%d/%d on interface '%s' err %d", channel, ChanToFreq(channel), interface, ret); nlmsg_free(msg); return ret; #endif }
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 }
int nl80211_setvapflag(const char *interface, char *errstr, int nflags, int *in_flags) { #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 -1; #else struct nl_sock *nl_handle; struct nl_cache *nl_cache; struct genl_family *nl80211; struct nl_msg *msg; if (nl80211_connect(interface, (void **) &nl_handle, (void **) &nl_cache, (void **) &nl80211, errstr) < 0) return -1; if ((msg = nlmsg_alloc()) == NULL) { snprintf(errstr, LORCON_STATUS_MAX, "%s failed to allocate message", __FUNCTION__); nl80211_disconnect(nl_handle); return -1; } genlmsg_put(msg, 0, 0, genl_family_get_id(nl80211), 0, 0, NL80211_CMD_SET_INTERFACE, 0); NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(interface)); NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_MONITOR); nl80211_parseflags(nflags, in_flags, msg); if (nl_send_auto_complete(nl_handle, msg) >= 0) { if (nl_wait_for_ack(nl_handle) < 0) { goto nla_put_failure; } } else { nla_put_failure: snprintf(errstr, LORCON_STATUS_MAX, "%s failed to set flags on " "interface '%s': %s", __FUNCTION__, interface, strerror(errno)); nlmsg_free(msg); nl80211_disconnect(nl_handle); return -1; } nlmsg_free(msg); nl80211_disconnect(nl_handle); return 0; #endif }
// 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 ipvs_nl_send_message(struct nl_msg *msg, nl_recvmsg_msg_cb_t func, void *arg) { int err = EINVAL; sock = nl_socket_alloc(); if (!sock) { nlmsg_free(msg); return -1; } if (genl_connect(sock) < 0) goto fail_genl; family = genl_ctrl_resolve(sock, IPVS_GENL_NAME); if (family < 0) goto fail_genl; /* To test connections and set the family */ if (msg == NULL) { nl_socket_free(sock); sock = NULL; return 0; } if (nl_socket_modify_cb(sock, NL_CB_VALID, NL_CB_CUSTOM, func, arg) != 0) goto fail_genl; if (nl_send_auto_complete(sock, msg) < 0) goto fail_genl; if ((err = -nl_recvmsgs_default(sock)) > 0) goto fail_genl; nlmsg_free(msg); nl_socket_free(sock); return 0; fail_genl: nl_socket_free(sock); sock = NULL; nlmsg_free(msg); errno = err; #ifndef FALLBACK_LIBNL1 errno = nlerr2syserr(err); #endif return -1; }
/** * Delete a rule * @arg sk Netlink socket. * @arg rule rule to delete * @arg flags additional netlink message flags * * Builds a netlink message by calling rtnl_rule_build_delete_request(), * sends the request to the kernel and waits for the next ACK to be * received and thus blocks until the request has been fullfilled. * * @return 0 on sucess or a negative error if an error occured. */ int rtnl_rule_delete(struct nl_sock *sk, struct rtnl_rule *rule, int flags) { struct nl_msg *msg; int err; if ((err = rtnl_rule_build_delete_request(rule, flags, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return wait_for_ack(sk); }
int xfrmnl_ae_set(struct nl_sock* sk, struct xfrmnl_ae* ae, int flags) { int err; struct nl_msg *msg; if ((err = build_xfrm_ae_message(ae, XFRM_MSG_NEWAE, flags|NLM_F_REPLACE, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return nl_wait_for_ack(sk); }
int nfnl_exp_query(struct nl_sock *sk, const struct nfnl_exp *exp, int flags) { struct nl_msg *msg; int err; if ((err = nfnl_exp_build_query_request(exp, flags, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return wait_for_ack(sk); }
int nfnl_ct_del(struct nl_sock *sk, const struct nfnl_ct *ct, int flags) { struct nl_msg *msg; int err; if ((err = nfnl_ct_build_delete_request(ct, flags, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return wait_for_ack(sk); }
/** * Change a classifier * @arg sk Netlink socket. * @arg cls classifier to change * @arg flags additional netlink message flags * * Builds a netlink message by calling rtnl_cls_build_change_request(), * sends the request to the kernel and waits for the next ACK to be * received and thus blocks until the request has been processed. * * @return 0 on sucess or a negative error if an error occured. */ int rtnl_cls_change(struct nl_sock *sk, struct rtnl_cls *cls, int flags) { struct nl_msg *msg; int err; if ((err = rtnl_cls_build_change_request(cls, flags, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); nlmsg_free(msg); if (err < 0) return err; return nl_wait_for_ack(sk); }
/* NOTE: this function consumes 'msg' */ static int _nl80211_send_and_recv (struct nl_sock *nl_sock, struct nl_cb *nl_cb, struct nl_msg *msg, int (*valid_handler)(struct nl_msg *, void *), void *valid_data) { struct nl_cb *cb; int err, done; g_return_val_if_fail (msg != NULL, -ENOMEM); cb = nl_cb_clone (nl_cb); if (!cb) { err = -ENOMEM; goto out; } err = nl_send_auto_complete (nl_sock, msg); if (err < 0) goto out; done = 0; nl_cb_err (cb, NL_CB_CUSTOM, error_handler, &done); nl_cb_set (cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &done); nl_cb_set (cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &done); if (valid_handler) nl_cb_set (cb, NL_CB_VALID, NL_CB_CUSTOM, valid_handler, valid_data); /* Loop until one of our NL callbacks says we're done; on success * done will be 1, on error it will be < 0. */ while (!done) { err = nl_recvmsgs (nl_sock, cb); if (err && err != -NLE_AGAIN) { nm_log_warn (LOGD_WIFI, "nl_recvmsgs() error: (%d) %s", err, nl_geterror (err)); break; } } if (err == 0 && done < 0) err = done; out: nl_cb_put (cb); nlmsg_free (msg); return err; }
/** * Request addition of new address * @arg handle Netlink handle. * @arg addr Address object representing the new address. * @arg flags Additional netlink message flags. * * Builds a netlink message by calling rtnl_addr_build_add_request(), * sends the request to the kernel and waits for the next ACK to be * received and thus blocks until the request has been fullfilled. * * @see rtnl_addr_build_add_request() * * @return 0 on sucess or a negative error if an error occured. */ int rtnl_addr_add(struct nl_handle *handle, struct rtnl_addr *addr, int flags) { struct nl_msg *msg; int err; msg = rtnl_addr_build_add_request(addr, flags); if (!msg) return nl_get_errno(); err = nl_send_auto_complete(handle, msg); nlmsg_free(msg); if (err < 0) return err; return nl_wait_for_ack(handle); }