LLDP (Link Layer Discovery Protocol) est un protocole de couche liaison de données qui permet aux appareils de découvrir et d'apprendre des informations sur les appareils voisins du réseau. Dans les grands réseaux, LLDP est utilisé pour configurer automatiquement la topologie du réseau et les informations de connexion. Le langage Go est un langage de programmation hautes performances, fiable, simultané et facile à écrire, de sorte que le protocole LLDP peut être implémenté à l'aide du langage Go.
Lors de la mise en œuvre de LLDP, vous devez comprendre la structure et les normes des cadres LLDP. Voici la structure de la trame LLDP :
Structure LLDP |
---|
En-tête LLDP (7 octets) |
Type TLV (2 octets) Longueur TLV (2 octets) Valeur (0-507 octets) |
... |
Type TLV (2 octets) Longueur TLV (2 octets) Valeur (0-507 octets) |
FCS (4 octets) |
Dans une trame LLDP , l'en-tête est composé de 7 octets : 2 octets d'en-tête LLDP (0x01 0x80), 4 octets d'adresse MAC, indiquant l'adresse MAC de l'expéditeur, et 1 octet TTL (Time To Live).
Dans le cadre LLDP, plusieurs éléments TLV (Type-Length-Value) sont inclus. Chaque TLV se compose de 3 parties : type (2 octets), longueur (2 octets) et valeur (0 à 507 octets). N'importe quel nombre d'éléments TLV peuvent être ajoutés, mais ils doivent se terminer par une balise de fin d'encapsulation (package TLV End).
Il convient de noter que lors de l'utilisation du protocole LLDP, il n'est pas nécessaire d'activer le mécanisme d'authentification d'une entité, donc d'autres méthodes peuvent être nécessaires pour garantir que les informations reçues proviennent d'un appareil réel.
Lorsque vous utilisez le langage Go pour implémenter LLDP, vous pouvez utiliser des bibliothèques tierces pour l'implémentation, telles que gopacket et lldp. Ces bibliothèques fournissent des méthodes qui simplifient la création et l'analyse des trames LLDP et aident à effectuer le traitement correspondant à LLDP. Voici un exemple d'utilisation de la bibliothèque 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, ð, &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)) }
La bibliothèque gopacket est utilisée ici pour créer une trame LLDP, et les adresses source et destination sont de type LLDP utilisant Ethernet. Ensuite, utilisez la structure de type LLDDPacket pour construire le paquet de données. Les TLV d'ID de châssis et d'ID de port sont des types TLV de base et peuvent être créés à l'aide de structures de type LLDPBasicTLV. Après avoir créé le TLV, ajoutez le End TLV au package. Enfin, sérialisez le package à l'aide des options de sérialisation. Le paquet sera écrit sur l'interface réseau.
Dans les applications pratiques, les paquets LLDP peuvent être surveillés et analysés via les ports. Voici un exemple utilisant la bibliothèque 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) } } }
Dans cet exemple, nous démarrons une goroutine asynchrone pour écouter sur l'interface réseau spécifiée (ici en0). Lors de la réception d'un message LLDP, utilisez le canal d'erreur pour imprimer l'erreur et imprimez le message reçu via le canal msg.
En bref, LLDP est un protocole très utile pour découvrir et comprendre des informations sur les appareils voisins d'un réseau. Le protocole LLDP peut être facilement implémenté à l'aide du langage Go. Avec la prise en charge de bibliothèques tierces, nous pouvons réaliser une création et une analyse de trames plus rapides et mieux gérer les tâches correspondant à LLDP.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!