1
1
package netflow
2
2
3
3
import (
4
+ "bytes"
4
5
"fmt"
5
6
"time"
7
+
8
+ "github.com/cloudflare/goflow/v3/decoders/utils"
6
9
)
7
10
8
11
const (
@@ -445,26 +448,98 @@ const (
445
448
IPFIX_FIELD_natThresholdEvent = 467
446
449
)
447
450
451
+ // IPFIXPacket is a representation of ipfix(netflow v10) protocol packet.
448
452
type IPFIXPacket struct {
449
- Version uint16
450
- Length uint16
451
- ExportTime uint32
452
- SequenceNumber uint32
453
+ // Version is version of ipfix records exported in this packet.
454
+ Version uint16
455
+
456
+ // Length is a total length of the IPFIX packet, measured in octets,
457
+ // including packet Header and Set(s).
458
+ Length uint16
459
+
460
+ // ExportTime is a time at which the IPFIX Message Header leaves the Exporter,
461
+ // expressed in seconds since the UNIX epoch of 1 January 1970 at
462
+ // 00:00 UTC, encoded as an unsigned 32-bit integer.
463
+ ExportTime uint32
464
+
465
+ // SequenceNumber is incremental sequence counter of all export packets sent by this export
466
+ // device; This value is cumulative, and it can be used to identify whether
467
+ // any export packets have been missed.
468
+ SequenceNumber uint32
469
+
470
+ // ObservationDomainId is a 32-bit identifier of the Observation Domain that
471
+ // is locally unique to the Exporting Process.
453
472
ObservationDomainId uint32
454
- FlowSets []interface {}
473
+
474
+ FlowSets
455
475
}
456
476
477
+ // ReadFrom reads into receiver's fields Uint values from buffer and returns
478
+ // boolean flag telling if it was a success.
479
+ //
480
+ // Value is treated as big endian.
481
+ func (x * IPFIXPacket ) ReadFrom (b * bytes.Buffer ) bool {
482
+ if ok := utils .ReadUint16FromBuffer (b , & x .Length ); ! ok {
483
+ return false
484
+ }
485
+ if ok := utils .ReadUint32FromBuffer (b , & x .ExportTime ); ! ok {
486
+ return false
487
+ }
488
+ if ok := utils .ReadUint32FromBuffer (b , & x .SequenceNumber ); ! ok {
489
+ return false
490
+ }
491
+ if ok := utils .ReadUint32FromBuffer (b , & x .ObservationDomainId ); ! ok {
492
+ return false
493
+ }
494
+ return true
495
+ }
496
+
497
+ // IPFIXOptionsTemplateFlowSet is a collection of Options Template Records.
457
498
type IPFIXOptionsTemplateFlowSet struct {
458
499
FlowSetHeader
459
500
Records []IPFIXOptionsTemplateRecord
460
501
}
461
502
503
+ // IPFIXOptionsTemplateRecord contains any combination of IANA-assigned and/or
504
+ // enterprise-specific Information Element identifiers.
462
505
type IPFIXOptionsTemplateRecord struct {
463
- TemplateId uint16
464
- FieldCount uint16
506
+ // TemplateId is a unique number in the range 256 to 65535 used for matching
507
+ // the type of IPFIX data it will be exporting.
508
+ TemplateId uint16
509
+
510
+ // FieldCount is a number of all fields in this Options Template Record,
511
+ // including the Scope Fields.
512
+ FieldCount uint16
513
+
514
+ // ScopeFieldCount is a number of scope fields in this Options Template
515
+ // Record. The Scope Fields are normal Fields, except that they are
516
+ // interpreted as scope at the Collector.
465
517
ScopeFieldCount uint16
466
- Options []Field
467
- Scopes []Field
518
+
519
+ // Options represents the type and length(in bytes) of the field that
520
+ // appears in the options record.
521
+ Options []Field
522
+
523
+ // Scopes is one or more Information Elements, specified in the Options
524
+ // Template Record.
525
+ Scopes []Field
526
+ }
527
+
528
+ // ReadFrom reads into receiver's fields Uint values from buffer and returns
529
+ // boolean flag telling if it was a success.
530
+ //
531
+ // Value is treated as big endian.
532
+ func (x * IPFIXOptionsTemplateRecord ) ReadFrom (b * bytes.Buffer ) bool {
533
+ if ok := utils .ReadUint16FromBuffer (b , & x .TemplateId ); ! ok {
534
+ return false
535
+ }
536
+ if ok := utils .ReadUint16FromBuffer (b , & x .FieldCount ); ! ok {
537
+ return false
538
+ }
539
+ if ok := utils .ReadUint16FromBuffer (b , & x .ScopeFieldCount ); ! ok {
540
+ return false
541
+ }
542
+ return true
468
543
}
469
544
470
545
func IPFIXTypeToString (typeId uint16 ) string {
@@ -950,7 +1025,6 @@ func (flowSet IPFIXOptionsTemplateFlowSet) String(TypeToString func(uint16) stri
950
1025
}
951
1026
952
1027
}
953
-
954
1028
return str
955
1029
}
956
1030
@@ -964,26 +1038,26 @@ func (p IPFIXPacket) String() string {
964
1038
str += fmt .Sprintf (" ExportTime: %v\n " , exportTime .String ())
965
1039
str += fmt .Sprintf (" SequenceNumber: %v\n " , p .SequenceNumber )
966
1040
str += fmt .Sprintf (" ObservationDomainId: %v\n " , p .ObservationDomainId )
967
- str += fmt .Sprintf (" FlowSets (%v):\n " , len (p .FlowSets ))
968
-
969
- for i , flowSet := range p .FlowSets {
970
- switch flowSet := flowSet .(type ) {
971
- case TemplateFlowSet :
972
- str += fmt .Sprintf (" - TemplateFlowSet %v:\n " , i )
973
- str += flowSet .String (IPFIXTypeToString )
974
- case IPFIXOptionsTemplateFlowSet :
975
- str += fmt .Sprintf (" - OptionsTemplateFlowSet %v:\n " , i )
976
- str += flowSet .String (IPFIXTypeToString )
977
- case DataFlowSet :
978
- str += fmt .Sprintf (" - DataFlowSet %v:\n " , i )
979
- str += flowSet .String (IPFIXTypeToString )
980
- case OptionsDataFlowSet :
981
- str += fmt .Sprintf (" - OptionsDataFlowSet %v:\n " , i )
982
- str += flowSet .String (IPFIXTypeToString , IPFIXTypeToString )
983
- default :
984
- str += fmt .Sprintf (" - (unknown type) %v: %v\n " , i , flowSet )
985
- }
1041
+ str += fmt .Sprintf (" FlowSets (%v):\n " , len (p .DataFS )+ len (p .IPFIXOptionsTemplateFS )+ len (p .OptionsDataFS )+ len (p .TemplateFS ))
1042
+
1043
+ for i , fs := range p .TemplateFS {
1044
+ str += fmt .Sprintf (" - TemplateFlowSet %v:\n " , i )
1045
+ str += fs .String (IPFIXTypeToString )
1046
+ }
1047
+
1048
+ for i , fs := range p .IPFIXOptionsTemplateFS {
1049
+ str += fmt .Sprintf (" - OptionsTemplateFlowSet %v:\n " , i )
1050
+ str += fs .String (IPFIXTypeToString )
986
1051
}
987
1052
1053
+ for i , fs := range p .DataFS {
1054
+ str += fmt .Sprintf (" - DataFlowSet %v:\n " , i )
1055
+ str += fs .String (IPFIXTypeToString )
1056
+ }
1057
+
1058
+ for i , fs := range p .OptionsDataFS {
1059
+ str += fmt .Sprintf (" - OptionsDataFlowSet %v:\n " , i )
1060
+ str += fs .String (IPFIXTypeToString , IPFIXTypeToString )
1061
+ }
988
1062
return str
989
1063
}
0 commit comments