原始以太网广播 [英] Raw ethernet broadcasting

查看:281
本文介绍了原始以太网广播的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我下载了WinDDK,并正在使用ndisprot 5x广播用户应用程序中的原始以太网数据包,并在大型且重复的数据集上将目标MAC全部指定为0xff,

I downloaded WinDDK and am using ndisprot 5x to broadcast raw ethernet packets from my user app, specifying destination MAC all 0xff's, on large and repetitive data sets it doesn't seem to be very productive.

当前最有效的方法是环回-将目标MAC和源MAC指定为我自己需要的速度,但是数据包永远不会离开我的网卡.

What currently works great is a loopback - specifying destination and source MAC's as my own I get needed speed, but the packet never leaves my network card.

也许我缺少一些ndis驱动程序选项,并等待广播使用此示例MS驱动程序完成?我想要的只是将数据包广播到网络,我并不真正在乎传输状态,并且希望尽快消除它.

Maybe I am missing some ndis driver options and wait for a broadcast to complete using this sample MS driver? All I want is the packet to be broadcasted to network and I don't really care about the delivery status and want to get rid of it as fast as possible.

这里只有2分的系统会有所帮助吗?我不确定是什么原因导致了延迟.

Would a system having only 2 points help here? I am not sure what is causing a lag.

推荐答案

在内核模式下无法消除发送完成路径.原因是网卡正忙于从内存中读取字节,直到最终发出发送完成.如果您没有在重新使用数据包之前等待发送完成,则网卡将没有机会读取完整的数据包.您最终将发送损坏的数据.

It's not possible to eliminate the send-completion path in kernel mode. The reason is that the network card is busy reading bytes from memory, until it finally issues a send-completion. If you didn't wait for send-completion before re-using the packet, then the network card wouldn't have had an opportunity to read the full packet. You'd end up sending corrupted data.

但是,没错,使用库存NDISPROT样本发送大量数据时效率很低.问题在于NDISPROT的用户模式示例应用程序将数据同步写入内核模式.这意味着您的线程开始写(发送数据包),然后阻塞直到写(发送数据包)完成. (该示例效率很低,因为NDISPROT示例的目的是说明如何在内核模式下与NDIS进行互操作,而不是说明用于用户内核通信的复杂技术.)

But, you're right that there is a big inefficiency when using the stock NDISPROT sample to send huge quantities of data. The problem is that the NDISPROT's usermode sample application writes data to kernelmode synchronously. That means that your thread begins a write (send packet), then blocks until the write (send packet) completes. (The sample is inefficient, because the point of the NDISPROT sample is to illustrate how to interoperate with NDIS in kernelmode, not to illustrate complicated techniques for user-kernel communication.)

您可以使用多种技术之一同时发布多个数据,从而大大加快这一步:

You can vastly speed this up by using one of several techniques to issue multiple pieces of data simultaneously:

  1. 使用多线程.除了在多个线程上并行执行之外,请执行与现在相同的操作.设置起来很容易,但是扩展性不是很好(要扩展至10倍的流量,您需要10倍的线程,然后开始在缓存问题上受到伤害).另外,如果必须按顺序发送数据集,则需要进行一系列复杂的同步操作,以确保线程按顺序发出请求.

  1. Use multithreading. Do the same thing you're doing now, except do it on multiple threads in parallel. This is pretty easy to set up, but it doesn't scale very well (to scale up to 10x traffic, you need 10x threads, and then you start to get hurt on caching issues). Plus, if your dataset must be sent in order, you need a bunch of complicated synchronization to make sure the threads issue requests in order.

对WriteFile和OVERLAPPED数据结构使用异步调用.这要求您在usermode应用程序上进行一些重新设计. (幸运的是,您无需触摸内核驱动程序,因为该驱动程序已支持此功能).使用OVERLAPPED写操作,您可以从单个线程发出多个同时写操作,然后在完成任何(或全部)写操作时得到通知.如果您对重叠的设计足够小心,则应该能够轻松填充100Mbps网络链接.

Use asynchronous calls with WriteFile and OVERLAPPED data structures. This requires you to do some retooling on the usermode app. (Fortunately you don't need to touch the kernel driver, since that already supports this). With OVERLAPPED writes, you can issue multiple simultaneous writes from a single thread, then get notified when any (or all) of them completes. If you're sufficiently careful with the overlapped design, you should be able to fill a 100Mbps network link easily.

更明确地说,这是您当前拥有的:

To be more explicit, this is what you currently have today:

Your app           NDISPROT driver         Network card         The network
---------------------------------------------------------------------------------
  WriteFile
   .      \-------> NdisProtWrite
   .                            \-------> NdisSendPackets
   .                                            |
   .                                   (copy packet payload
   .                                    from system RAM to
   .                                    network card's buffer)
   .                                            |
   .                                            |---------------> Start sending
   .             NdisProtSendComplete <---------|                      .
  WriteFile <----/                              |                      .
   returns                                      |<--------------- Finish sending

如您所见,在网卡将数据包有效载荷从RAM复制到NIC硬件的整个过程中,您的usermode应用都停留在WriteFile中.相反,如果您使用异步写入内核模式,您将获得以下结果:

As you can see, your usermode app is stuck in WriteFile the entire time that the network card copies the packet payload from RAM to the NIC hardware. Instead, if you use asynchronous writes to kernelmode, you'll wind up with this:

Your app           NDISPROT driver         Network card         The network
---------------------------------------------------------------------------------
  WriteFile
   .      \-------> NdisProtWrite
   .               |            \-------> NdisSendPackets
  WriteFile <------/                           |
   returns                              (copy packet payload
                                        from system RAM to
                                        network card's buffer)
                                                |
                                                |---------------> Start sending
                 NdisProtSendComplete <---------|                      .
  Async write <--/                              |                      .
   completes                                    |<--------------- Finish sending

在这种设置下,WriteFile返回的速度更快,因此您有机会在NIC仍在读取第一个数据包时将另一个数据包(或10个)排队.您可以使用任何常用的OVERLAPPED技术来确定何时完成写(发送数据包),并且可以重用数据缓冲区.

In this setup, WriteFile returns more quickly, and so you have a chance to queue up another packet (or 10) while the NIC is still reading the first packet. You can use any of the usual OVERLAPPED techniques to determine when the write (send packet) has completed, and you can reuse the data buffer.

要开始使用异步I/O,请从

To get started with asynchronous I/O, start with this documentation. (Oops, looks like their diagrams are rotated 90° from my awesome ASCII-art...).

这篇关于原始以太网广播的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆