【发布时间】:2019-12-24 15:02:29
【问题描述】:
我查看了 libtins 并在示例中找到了 ARP Monitor 示例。 示例代码如下:
#include <tins/tins.h>
#include <map>
#include <iostream>
#include <functional>
using std::cout;
using std::endl;
using std::map;
using std::bind;
using namespace Tins;
class arp_monitor {
public:
void run(Sniffer& sniffer);
private:
bool callback(const PDU& pdu);
map<IPv4Address, HWAddress<6>> addresses;
};
void arp_monitor::run(Sniffer& sniffer) {
sniffer.sniff_loop(
bind(
&arp_monitor::callback,
this,
std::placeholders::_1
)
);
}
bool arp_monitor::callback(const PDU& pdu) {
// Retrieve the ARP layer
const ARP& arp = pdu.rfind_pdu<ARP>();
// Is it an ARP reply?
if (arp.opcode() == ARP::REPLY) {
// Let's check if there's already an entry for this address
auto iter = addresses.find(arp.sender_ip_addr());
if (iter == addresses.end()) {
// We haven't seen this address. Save it.
addresses.insert({ arp.sender_ip_addr(), arp.sender_hw_addr()});
cout << "[INFO] " << arp.sender_ip_addr() << " is at "
<< arp.sender_hw_addr() << std::endl;
}
else {
// We've seen this address. If it's not the same HW address, inform it
if (arp.sender_hw_addr() != iter->second) {
cout << "[WARNING] " << arp.sender_ip_addr() << " is at "
<< iter->second << " but also at " << arp.sender_hw_addr()
<< endl;
}
}
}
return true;
}
int main(int argc, char* argv[]) {
if(argc != 2) {
cout << "Usage: " <<* argv << " <interface>" << endl;
return 1;
}
arp_monitor monitor;
// Sniffer configuration
SnifferConfiguration config;
config.set_promisc_mode(true);
config.set_filter("arp");
try {
// Sniff on the provided interface in promiscuous mode
Sniffer sniffer(argv[1], config);
// Only capture arp packets
monitor.run(sniffer);
}
catch (std::exception& ex) {
std::cerr << "Error: " << ex.what() << std::endl;
}
}
我在这里运行此代码:
myprogram.exe eth0
结果是:
错误:打开适配器时出错:系统找不到给定的设备。 (20)
以上词语的定义:
eth0:我的网络设备
libtins:高级、多平台 C++ 网络数据包嗅探和制作库
ARP:地址解析协议
我在 Windows 上只在一个名为“Shadow”的用户上运行它
【问题讨论】:
-
你在用windows吗? (因为
myprogram.exe).. -
检查 Tins 是否没有提供枚举设备的方法。此外,这是否有效可能在很大程度上取决于执行它的用户,请在您的问题中包含该信息。
-
@JuanRamirez 你也可以在 Unix 系统中编译
.exe文件。使用-o参数传递时,只需在文件名中包含.exe。 -
@JoelTrauger 是的,它被称为交叉编译...但是
eth0是一个unix 接口,Windows 程序将无法找到任何具有该名称的接口。 -
检查this answer at unix.stackexchange,它比我能想出的任何东西都要复杂。