link.c文件代码内容(调试打印已添加):
#include <net/if.h>
#include <errno.h>
#include <string.h>
#include <stdbool.h>
#include <netlink/genl/genl.h>
#include <netlink/genl/family.h>
#include <netlink/genl/ctrl.h>
#include <netlink/msg.h>
#include <netlink/attr.h>
#include "nl80211.h"
#include "iw.h"
/* ========== 调试宏定义 ========== */
#define IW_DEBUG_ENABLED 1
#ifdef IW_DEBUG_ENABLED
#define IW_DEBUG(fmt, ...) \
do { \
fprintf(stderr, "IW-DEBUG %s:%d %s ", FILE, LINE, func); \
fprintf(stderr, fmt, ##VA_ARGS); \
fflush(stderr); \
} while(0)
#else
#define IW_DEBUG(fmt, ...)
#endif
#define IW_INFO(fmt, ...) \
do { \
fprintf(stderr, "IW-INFO " fmt, ##VA_ARGS); \
fflush(stderr); \
} while(0)
#define IW_ERROR(fmt, ...) \
do { \
fprintf(stderr, "IW-ERROR %s:%d: " fmt, FILE, LINE, ##VA_ARGS); \
fflush(stderr); \
} while(0)
/* ========== 调试宏定义结束 ========== */
struct link_result {
uint8_t sta_addr8;
bool link_found;
bool anything_found;
bool mld;
};
static struct link_result lr = { .link_found = false };
static int link_bss_handler(struct nl_msg *msg, void *arg)
{
IW_DEBUG("开始处理BSS消息\n");
IW_DEBUG("msg=%p, arg=%p\n", msg, arg);
struct nlattr *tbNL80211_ATTR_MAX + 1;
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
struct nlattr *bssNL80211_BSS_MAX + 1;
static struct nla_policy bss_policyNL80211_BSS_MAX + 1 = {
NL80211_BSS_TSF = { .type = NLA_U64 },
NL80211_BSS_FREQUENCY = { .type = NLA_U32 },
NL80211_BSS_FREQUENCY_OFFSET = { .type = NLA_U32 },
NL80211_BSS_BSSID = { },
NL80211_BSS_BEACON_INTERVAL = { .type = NLA_U16 },
NL80211_BSS_CAPABILITY = { .type = NLA_U16 },
NL80211_BSS_INFORMATION_ELEMENTS = { },
NL80211_BSS_SIGNAL_MBM = { .type = NLA_U32 },
NL80211_BSS_SIGNAL_UNSPEC = { .type = NLA_U8 },
NL80211_BSS_STATUS = { .type = NLA_U32 },
};
struct link_result *result = arg;
char mac_addr20, dev20, link_addr20;
int link_id = -1;
const char *indent = "\t";
int freq_offset = 0;
int i;
int attr_count = 0, bss_attr_count = 0;
IW_DEBUG("解析Netlink消息属性\n");
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL);
/* 调试:输出所有解析到的属性(不尝试访问未定义的数组) */
IW_DEBUG("解析到的Netlink属性:\n");
for (i = 0; i <= NL80211_ATTR_MAX; i++) {
if (tbi) {
attr_count++;
IW_DEBUG(" tb%d 存在,长度=%d\n", i, nla_len(tbi));
}
}
IW_DEBUG("总共找到 %d 个Netlink属性\n", attr_count);
if (!tbNL80211_ATTR_BSS) {
IW_ERROR("缺少NL80211_ATTR_BSS属性\n");
fprintf(stderr, "bss info missing!\n");
return NL_SKIP;
} else {
IW_DEBUG("找到NL80211_ATTR_BSS属性\n");
}
IW_DEBUG("开始解析嵌套的BSS属性\n");
if (nla_parse_nested(bss, NL80211_BSS_MAX,
tbNL80211_ATTR_BSS,
bss_policy)) {
IW_ERROR("解析嵌套属性失败\n");
fprintf(stderr, "failed to parse nested attributes!\n");
return NL_SKIP;
} else {
IW_DEBUG("成功解析嵌套属性\n");
}
/* 调试:输出BSS属性(不尝试访问未定义的数组) */
IW_DEBUG("解析到的BSS属性:\n");
for (i = 0; i <= NL80211_BSS_MAX; i++) {
if (bssi) {
bss_attr_count++;
IW_DEBUG(" bss%d 存在,长度=%d\n", i, nla_len(bssi));
}
}
IW_DEBUG("总共找到 %d 个BSS属性\n", bss_attr_count);
if (!bssNL80211_BSS_BSSID) {
IW_DEBUG("缺少NL80211_BSS_BSSID,跳过\n");
return NL_SKIP;
} else {
IW_DEBUG("找到NL80211_BSS_BSSID属性\n");
}
if (!bssNL80211_BSS_STATUS) {
IW_DEBUG("缺少NL80211_BSS_STATUS,跳过\n");
return NL_SKIP;
} else {
IW_DEBUG("找到NL80211_BSS_STATUS属性\n");
}
mac_addr_n2a(mac_addr, nla_data(bssNL80211_BSS_BSSID));
if_indextoname(nla_get_u32(tbNL80211_ATTR_IFINDEX), dev);
IW_DEBUG("接口信息: BSSID=%s, 设备=%s\n", mac_addr, dev);
int status = nla_get_u32(bssNL80211_BSS_STATUS);
IW_DEBUG("BSS状态: %d\n", status);
switch (status) {
case NL80211_BSS_STATUS_AUTHENTICATED:
IW_DEBUG("状态: 已认证\n");
break;
case NL80211_BSS_STATUS_ASSOCIATED:
IW_DEBUG("状态: 已关联\n");
break;
case NL80211_BSS_STATUS_IBSS_JOINED:
IW_DEBUG("状态: 已加入IBSS\n");
break;
default:
IW_DEBUG("状态: 未知 (%d)\n", status);
break;
}
if (bssNL80211_BSS_MLO_LINK_ID) {
link_id = nla_get_u8(bssNL80211_BSS_MLO_LINK_ID);
IW_DEBUG("MLO链路ID: %d\n", link_id);
} else {
IW_DEBUG("无MLO链路ID属性\n");
}
if (bssNL80211_BSS_MLD_ADDR) {
IW_DEBUG("检测到MLD地址,这是多链路设备\n");
mac_addr_n2a(link_addr, nla_data(bssNL80211_BSS_BSSID));
indent = "\t\t";
if (result->mld) {
IW_DEBUG("设备已经是MLD设备\n");
if (memcmp(result->sta_addr,
nla_data(bssNL80211_BSS_MLD_ADDR), 6)) {
mac_addr_n2a(mac_addr, nla_data(bssNL80211_BSS_MLD_ADDR));
IW_ERROR("MLD地址不一致: 期望 %02x:%02x:%02x:%02x:%02x:%02x, 实际 %s\n",
result->sta_addr0, result->sta_addr1, result->sta_addr2,
result->sta_addr3, result->sta_addr4, result->sta_addr5,
mac_addr);
printf("!! inconsistent MLD address information (%s)\n",
mac_addr);
} else {
IW_DEBUG("MLD地址一致\n");
}
} else {
IW_DEBUG("首次设置设备为MLD设备\n");
mac_addr_n2a(mac_addr, nla_data(bssNL80211_BSS_MLD_ADDR));
result->mld = true;
memcpy(result->sta_addr,
nla_data(bssNL80211_BSS_MLD_ADDR), 6);
IW_DEBUG("设置MLD地址: %s\n", mac_addr);
if (nla_get_u32(bssNL80211_BSS_STATUS) == NL80211_BSS_STATUS_ASSOCIATED) {
IW_INFO("已连接到MLD设备 %s (接口: %s)\n", mac_addr, dev);
printf("Connected to %s (on %s)\n", mac_addr, dev);
}
if (bssNL80211_BSS_INFORMATION_ELEMENTS) {
IW_DEBUG("打印MLD信息元素\n");
print_ies(nla_data(bssNL80211_BSS_INFORMATION_ELEMENTS),
nla_len(bssNL80211_BSS_INFORMATION_ELEMENTS),
false, PRINT_LINK_MLO_MLD, false);
}
}
} else {
IW_DEBUG("非MLD设备\n");
memcpy(result->sta_addr, nla_data(bssNL80211_BSS_BSSID), 6);
IW_DEBUG("设置STA地址: %02x:%02x:%02x:%02x:%02x:%02x\n",
result->sta_addr0, result->sta_addr1, result->sta_addr2,
result->sta_addr3, result->sta_addr4, result->sta_addr5);
}
/* 输出连接状态 */
switch (status) {
case NL80211_BSS_STATUS_ASSOCIATED:
if (result->mld) {
IW_INFO("MLD链路 %d BSSID %s\n", link_id, link_addr);
printf("\tLink %d BSSID %s\n", link_id, link_addr);
} else {
IW_INFO("已连接到 %s (接口: %s)\n", mac_addr, dev);
printf("Connected to %s (on %s)\n", mac_addr, dev);
}
break;
case NL80211_BSS_STATUS_AUTHENTICATED:
IW_INFO("已认证到 %s (接口: %s)\n", mac_addr, dev);
printf("Authenticated with %s (on %s)\n", mac_addr, dev);
return NL_SKIP;
case NL80211_BSS_STATUS_IBSS_JOINED:
IW_INFO("已加入IBSS %s (接口: %s)\n", mac_addr, dev);
printf("Joined IBSS %s (on %s)\n", mac_addr, dev);
break;
default:
IW_DEBUG("未知状态,跳过\n");
return NL_SKIP;
}
result->anything_found = true;
IW_DEBUG("设置anything_found=true\n");
if (bssNL80211_BSS_INFORMATION_ELEMENTS) {
IW_DEBUG("打印信息元素\n");
print_ies(nla_data(bssNL80211_BSS_INFORMATION_ELEMENTS),
nla_len(bssNL80211_BSS_INFORMATION_ELEMENTS),
false, result->mld ? PRINT_LINK_MLO_LINK : PRINT_LINK,
false);
} else {
IW_DEBUG("无信息元素属性\n");
}
if (bssNL80211_BSS_FREQUENCY_OFFSET) {
freq_offset = nla_get_u32(bssNL80211_BSS_FREQUENCY_OFFSET);
IW_DEBUG("频率偏移: %d\n", freq_offset);
} else {
IW_DEBUG("无频率偏移属性\n");
}
if (bssNL80211_BSS_FREQUENCY) {
int freq = nla_get_u32(bssNL80211_BSS_FREQUENCY);
IW_INFO("频率: %d.%d MHz\n", freq, freq_offset);
printf("%sfreq: %d.%d\n", indent, freq, freq_offset);
} else {
IW_DEBUG("无频率属性\n");
}
if (bssNL80211_BSS_SIGNAL_MBM) {
int signal_mbm = nla_get_u32(bssNL80211_BSS_SIGNAL_MBM);
float signal_dbm = signal_mbm / 100.0;
IW_DEBUG("信号强度: %d mBm (%.1f dBm)\n", signal_mbm, signal_dbm);
} else {
IW_DEBUG("无信号强度(MBM)属性\n");
}
if (bssNL80211_BSS_SIGNAL_UNSPEC) {
int8_t signal = (int8_t)nla_get_u8(bssNL80211_BSS_SIGNAL_UNSPEC);
IW_DEBUG("信号强度(未指定): %d\n", signal);
} else {
IW_DEBUG("无信号强度(未指定)属性\n");
}
if (nla_get_u32(bssNL80211_BSS_STATUS) != NL80211_BSS_STATUS_ASSOCIATED) {
IW_DEBUG("非关联状态,跳过站点信息获取\n");
return NL_SKIP;
}
/* 只有关联状态才需要获取站点信息 */
result->link_found = true;
IW_DEBUG("设置link_found=true\n");
IW_DEBUG("link_bss_handler处理完成\n");
return NL_SKIP;
}
static int handle_scan_for_link(struct nl80211_state *state,
struct nl_msg *msg,
int argc, char **argv,
enum id_input id)
{
IW_DEBUG("处理扫描链接命令\n");
IW_DEBUG("状态: %p, 消息: %p, 参数: %d, ID: %d\n", state, msg, argc, id);
for (int i = 0; i < argc; i++) {
IW_DEBUG(" argv%d: %s\n", i, argvi);
}
if (argc > 0) {
IW_ERROR("扫描链接命令不接受额外参数\n");
return 1;
}
IW_DEBUG("注册link_bss_handler回调\n");
register_handler(link_bss_handler, &lr);
IW_DEBUG("扫描链接命令处理完成\n");
return 0;
}
static int print_link_sta(struct nl_msg *msg, void *arg)
{
IW_DEBUG("打印站点信息\n");
IW_DEBUG("msg=%p, arg=%p\n", msg, arg);
struct nlattr *tbNL80211_ATTR_MAX + 1;
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
struct nlattr *sinfoNL80211_STA_INFO_MAX + 1;
struct nlattr *binfoNL80211_STA_BSS_PARAM_MAX + 1;
static struct nla_policy stats_policyNL80211_STA_INFO_MAX + 1 = {
NL80211_STA_INFO_INACTIVE_TIME = { .type = NLA_U32 },
NL80211_STA_INFO_RX_BYTES = { .type = NLA_U32 },
NL80211_STA_INFO_TX_BYTES = { .type = NLA_U32 },
NL80211_STA_INFO_RX_PACKETS = { .type = NLA_U32 },
NL80211_STA_INFO_TX_PACKETS = { .type = NLA_U32 },
NL80211_STA_INFO_SIGNAL = { .type = NLA_U8 },
NL80211_STA_INFO_RX_BITRATE = { .type = NLA_NESTED },
NL80211_STA_INFO_TX_BITRATE = { .type = NLA_NESTED },
NL80211_STA_INFO_LLID = { .type = NLA_U16 },
NL80211_STA_INFO_PLID = { .type = NLA_U16 },
NL80211_STA_INFO_PLINK_STATE = { .type = NLA_U8 },
};
static struct nla_policy bss_policyNL80211_STA_BSS_PARAM_MAX + 1 = {
NL80211_STA_BSS_PARAM_CTS_PROT = { .type = NLA_FLAG },
NL80211_STA_BSS_PARAM_SHORT_PREAMBLE = { .type = NLA_FLAG },
NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME = { .type = NLA_FLAG },
NL80211_STA_BSS_PARAM_DTIM_PERIOD = { .type = NLA_U8 },
NL80211_STA_BSS_PARAM_BEACON_INTERVAL = { .type = NLA_U16 },
};
int attr_count = 0, sinfo_attr_count = 0;
IW_DEBUG("解析Netlink消息属性\n");
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL);
/* 调试:统计属性数量 */
for (int i = 0; i <= NL80211_ATTR_MAX; i++) {
if (tbi) {
attr_count++;
}
}
IW_DEBUG("找到 %d 个Netlink属性\n", attr_count);
if (!tbNL80211_ATTR_STA_INFO) {
IW_ERROR("缺少NL80211_ATTR_STA_INFO属性\n");
fprintf(stderr, "sta stats missing!\n");
return NL_SKIP;
} else {
IW_DEBUG("找到NL80211_ATTR_STA_INFO属性\n");
}
IW_DEBUG("开始解析嵌套的站点信息属性\n");
if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
tbNL80211_ATTR_STA_INFO,
stats_policy)) {
IW_ERROR("解析嵌套站点信息属性失败\n");
fprintf(stderr, "failed to parse nested attributes!\n");
return NL_SKIP;
} else {
IW_DEBUG("成功解析嵌套站点信息属性\n");
}
/* 统计站点信息属性数量 */
for (int i = 0; i <= NL80211_STA_INFO_MAX; i++) {
if (sinfoi) {
sinfo_attr_count++;
}
}
IW_DEBUG("找到 %d 个站点信息属性\n", sinfo_attr_count);
IW_DEBUG("输出接收统计\n");
if (sinfoNL80211_STA_INFO_RX_BYTES && sinfoNL80211_STA_INFO_RX_PACKETS) {
uint32_t rx_bytes = nla_get_u32(sinfoNL80211_STA_INFO_RX_BYTES);
uint32_t rx_packets = nla_get_u32(sinfoNL80211_STA_INFO_RX_PACKETS);
IW_DEBUG("接收: %u 字节, %u 包\n", rx_bytes, rx_packets);
printf("\tRX: %u bytes (%u packets)\n", rx_bytes, rx_packets);
} else {
IW_DEBUG("无接收统计信息\n");
}
IW_DEBUG("输出发送统计\n");
if (sinfoNL80211_STA_INFO_TX_BYTES && sinfoNL80211_STA_INFO_TX_PACKETS) {
uint32_t tx_bytes = nla_get_u32(sinfoNL80211_STA_INFO_TX_BYTES);
uint32_t tx_packets = nla_get_u32(sinfoNL80211_STA_INFO_TX_PACKETS);
IW_DEBUG("发送: %u 字节, %u 包\n", tx_bytes, tx_packets);
printf("\tTX: %u bytes (%u packets)\n", tx_bytes, tx_packets);
} else {
IW_DEBUG("无发送统计信息\n");
}
IW_DEBUG("输出信号强度\n");
if (sinfoNL80211_STA_INFO_SIGNAL) {
int8_t signal = (int8_t)nla_get_u8(sinfoNL80211_STA_INFO_SIGNAL);
IW_DEBUG("信号强度: %d dBm\n", signal);
printf("\tsignal: %d dBm\n", signal);
} else {
IW_DEBUG("无信号强度信息\n");
}
if (sinfoNL80211_STA_INFO_RX_BITRATE) {
IW_DEBUG("解析接收速率\n");
char buf100;
parse_bitrate(sinfoNL80211_STA_INFO_RX_BITRATE, buf, sizeof(buf));
IW_INFO("接收速率: %s\n", buf);
printf("\trx bitrate: %s\n", buf);
} else {
IW_DEBUG("无接收速率信息\n");
}
if (sinfoNL80211_STA_INFO_TX_BITRATE) {
IW_DEBUG("解析发送速率\n");
char buf100;
parse_bitrate(sinfoNL80211_STA_INFO_TX_BITRATE, buf, sizeof(buf));
IW_INFO("发送速率: %s\n", buf);
printf("\ttx bitrate: %s\n", buf);
} else {
IW_DEBUG("无发送速率信息\n");
}
if (sinfoNL80211_STA_INFO_BSS_PARAM) {
IW_DEBUG("解析BSS参数\n");
int bss_param_count = 0;
if (nla_parse_nested(binfo, NL80211_STA_BSS_PARAM_MAX,
sinfoNL80211_STA_INFO_BSS_PARAM,
bss_policy)) {
IW_ERROR("解析嵌套BSS参数失败\n");
fprintf(stderr, "failed to parse nested bss parameters!\n");
} else {
IW_DEBUG("成功解析BSS参数\n");
/* 统计BSS参数数量 */
for (int i = 0; i <= NL80211_STA_BSS_PARAM_MAX; i++) {
if (binfoi) {
bss_param_count++;
}
}
IW_DEBUG("找到 %d 个BSS参数\n", bss_param_count);
char *delim = "";
printf("\tbss flags: ");
IW_DEBUG("输出BSS标志\n");
if (binfoNL80211_STA_BSS_PARAM_CTS_PROT) {
IW_DEBUG("CTS保护已启用\n");
printf("CTS-protection");
delim = " ";
}
if (binfoNL80211_STA_BSS_PARAM_SHORT_PREAMBLE) {
IW_DEBUG("短前导码已启用\n");
printf("%sshort-preamble", delim);
delim = " ";
}
if (binfoNL80211_STA_BSS_PARAM_SHORT_SLOT_TIME) {
IW_DEBUG("短时隙已启用\n");
printf("%sshort-slot-time", delim);
}
IW_DEBUG("\n");
printf("\n");
if (binfoNL80211_STA_BSS_PARAM_DTIM_PERIOD) {
uint8_t dtim = nla_get_u8(binfoNL80211_STA_BSS_PARAM_DTIM_PERIOD);
IW_DEBUG("DTIM周期: %d\n", dtim);
printf("\tdtim period: %d\n", dtim);
} else {
IW_DEBUG("无DTIM周期信息\n");
}
if (binfoNL80211_STA_BSS_PARAM_BEACON_INTERVAL) {
uint16_t beacon_int = nla_get_u16(binfoNL80211_STA_BSS_PARAM_BEACON_INTERVAL);
IW_DEBUG("信标间隔: %d\n", beacon_int);
printf("\tbeacon int: %d\n", beacon_int);
} else {
IW_DEBUG("无信标间隔信息\n");
}
}
} else {
IW_DEBUG("无BSS参数信息\n");
}
IW_DEBUG("站点信息打印完成\n");
return NL_SKIP;
}
static int handle_link_sta(struct nl80211_state *state,
struct nl_msg *msg,
int argc, char **argv,
enum id_input id)
{
IW_DEBUG("处理链接站点命令\n");
IW_DEBUG("状态: %p, 消息: %p, 参数: %d, ID: %d\n", state, msg, argc, id);
for (int i = 0; i < argc; i++) {
IW_DEBUG(" argv%d: %s\n", i, argvi);
}
if (argc < 1) {
IW_ERROR("缺少MAC地址参数\n");
return 1;
}
unsigned char mac_addrETH_ALEN;
IW_DEBUG("解析MAC地址: %s\n", argv0);
if (mac_addr_a2n(mac_addr, argv0)) {
IW_ERROR("无效的MAC地址: %s\n", argv0);
fprintf(stderr, "invalid mac address\n");
return 2;
}
IW_DEBUG("解析的MAC地址: %02x:%02x:%02x:%02x:%02x:%02x\n",
mac_addr0, mac_addr1, mac_addr2,
mac_addr3, mac_addr4, mac_addr5);
argc--;
argv++;
if (argc) {
IW_ERROR("有多余参数\n");
return 1;
}
IW_DEBUG("将MAC地址添加到Netlink消息\n");
NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
IW_DEBUG("注册print_link_sta回调\n");
register_handler(print_link_sta, NULL);
IW_DEBUG("链接站点命令处理完成\n");
return 0;
nla_put_failure:
IW_ERROR("添加Netlink属性失败\n");
return -ENOBUFS;
}
static int handle_link(struct nl80211_state *state,
struct nl_msg *msg, int argc, char **argv,
enum id_input id)
{
IW_DEBUG("处理链接命令\n");
IW_DEBUG("状态: %p, 消息: %p, 参数: %d, ID: %d\n", state, msg, argc, id);
for (int i = 0; i < argc; i++) {
IW_DEBUG(" argv%d: %s\n", i, argvi);
}
char *link_argv\[\] = {
NULL,
"link",
"get_bss",
NULL,
};
char *station_argv\[\] = {
NULL,
"link",
"get_sta",
NULL,
NULL,
};
char addr_buf3 \* 6;
int err;
/* 重置全局状态 */
IW_DEBUG("重置link_result状态\n");
memset(&lr, 0, sizeof(lr));
IW_DEBUG("当前lr状态: link_found=%d, anything_found=%d, mld=%d\n",
lr.link_found, lr.anything_found, lr.mld);
/* 检查STA地址是否被正确清除 */
IW_DEBUG("STA地址: %02x:%02x:%02x:%02x:%02x:%02x\n",
lr.sta_addr0, lr.sta_addr1, lr.sta_addr2,
lr.sta_addr3, lr.sta_addr4, lr.sta_addr5);
link_argv0 = argv0;
IW_DEBUG("调用handle_cmd获取BSS信息\n");
IW_DEBUG("参数: %s %s %s\n",
link_argv0 ? link_argv0 : "(null)",
link_argv1 ? link_argv1 : "(null)",
link_argv2 ? link_argv2 : "(null)");
err = handle_cmd(state, id, 3, link_argv);
IW_DEBUG("handle_cmd返回: %d\n", err);
if (err) {
IW_ERROR("获取BSS信息失败: %d\n", err);
return err;
}
IW_DEBUG("扫描后lr状态: link_found=%d, anything_found=%d, mld=%d\n",
lr.link_found, lr.anything_found, lr.mld);
IW_DEBUG("扫描后STA地址: %02x:%02x:%02x:%02x:%02x:%02x\n",
lr.sta_addr0, lr.sta_addr1, lr.sta_addr2,
lr.sta_addr3, lr.sta_addr4, lr.sta_addr5);
if (!lr.link_found) {
if (!lr.anything_found) {
IW_INFO("未找到连接\n");
printf("Not connected.\n");
} else {
IW_DEBUG("找到BSS但未关联\n");
}
return 0;
}
IW_DEBUG("找到有效连接\n");
mac_addr_n2a(addr_buf, lr.sta_addr);
addr_buf17 = '\0';
IW_DEBUG("连接到的AP地址: %s\n", addr_buf);
IW_DEBUG("是否MLD: %s\n", lr.mld ? "是" : "否");
if (lr.mld) {
IW_INFO("MLD %s 统计:\n", addr_buf);
printf("MLD %s stats:\n", addr_buf);
}
station_argv0 = argv0;
station_argv3 = addr_buf;
IW_DEBUG("调用handle_cmd获取站点统计信息\n");
IW_DEBUG("参数: %s %s %s %s\n",
station_argv0 ? station_argv0 : "(null)",
station_argv1 ? station_argv1 : "(null)",
station_argv2 ? station_argv2 : "(null)",
station_argv3 ? station_argv3 : "(null)");
int result = handle_cmd(state, id, 4, station_argv);
IW_DEBUG("handle_cmd返回: %d\n", result);
return result;
}
TOPLEVEL(link, NULL, 0, 0, CIB_NETDEV, handle_link,
"Print information about the current connection, if any.");
HIDDEN(link, get_sta, "<mac-addr>", NL80211_CMD_GET_STATION, 0,
CIB_NETDEV, handle_link_sta);
HIDDEN(link, get_bss, NULL, NL80211_CMD_GET_SCAN, NLM_F_DUMP,
CIB_NETDEV, handle_scan_for_link);
连接的wifi:

运行该命令的打印日志:
root@OpenWrt:~# iw dev phy0-sta0 link
DEBUG iw tool starting. argc=4
argv0: iw
argv1: dev
argv2: phy0-sta0
argv3: link
DEBUG __handle_cmd: idby=1, argc=2, argv0=phy0-sta0
DEBUG command_idby=0, devidx=0
DEBUG section=(null)
DEBUG selected command: link
IW-DEBUG link.c:556 handle_link 处理链接命令
IW-DEBUG link.c:557 handle_link 状态: 0x7fcccaaf40, 消息: 0, 参数: 2, ID: 1
IW-DEBUG link.c:560 handle_link argv0: phy0-sta0
IW-DEBUG link.c:560 handle_link argv1: link
IW-DEBUG link.c:580 handle_link 重置link_result状态
IW-DEBUG link.c:583 handle_link 当前lr状态: link_found=0, anything_found=0, mld=0
IW-DEBUG link.c:587 handle_link STA地址: 00:00:00:00:00:00
IW-DEBUG link.c:593 handle_link 调用handle_cmd获取BSS信息
IW-DEBUG\] link.c:594 \[handle_link\] 参数: \[phy0-sta0\] \[link\] \[get_bss
DEBUG __handle_cmd: idby=1, argc=3, argv0=phy0-sta0
DEBUG command_idby=0, devidx=0
DEBUG section=(null)
DEBUG selected command: get_bss
IW-DEBUG link.c:298 handle_scan_for_link 处理扫描链接命令
IW-DEBUG link.c:299 handle_scan_for_link 状态: 0x7fcccaaf40, 消息: 0x7fa1dc9160, 参数: 0, ID: 1
IW-DEBUG link.c:310 handle_scan_for_link 注册link_bss_handler回调
IW-DEBUG link.c:313 handle_scan_for_link 扫描链接命令处理完成
DEBUG About to send NL command: 0x20
DEBUG nl_send_auto_complete returned: 28
IW-DEBUG link.c:53 link_bss_handler 开始处理BSS消息
IW-DEBUG link.c:54 link_bss_handler msg=0x7fa1dc91c0, arg=0x442391
IW-DEBUG link.c:79 link_bss_handler 解析Netlink消息属性
IW-DEBUG link.c:84 link_bss_handler 解析到的Netlink属性:
IW-DEBUG link.c:88 link_bss_handler tb3 存在,长度=4
IW-DEBUG link.c:88 link_bss_handler tb46 存在,长度=4
IW-DEBUG link.c:88 link_bss_handler tb47 存在,长度=336
IW-DEBUG link.c:88 link_bss_handler tb153 存在,长度=8
IW-DEBUG link.c:91 link_bss_handler 总共找到 4 个Netlink属性
IW-DEBUG link.c:98 link_bss_handler 找到NL80211_ATTR_BSS属性
IW-DEBUG link.c:101 link_bss_handler 开始解析嵌套的BSS属性
IW-DEBUG link.c:109 link_bss_handler 成功解析嵌套属性
IW-DEBUG link.c:113 link_bss_handler 解析到的BSS属性:
IW-DEBUG link.c:117 link_bss_handler bss1 存在,长度=6
IW-DEBUG link.c:117 link_bss_handler bss2 存在,长度=4
IW-DEBUG link.c:117 link_bss_handler bss3 存在,长度=8
IW-DEBUG link.c:117 link_bss_handler bss4 存在,长度=2
IW-DEBUG link.c:117 link_bss_handler bss5 存在,长度=2
IW-DEBUG link.c:117 link_bss_handler bss6 存在,长度=229
IW-DEBUG link.c:117 link_bss_handler bss7 存在,长度=4
IW-DEBUG link.c:117 link_bss_handler bss9 存在,长度=4
IW-DEBUG link.c:117 link_bss_handler bss10 存在,长度=4
IW-DEBUG link.c:117 link_bss_handler bss15 存在,长度=8
IW-DEBUG link.c:117 link_bss_handler bss20 存在,长度=4
IW-DEBUG link.c:117 link_bss_handler bss23 存在,长度=4
IW-DEBUG link.c:120 link_bss_handler 总共找到 12 个BSS属性
IW-DEBUG link.c:126 link_bss_handler 找到NL80211_BSS_BSSID属性
IW-DEBUG link.c:133 link_bss_handler 找到NL80211_BSS_STATUS属性
IW-DEBUG link.c:139 link_bss_handler 接口信息: BSSID=80:af:ca:ed:a7:67, 设备=phy0-sta0
IW-DEBUG link.c:142 link_bss_handler BSS状态: 1
IW-DEBUG link.c:149 link_bss_handler 状态: 已关联
IW-DEBUG link.c:163 link_bss_handler 无MLO链路ID属性
IW-DEBUG link.c:206 link_bss_handler 非MLD设备
IW-DEBUG link.c:208 link_bss_handler 设置STA地址: 80:af:ca:ed:a7:67
IW-INFO 已连接到 80:af:ca:ed:a7:67 (接口: phy0-sta0)
Connected to 80:af:ca:ed:a7:67 (on phy0-sta0)
IW-DEBUG link.c:238 link_bss_handler 设置anything_found=true
IW-DEBUG link.c:241 link_bss_handler 打印信息元素
SSID: WIFI-2.4G
IW-DEBUG link.c:252 link_bss_handler 频率偏移: 0
IW-INFO 频率: 2412.0 MHz
freq: 2412.0
IW-DEBUG link.c:268 link_bss_handler 信号强度: -1900 mBm (-19.0 dBm)
IW-DEBUG link.c:277 link_bss_handler 无信号强度(未指定)属性
IW-DEBUG link.c:287 link_bss_handler 设置link_found=true
IW-DEBUG link.c:289 link_bss_handler link_bss_handler处理完成
IW-DEBUG link.c:600 handle_link handle_cmd返回: 0
IW-DEBUG link.c:607 handle_link 扫描后lr状态: link_found=1, anything_found=1, mld=0
IW-DEBUG link.c:610 handle_link 扫描后STA地址: 80:af:ca:ed:a7:67
IW-DEBUG link.c:624 handle_link 找到有效连接
IW-DEBUG link.c:629 handle_link 连接到的AP地址: 80:af:ca:ed:a7:67
IW-DEBUG link.c:630 handle_link 是否MLD: 否
IW-DEBUG link.c:640 handle_link 调用handle_cmd获取站点统计信息
IW-DEBUG\] link.c:641 \[handle_link\] 参数: \[phy0-sta0\] \[link\] \[get_sta\] \[80:af:ca:ed:a7:67
DEBUG __handle_cmd: idby=1, argc=4, argv0=phy0-sta0
DEBUG command_idby=0, devidx=0
DEBUG section=(null)
DEBUG selected command: get_sta
IW-DEBUG link.c:505 handle_link_sta 处理链接站点命令
IW-DEBUG link.c:506 handle_link_sta 状态: 0x7fcccaaf40, 消息: 0x7fa1dc9110, 参数: 1, ID: 1
IW-DEBUG link.c:509 handle_link_sta argv0: 80:af:ca:ed:a7:67
IW-DEBUG link.c:519 handle_link_sta 解析MAC地址: 80:af:ca:ed:a7:67
IW-DEBUG link.c:526 handle_link_sta 解析的MAC地址: 80:af:ca:ed:a7:67
IW-DEBUG link.c:538 handle_link_sta 将MAC地址添加到Netlink消息
IW-DEBUG link.c:541 handle_link_sta 注册print_link_sta回调
IW-DEBUG link.c:544 handle_link_sta 链接站点命令处理完成
DEBUG About to send NL command: 0x11
DEBUG nl_send_auto_complete returned: 40
IW-DEBUG link.c:319 print_link_sta 打印站点信息
IW-DEBUG link.c:320 print_link_sta msg=0x7fa1dc91d0, arg=0
IW-DEBUG link.c:348 print_link_sta 解析Netlink消息属性
IW-DEBUG link.c:358 print_link_sta 找到 4 个Netlink属性
IW-DEBUG link.c:365 print_link_sta 找到NL80211_ATTR_STA_INFO属性
IW-DEBUG link.c:368 print_link_sta 开始解析嵌套的站点信息属性
IW-DEBUG link.c:376 print_link_sta 成功解析嵌套站点信息属性
IW-DEBUG link.c:385 print_link_sta 找到 12 个站点信息属性
IW-DEBUG link.c:387 print_link_sta 输出接收统计
IW-DEBUG link.c:391 print_link_sta 接收: 9199 字节, 31 包
RX: 9199 bytes (31 packets)
IW-DEBUG link.c:397 print_link_sta 输出发送统计
IW-DEBUG link.c:401 print_link_sta 发送: 7189 字节, 38 包
TX: 7189 bytes (38 packets)
IW-DEBUG link.c:407 print_link_sta 输出信号强度
IW-DEBUG link.c:410 print_link_sta 信号强度: -21 dBm
signal: -21 dBm
IW-DEBUG link.c:417 print_link_sta 解析接收速率
IW-INFO 接收速率: 65.0 MBit/s
rx bitrate: 65.0 MBit/s
IW-DEBUG link.c:427 print_link_sta 解析发送速率
IW-INFO 发送速率: 72.2 MBit/s
tx bitrate: 72.2 MBit/s
IW-DEBUG link.c:437 print_link_sta 解析BSS参数
IW-DEBUG link.c:445 print_link_sta 成功解析BSS参数
IW-DEBUG link.c:453 print_link_sta 找到 4 个BSS参数
IW-DEBUG link.c:457 print_link_sta 输出BSS标志
IW-DEBUG link.c:465 print_link_sta 短前导码已启用
IW-DEBUG link.c:470 print_link_sta 短时隙已启用
IW-DEBUG\] link.c:473 \[print_link_sta
bss flags: short-preamble short-slot-time
IW-DEBUG link.c:478 print_link_sta DTIM周期: 2
dtim period: 2
IW-DEBUG link.c:486 print_link_sta 信标间隔: 100
beacon int: 100
IW-DEBUG link.c:496 print_link_sta 站点信息打印完成
IW-DEBUG link.c:648 handle_link handle_cmd返回: 0
root@OpenWrt:~#