@@ -56,6 +56,15 @@ const (
56
56
OSPFv3_ET MRTType = 49
57
57
)
58
58
59
+ func (t MRTType ) HasExtendedTimestamp () bool {
60
+ switch t {
61
+ case BGP4MP_ET , ISIS_ET , OSPFv3_ET :
62
+ return true
63
+ default :
64
+ return false
65
+ }
66
+ }
67
+
59
68
type MRTSubTyper interface {
60
69
ToUint16 () uint16
61
70
}
@@ -111,7 +120,7 @@ const (
111
120
ESTABLISHED BGPState = 6
112
121
)
113
122
114
- func packValues (values [] interface {} ) ([]byte , error ) {
123
+ func packValues (values ... any ) ([]byte , error ) {
115
124
b := new (bytes.Buffer )
116
125
for _ , v := range values {
117
126
err := binary .Write (b , binary .BigEndian , v )
@@ -123,10 +132,11 @@ func packValues(values []interface{}) ([]byte, error) {
123
132
}
124
133
125
134
type MRTHeader struct {
126
- Timestamp uint32
127
- Type MRTType
128
- SubType uint16
129
- Len uint32
135
+ Timestamp uint32
136
+ Type MRTType
137
+ SubType uint16
138
+ Len uint32
139
+ ExtendedTimestampMicroseconds uint32
130
140
}
131
141
132
142
func (h * MRTHeader ) DecodeFromBytes (data []byte ) error {
@@ -137,25 +147,38 @@ func (h *MRTHeader) DecodeFromBytes(data []byte) error {
137
147
h .Type = MRTType (binary .BigEndian .Uint16 (data [4 :6 ]))
138
148
h .SubType = binary .BigEndian .Uint16 (data [6 :8 ])
139
149
h .Len = binary .BigEndian .Uint32 (data [8 :12 ])
150
+ if h .Type .HasExtendedTimestamp () {
151
+ h .ExtendedTimestampMicroseconds = binary .BigEndian .Uint32 (data [12 :16 ])
152
+ }
140
153
return nil
141
154
}
142
155
143
156
func (h * MRTHeader ) Serialize () ([]byte , error ) {
144
- return packValues ([]interface {}{h .Timestamp , h .Type , h .SubType , h .Len })
157
+ fields := []any {h .Timestamp , h .Type , h .SubType , h .Len }
158
+ if h .Type .HasExtendedTimestamp () {
159
+ fields = append (fields , h .ExtendedTimestampMicroseconds )
160
+ }
161
+ return packValues (fields ... )
145
162
}
146
163
147
- func NewMRTHeader (timestamp uint32 , t MRTType , subtype MRTSubTyper , l uint32 ) (* MRTHeader , error ) {
164
+ func NewMRTHeader (timestamp time.Time , t MRTType , subtype MRTSubTyper , l uint32 ) (* MRTHeader , error ) {
165
+ ms := uint32 (0 )
166
+ if t .HasExtendedTimestamp () {
167
+ ms = uint32 (timestamp .UnixMicro () - timestamp .Unix ()* 1000000 )
168
+ }
148
169
return & MRTHeader {
149
- Timestamp : timestamp ,
150
- Type : t ,
151
- SubType : subtype .ToUint16 (),
152
- Len : l ,
170
+ Timestamp : uint32 (timestamp .Unix ()),
171
+ Type : t ,
172
+ SubType : subtype .ToUint16 (),
173
+ Len : l ,
174
+ ExtendedTimestampMicroseconds : ms ,
153
175
}, nil
154
176
}
155
177
156
178
func (h * MRTHeader ) GetTime () time.Time {
157
179
t := int64 (h .Timestamp )
158
- return time .Unix (t , 0 )
180
+ ms := int64 (h .ExtendedTimestampMicroseconds )
181
+ return time .Unix (t , ms * 1000 )
159
182
}
160
183
161
184
type MRTMessage struct {
@@ -176,7 +199,7 @@ func (m *MRTMessage) Serialize() ([]byte, error) {
176
199
return append (bbuf , buf ... ), nil
177
200
}
178
201
179
- func NewMRTMessage (timestamp uint32 , t MRTType , subtype MRTSubTyper , body Body ) (* MRTMessage , error ) {
202
+ func NewMRTMessage (timestamp time. Time , t MRTType , subtype MRTSubTyper , body Body ) (* MRTMessage , error ) {
180
203
header , err := NewMRTHeader (timestamp , t , subtype , 0 )
181
204
if err != nil {
182
205
return nil , err
@@ -252,12 +275,12 @@ func (p *Peer) Serialize() ([]byte, error) {
252
275
buf = append (buf , p .IpAddress .To4 ()... )
253
276
}
254
277
if p .Type & (1 << 1 ) > 0 {
255
- bbuf , err = packValues ([] interface {}{ p .AS } )
278
+ bbuf , err = packValues (p .AS )
256
279
} else {
257
280
if p .AS > uint32 (math .MaxUint16 ) {
258
281
return nil , fmt .Errorf ("AS number is beyond 2 octet. %d > %d" , p .AS , math .MaxUint16 )
259
282
}
260
- bbuf , err = packValues ([] interface {}{ uint16 (p .AS )} )
283
+ bbuf , err = packValues (uint16 (p .AS ))
261
284
}
262
285
if err != nil {
263
286
return nil , err
@@ -461,7 +484,6 @@ func (e *RibEntry) String() string {
461
484
} else {
462
485
return fmt .Sprintf ("RIB_ENTRY: PeerIndex [%d] OriginatedTime [%d] PathAttributes [%v]" , e .PeerIndex , e .OriginatedTime , e .PathAttributes )
463
486
}
464
-
465
487
}
466
488
467
489
type Rib struct {
@@ -527,7 +549,7 @@ func (u *Rib) Serialize() ([]byte, error) {
527
549
return nil , err
528
550
}
529
551
buf = append (buf , bbuf ... )
530
- bbuf , err = packValues ([] interface {}{ uint16 (len (u .Entries ))} )
552
+ bbuf , err = packValues (uint16 (len (u .Entries )))
531
553
if err != nil {
532
554
return nil , err
533
555
}
@@ -716,13 +738,13 @@ func (m *BGP4MPHeader) decodeFromBytes(data []byte) ([]byte, error) {
716
738
}
717
739
718
740
func (m * BGP4MPHeader ) serialize () ([]byte , error ) {
719
- var values []interface {}
741
+ var values []any
720
742
if m .isAS4 {
721
- values = []interface {} {m .PeerAS , m .LocalAS , m .InterfaceIndex , m .AddressFamily }
743
+ values = []any {m .PeerAS , m .LocalAS , m .InterfaceIndex , m .AddressFamily }
722
744
} else {
723
- values = []interface {} {uint16 (m .PeerAS ), uint16 (m .LocalAS ), m .InterfaceIndex , m .AddressFamily }
745
+ values = []any {uint16 (m .PeerAS ), uint16 (m .LocalAS ), m .InterfaceIndex , m .AddressFamily }
724
746
}
725
- buf , err := packValues (values )
747
+ buf , err := packValues (values ... )
726
748
if err != nil {
727
749
return nil , err
728
750
}
@@ -792,7 +814,7 @@ func (m *BGP4MPStateChange) Serialize() ([]byte, error) {
792
814
if err != nil {
793
815
return nil , err
794
816
}
795
- bbuf , err := packValues ([] interface {}{ m .OldState , m .NewState } )
817
+ bbuf , err := packValues (m .OldState , m .NewState )
796
818
if err != nil {
797
819
return nil , err
798
820
}
@@ -907,14 +929,14 @@ func SplitMrt(data []byte, atEOF bool) (advance int, token []byte, err error) {
907
929
if cap (data ) < MRT_COMMON_HEADER_LEN { // read more
908
930
return 0 , nil , nil
909
931
}
910
- //this reads the data
932
+ // this reads the data
911
933
hdr := & MRTHeader {}
912
934
errh := hdr .DecodeFromBytes (data [:MRT_COMMON_HEADER_LEN ])
913
935
if errh != nil {
914
936
return 0 , nil , errh
915
937
}
916
938
totlen := int (hdr .Len + MRT_COMMON_HEADER_LEN )
917
- if len (data ) < totlen { //need to read more
939
+ if len (data ) < totlen { // need to read more
918
940
return 0 , nil , nil
919
941
}
920
942
return totlen , data [0 :totlen ], nil
0 commit comments