LLDP (Link Layer Discovery Protocol) は、デバイスがネットワーク内の隣接デバイスに関する情報を検出して学習できるようにするデータリンク層プロトコルです。大規模なネットワークでは、LLDP を使用してネットワーク トポロジと接続情報が自動的に構成されます。 Go 言語は高性能で信頼性が高く、同時実行が容易なプログラミング言語であるため、Go 言語を使用して LLDP プロトコルを実装できます。
LLDP を実装するときは、LLDP フレームの構造と標準を理解する必要があります。 LLDP フレームの構造は次のとおりです。
LLDP 構造 |
---|
LLDP ヘッダー (7 バイト) ) |
TLV タイプ (2 バイト) TLV 長さ (2 バイト) 値 (0 ~ 507 バイト) |
. .. |
package main import ( "bytes" "fmt" "net" "time" "github.com/google/gopacket" "github.com/google/gopacket/layers" ) func main() { // 构造LLDP帧 srcMac := net.HardwareAddr{0xa0, 0x36, 0x9f, 0x10, 0xca, 0x00} // 发送方的MAC地址 dstMac, _ := net.ParseMAC("01:80:C2:00:00:0E") // 目标MAC地址 eth := layers.Ethernet{ SrcMAC: srcMac, DstMAC: dstMac, EthernetType: layers.EthernetTypeLLDP, } ttll := layers.TTL{LayerType: layers.LayerTypeTTL, TTL: 120} // TTL 120 chassisID := layers.LLDPBasicTLV{ Type: layers.LLDPBasicTLVTypeChassisID, Length: 7, Value: []byte{0x04, 0x24, 0x16, 0x12, 0x34, 0x56}, } // 构造Chassis ID TLV portID := layers.LLDPBasicTLV{ Type: layers.LLDPBasicTLVTypePortID, Length: 4, Value: []byte{0x01, 0x23, 0x45, 0x67}, } // 构造Port ID TLV // 构造End TLV, 其中Value为空 endOfLLDPDU := layers.LLDPBasicTLV{ Type: layers.LLDPBasicTLVTypeEndOfLLDPDU, Length: 0, Value: []byte{}, } lldp := layers.LLDPPacket{ BaseLayer: layers.BaseLayer{}, ChassisID: chassisID, PortID: portID, TTL: ttll, } lldp.TLVs = append(lldp.TLVs, endOfLLDPDU) // 确定网络接口,并构造数据包 nic, _ := net.InterfaceByName("en0") // 获取本地网络接口, en0是Mac上的有线网络接口 buffer := gopacket.NewSerializeBuffer() options := gopacket.SerializeOptions{} gopacket.SerializeLayers(buffer, options, ð, &lldp, ) outgoingPacket := buffer.Bytes() // 打开网络设备, 并将LLDP包写入device中 handle, _ := net.ListenPacket("en0", "LLDP") // 打开套接字 defer handle.Close() handle.WriteTo(outgoingPacket, nil, &net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}) // 向目标MAC发送包 fmt.Println("LLDP packet sent at", time.Now().Format(time.Stamp)) }ここでは gopacket ライブラリを使用して LLDP フレームを作成し、イーサネット タイプの送信元アドレスと宛先アドレスは LLDP です。次に、LLDPacket タイプの構造を使用してデータ パケットを構築します。シャーシ ID およびポート ID TLV は基本的な TLV タイプであり、タイプ LLDPBasicTLV の構造を使用して作成できます。 TLV を作成した後、End TLV をパッケージに追加します。最後に、シリアル化オプションを使用してパッケージをシリアル化します。パケットはネットワーク インターフェイスに書き込まれます。 実際のアプリケーションでは、ポート経由で LLDP パケットを監視および解析できます。以下は、lldp ライブラリを使用した例です。
package main import ( "fmt" "log" "time" "github.com/atikur-rabbi/lldp" ) func main() { msgChan := make(chan lldp.Message) errorChan := make(chan error) // 监听网络接口 go lldp.Listen("en0", msgChan, errorChan) // 在error通道上显示所有错误, 并打印收到的LLDP消息 for { select { case e := <-errorChan: log.Println("error occured", e) case msg := <-msgChan: log.Printf("Received LLDP packet from %v: %v\n", msg.RemoteAddr, msg.Message) } } }この例では、指定されたネットワーク インターフェイス (ここでは en0) をリッスンする非同期ゴルーチンを開始します。 LLDP メッセージを受信するときは、エラー チャネルを使用してエラーを出力し、受信したメッセージを msg チャネルを通じて出力します。 つまり、LLDP は、ネットワーク内の隣接デバイスに関する情報を検出して理解するために使用できる、非常に便利なプロトコルです。 LLDP プロトコルは、Go 言語を使用して簡単に実装できます。サードパーティのライブラリのサポートにより、フレームの作成と解析が高速になり、LLDP に対応するタスクをより適切に処理できるようになります。
以上がgolangでLLDPプロトコルを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。