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

19

我花了最近几天的时间翻阅手册、文档和任何谷歌搜索出来的内容,但是我现在比一开始更加困惑了。

这里是我的需求:我想使用自己的第3-x层协议通过Linux系统的无线接口(802.11)发送和接收数据包,并使用C/C++语言。目前为止还好,我不需要信标、关联或任何与AP/SSID相关的东西。但是,对于数据传输,我希望MAC层表现得“像往常一样”,也就是说单播数据包会被ACK,重传、退避等。另外,我还希望享受扩展的QoS能力(具有4个队列和不同的接入类别的802.11e)。另一方面,混杂模式不是一个问题,我只需要广播包和发送到特定站点的数据包。

应该怎么做才是正确的?大多数关于原始套接字访问的文档似乎都集中在网络抓包上,这并没有什么帮助。我已经尝试了一段时间的监控模式,但是从我所读到的资料来看,在监视模式下接收到的数据包不会进行ACK等操作。

如果没有监视模式,有什么替代方案?使用自组网模式和Unix原始套接字吗?还是需要调整驱动程序?

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

提前感谢。


1
你可以查看是否有开源的软件解决方案来生成测试流量,即混合有效和无效数据包,以查看另一端的设备如何处理。假定这将能够执行完整的常规操作,同时也能进行任意变化(以引入所需的错误)。如果存在这样的解决方案,你可能可以使用它或从中学习。 - Chris Stratton
5个回答

7

802.11是第二层(和第一层)协议规范。它被设计成可以让更高层的协议将其视为以太网网络。寻址和行为通常是相同的。所以对于第三层协议,您不需要考虑802.11,并且应该编写您的代码,就好像您期望它在以太网网络上运行。

要使它工作,您首先应该连接到某种无线网络(这在概念上等同于将电缆插入以太网卡)。在此处,您可以选择ad-hoc(又名IBSS)或基础设施(又名BSS)网络(或一旦802.11ad获批,可以选择PBSS;)。

没有任何与网络关联的操作卡片(只是在空气中发出数据包)不是一个好主意,有几个原因。最重要的是它非常依赖于硬件,并且不可靠。您仍然可以在一侧使用RF mon(也称为监控模式)界面并在另一侧使用数据包注入(使用radiotap标头)来执行此操作,但我不建议这样做。即使您有一组相同的卡片,您也很可能在某些时候遇到难以解释和随机的行为。 802.11 NIC不是为这种操作而设计的,并且在固件内保留了不同的状态(请阅读有关FullMAC与SoftMAC卡的文章)。即使是SoftMAC卡也有很大差异。例如,在监控模式下,正如您所说,卡片不应该确认接收到的数据包,但有些卡片仍然会确认已接收到的帧,因为它们的决定仅基于该帧是否寻址给他们。一些卡片甚至可能尝试ACK所有它们看到的帧。重新传输也将发生类似的事情:某些卡片将只发送注入数据包一次(这就是它应该工作的方式)。在其他NIC中,重传由硬件(和固件)处理,并且驱动程序无法关闭它,因此即使使用注入的数据,您也将获得自动重传。

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

如果您想了解各种模式下的MAC行为,您将不得不阅读mac80211代码或802.11标准本身。http://linuxwireless.org wiki可以帮助您一些事情,但内核黑客通常太忙了,除了在代码中写注释之外,他们不会编写其他文档;)

第三层协议的实现也可以在内核或用户模式下完成(使用原始套接字)。通常内核端比较难实现,但更强大。


2
因为您想创建自己的网络层协议(替代IP),关键词是:"原始以太网套接字"。因此,请忽略"原始IP套接字"相关内容。
以下是开始的地方:
int sockfd = socket( PF_PACKET, SOCK_RAW, htons(XXX) ); 

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

通过关键字在Google上搜索,可以找到更多信息。一个非常完整的例子在这里

编辑:示例链接似乎目前已经失效:另一个例子


这个示例链接似乎不再有效。您能否分享一个更新的链接(或者给出一些参考信息,以便搜索到它)? - Ashray Malhotra

1

你可能需要类似 libpcap 的东西。

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


1
首先,在尝试传输原始802.12帧时,您需要注意一个问题-设备驱动程序必须支持数据包注入。
您提到了监视模式,这在高级别上相当于注入能力的接收端-这不是一种“模式”,而是一种能力/特性。我之所以这样说,是因为Linux上的一些892.11设备驱动程序要么:
1. 支持监视模式和帧注入 2. 支持监视模式但不支持帧注入 3. 两者都不支持
我不知道有什么简单的方法可以检查驱动程序是否支持帧注入,除非尝试进行帧注入并在另一台设备上嗅探空气以确认它是否被看到。
通常可以通过使用sudo wlan0 set monitor来检查监视模式,并查看返回代码和/或输出来检查。
几年前我曾经做过这方面的工作,当时很少有设备“开箱即用”支持监视模式和帧注入。许多设备只支持修改后的供应商或内核驱动程序的监视模式。

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

我特别提到了监控/注入功能,因为几年前我第一次参与类似的项目时,需要使用官方内核驱动的修补版本来支持监控模式- 它是rtl8812au芯片组。那时,我错误地假设驱动程序中的监控模式支持意味着完全的注入支持。我花了两天时间不停地尝试,以为我的应用程序中的帧构建不正确,导致没有帧离开卡。结果证明,我需要使用更近期的驱动程序分支才能获得完整的注入支持。这种驱动程序特别支持监控模式和帧注入。诊断该问题最令人沮丧的事情是,在尝试传输帧时,我没有收到任何系统调用或内核消息中的错误提示 - 这些帧只是在某个地方被静默丢弃,可能是在驱动程序中。
关于如何实现这一点的主要问题,答案几乎肯定是libpcap,如果您正在使用C/C++编写应用程序,因为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的情况下执行此操作,那么这是您应该更深入研究的事情。除非您有一个非常好的理由,否则我不建议这样做。


0

听起来你把媒体层和传输层搞混了。

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

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

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

希望这能给你提供一些更好的上下文和关键词。


2
OP不会混合层。在802.11中有确认和重传,详见www.sss-mag.com/pdf/802_11tut.pdf。 - abb
我的错,我看到了ACK、重传和退避,把它们都与传输层联系起来了。 - Seth Noble

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接