bool linux_unicast_router::lookup_prefix(const in6_addr &addr, lookup_result &reply) const { /* Not fully inited yet */ if (rt_bcast_sock.fd() < 0) return false; netlink_msg *msg = (netlink_msg *)buffer; msg->build(RTM_GETROUTE); msg->addattr(RTA_DST, &addr, sizeof(in6_addr)); msg->r.rtm_dst_len = 128; reply.dev = -1; if (send_nlmsg(msg, msg)) { if (msg->r.rtm_family != AF_INET6) return false; rtattr *tb[RTA_MAX + 1]; memset(tb, 0, sizeof(tb)); msg->parse_rtatable(tb, RTA_MAX, RTM_RTA(NLMSG_DATA(&msg->n)), msg->length() - NLMSG_LENGTH(sizeof(rtmsg))); parse_prefix_rec(tb, msg->r.rtm_dst_len, msg->r.rtm_protocol, reply); return true; } return false; }
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 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; }