>백엔드 개발 >Golang >golang에서 LLDP 프로토콜을 구현하는 방법

golang에서 LLDP 프로토콜을 구현하는 방법

PHPz
PHPz원래의
2023-04-18 09:07:231027검색

LLDP(Link Layer Discovery Protocol)는 장치가 네트워크에서 인접 장치에 대한 정보를 검색하고 학습할 수 있도록 하는 데이터 링크 계층 프로토콜입니다. 대규모 네트워크에서는 LLDP를 사용하여 네트워크 토폴로지 및 연결 정보를 자동으로 구성합니다. Go 언어는 고성능이고 안정적이며 동시에 작성하기 쉬운 프로그래밍 언어이므로 Go 언어를 사용하여 LLDP 프로토콜을 구현할 수 있습니다.

LLDP를 구현할 때는 LLDP 프레임의 구조와 표준을 이해해야 합니다. LLDP 프레임의 구조는 다음과 같습니다.

LLDP 구조
LLDP 헤더(7바이트)
TLV 유형(2바이트) TLV 길이(2바이트) 값(0~507) 바이트)
...
TLV 유형(2바이트) TLV 길이(2바이트) 값(0~507바이트)
FCS(4바이트)

LLDP 프레임 , 헤더는 LLDP 헤더(0x01 0x80) 2바이트, 송신자의 MAC 주소를 나타내는 MAC 주소 4바이트, TTL(Time To Live) 1바이트 등 7바이트로 구성됩니다.

LLDP 프레임에는 여러 TLV(Type-Length-Value) 요소가 포함됩니다. 각 TLV는 유형(2바이트), 길이(2바이트), 값(0~507바이트)의 세 부분으로 구성됩니다. TLV 요소는 원하는 수만큼 추가할 수 있지만 캡슐화 종료 태그(TLV ​​종료 패키지)로 끝나야 합니다.

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 유형입니다. 그런 다음 LLDPPacket 유형 구조를 사용하여 데이터 패킷을 구성합니다. 섀시 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.