Added some stuff to handle libnl calls easy.
FossilOrigin-Name: 5ca8884ce8acf063ea5728da2097a0f4f48d86b7fde7cb225bf0f6d0b644b3c9
This commit is contained in:
		
							
								
								
									
										287
									
								
								src/wtp/nlt.c
									
									
									
									
									
								
							
							
						
						
									
										287
									
								
								src/wtp/nlt.c
									
									
									
									
									
								
							| @ -3,80 +3,293 @@ | ||||
| #include "netlink/genl/ctrl.h" | ||||
| #include <netlink/msg.h> | ||||
|  | ||||
|  | ||||
| #include "capwap/cw_log.h" | ||||
| #include "nlt.h" | ||||
|  | ||||
| /* | ||||
| int nlt_send_and_recvmsg(struct nl_sock *sk, struct nl_msg *msg) | ||||
|  | ||||
| static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) | ||||
| { | ||||
| 	struct nl_cb * cb = nl_socket_get_cb(sk); | ||||
|  | ||||
| 	printf("Error handler ------lllllllllllllllllllllllllllllllllllllllllllllllllllllll\n"); | ||||
| 	int *ret = arg; | ||||
| 	*ret = err->error; | ||||
| 	printf("Err: %d\n", *ret); | ||||
| 	return NL_SKIP; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| static int add_wiphyinfo(struct nlattr *msgattribs[NL80211_ATTR_MAX + 1], | ||||
| 			 struct nlt_wiphyinfo **wiphyinfos) | ||||
| { | ||||
| 	if (!msgattribs[NL80211_ATTR_WIPHY]) { | ||||
| 		return NL_SKIP; | ||||
| 	} | ||||
|  | ||||
| 	int index = nla_get_u32(msgattribs[NL80211_ATTR_WIPHY]); | ||||
|  | ||||
|  | ||||
| 	struct nlt_wiphyinfo *wi = wiphyinfos[index]; | ||||
|  | ||||
| 	if (!wi) { | ||||
| 		wi = malloc(sizeof(struct nlt_wiphyinfo)); | ||||
| 		memset(wi, 0, sizeof(struct nlt_wiphyinfo)); | ||||
| 		wiphyinfos[index] = wi; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	if (msgattribs[NL80211_ATTR_WIPHY_NAME] && !wi->name) { | ||||
| 		wi->name = strdup(nla_get_string(msgattribs[NL80211_ATTR_WIPHY_NAME])); | ||||
| 	} | ||||
|  | ||||
|  | ||||
|  | ||||
| 	return 0; | ||||
|  | ||||
| } | ||||
|  | ||||
| */ | ||||
|  | ||||
| /* | ||||
| struct nlt_ifinfo { | ||||
| 	const char *ifname; | ||||
| 	int ifindex; | ||||
| 	int iftype; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| struct nlt_msg { | ||||
| 	int cmd; | ||||
| 	struct nlattr *attribs[NL80211_ATTR_MAX + 1]; | ||||
| }; | ||||
|  | ||||
| static int nlt_parse(struct nl_msg *msg, struct nlt_msg *r) | ||||
| { | ||||
| 	struct nlmsghdr *msghdr = nlmsg_hdr(msg); | ||||
| 	struct genlmsghdr *ghdr = (struct genlmsghdr *) nlmsg_data(msghdr); | ||||
| 	int rc; | ||||
| 	rc = nla_parse(r->attribs, NL80211_ATTR_MAX, genlmsg_attrdata(ghdr, 0), | ||||
| 		       genlmsg_attrlen(ghdr, 0), NULL); | ||||
| 	if (rc < 0) | ||||
| 		return rc; | ||||
| 	r->cmd = ghdr->cmd; | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int get_ifinfo_cb(struct nl_msg *msg, void *arg) | ||||
| { | ||||
| 	struct nlt_ifinfo *cb_data = (struct ifindex_cb_data *) arg; | ||||
| 	struct nlt_ifinfo *ifinfo = (struct nlt_ifinfo *) arg; | ||||
|  | ||||
| 	struct nlt_msg r; | ||||
| 	nlt_parse(msg, &r); | ||||
|  | ||||
|  | ||||
| 	if (r.cmd != NL80211_CMD_NEW_INTERFACE) | ||||
| 		return NL_OK; | ||||
|  | ||||
|  | ||||
| 	if (ifinfo->ifname != NULL) { | ||||
| 		printf("! if info != 0\n"); | ||||
|  | ||||
| 		if (!r.attribs[NL80211_ATTR_IFNAME]) | ||||
| 			return NL_OK; | ||||
|  | ||||
| 		const char *cbname = nla_get_string(r.attribs[NL80211_ATTR_IFNAME]); | ||||
| 		printf("Callback name %s\n", cbname); | ||||
|  | ||||
| 		if (strcmp(ifinfo->ifname, nla_get_string(r.attribs[NL80211_ATTR_IFNAME])) | ||||
| 		    != 0) | ||||
| 			return NL_OK; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	if (r.attribs[NL80211_ATTR_IFNAME]) { | ||||
| 		if (ifinfo->ifname == NULL) | ||||
| 			ifinfo->ifname = strdup(nla_get_string(r.attribs[NL80211_ATTR_IFNAME])); | ||||
| 	} | ||||
|  | ||||
| 	if (r.attribs[NL80211_ATTR_IFINDEX]) | ||||
| 		ifinfo->ifindex = nla_get_u32(r.attribs[NL80211_ATTR_IFINDEX]); | ||||
|  | ||||
| 	if (r.attribs[NL80211_ATTR_IFTYPE]) | ||||
| 		ifinfo->iftype = nla_get_u32(r.attribs[NL80211_ATTR_IFTYPE]); | ||||
|  | ||||
|  | ||||
|  | ||||
| 	return NL_OK; | ||||
| } | ||||
|  | ||||
|  | ||||
| int nlt_init_ifinfo(struct nlt_ifinfo *ifinfo) | ||||
| { | ||||
| 	memset(ifinfo, 0, sizeof(struct nlt_ifinfo)); | ||||
| 	ifinfo->ifindex = -1; | ||||
| } | ||||
|  | ||||
|  | ||||
| struct nl_cb *get_nl_cb(int (*fun) (struct nl_msg *, void *arg), void *arg) | ||||
| { | ||||
| 	struct nl_cb *nl_cb = nl_cb_alloc(NL_CB_CUSTOM); | ||||
| 	if (!nl_cb) | ||||
| 		return 0; | ||||
|  | ||||
| 	int err; | ||||
| 	nl_cb_set(nl_cb, NL_CB_VALID, NL_CB_CUSTOM, fun, arg); | ||||
| 	nl_cb_err(nl_cb, NL_CB_CUSTOM, error_handler, &err); | ||||
| 	return nl_cb; | ||||
| } | ||||
|  | ||||
|  | ||||
| struct nl_msg *nlt_nl_msg_new(struct nl_sock * sk, int cmd, int flags) | ||||
| { | ||||
| 	struct nl_msg *msg = nlmsg_alloc(); | ||||
| 	if (!msg) | ||||
| 		return 0; | ||||
|  | ||||
|  | ||||
| 	int family_id = genl_ctrl_resolve(sk, "nl80211"); | ||||
|  | ||||
| 	genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, family_id, 0, flags, cmd, 0); | ||||
| 	return msg; | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| 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 nlCallback(struct nl_msg *msg, void *arg) | ||||
| { | ||||
|  | ||||
| 	printf("Yeaaaaaaaaaa! The ifindex callback is here\n"); | ||||
| 	struct nlmsghdr *msghdr = nlmsg_hdr(msg); | ||||
| 	struct nlattr *msgattribs[NL80211_ATTR_MAX + 1]; | ||||
|  | ||||
| 	struct genlmsghdr *ghdr = (struct genlmsghdr *) nlmsg_data(msghdr); | ||||
|  | ||||
| 	int rc; | ||||
| 	rc = nla_parse(msgattribs, NL80211_ATTR_MAX, | ||||
| 		       genlmsg_attrdata(ghdr, 0), genlmsg_attrlen(ghdr, 0), | ||||
| 		       NULL); | ||||
| 	rc = nla_parse(msgattribs, NL80211_ATTR_MAX, genlmsg_attrdata(ghdr, 0), | ||||
| 		       genlmsg_attrlen(ghdr, 0), NULL); | ||||
|  | ||||
| 	if (rc < 0) { | ||||
| 		cw_dbg(DBG_DRV_ERR, "nla_parse failed: %d %d", rc, | ||||
| 		       nl_geterror(rc)); | ||||
| 		cw_dbg(DBG_DRV_ERR, "nla_parse failed: %d %d", rc, nl_geterror(rc)); | ||||
| 		return NL_SKIP; | ||||
| 	} | ||||
|  | ||||
| 	int cmd = ghdr->cmd; | ||||
| 	cw_dbg(DBG_DRV, "NL Callback, cmd=%d - %s", cmd, | ||||
| 	       nlt_get_cmdname(cmd)); | ||||
| //      cw_dbg(DBG_DRV,"NL Callback, cmd=%d - %s",cmd,nlt_get_cmdname(cmd)); | ||||
|  | ||||
| 	if (cmd != NL80211_CMD_NEWINTERFACE) | ||||
| 		return NL_OK; | ||||
| 	switch (cmd) { | ||||
| 		case NL80211_CMD_NEW_WIPHY: | ||||
| 			add_wiphy_data(msgattribs, arg); | ||||
| 			break; | ||||
| //              case NL80211_CMD_NEW_INTERFACE: | ||||
| //                      add_interface_data(msgattribs); | ||||
|  | ||||
| 		default: | ||||
| 			printf("Default\n"); | ||||
|  | ||||
|  | ||||
| 	if (cmd == NL80211_CMD_NEW_INTERFACE) { | ||||
| 		if (msgattribs[NL80211_ATTR_IFNAME]) { | ||||
| 			printf("IFNAME = %s\n", | ||||
| 			       nla_get_string(msgattribs | ||||
| 					      [NL80211_ATTR_IFNAME])); | ||||
|  | ||||
| 			cb_data->index = | ||||
| 			    nla_get_u32(msgattribs[NL80211_ATTR_IFINDEX]); | ||||
| 			cb_data->type = | ||||
| 			    nla_get_u32(msgattribs[NL80211_ATTR_IFTYPE]); | ||||
|  | ||||
|  | ||||
| 		} | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	return NL_OK; | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| */ | ||||
|  | ||||
| int nlt_get_ifinfo(const char *ifname,struct nlt_ifinfo * ifinfo) | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| static int get_wiphy_info_cb(struct nl_msg * msg,void * arg) | ||||
| { | ||||
| 	printf("hui\n"); | ||||
| 	struct nlt_msg m; | ||||
| 	nlt_parse(msg, &m); | ||||
|  | ||||
| 	printf ("CMD: %d - %s\n",m.cmd,nlt_get_cmdname(m.cmd)); | ||||
|  | ||||
| 	if (m.cmd != NL80211_CMD_NEW_WIPHY) | ||||
| 		return NL_SKIP; | ||||
|  | ||||
| 	printf("New wiphy\n"); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| int nlt_get_wiphy_list(struct nl_sock *sk) | ||||
| { | ||||
| 	struct nl_msg * msg = nlt_nl_msg_new(sk,NL80211_CMD_GET_WIPHY,NLM_F_DUMP); | ||||
| 	nl_send_auto(sk, msg); | ||||
| 	struct nl_cb *nl_cb = get_nl_cb(get_wiphy_info_cb,0); | ||||
| //	while(1){ | ||||
| 		int nlr = nl_recvmsgs(sk, nl_cb); | ||||
| //	} | ||||
|  | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user