ホームページ  >  記事  >  バックエンド開発  >  golangでLLDPプロトコルを実装する方法

golangでLLDPプロトコルを実装する方法

PHPz
PHPzオリジナル
2023-04-18 09:07:23964ブラウズ

LLDP (Link Layer Discovery Protocol) は、デバイスがネットワーク内の隣接デバイスに関する情報を検出して学習できるようにするデータリンク層プロトコルです。大規模なネットワークでは、LLDP を使用してネットワーク トポロジと接続情報が自動的に構成されます。 Go 言語は高性能で信頼性が高く、同時実行が容易なプログラミング言語であるため、Go 言語を使用して LLDP プロトコルを実装できます。

LLDP を実装するときは、LLDP フレームの構造と標準を理解する必要があります。 LLDP フレームの構造は次のとおりです。

##TLV タイプ (2 バイト) TLV 長さ (2 バイト) 値 (0 ~ 507 バイト) FCS (4 バイト)
LLDP 構造
LLDP ヘッダー (7 バイト) )
TLV タイプ (2 バイト) TLV 長さ (2 バイト) 値 (0 ~ 507 バイト)
. ..
LLDP フレームでは、ヘッダーは 7 バイトで構成されます。2 バイトの LLDP ヘッダー (0x01 0x80)、送信者の MAC アドレスを示す 4 バイトの MAC アドレス、および 1 バイトの TTL (有効期間)。

LLDP フレームには、複数の TLV (Type-Length-Value) 要素が含まれます。各 TLV は、タイプ (2 バイト)、長さ (2 バイト)、および値 (0 ~ 507 バイト) の 3 つの部分で構成されます。 TLV 要素はいくつでも追加できますが、カプセル化終了タグ (TLV End パッケージ) で終わる必要があります。

LLDP プロトコルを使用する場合、エンティティの認証メカニズムを有効にする必要がないため、受信した情報が実際のデバイスからのものであることを確認するために他の方法を使用する必要がある場合があることに注意してください。

Go 言語を使用して LLDP を実装する場合、gopacket や lldp などのサードパーティ ライブラリを実装に使用できます。これらのライブラリは、LLDP フレームの作成と解析を簡素化し、LLDP に対応する処理の実行を支援するメソッドを提供します。次に、gopacket ライブラリの使用例を示します。

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,
        &eth,
        &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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。