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 */ }
int reroute_path_selection_frames(char* ifname) { struct nl_msg *msg; uint8_t cmd = NL80211_CMD_REGISTER_FRAME; int ret; char *pret; char action_code[2] = { 0x20, 0x00 }; int ifindex = if_nametoindex(ifname); msg = nlmsg_alloc(); if (!msg) return -ENOMEM; pret = genlmsg_put(msg, 0, 0, genl_family_get_id(nlcfg.nl80211), 0, 0, cmd, 0); if (pret == NULL) goto nla_put_failure; NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex); NLA_PUT(msg, NL80211_ATTR_FRAME_MATCH, sizeof(action_code), action_code); ret = send_and_recv_msgs(msg, receive_ps_frames, NULL); if (ret) printf("Registering for path selection frames failed: %d (%s)\n", ret, strerror(-ret)); else printf("Registering for path selection frames succeeded. Yay!\n"); return ret; nla_put_failure: return -ENOBUFS; }
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 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); }
static bool nl80211_msg_prepare(struct nl_msg **const msgp, const enum nl80211_commands cmd, const char *const interface) { struct nl_msg *msg = nlmsg_alloc(); if (!msg) { fprintf(stderr, "failed to allocate netlink message\n"); return false; } if (!genlmsg_put(msg, 0, 0, genl_family_get_id(family), 0, 0 /*flags*/, cmd, 0)) { fprintf(stderr, "failed to add generic netlink headers\n"); goto nla_put_failure; } if (interface) { //TODO: PHY commands don't need interface name but wiphy index unsigned int if_index = if_nametoindex(interface); if (!if_index) { fprintf(stderr, "interface %s does not exist\n", interface); goto nla_put_failure; } NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_index); } *msgp = msg; return true; nla_put_failure: nlmsg_free(msg); return false; }
static int wpa_driver_get_power_save(void *priv, int *state) { struct i802_bss *bss = priv; struct wpa_driver_nl80211_data *drv = bss->drv; struct nl_msg *msg; int ret = -1; enum nl80211_ps_state ps_state; msg = nlmsg_alloc(); if (!msg) return -1; genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0, NL80211_CMD_GET_POWER_SAVE, 0); NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex); ret = send_and_recv_msgs(drv, msg, get_power_mode_handler, state); msg = NULL; if (ret < 0) wpa_printf(MSG_ERROR, "nl80211: Get power mode fail: %d", ret); nla_put_failure: nlmsg_free(msg); return ret; }
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 */ }
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; }
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 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 }
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 }
int join_mesh(char* ifname, char *mesh_id, int mesh_id_len, char *vendor_ie, int vendor_ie_len) { struct nl_msg *msg; uint8_t cmd = NL80211_CMD_JOIN_MESH; int ret; char *pret; int ifindex = if_nametoindex(ifname); msg = nlmsg_alloc(); if (!msg) return -ENOMEM; if (!mesh_id || !mesh_id_len) return -EINVAL; printf("o11s-pathseld: Staring mesh with mesh id = %s\n", mesh_id); pret = genlmsg_put(msg, 0, 0, genl_family_get_id(nlcfg.nl80211), 0, 0, cmd, 0); if (pret == NULL) goto nla_put_failure; if (vendor_ie) { struct nlattr *container = nla_nest_start(msg, NL80211_ATTR_MESH_PARAMS); if (!container) return -ENOBUFS; NLA_PUT(msg, NL80211_MESHCONF_VENDOR_PATH_SEL_IE, vendor_ie_len, vendor_ie); NLA_PUT_U8(msg, NL80211_MESHCONF_ENABLE_VENDOR_PATH_SEL, 1); NLA_PUT_U8(msg, NL80211_MESHCONF_ENABLE_VENDOR_METRIC, 1); nla_nest_end(msg, container); } NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex); NLA_PUT(msg, NL80211_ATTR_MESH_ID, mesh_id_len, mesh_id); ret = send_and_recv_msgs(msg, NULL, NULL); if (ret) printf("Mesh start failed: %d (%s)\n", ret, strerror(-ret)); else printf("Mesh start succeeded. Yay!\n"); return ret; nla_put_failure: return -ENOBUFS; }
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; }
struct nl_msg *unl_genl_msg(struct unl *unl, int cmd, bool dump) { struct nl_msg *msg; int flags = 0; msg = nlmsg_alloc(); if (!msg) goto out; if (dump) flags |= NLM_F_DUMP; genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, genl_family_get_id(unl->family), 0, flags, cmd, 0); out: return msg; }
static int set_mesh_conf(struct netlink_config_s *nlcfg, struct mesh_node *mesh, uint32_t changed) { struct nl_msg *msg; uint8_t cmd = NL80211_CMD_SET_MESH_CONFIG; int ret = 0; char *pret; sae_debug(MESHD_DEBUG, "%s(%p, %d)\n", __FUNCTION__, nlcfg, changed); msg = nlmsg_alloc(); if (!msg) return -ENOMEM; pret = genlmsg_put(msg, 0, NL_AUTO_SEQ, genl_family_get_id(nlcfg->nl80211), 0, 0, cmd, 0); if (pret == NULL) goto nla_put_failure; struct nlattr *container = nla_nest_start(msg, NL80211_ATTR_MESH_CONFIG); if (!container) goto nla_put_failure; if (changed & MESH_CONF_CHANGED_HT) NLA_PUT_U32(msg, NL80211_MESHCONF_HT_OPMODE, mesh->conf->ht_prot_mode); nla_nest_end(msg, container); NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, nlcfg->ifindex); ret = send_nlmsg(nlcfg->nl_sock, msg); sae_debug(MESHD_DEBUG, "set meshconf (seq num=%d)\n", nlmsg_hdr(msg)->nlmsg_seq); if (ret < 0) sae_debug(MESHD_DEBUG, "set meshconf failed: %d (%s)\n", ret, strerror(-ret)); return ret; nla_put_failure: nlmsg_free(msg); return -ENOBUFS; }
static struct nl_msg * wprobe_new_msg(const char *ifname, int cmd, bool dump) { struct nl_msg *msg; uint32_t flags = 0; msg = nlmsg_alloc(); if (!msg) return NULL; if (dump) flags |= NLM_F_DUMP; genlmsg_put(msg, 0, 0, genl_family_get_id(family), 0, flags, cmd, 0); NLA_PUT_STRING(msg, WPROBE_ATTR_INTERFACE, ifname); nla_put_failure: return msg; }
static int tx_frame(struct netlink_config_s *nlcfg, struct mesh_node *mesh, unsigned char *frame, int len) { struct nl_msg *msg; uint8_t cmd = NL80211_CMD_FRAME; int ret = 0; char *pret; sae_debug(MESHD_DEBUG, "%s(%p, %p, %d)\n", __FUNCTION__, nlcfg, frame, len); msg = nlmsg_alloc(); if (!msg) return -ENOMEM; if (!frame || !len) return -EINVAL; pret = genlmsg_put(msg, 0, NL_AUTO_SEQ, genl_family_get_id(nlcfg->nl80211), 0, 0, cmd, 0); if (pret == NULL) goto nla_put_failure; NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, nlcfg->ifindex); NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, mesh->freq); NLA_PUT(msg, NL80211_ATTR_FRAME, len, frame); ret = send_nlmsg(nlcfg->nl_sock, msg); sae_debug(MESHD_DEBUG, "tx frame (seq num=%d)\n", nlmsg_hdr(msg)->nlmsg_seq); if (ret < 0) sae_debug(MESHD_DEBUG, "tx frame failed: %d (%s)\n", ret, strerror(-ret)); else sae_hexdump(MESHD_DEBUG, "tx frame", frame, len); return ret; nla_put_failure: nlmsg_free(msg); return -ENOBUFS; }
static int handle_interface_del(struct nl80211_state *state, char *phy, char *dev, int argc, char **argv) { int err; struct nl_msg *msg; if (argc) { fprintf(stderr, "too many arguments\n"); return -1; } msg = nlmsg_alloc(); if (!msg) return -1; genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0, 0, NL80211_CMD_DEL_INTERFACE, 0); if (!dev) { fprintf(stderr, "need device\n"); nlmsg_free(msg); return -1; } NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(dev)); if ((err = nl_send_auto_complete(state->nl_handle, msg)) < 0 || (err = nl_wait_for_ack(state->nl_handle)) < 0) { nla_put_failure: fprintf(stderr, "failed to remove interface: %d\n", err); nlmsg_free(msg); return -1; } nlmsg_free(msg); return 0; }
static int nl80211_set_wowlan_triggers(struct i802_bss *bss, int enable) { struct nl_msg *msg, *pats = NULL; struct nlattr *wowtrig, *pat; int i, ret = -1; int filters; bss->drv->wowlan_enabled = !!enable; msg = nlmsg_alloc(); if (!msg) return -ENOMEM; genlmsg_put(msg, 0, 0, genl_family_get_id(bss->drv->nl80211), 0, 0, NL80211_CMD_SET_WOWLAN, 0); NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->drv->first_bss.ifindex); wowtrig = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS); if (!wowtrig) { ret = -ENOBUFS; goto nla_put_failure; } if (!enable) { NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_ANY); } else { pats = nlmsg_alloc(); if (!pats) { ret = -ENOMEM; goto nla_put_failure; } /* In ginger filter 0 and 1 are always set but in ICS we * only enable unicast. Make sure to always set it, otherwise * unicast packets will be dropped. * bcast packets are dropped and handled by the firmware */ filters = bss->drv->wowlan_triggers |= 1; for (i = 0; i < NR_RX_FILTERS; i++) { if (filters & (1 << i)) { struct rx_filter *rx_filter = &rx_filters[i]; int patnr = 1; u8 *pattern = nl80211_rx_filter_get_pattern(rx_filter,bss); if (!pattern) continue; pat = nla_nest_start(pats, patnr++); NLA_PUT(pats, NL80211_WOWLAN_PKTPAT_MASK, rx_filter->mask_len, rx_filter->mask); NLA_PUT(pats, NL80211_WOWLAN_PKTPAT_PATTERN, rx_filter->pattern_len, pattern); nla_nest_end(pats, pat); } } } if (pats) nla_put_nested(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN, pats); nla_nest_end(msg, wowtrig); ret = send_and_recv_msgs(bss->drv, msg, NULL, NULL); if (ret < 0) wpa_printf(MSG_ERROR, "Failed to set WoWLAN trigger:%d\n", ret); if (pats) nlmsg_free(pats); return 0; nla_put_failure: nlmsg_free(msg); return ret; }
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; }
static int handle_interface_add(struct nl80211_state *state, char *phy, char *dev, int argc, char **argv) { char *name; char *mesh_id = NULL; enum nl80211_iftype type; int tpset, err; struct nl_msg *msg; if (argc < 1) { fprintf(stderr, "not enough arguments\n"); return -1; } name = argv[0]; argc--; argv++; tpset = get_if_type(&argc, &argv, &type); if (tpset == 0) fprintf(stderr, "you must specify an interface type\n"); if (tpset <= 0) return -1; if (argc) { if (strcmp(argv[0], "mesh_id") != 0) { fprintf(stderr, "option %s not supported\n", argv[0]); return -1; } argc--; argv++; if (!argc) { fprintf(stderr, "not enough arguments\n"); return -1; } mesh_id = argv[0]; argc--; argv++; } if (argc) { fprintf(stderr, "too many arguments\n"); return -1; } msg = nlmsg_alloc(); if (!msg) { fprintf(stderr, "failed to allocate netlink msg\n"); return -1; } genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0, 0, NL80211_CMD_NEW_INTERFACE, 0); if (dev) NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(dev)); if (phy) return -1; /* XXX TODO */ NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, name); if (tpset) NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, type); if (mesh_id) NLA_PUT(msg, NL80211_ATTR_MESH_ID, strlen(mesh_id), mesh_id); if ((err = nl_send_auto_complete(state->nl_handle, msg)) < 0 || (err = nl_wait_for_ack(state->nl_handle)) < 0) { nla_put_failure: fprintf(stderr, "failed to create interface: %d\n", err); nlmsg_free(msg); return -1; } nlmsg_free(msg); return 0; }