码迷,mamicode.com
首页 > 其他好文 > 详细

LLDP报文格式

时间:2014-07-23 13:07:16      阅读:646      评论:0      收藏:0      [点我收藏+]

标签:floodlight controlle   lldp   tlv   



     前面已经知道了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.)报文格式如下:
bubuko.com,布布扣

type-length-value 的设计很常见(比如netlink中attribute也是这种格式),这里的TLV结构是:
bubuko.com,布布扣
bubuko.com,布布扣

此时再看代码就很容易理解:
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 ;
     }
}



LLDP报文格式

标签:floodlight controlle   lldp   tlv   

原文地址:http://blog.csdn.net/vonzhoufz/article/details/38061131

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!