使用 SharpPcap 和 Packet.Net 发送 LLDP 数据包

Sending an LLDP packet using SharpPcap and Packet.Net

所以,我花了一个下午尝试使用 SharpPcap 和 Packet.Net 在 c# 中发送 LLDP 数据包。

我想出的是带有 NullReferenceException 的炸弹。我知道为什么,但我不知道该怎么办。

这是我的代码:

namespace LLDPTest {
    using System;
    using System.Linq;
    using System.Net.NetworkInformation;
    using System.Threading;

    using PacketDotNet;

    using SharpPcap.WinPcap;

    class Program {
        static void Main(string[] args) {
            //var timer = new Timer(state => SendLLDPPacketOnAllInterfaces(), null, 0, 1000);
            SendLLDPPacketOnAllInterfaces();
            Console.ReadLine();
        }

        private static void SendLLDPPacketOnAllInterfaces() {
            var winPcapDeviceList = WinPcapDeviceList.Instance;

            foreach (var device in winPcapDeviceList.Where(device => device.Interface.GatewayAddress != null)) {
                SendLLDPPacket(device);
            }
        }

        private static void SendLLDPPacket(WinPcapDevice device) {
            var packet = LLDPPacket.RandomPacket();

            //packet.Header = ???

            var ethernetPacket = new EthernetPacket(device.Addresses[1].Addr.hardwareAddress, PhysicalAddress.Parse("01-80-C2-00-00-0E"), EthernetPacketType.LLDP);

            ethernetPacket.PayloadPacket = packet;

            device.Open();
            device.SendPacket(ethernetPacket);
            device.Close();
            Console.WriteLine("LLDP packet sent!");
        }
    }
}

第36行抛出异常(device.SendPacket(ethernetPacket);)

原因是数据包的header属性不能为空。在执行以下检查的 Packet.cs 的第 229 行抛出异常:

                if ((this.header.Bytes != this.payloadPacketOrData.ThePacket.header.Bytes) || ((this.header.Offset + this.header.Length) != this.payloadPacketOrData.ThePacket.header.Offset))
                {
                    return false;
                }

长话短说,我根本不知道应该将 header 属性 设置为什么,Google 或其他任何地方都没有示例。

编辑: this.payloadPacketOrData.ThePacket.header 为空。这是调用 LLDPPacket.RandomPacket(); 产生的数据包。不幸的是 header 属性 没有 setter.

EDIT2: 我正在使用来自 NuGet 的两个数据包的最新版本。

EDIT3: http://wiki.wireshark.org/LinkLayerDiscoveryProtocol

It's interesting to note that unlike the LLDP drafts referenced above, the final LLDP standard abandoned the notion of an LLDP Header and instead simply mandated the presence of certain TLVs. In the various draft documents the LLDP Header was supposed to include a Version field. The current LLDP standard does not include any notion of a Version.

唉。我不知道为什么,但在检查了单元测试 (https://github.com/antmicro/Packet.Net/blob/master/Test/PacketType/LldpTest.cs) 之后,我偶然发现了解决方案(第 78-79 行):

var packet = LLDPPacket.RandomPacket();
var lldpBytes = packet.Bytes;
var lldpPacket = new LLDPPacket(new ByteArraySegment(lldpBytes));

我不知道为什么作者所说的 "reparsing" 是必要的,但现在它起作用了。