发出 Netlink 命令时出错 get_station
Error in issuing Netlink command get_station
我想通过 libnl
使用 Netlink 获取电台信息。我发出命令 NL80211_CMD_GET_STATION
。在发送消息之前,我根据 nl80211.h
文件中的说明添加属性 NL80211_ATTR_MAC
和 NL80211_ATTR_IFINDEX
及其各自的值。我写了一个带有错误检查的简单代码:
int main(int argc, char **argv)
{
struct nl_sock *sk; /* Socket */
struct nl_msg *msg; /* Netlink message struct */
int err; /* Message flags */
unsigned char mac_adr[ETH_ALEN]; /* MAC address */
char path[50]="", if_name[] = "wlp4s0"; /* Interface name */
strcat(path, "/sys/class/net/");
strcat(path, if_name);
strcat(path, "/address");
/* allocate socket */
if (!(sk = nl_socket_alloc()))
{
printf("Error in creating socket!\n");
return -1;
}
/* Connect to generic netlink */
if (genl_connect(sk) < 0)
{
printf("Error in connecting socket to Generic Netlink!\n");
return -1;
}
/* Find the nl80211 driver ID */
NL_family = genl_ctrl_resolve(sk, "nl80211");
if (NL_family < 0)
{
printf("Error in getting nl80211 Netlink message ID!\n");
return -1;
}
/* Attach a callback */
err = nl_socket_modify_cb(sk, NL_CB_VALID, NL_CB_CUSTOM,
nlCallback, NULL);
if (err < 0)
{
printf("Error in a Callback to Netlink socket!\n");
return -1;
}
/* Create a new message */
if (!(msg = nlmsg_alloc()))
{
printf("Error in allocating Netlink message!\n");
return -1;
}
/* Setup the message */
if (!genlmsg_put(msg, 0, NL_AUTO_SEQ, NL_family, 0, 0,
NL80211_CMD_GET_STATION, 0))
{
printf("Error in creating Netlink message!\n");
return -1;
}
/* Add message attributes */
/* Putting MAC address */
if (get_mac(mac_adr, path) < 0)
{
printf ("Error in getting MAC address!\n");
return -1;
}
NLA_PUT(msg, NL80211_ATTR_MAC, sizeof(mac_adr), mac_adr);
/* Interface attribute */
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
/* Send the messge (this frees it) */
err = nl_send_auto(sk, msg);
if (err < 0)
{
printf ("Error in sending the messages!\n");
return -1;
}
printf("Sent %d Bytes\n", err);
/* Block execution to receive the answer from the kernel */
err = nl_recvmsgs_default(sk);
if (err < 0)
{
printf("Error in receiving Netlink message! Error: %s\n", nl_geterror(err));
return -1;
}
return 0;
nla_put_failure:
nlmsg_free(msg);
printf("Error in Attribute Put\n");
return -1;
}
当我 运行 程序时,它在代码末尾使用函数 nl_recvmsgs_default(sk)
尝试接收来自内核的回复时生成错误 object not found
。
我使用相同的代码获取与命令NL80211_CMD_GET_INTERFACE
相同接口的类型。我使用属性 NL80211_ATTR_IFINDEX
发送此命令的消息。该程序适用于 NL80211_CMD_GET_INTERFACE
并打印接口类型!因此,我怀疑我获取 MAC 地址的方式有问题。
这是我为从文件中获取 MAC 地址而编写的函数:
int get_mac(unsigned char *mac_adr, char *path)
{
int c, i = 0, j = 0, d1, d2;
char mac_str[20];
FILE *file;
file = fopen(path, "r");
if (file) {
while ((c = getc(file)) != EOF)
mac_str[i++] = c;
mac_str[i] = 0;
fclose(file);
}
else return -1;
for (i=0; i<=(ETH_ALEN-1)*3; i+=3)
{
if (mac_str[i]>='0' && mac_str[i]<='9')
d1 = mac_str[i] - '0';
else if (mac_str[i]>='a' && mac_str[i]<='f')
d1 = mac_str[i] - 'a' + 10;
if (mac_str[i+1]>='0' && mac_str[i+1]<='9')
d2 = mac_str[i+1] - '0';
else if (mac_str[i+1]>='a' && mac_str[i+1]<='f')
d2 = mac_str[i+1] - 'a' + 10;
mac_adr[j++] = d1*16+d2;
}
return 1;
}
如果接口名称是 wlp4s0
,则包含 MAC 地址的文件将位于路径 /sys/class/net/wlp4s0/address
中。什么会导致执行 NL80211_CMD_GET_STATION
时出现问题?
出现此错误是否可能是因为命令 NL80211_CMD_GET_STATION
需要 root 用户而 NL80211_CMD_GET_INTERFACE
不需要?
但我当然对 root 用户使用 NL80211_CMD_GET_STATION
。
无线客户端应该连接到 AP,您需要使用 MAC AP 地址而不是客户端地址。
您可以查看使用示例 NL80211_CMD_GET_STATION here (source of iw tool)
我想通过 libnl
使用 Netlink 获取电台信息。我发出命令 NL80211_CMD_GET_STATION
。在发送消息之前,我根据 nl80211.h
文件中的说明添加属性 NL80211_ATTR_MAC
和 NL80211_ATTR_IFINDEX
及其各自的值。我写了一个带有错误检查的简单代码:
int main(int argc, char **argv)
{
struct nl_sock *sk; /* Socket */
struct nl_msg *msg; /* Netlink message struct */
int err; /* Message flags */
unsigned char mac_adr[ETH_ALEN]; /* MAC address */
char path[50]="", if_name[] = "wlp4s0"; /* Interface name */
strcat(path, "/sys/class/net/");
strcat(path, if_name);
strcat(path, "/address");
/* allocate socket */
if (!(sk = nl_socket_alloc()))
{
printf("Error in creating socket!\n");
return -1;
}
/* Connect to generic netlink */
if (genl_connect(sk) < 0)
{
printf("Error in connecting socket to Generic Netlink!\n");
return -1;
}
/* Find the nl80211 driver ID */
NL_family = genl_ctrl_resolve(sk, "nl80211");
if (NL_family < 0)
{
printf("Error in getting nl80211 Netlink message ID!\n");
return -1;
}
/* Attach a callback */
err = nl_socket_modify_cb(sk, NL_CB_VALID, NL_CB_CUSTOM,
nlCallback, NULL);
if (err < 0)
{
printf("Error in a Callback to Netlink socket!\n");
return -1;
}
/* Create a new message */
if (!(msg = nlmsg_alloc()))
{
printf("Error in allocating Netlink message!\n");
return -1;
}
/* Setup the message */
if (!genlmsg_put(msg, 0, NL_AUTO_SEQ, NL_family, 0, 0,
NL80211_CMD_GET_STATION, 0))
{
printf("Error in creating Netlink message!\n");
return -1;
}
/* Add message attributes */
/* Putting MAC address */
if (get_mac(mac_adr, path) < 0)
{
printf ("Error in getting MAC address!\n");
return -1;
}
NLA_PUT(msg, NL80211_ATTR_MAC, sizeof(mac_adr), mac_adr);
/* Interface attribute */
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
/* Send the messge (this frees it) */
err = nl_send_auto(sk, msg);
if (err < 0)
{
printf ("Error in sending the messages!\n");
return -1;
}
printf("Sent %d Bytes\n", err);
/* Block execution to receive the answer from the kernel */
err = nl_recvmsgs_default(sk);
if (err < 0)
{
printf("Error in receiving Netlink message! Error: %s\n", nl_geterror(err));
return -1;
}
return 0;
nla_put_failure:
nlmsg_free(msg);
printf("Error in Attribute Put\n");
return -1;
}
当我 运行 程序时,它在代码末尾使用函数 nl_recvmsgs_default(sk)
尝试接收来自内核的回复时生成错误 object not found
。
我使用相同的代码获取与命令NL80211_CMD_GET_INTERFACE
相同接口的类型。我使用属性 NL80211_ATTR_IFINDEX
发送此命令的消息。该程序适用于 NL80211_CMD_GET_INTERFACE
并打印接口类型!因此,我怀疑我获取 MAC 地址的方式有问题。
这是我为从文件中获取 MAC 地址而编写的函数:
int get_mac(unsigned char *mac_adr, char *path)
{
int c, i = 0, j = 0, d1, d2;
char mac_str[20];
FILE *file;
file = fopen(path, "r");
if (file) {
while ((c = getc(file)) != EOF)
mac_str[i++] = c;
mac_str[i] = 0;
fclose(file);
}
else return -1;
for (i=0; i<=(ETH_ALEN-1)*3; i+=3)
{
if (mac_str[i]>='0' && mac_str[i]<='9')
d1 = mac_str[i] - '0';
else if (mac_str[i]>='a' && mac_str[i]<='f')
d1 = mac_str[i] - 'a' + 10;
if (mac_str[i+1]>='0' && mac_str[i+1]<='9')
d2 = mac_str[i+1] - '0';
else if (mac_str[i+1]>='a' && mac_str[i+1]<='f')
d2 = mac_str[i+1] - 'a' + 10;
mac_adr[j++] = d1*16+d2;
}
return 1;
}
如果接口名称是 wlp4s0
,则包含 MAC 地址的文件将位于路径 /sys/class/net/wlp4s0/address
中。什么会导致执行 NL80211_CMD_GET_STATION
时出现问题?
出现此错误是否可能是因为命令 NL80211_CMD_GET_STATION
需要 root 用户而 NL80211_CMD_GET_INTERFACE
不需要?
但我当然对 root 用户使用 NL80211_CMD_GET_STATION
。
无线客户端应该连接到 AP,您需要使用 MAC AP 地址而不是客户端地址。
您可以查看使用示例 NL80211_CMD_GET_STATION here (source of iw tool)