在MAC层访问无线接口(802.11)(Linux)

时间:2012-02-08 11:22:21

标签: linux network-programming network-protocols raw-sockets systems-programming

我花了最后几天阅读手册,文档以及谷歌提出的任何其他内容,但我想我现在比起初时更加困惑。

以下是我想要做的事情:我想通过带有C / C ++的Linux系统上的无线接口(802.11)使用我自己的第3层协议发送和接收数据包。 到现在为止还挺好。我不需要信标,关联或任何AP / SSID相关的东西。然而,对于数据传输,我希望MAC层“像往常一样”,这意味着单播数据包是ACK,重传,退避等。我还想享受扩展的QoS功能(802.11e有4个队列和不同的访问类别)。另一方面,混杂模式不是一个问题,我只需要广播数据包和发送到特定站的数据包。

什么是正确的方法呢?关于原始套接字访问的大多数文档似乎都集中在网络嗅探上,但这并没有帮助。我一直在玩监控模式一段时间了,但从我到目前为止所读到的,在监控模式等情况下接收的数据包没有被确认。 没有监控模式,可以选择什么?使用 ad hoc模式和unix原始套接字?或者我是否必须摆弄司机?

我不是在寻找一个完整的解决方案,只是一些好的想法,从哪里开始。我通读了socket(2),socket(7)和packet(7)的手册页,但这对于不同模式下MAC层的行为没有帮助。

提前致谢。

5 个答案:

答案 0 :(得分:7)

802.11是第2层(和1)协议规范。它的设计方式允许更高层协议将其视为以太网。寻址和行为通常是一样的。因此,对于第3层协议,您根本不应该关注802.11并编写代码,就好像您希望它在以太网上运行一样。

要使其正常工作,您应首先连接到某种无线网络(概念上等于将电线插入以太网卡)。在这里,您可以选择ad-hoc(也称为IBSS)或基础设施(也称为BSS)网络(或一旦802.11ad获得批准,就可以选择PBSS)。

由于几个原因,与网络没有任何关联的操作卡(只是在空中吐出数据包)并不是一个好主意。最重要的是,它非常依赖于硬件并且不可靠。您仍然可以使用一侧的RF mon(AKA监控模式)接口和另一侧的数据包注入(使用radiotap接头),但我不建议这样做。即使你有一套相同的卡片,你很可能会在某些时候难以解释和随机行为。 802.11 NIC并非专为此类操作而设计,并且在固件内保持不同的状态挂载(请参阅FullMAC与SoftMAC卡)。甚至SoftMAC卡也有很大不同。例如理论上在监控模式下,正如您所说,卡不应该确认收到的数据包。虽然确认收到的帧仍然存在卡,因为它们的决定完全基于所述帧被发送给它们的事实。有些卡甚至可能会尝试确认他们看到的所有帧。重传会发生类似的事情:一些卡只会发送一次注入的数据包(它应该如何工作)。在其他NIC中,重新传输由硬件(和固件)处理,驱动程序无法将其关闭,因此即使注入数据,您也将获得自动重传。

坚持使用第3层并使用现有模式(如ad hoc),将为您提供所需的所有功能以及更多功能(QoS等)。您发送到接口的以太网帧将由内核“转换”为具有QoS映射等的802.11格式。

如果您想了解各种模式下的MAC行为,您必须阅读 mac80211 代码或802.11标准本身。 http://linuxwireless.org wiki我帮你做了一些事情,但内核黑客通常忙于编写代码中的注释以外的文档;)

L3协议实现本身也可以在内核或用户模式下完成(使用原始套接字)。像往常一样,内核方面会更难做,但更强大。

答案 1 :(得分:3)

因为您要创建自己的网络层协议(替换IP),关键字是:“raw ethernet socket”。所以忽略“Raw IP socket”的东西。

这是从哪里开始的:

int sockfd = socket( PF_PACKET, SOCK_RAW, htons(XXX) ); 

正确的手册页是:packet(7)

通过Google搜索关键字查找更多信息。 一个相当完整的例子here

答案 2 :(得分:1)

可能你想要像libpcap这样的东西。

Libpcap允许您从/向网络接口读取/注入原始数据包。

答案 3 :(得分:1)

首先,当您尝试传输原始802.12帧时,您应该注意一些事项-设备驱动程序必须支持数据包注入。

您提到了监控器模式,它在某种程度上与注射能力的rx等效,不是“模式”,而是一种能力/功能。我之所以这样说,是因为Linux上有一些892.11设备驱动程序:

  1. 支持监视器模式和帧注入
  2. 支持监视器模式和 not 帧注入
  3. 都不支持

除了尝试进行帧注入并在另一台设备上嗅探空气以确认是否可见之外,我没有其他简单的方法来检查驱动程序是否支持帧注入。

通常可以通过使用sudo wlan0 set monitor来查看监视模式,并查看返回代码和/或输出是什么。

我从事此工作已经有几年了,但是当时,很少有设备支持“开箱即用”的监控模式和帧注入。许多只支持带有修改版本的供应商或内核驱动程序的监控器模式

您需要确保设备上有完全支持两者的驱动程序。这类任务(帧监视和注入)对于倾向于使用Kali Linux的渗透测试人员来说很常见,这实际上只是一个Ubuntu发行版,在其存储库中预装了许多“黑客”工具和(经过修改的)802.11设备驱动程序。通常,您可以使用搜索引擎来找到推荐给Kali用户的设备和驱动程序,从而节省找到支持良好的卡的时间

我明确地提高了此监视器/注入功能,因为几年前当我第一次从事类似项目时,我需要使用官方内核驱动程序的修补程序版本来支持监视器模式-这是rtl8812au芯片组。当时,我做出了一个错误的假设,即驱动程序中对监视模式的支持意味着完全注入支持。我花了2天的时间将头撞在墙上,确信我的框架在我的应用程序中无法正确构建,因此没有框架离开卡。原来,我需要一个driver的较新分支来获取完整的注射支持。该驱动程序现在特别支持监视器模式和帧注入。诊断该问题最令人沮丧的是,在尝试传输帧时,我没有从系统调用或内核消息中收到任何错误-它们只是被静默丢弃在某个地方,大概是在驱动程序中

关于如何执行此操作的主要问题-如果您使用C / C ++编写应用程序,那么答案肯定是libpcap,因为libpcap不仅提供数据包捕获API,而且还提供数据包注入API

如果您使用Python进行操作,scapy是一个很好的选择。 Python / scapy的好处是

  1. Python代码比C编写要快得多
  2. scapy提供了大量类,可用于直观地逐层创建框架
  3. 由于图层是作为类实现的,因此您还可以扩展和“注册”现有的类,以使某些帧更易于创建(或在接收时进行解析)

您可以直接使用带有原始套接字的UNIX套接字API在C语言中进行此操作-但您必须处理libpcap存在的问题以从您那里抽象出来-例如进行原始帧传输时可能需要的基础系统调用,除了标准的socket()send()recv()调用之外。我推测您至少需要几个ioctl调用,这些调用至少特定于内核802.11x子系统/框架-这些ioctl()调用及其值可能无法完全移植不同的主要内核版本。我承认我最终没有使用纯C(没有libpcap)方法,所以我不确定这个潜在问题的100%。如果您打算在没有libpcap的情况下进行操作,则应该多加注意。我不建议您这么做,除非您有充分的理由

答案 4 :(得分:0)

听起来你正在混淆媒体和传输层。

802.11通常被称为“链接”,“物理”或“媒体”层,这意味着它只处理原始数据报的传输。

ACK,重传,退避(流控制)等概念适用于“传输”层,这些特定术语与TCP / IP密切相关。

从头开始实现您自己的完整传输层非常困难,几乎肯定不是您想要做的事情。如果您想在自己的802.11自定义解释之上使用现有的TCP / IP堆栈,那么您可能想要创建一个虚拟网络接口。这将充当TCP / IP和媒体层之间的中介。

希望这能为您提供更好的上下文和关键字。