LLDP报文格式

LLDP报文格式前面已经知道了FloodlightController是通过从SW发送LLDP帧来获得链路信息的,链路层发现协议(L2)是通过在本地网络中广播LLDP报文来通告自己的设备信息,从而服务于拓扑计算,(wikipedia:LLDPinformationissentbydevicesfromeachoftheirinterfacesatafixedinterval,i

大家好,又见面了,我是你们的朋友全栈君。


     前面已经知道了Floodlight Controller是通过从SW发送LLDP帧来获得链路信息的,链路层发现协议(L2)是通过在本地网络中广播LLDP报文来通告自己的设备信息,从而服务于拓扑计算,(wikipedia:LLDP information is sent by devices from each of their interfaces at a fixed interval, in the form of an Ethernet frame. Each frame contains one LLDP Data Unit (LLDPDU). Each LLDPDU is a sequence of type-length-value (TLV) structures.)报文格式如下:
LLDP报文格式

type-length-value 的设计很常见(比如netlink中attribute也是这种格式),这里的TLV结构是:
LLDP报文格式
LLDP报文格式

此时再看代码就很容易理解:
public 
class 
LLDPTLV {
     
protected 
byte 
type 
;
     
protected 
short 
length 
;
     
protected 
byte
[] 
value 
;

     
public 
byte 
getType() {
           
return 
type 
;
     }

     
public 
LLDPTLV setType( 
byte 
type) {
           
this
.
type 
= type;
           
return 
this 
;
     }

     
public 
short 
getLength() {
           
return 
length 
;
     }

     
public 
LLDPTLV setLength( 
short 
length) {
           
this
.
length 
= length;
           
return 
this 
;
     }

     
public 
byte
[] getValue() {
           
return 
value 
;
     }

     
public 
LLDPTLV setValue( 
byte
[] value) {
           
this
.
value 
= value;
           
return 
this 
;
     }

     
// serialization – Turn data into a stream of bytes
     
public 
byte
[] serialize() {
           
// type = 7 bits
           
// info string length 9 bits, each value == byte
           
// info string
           
short 
scratch = (
short
) (((0x7f & 
this
. 
type
) << 9) | (0x1ff & 
this 
.
length 
));
           
// 7+9 = 2B
           
byte
[] data = 
new 
byte
[2 + 
this
.
length 
];
          ByteBuffer bb = ByteBuffer. wrap(data);
          bb.putShort(scratch);
           
if 
(
this 
.
value 
!= 
null
)
              bb.put( 
this
.
value 
);
           
return 
data;
     }

     
// deserialization – Turn a stream of bytes back into a copy of the original
     
// object.
     
public 
LLDPTLV deserialize(ByteBuffer bb) {
           
short 
sscratch;
          sscratch = bb.getShort();
           
this
.
type 
= (
byte
) ((sscratch >> 9) & 0x7f);
           
this
.
length 
= (
short
) (sscratch & 0x1ff);
           
if 
(
this 
.
length 
> 0) {
               
this
.
value 
= 
new 
byte
[ 
this
.
length 
];

               
// if there is an underrun just toss the TLV
               
if 
(bb.remaining() < 
this
.
length
)
                    
return 
null 
;
              bb.get( 
this
.
value 
);
          }
           
return 
this 
;
     }
}

public 
class 
LLDP 
extends 
BasePacket {
     
protected 
LLDPTLV 
chassisId
;
     
protected 
LLDPTLV 
portId
;
     
protected 
LLDPTLV 
ttl
;
     
protected 
List<LLDPTLV> 
optionalTLVList
;
     
protected 
short 
ethType 
;
     
//上述几个字段都是LLDP协议规定的

     
public 
LLDP() {
           
this
.
optionalTLVList 
= 
new 
ArrayList<LLDPTLV>();
           
this
.
ethType 
= Ethernet.
TYPE_LLDP
; 
// 0x88cc
     }
     
public 
LLDPTLV getChassisId() {
           
return 
chassisId 
;
     }

     
public 
LLDP setChassisId(LLDPTLV chassisId) {
           
this
.
chassisId 
= chassisId;
           
return 
this 
;
     }

     
public 
LLDPTLV getPortId() {
           
return 
portId 
;
     }

     
public 
LLDP setPortId(LLDPTLV portId) {
           
this
.
portId 
= portId;
           
return 
this 
;
     }

     
public 
LLDPTLV getTtl() {
           
return 
ttl 
;
     }

     
public 
LLDP setTtl(LLDPTLV ttl) {
           
this
.
ttl 
= ttl;
           
return 
this 
;
     }

     
public 
List<LLDPTLV> getOptionalTLVList() {
           
return 
optionalTLVList 
;
     }

     
public 
LLDP setOptionalTLVList(List<LLDPTLV> optionalTLVList) {
           
this
.
optionalTLVList 
= optionalTLVList;
           
return 
this 
;
     }

     
@Override
     
public 
byte
[] serialize() {
           
int 
length = 2 + 
this
.
chassisId
.getLength() + 2
                   + 
this
.
portId 
.getLength() + 2 + 
this
.
ttl 
.getLength() + 2;
           
for 
(LLDPTLV tlv : 
this
.
optionalTLVList
) {
              length += 2 + tlv.getLength();
          }

           
byte
[] data = 
new 
byte
[length];
          ByteBuffer bb = ByteBuffer. wrap(data);
          bb.put( 
this
.
chassisId 
.serialize());
          bb.put( 
this
.
portId 
.serialize());
          bb.put( 
this
.
ttl 
.serialize());
           
for 
(LLDPTLV tlv : 
this
.
optionalTLVList
) {
              bb.put(tlv.serialize());
          }
          bb.putShort(( 
short
) 0); 
// End of LLDPDU

           
if 
(
this 
.
parent 
!= 
null 
&& 
this
. 
parent 
instanceof 
Ethernet)
              ((Ethernet) 
this
.
parent 
).setEtherType(
ethType
);

           
return 
data;
     }

     
@Override
     
public 
IPacket deserialize( 
byte
[] data, 
int 
offset, 
int 
length) {
          ByteBuffer bb = ByteBuffer. wrap(data, offset, length);
          LLDPTLV tlv;
           
do 
{
              tlv = 
new 
LLDPTLV().deserialize(bb);

               
// if there was a failure to deserialize stop processing TLVs
               
if 
(tlv == 
null 
)
                    
break
;
               
switch 
(tlv.getType()) {
               
case 
0x0:
                    
// can throw this one away, its just an end delimiter
                    
break
;
               
case 
0x1:
                    
this
.
chassisId 
= tlv;
                    
break
;
               
case 
0x2:
                    
this
.
portId 
= tlv;
                    
break
;
               
case 
0x3:
                    
this
.
ttl 
= tlv;
                    
break
;
               
default
:
                    
this
.
optionalTLVList 
.add(tlv);
                    
break
;
              }
          } 
while 
(tlv.getType() != 0 && bb.hasRemaining());
           
return 
this 
;
     }
}


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/140278.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • php判断当前访问的是在国内还是在国外_怎么判断非法ip地址

    php判断当前访问的是在国内还是在国外_怎么判断非法ip地址方案一使用淘宝接口/***使用淘宝接口判断ip*@param$ip*@returnbool*/publicfunctionjudgeIpByTaobao($ip){$url=”http://ip.taobao.com/service/getIpInfo.php?ip=”.$ip;$res=f

    2025年11月29日
    8
  • SLAM:gmapping

    SLAM:gmappingPackageSummaryReleasedDocumentedThispackagecontainsaROSwrapperforOpenSlam’sGmapping.Thegmappingpackageprovideslaser-basedSLAM(SimultaneousLocalizationandMapping),asaROSn…

    2022年6月22日
    35
  • C++虚函数详解

    C++虚函数详解C++虚函数详解前言C++的特性使得我们可以使用函数继承的方法快速实现开发,而为了满足多态与泛型编程这一性质,C++允许用户使用虚函数**(virtualfunction)来完成运行时决议这一操作,这与一般的编译时决定**有着本质的区别。虚函数表实现原理虚函数的实现是由两个部分组成的,虚函数指针与虚函数表。虚函数指针虚函数指针**(virtualfunctionpointer)*…

    2022年7月26日
    8
  • bat批处理命令大全_文件批处理命令

    bat批处理命令大全_文件批处理命令批处理文件(batchfile)包含一系列DOS命令,通常用于自动执行重复性任务。用户只需双击批处理文件便可执行任务,而无需重复输入相同指令。编写批处理文件非常简单,但难点在于确保一切按顺序执行。编写严谨的批处理文件可以极大程度地节省时间,在应对重复性工作时尤其有效在Windows中善用批处理可以简化很多重复工作批处理? 批处理(Batch),也称为批处理脚本。顾名思义,批处理就是对某对象进行批量的处理。批处理文件的扩展名为bat 目前比较常见的批处理包含两类: DOS批

    2022年8月22日
    8
  • vga转HDMI与hdmi转VGA区别

    vga转HDMI与hdmi转VGA区别

    2022年2月7日
    165
  • js定时器与延时器_JS做定时器倒计时

    js定时器与延时器_JS做定时器倒计时定时器创建定时器window.setInterval(方法类型,间隔时间(1000=1秒))vartimer=window.setInterval(func,2000);vari=0functionfunc(){console.log(“你好”,i)i+=1}清除定时器window.clearInterval(定时器名)functionting(){//清除定时器window.clearInterval(timer…

    2025年8月24日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号