diff --git a/go.mod b/go.mod index 77295ff45..1ac939980 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/cilium/ebpf v0.16.0 github.com/fsnotify/fsnotify v1.7.0 github.com/gavv/monotime v0.0.0-20190418164738-30dba4353424 - github.com/gopacket/gopacket v1.2.0 + github.com/gopacket/gopacket v1.3.1 github.com/mariomac/guara v0.0.0-20220523124851-5fc279816f1f github.com/mdlayher/ethernet v0.0.0-20220221185849-529eae5b6118 github.com/netobserv/flowlogs-pipeline v1.6.1-crc0.0.20240930010330-bc3d4ebb4a88 diff --git a/go.sum b/go.sum index e6d74d1ee..78153f9f5 100644 --- a/go.sum +++ b/go.sum @@ -438,8 +438,8 @@ github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= -github.com/gopacket/gopacket v1.2.0 h1:eXbzFad7f73P1n2EJHQlsKuvIMJjVXK5tXoSca78I3A= -github.com/gopacket/gopacket v1.2.0/go.mod h1:BrAKEy5EOGQ76LSqh7DMAr7z0NNPdczWm2GxCG7+I8M= +github.com/gopacket/gopacket v1.3.1 h1:ZppWyLrOJNZPe5XkdjLbtuTkfQoxQ0xyMJzQCqtqaPU= +github.com/gopacket/gopacket v1.3.1/go.mod h1:3I13qcqSpB2R9fFQg866OOgzylYkZxLTmkvcXhvf6qg= github.com/gophercloud/gophercloud v0.13.0/go.mod h1:VX0Ibx85B60B5XOrZr6kaNwrmPUzcmMpwxvQ1WQIIWM= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= diff --git a/vendor/github.com/gopacket/gopacket/layers/.lint_blacklist b/vendor/github.com/gopacket/gopacket/layers/.lint_blacklist index fded4f665..1950bc707 100644 --- a/vendor/github.com/gopacket/gopacket/layers/.lint_blacklist +++ b/vendor/github.com/gopacket/gopacket/layers/.lint_blacklist @@ -15,6 +15,7 @@ linux_sll.go llc.go lldp.go mpls.go +multipathtcp.go ndp.go ntp.go ospf.go diff --git a/vendor/github.com/gopacket/gopacket/layers/dns.go b/vendor/github.com/gopacket/gopacket/layers/dns.go index 0e7237e9b..eb39daff6 100644 --- a/vendor/github.com/gopacket/gopacket/layers/dns.go +++ b/vendor/github.com/gopacket/gopacket/layers/dns.go @@ -1,4 +1,4 @@ -// Copyright 2014, 2018 GoPacket Authors. All rights reserved. +// Copyright 2014, 2018, 2024 GoPacket Authors. All rights reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the LICENSE file in the root of the source @@ -52,26 +52,30 @@ type DNSType uint16 // DNSType known values. const ( - DNSTypeA DNSType = 1 // a host address - DNSTypeNS DNSType = 2 // an authoritative name server - DNSTypeMD DNSType = 3 // a mail destination (Obsolete - use MX) - DNSTypeMF DNSType = 4 // a mail forwarder (Obsolete - use MX) - DNSTypeCNAME DNSType = 5 // the canonical name for an alias - DNSTypeSOA DNSType = 6 // marks the start of a zone of authority - DNSTypeMB DNSType = 7 // a mailbox domain name (EXPERIMENTAL) - DNSTypeMG DNSType = 8 // a mail group member (EXPERIMENTAL) - DNSTypeMR DNSType = 9 // a mail rename domain name (EXPERIMENTAL) - DNSTypeNULL DNSType = 10 // a null RR (EXPERIMENTAL) - DNSTypeWKS DNSType = 11 // a well known service description - DNSTypePTR DNSType = 12 // a domain name pointer - DNSTypeHINFO DNSType = 13 // host information - DNSTypeMINFO DNSType = 14 // mailbox or mail list information - DNSTypeMX DNSType = 15 // mail exchange - DNSTypeTXT DNSType = 16 // text strings - DNSTypeAAAA DNSType = 28 // a IPv6 host address [RFC3596] - DNSTypeSRV DNSType = 33 // server discovery [RFC2782] [RFC6195] - DNSTypeOPT DNSType = 41 // OPT Pseudo-RR [RFC6891] - DNSTypeURI DNSType = 256 // URI RR [RFC7553] + DNSTypeA DNSType = 1 // a host address + DNSTypeNS DNSType = 2 // an authoritative name server + DNSTypeMD DNSType = 3 // a mail destination (Obsolete - use MX) + DNSTypeMF DNSType = 4 // a mail forwarder (Obsolete - use MX) + DNSTypeCNAME DNSType = 5 // the canonical name for an alias + DNSTypeSOA DNSType = 6 // marks the start of a zone of authority + DNSTypeMB DNSType = 7 // a mailbox domain name (EXPERIMENTAL) + DNSTypeMG DNSType = 8 // a mail group member (EXPERIMENTAL) + DNSTypeMR DNSType = 9 // a mail rename domain name (EXPERIMENTAL) + DNSTypeNULL DNSType = 10 // a null RR (EXPERIMENTAL) + DNSTypeWKS DNSType = 11 // a well known service description + DNSTypePTR DNSType = 12 // a domain name pointer + DNSTypeHINFO DNSType = 13 // host information + DNSTypeMINFO DNSType = 14 // mailbox or mail list information + DNSTypeMX DNSType = 15 // mail exchange + DNSTypeTXT DNSType = 16 // text strings + DNSTypeAAAA DNSType = 28 // a IPv6 host address [RFC3596] + DNSTypeSRV DNSType = 33 // server discovery [RFC2782] [RFC6195] + DNSTypeOPT DNSType = 41 // OPT Pseudo-RR [RFC6891] + DNSTypeRRSIG DNSType = 46 // RRSIG RR [RFC4034][RFC3755] + DNSTypeDNSKEY DNSType = 48 // DNSKEY RR [RFC4034][RFC3755] + DNSTypeSVCB DNSType = 64 // SVCB DNS RR [RFC9460] + DNSTypeHTTPS DNSType = 65 // HTTPS RR [RFC9460] + DNSTypeURI DNSType = 256 // URI RR [RFC7553] ) func (dt DNSType) String() string { @@ -116,6 +120,14 @@ func (dt DNSType) String() string { return "SRV" case DNSTypeOPT: return "OPT" + case DNSTypeRRSIG: + return "RRSIG" + case DNSTypeDNSKEY: + return "DNSKEY" + case DNSTypeSVCB: + return "SVCB" + case DNSTypeHTTPS: + return "HTTPS" case DNSTypeURI: return "URI" } @@ -157,7 +169,7 @@ func (drc DNSResponseCode) String() string { case DNSResponseCodeFormErr: return "Format Error" case DNSResponseCodeServFail: - return "Server Failure " + return "Server Failure" case DNSResponseCodeNXDomain: return "Non-Existent Domain" case DNSResponseCodeNotImp: @@ -445,6 +457,12 @@ func recSize(rr *DNSResourceRecord) int { l += len(opt.Data) } return l + case DNSTypeRRSIG: + return rr.RRSIG.size() + case DNSTypeDNSKEY: + return rr.DNSKEY.size() + case DNSTypeSVCB, DNSTypeHTTPS: + return rr.SVCB.size() } return 0 @@ -700,6 +718,9 @@ type DNSResourceRecord struct { SRV DNSSRV MX DNSMX OPT []DNSOPT // See RFC 6891, section 6.1.2 + RRSIG DNSRRSIG // See RFC 4034, section 3.1 + DNSKEY DNSKEY // See RFC 4034, section 2.1 + SVCB DNSSVCB // See RFC 9460, this contains both SVCB and HTTPS URI DNSURI // Undecoded TXT for backward compatibility @@ -816,6 +837,12 @@ func (rr *DNSResourceRecord) encode(data []byte, offset int, opts gopacket.Seria copy(data[noff2+4:], opt.Data) noff2 += 4 + len(opt.Data) } + case DNSTypeRRSIG: + rr.RRSIG.encode(data, noff+10) + case DNSTypeDNSKEY: + rr.DNSKEY.encode(data, noff+10) + case DNSTypeSVCB, DNSTypeHTTPS: + rr.SVCB.encode(data, noff+10) default: return 0, fmt.Errorf("serializing resource record of type %v not supported", rr.Type) } @@ -903,6 +930,47 @@ func decodeOPTs(data []byte, offset int) ([]DNSOPT, error) { return allOPT, nil } +func decodeSVCB(data []byte, offset int, buffer *[]byte) (DNSSVCB, error) { + var svcb DNSSVCB + end := len(data) + + if offset == end { + return svcb, fmt.Errorf("DNSSVCB record is empty") + } + + if offset+3 > end { + return svcb, fmt.Errorf("DNSSVCB record is of length %d, it should be at least length 3", end-offset) + } + priority := binary.BigEndian.Uint16(data[offset:]) + target, ofs, err := decodeName(data, offset+2, buffer, 1) + if err != nil { + return svcb, err + } + + var params []DNSSvcParam + for ofs < end { + if offset+4 > end { + return svcb, fmt.Errorf("DNSSVCB record truncated in SvcParams") + } + key := DNSSvcParamKey(binary.BigEndian.Uint16(data[ofs:])) + l := int(binary.BigEndian.Uint16(data[ofs+2:])) + if ofs+4+l > end { + return svcb, fmt.Errorf("DNSSVCB record truncated in SvcParams") + } + params = append(params, DNSSvcParam{ + Key: key, + Value: data[ofs+4 : ofs+4+l], + }) + ofs += 4 + l + } + + return DNSSVCB{ + Priority: priority, + Target: target, + Params: params, + }, nil +} + func (rr *DNSResourceRecord) decodeRData(data []byte, offset int, buffer *[]byte) error { switch rr.Type { case DNSTypeA: @@ -988,6 +1056,22 @@ func (rr *DNSResourceRecord) decodeRData(data []byte, offset int, buffer *[]byte return err } rr.OPT = allOPT + case DNSTypeRRSIG: + err := rr.RRSIG.decode(data, offset) + if err != nil { + return err + } + case DNSTypeDNSKEY: + err := rr.DNSKEY.decode(data, offset) + if err != nil { + return err + } + case DNSTypeSVCB, DNSTypeHTTPS: + svcb, err := decodeSVCB(data, offset, buffer) + if err != nil { + return err + } + rr.SVCB = svcb } return nil } @@ -1013,6 +1097,277 @@ type DNSMX struct { Name []byte } +// DNSSVCB resource record is used to facilitate the lookup of +// information needed to make connections to network services, such as +// for HTTP origins. +type DNSSVCB struct { + Priority uint16 + Target []byte + Params []DNSSvcParam +} + +func (svcb DNSSVCB) size() int { + // Target. + sz := len(svcb.Target) + if sz == 0 { + sz++ + } else { + sz += 2 + } + // Priority. + sz += 2 + + // Params. + for _, param := range svcb.Params { + sz += param.size() + } + return sz +} + +func (svcb DNSSVCB) String() string { + return fmt.Sprintf("%v [%s] %v", + svcb.Priority, string(svcb.Target), svcb.Params) +} + +func (svcb DNSSVCB) encode(data []byte, offset int) { + binary.BigEndian.PutUint16(data[offset:], svcb.Priority) + offset = encodeName(svcb.Target, data, offset+2) + + for _, param := range svcb.Params { + offset = param.encode(data, offset) + } +} + +// DNSSvcParamKey defines SVCB service parameter keys. +type DNSSvcParamKey uint16 + +func (key DNSSvcParamKey) String() string { + switch key { + default: + return "Unknown" + case DNSSvcParamKeyMandatory: + return "mandatory" + case DNSSvcParamKeyAlpn: + return "alpn" + case DNSSvcParamKeyNoDefaultAlpn: + return "no-default-alpn" + case DNSSvcParamKeyPort: + return "port" + case DNSSvcParamKeyIPv4Hint: + return "ipv4hint" + case DNSSvcParamKeyECH: + return "ech" + case DNSSvcParamKeyIPv6Hint: + return "ipv6hint" + case DNSSvcParamKeyDoHPath: + return "dohpath" + case DNSSvcParamKeyOHTTP: + return "ohttp" + case DNSSvcParamKeyDoHURI: + return "dohuri" + case DNSSvcParamKeyInvalidKey: + return "Invalid key" + } +} + +// DNSSvcParamKey known values. +const ( + DNSSvcParamKeyMandatory DNSSvcParamKey = 0 // RFC9460, Section 8 + DNSSvcParamKeyAlpn DNSSvcParamKey = 1 // RFC9460, Section 7.1 + DNSSvcParamKeyNoDefaultAlpn DNSSvcParamKey = 2 // RFC9460, Section 7.1 + DNSSvcParamKeyPort DNSSvcParamKey = 3 // RFC9460, Section 7.2 + DNSSvcParamKeyIPv4Hint DNSSvcParamKey = 4 // RFC9460, Section 7.3 + DNSSvcParamKeyECH DNSSvcParamKey = 5 // RFC9460 + DNSSvcParamKeyIPv6Hint DNSSvcParamKey = 6 // RFC9460, Section 7.3 + DNSSvcParamKeyDoHPath DNSSvcParamKey = 7 // RFC9461 + DNSSvcParamKeyOHTTP DNSSvcParamKey = 8 // RFC9540, Section 4 + DNSSvcParamKeyDoHURI DNSSvcParamKey = 32768 // draft-pauly-add-resolver-discovery-00.html + DNSSvcParamKeyInvalidKey DNSSvcParamKey = 65535 // RFC9460 +) + +// DNSSvcParam is a service param, see RFC9460, section 2.2. +type DNSSvcParam struct { + Key DNSSvcParamKey + Value []byte +} + +func (param DNSSvcParam) size() int { + return 2 + 2 + len(param.Value) +} + +func (param DNSSvcParam) encode(data []byte, offset int) int { + binary.BigEndian.PutUint16(data[offset:], uint16(param.Key)) + offset += 2 + binary.BigEndian.PutUint16(data[offset:], uint16(len(param.Value))) + offset += 2 + copy(data[offset:], param.Value) + offset += len(param.Value) + + return offset +} + +func (param DNSSvcParam) String() string { + return fmt.Sprintf("%s=%x", param.Key, param.Value) +} + +// DNSRRSIG is a DNS RRSIG record, see RFC 4034, section 3.1 +type DNSRRSIG struct { + TypeCovered DNSType + Algorithm DNSSECAlgorithm + Labels uint8 + OriginalTTL, Expiration, Inception uint32 + KeyTag uint16 + SignerName, Signature []byte +} + +func (rrsig DNSRRSIG) size() int { + // 18 bytes for the fixed fields, 2 bytes for the first Label Length, and ending 0x00 byte. + return 18 + len(rrsig.SignerName) + 2 + len(rrsig.Signature) +} + +func (rrsig DNSRRSIG) String() string { + return fmt.Sprintf("RRSIG %d %d %d %d %d %d %d %v %v", + rrsig.TypeCovered, rrsig.Algorithm, rrsig.Labels, rrsig.OriginalTTL, + rrsig.Expiration, rrsig.Inception, rrsig.KeyTag, rrsig.SignerName, rrsig.Signature) +} + +// RRSIG RDATA Wire Format +// 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Type Covered | Algorithm | Labels | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Original TTL | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Signature Expiration | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Signature Inception | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Key Tag | / +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Signer’s Name / +// / / +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// / / +// / Signature / +// / / +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +func (rrsig *DNSRRSIG) decode(data []byte, offset int) error { + if len(data) < offset+18 { + return errors.New("RRSIG too small") + } + var err error + rrsig.TypeCovered = DNSType(binary.BigEndian.Uint16(data[offset:])) + rrsig.Algorithm = DNSSECAlgorithm(data[offset+2]) + rrsig.Labels = data[offset+3] + rrsig.OriginalTTL = binary.BigEndian.Uint32(data[offset+4:]) + rrsig.Expiration = binary.BigEndian.Uint32(data[offset+8:]) + rrsig.Inception = binary.BigEndian.Uint32(data[offset+12:]) + rrsig.KeyTag = binary.BigEndian.Uint16(data[offset+16:]) + _, offset, err = decodeName(data, offset+18, &rrsig.SignerName, 1) + rrsig.SignerName = rrsig.SignerName[1:] // remove the first '.' + if err != nil { + return err + } + rrsig.Signature = data[offset:] + return nil +} + +func (rrsig DNSRRSIG) encode(data []byte, offset int) { + binary.BigEndian.PutUint16(data[offset:], uint16(rrsig.TypeCovered)) + data[offset+2] = uint8(rrsig.Algorithm) + data[offset+3] = rrsig.Labels + binary.BigEndian.PutUint32(data[offset+4:], rrsig.OriginalTTL) + binary.BigEndian.PutUint32(data[offset+8:], rrsig.Expiration) + binary.BigEndian.PutUint32(data[offset+12:], rrsig.Inception) + binary.BigEndian.PutUint16(data[offset+16:], rrsig.KeyTag) + offset += encodeName(rrsig.SignerName, data[offset+18:], 0) + 18 + copy(data[offset:], rrsig.Signature) +} + +// DNSSECAlgorithm common values +const ( + DNSSECAlgorithmRSAMD5 DNSSECAlgorithm = 1 + DNSSECAlgorithmDH DNSSECAlgorithm = 3 + DNSSECAlgorithmDSASHA1 DNSSECAlgorithm = 3 + DNSSECAlgorithmECC DNSSECAlgorithm = 4 + DNSSECAlgorithmRSASHA1 DNSSECAlgorithm = 5 + DNSSECAlgorithmDSASHA1NSEC3 DNSSECAlgorithm = 6 + DNSSECAlgorithmRSASHA1NSEC3 DNSSECAlgorithm = 7 + DNSSECAlgorithmRSASHA256 DNSSECAlgorithm = 8 + DNSSECAlgorithmRSASHA512 DNSSECAlgorithm = 10 + DNSSECAlgorithmECCGOST DNSSECAlgorithm = 12 + DNSSECAlgorithmECDSAP256SHA256 DNSSECAlgorithm = 13 + DNSSECAlgorithmECDSAP384SHA384 DNSSECAlgorithm = 14 + DNSSECAlgorithmED25519 DNSSECAlgorithm = 15 + DNSSECAlgorithmED448 DNSSECAlgorithm = 16 +) + +// DNSSECAlgorithm represents the algorithm used in a DNSSEC record, see RFC 4034, section 5.1 +type DNSSECAlgorithm uint8 + +// DNSKEY is a DNSKEY record, see RFC 4034, section 2.1 +type DNSKEY struct { + Flags DNSKEYFlag + Protocol DNSKEYProtocol + Algorithm DNSSECAlgorithm + PublicKey []byte +} + +func (dnskey DNSKEY) size() int { + return 4 + len(dnskey.PublicKey) +} + +func (dnskey DNSKEY) String() string { + return fmt.Sprintf("DNSKEY %d %d %d %v", + dnskey.Flags, dnskey.Protocol, dnskey.Algorithm, dnskey.PublicKey) +} + +// DNSKEY RDATA Wire Format +// 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Flags | Protocol | Algorithm | | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// / / +// / Public Key / +// / / +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +func (dnskey *DNSKEY) decode(data []byte, offset int) error { + if len(data) < offset+4 { + return errors.New("DNSKEY too small") + } + dnskey.Flags = DNSKEYFlag(binary.BigEndian.Uint16(data[offset:])) + dnskey.Protocol = DNSKEYProtocol(data[offset+2]) + dnskey.Algorithm = DNSSECAlgorithm(data[offset+3]) + dnskey.PublicKey = data[offset+4:] + return nil +} + +func (dnskey DNSKEY) encode(data []byte, offset int) { + binary.BigEndian.PutUint16(data[offset:], uint16(dnskey.Flags)) + data[offset+2] = uint8(dnskey.Protocol) + data[offset+3] = uint8(dnskey.Algorithm) + copy(data[offset+4:], dnskey.PublicKey) +} + +// DNSKEYFlag common values +const ( + DNSKEYFlagOtherKey DNSKEYFlag = 0 + DNSKEYFlagZoneKey DNSKEYFlag = 256 + DNSKEYFlagSecureEntryPoint DNSKEYFlag = 257 +) + +// DNSKEYFlag represents the key type of a DNSKEY record, see RFC 4034, section 2.1.1 +type DNSKEYFlag uint16 + +// DNSKEYProtocol common values, see RFC 4034, section 2.1.2 +const ( + DNSKEYProtocolReserved DNSKEYProtocol = 0 + DNSKEYProtocolValue DNSKEYProtocol = 3 +) + +type DNSKEYProtocol uint8 + // DNSURI is a URI record, defining a target (URI) of a server/service type DNSURI struct { Priority, Weight uint16 diff --git a/vendor/github.com/gopacket/gopacket/layers/dot11.go b/vendor/github.com/gopacket/gopacket/layers/dot11.go index 2b184779a..68887d7db 100644 --- a/vendor/github.com/gopacket/gopacket/layers/dot11.go +++ b/vendor/github.com/gopacket/gopacket/layers/dot11.go @@ -412,6 +412,15 @@ const ( Dot11InformationElementIDWhiteSpaceMap Dot11InformationElementID = 205 Dot11InformationElementIDFineTuningMeasureParams Dot11InformationElementID = 206 Dot11InformationElementIDVendor Dot11InformationElementID = 221 + Dot11InformationElementIDQosParameter Dot11InformationElementID = 222 + Dot11InformationElementIDS1GOperation Dot11InformationElementID = 232 + Dot11InformationElementIDCAGNumber Dot11InformationElementID = 237 + Dot11InformationElementIDAPCSN Dot11InformationElementID = 239 + Dot11InformationElementIDFILSIndication Dot11InformationElementID = 240 + Dot11InformationElementIDDILS Dot11InformationElementID = 241 + Dot11InformationElementIDFragment Dot11InformationElementID = 242 + Dot11InformationElementIDRSNX Dot11InformationElementID = 244 + Dot11InformationElementIDExtension Dot11InformationElementID = 255 ) // String provides a human readable string for Dot11InformationElementID. @@ -762,11 +771,139 @@ func (a Dot11InformationElementID) String() string { return "Fine Tuning Measure Parameters" case Dot11InformationElementIDVendor: return "Vendor" + case Dot11InformationElementIDS1GOperation: + return "IDS1G Operation" + case Dot11InformationElementIDCAGNumber: + return "CAG Number" + case Dot11InformationElementIDAPCSN: + return "APCSN" + case Dot11InformationElementIDFILSIndication: + return "FILS Indication" + case Dot11InformationElementIDDILS: + return "DILS" + case Dot11InformationElementIDFragment: + return "Fragment" + case Dot11InformationElementIDRSNX: + return "RSNX" + case Dot11InformationElementIDExtension: + return "Extension" default: return "Unknown information element id" } } +type Dot11InformationElementExtId uint8 + +const ( + Dot11InformationElementExtIDAssocDelayInfo Dot11InformationElementExtId = 1 + Dot11InformationElementExtIDFilsReqParams Dot11InformationElementExtId = 2 + Dot11InformationElementExtIDFilsKeyConfirm Dot11InformationElementExtId = 3 + Dot11InformationElementExtIDFilsSession Dot11InformationElementExtId = 4 + Dot11InformationElementExtIDFilsHLPContainer Dot11InformationElementExtId = 5 + Dot11InformationElementExtIDFilsIPAddrAssign Dot11InformationElementExtId = 6 + Dot11InformationElementExtIDKeyDelivery Dot11InformationElementExtId = 7 + Dot11InformationElementExtIDFilsWrappedData Dot11InformationElementExtId = 8 + Dot11InformationElementExtIDFilsPublicKey Dot11InformationElementExtId = 12 + Dot11InformationElementExtIDFilsNonce Dot11InformationElementExtId = 13 + Dot11InformationElementExtIDFutureChanGuidance Dot11InformationElementExtId = 14 + Dot11InformationElementExtIDHeCapability Dot11InformationElementExtId = 35 + Dot11InformationElementExtIDHEOperation Dot11InformationElementExtId = 36 + Dot11InformationElementExtIDUora Dot11InformationElementExtId = 37 + Dot11InformationElementExtIDHeMuEdca Dot11InformationElementExtId = 38 + Dot11InformationElementExtIDHeSpr Dot11InformationElementExtId = 39 + Dot11InformationElementExtIDNdpFeedbackReportParamset Dot11InformationElementExtId = 41 + Dot11InformationElementExtIDBssColorChgAnn Dot11InformationElementExtId = 42 + Dot11InformationElementExtIDQuietTimePeriodSetup Dot11InformationElementExtId = 43 + Dot11InformationElementExtIDEssReport Dot11InformationElementExtId = 45 + Dot11InformationElementExtIDOps Dot11InformationElementExtId = 46 + Dot11InformationElementExtIDHeBssLoad Dot11InformationElementExtId = 47 + Dot11InformationElementExtIDMaxChannelSwitchTime Dot11InformationElementExtId = 52 + Dot11InformationElementExtIDMultipleBssidConfiguration Dot11InformationElementExtId = 55 + Dot11InformationElementExtIDNonInheritance Dot11InformationElementExtId = 56 + Dot11InformationElementExtIDKnownBssid Dot11InformationElementExtId = 57 + Dot11InformationElementExtIDShortSsidList Dot11InformationElementExtId = 58 + Dot11InformationElementExtIDHe6ghzCApA Dot11InformationElementExtId = 59 + Dot11InformationElementExtIDuLMuPowerCapA Dot11InformationElementExtId = 60 + Dot11InformationElementExtIDEhTOperation Dot11InformationElementExtId = 106 + Dot11InformationElementExtIDEhtMultiLink Dot11InformationElementExtId = 107 + Dot11InformationElementExtIDEHhCapability Dot11InformationElementExtId = 108 +) + +// String provides a human readable string for Dot11InformationElementExtId. +// This string is possibly subject to change over time; if you're storing this +// persistently, you should probably store the Dot11InformationElementExtId value, +// not its string. +func (a Dot11InformationElementExtId) String() string { + switch a { + case Dot11InformationElementExtIDAssocDelayInfo: + return "Association Delay Information" + case Dot11InformationElementExtIDFilsReqParams: + return "FILS Request Parameters" + case Dot11InformationElementExtIDFilsKeyConfirm: + return "FILS Key Confirmation" + case Dot11InformationElementExtIDFilsSession: + return "FILS Session" + case Dot11InformationElementExtIDFilsHLPContainer: + return "FILS HLP Container" + case Dot11InformationElementExtIDFilsIPAddrAssign: + return "FILS IP Address Assignment" + case Dot11InformationElementExtIDKeyDelivery: + return "Key Delivery" + case Dot11InformationElementExtIDFilsWrappedData: + return "FILS Wrapped Data" + case Dot11InformationElementExtIDFilsPublicKey: + return "FILS Public Key" + case Dot11InformationElementExtIDFilsNonce: + return "FILS Nonce" + case Dot11InformationElementExtIDFutureChanGuidance: + return "Future Channel Guidance" + case Dot11InformationElementExtIDHeCapability: + return "HE Capability" + case Dot11InformationElementExtIDHEOperation: + return "HE Operation" + case Dot11InformationElementExtIDUora: + return "UORA" + case Dot11InformationElementExtIDHeMuEdca: + return "HE MU EDCA" + case Dot11InformationElementExtIDHeSpr: + return "HE Spatial Reuse Parameter" + case Dot11InformationElementExtIDNdpFeedbackReportParamset: + return "NDP Feedback Report Parameter Set" + case Dot11InformationElementExtIDBssColorChgAnn: + return "BSS Color Change Announcement" + case Dot11InformationElementExtIDQuietTimePeriodSetup: + return "Quiet Time Period Setup" + case Dot11InformationElementExtIDEssReport: + return "ESS Report" + case Dot11InformationElementExtIDOps: + return "Operating Mode Notification" + case Dot11InformationElementExtIDHeBssLoad: + return "HE BSS Load" + case Dot11InformationElementExtIDMaxChannelSwitchTime: + return "Maximum Channel Switching Time" + case Dot11InformationElementExtIDMultipleBssidConfiguration: + return "Multiple BSSID Configuration" + case Dot11InformationElementExtIDNonInheritance: + return "Non-Inheritance" + case Dot11InformationElementExtIDKnownBssid: + return "Known BSSID" + case Dot11InformationElementExtIDShortSsidList: + return "Short SSID List" + case Dot11InformationElementExtIDHe6ghzCApA: + return "HE 6 GHz Capabilities" + case Dot11InformationElementExtIDuLMuPowerCapA: + return "uL MU Power Capability" + case Dot11InformationElementExtIDEhTOperation: + return "EH-Transition Operation" + case Dot11InformationElementExtIDEhtMultiLink: + return "EHT Multi-link" + case Dot11InformationElementExtIDEHhCapability: + return "EH-Transition HE Capabilities" + default: + return "Unknown information element extended id" + } +} + // Dot11 provides an IEEE 802.11 base packet header. // See http://standards.ieee.org/findstds/standard/802.11-2012.html // for excruciating detail. @@ -935,7 +1072,7 @@ func (m *Dot11) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { switch mainType { case Dot11TypeCtrl: switch m.Type { - case Dot11TypeCtrlRTS, Dot11TypeCtrlPowersavePoll, Dot11TypeCtrlCFEnd, Dot11TypeCtrlCFEndAck: + case Dot11TypeCtrlRTS, Dot11TypeCtrlPowersavePoll, Dot11TypeCtrlCFEnd, Dot11TypeCtrlCFEndAck, Dot11TypeCtrlBlockAck, Dot11TypeCtrlBlockAckReq: if len(data) < offset+6 { df.SetTruncated() return fmt.Errorf("Dot11 length %v too short, %v required", len(data), offset+6) @@ -1440,10 +1577,11 @@ func (m *Dot11DataQOSCFAckPollNoData) NextLayerType() gopacket.LayerType { type Dot11InformationElement struct { BaseLayer - ID Dot11InformationElementID - Length uint8 - OUI []byte - Info []byte + ID Dot11InformationElementID + Length uint8 + OUI []byte + Info []byte + ExtensionID Dot11InformationElementExtId } func (m *Dot11InformationElement) LayerType() gopacket.LayerType { @@ -1470,14 +1608,19 @@ func (m *Dot11InformationElement) DecodeFromBytes(data []byte, df gopacket.Decod df.SetTruncated() return fmt.Errorf("Dot11InformationElement length %v too short, %v required", len(data), offset+int(m.Length)) } - if len(data) < offset+4 { - df.SetTruncated() - return fmt.Errorf("vendor extension size < %d", offset+int(m.Length)) - } + if m.ID == 221 { + if len(data) < offset+4 { + df.SetTruncated() + return fmt.Errorf("vendor extension size < %d", offset+int(m.Length)) + } + // Vendor extension m.OUI = data[offset : offset+4] m.Info = data[offset+4 : offset+int(m.Length)] + } else if m.ID == 255 { + m.ExtensionID = Dot11InformationElementExtId(data[offset]) + m.Info = data[offset+1 : offset+int(m.Length)] } else { m.Info = data[offset : offset+int(m.Length)] } @@ -1503,6 +1646,8 @@ func (d *Dot11InformationElement) String() string { return fmt.Sprintf("802.11 Information Element (ID: %v, Length: %v, Rates: %s Mbit)", d.ID, d.Length, rates) } else if d.ID == 221 { return fmt.Sprintf("802.11 Information Element (ID: %v, Length: %v, OUI: %X, Info: %X)", d.ID, d.Length, d.OUI, d.Info) + } else if d.ID == 255 { + return fmt.Sprintf("802.11 Information Element Extension (ID: %v, Length %v, Info %X)", d.ExtensionID, d.Length, d.Info) } else { return fmt.Sprintf("802.11 Information Element (ID: %v, Length: %v, Info: %X)", d.ID, d.Length, d.Info) } diff --git a/vendor/github.com/gopacket/gopacket/layers/enums.go b/vendor/github.com/gopacket/gopacket/layers/enums.go index d76eed34c..0dadd4606 100644 --- a/vendor/github.com/gopacket/gopacket/layers/enums.go +++ b/vendor/github.com/gopacket/gopacket/layers/enums.go @@ -40,6 +40,7 @@ const ( EthernetTypeCiscoDiscovery EthernetType = 0x2000 EthernetTypeNortelDiscovery EthernetType = 0x01a2 EthernetTypeTransparentEthernetBridging EthernetType = 0x6558 + EthernetTypeMerakiDiscoveryProtocol EthernetType = 0x712 EthernetTypeDot1Q EthernetType = 0x8100 EthernetTypePPP EthernetType = 0x880b EthernetTypePPPoEDiscovery EthernetType = 0x8863 @@ -323,6 +324,7 @@ func initActualTypeData() { EthernetTypeMetadata[EthernetTypeQinQ] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot1Q), Name: "Dot1Q", LayerType: LayerTypeDot1Q} EthernetTypeMetadata[EthernetTypeTransparentEthernetBridging] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEthernet), Name: "TransparentEthernetBridging", LayerType: LayerTypeEthernet} EthernetTypeMetadata[EthernetTypeERSPAN] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeERSPANII), Name: "ERSPAN Type II", LayerType: LayerTypeERSPANII} + EthernetTypeMetadata[EthernetTypeMerakiDiscoveryProtocol] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeMDP), Name: "MDP", LayerType: LayerTypeMDP} IPProtocolMetadata[IPProtocolIPv4] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4), Name: "IPv4", LayerType: LayerTypeIPv4} IPProtocolMetadata[IPProtocolTCP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeTCP), Name: "TCP", LayerType: LayerTypeTCP} diff --git a/vendor/github.com/gopacket/gopacket/layers/gtp.go b/vendor/github.com/gopacket/gopacket/layers/gtp.go index 82b80bede..621250e03 100644 --- a/vendor/github.com/gopacket/gopacket/layers/gtp.go +++ b/vendor/github.com/gopacket/gopacket/layers/gtp.go @@ -109,15 +109,50 @@ func (g *GTPv1U) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error // SerializationBuffer, implementing gopacket.SerializableLayer. // See the docs for gopacket.SerializableLayer for more info. func (g *GTPv1U) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + var nextExtensionHeaderType byte + for i := len(g.GTPExtensionHeaders) - 1; i >= 0; i-- { + g.ExtensionHeaderFlag = true + eh := g.GTPExtensionHeaders[i] + lContent := len(eh.Content) + if lContent%4 != 2 { + return fmt.Errorf("GTP packet extension header %d has invalid length: %d bytes", i, lContent) + } + + data, err := b.PrependBytes(lContent + 2) // two extra bytes for length and next extension header type + if err != nil { + return err + } + + data[0] = byte((lContent + 2) / 4) // in 4-octet units + data[lContent+1] = nextExtensionHeaderType + copy(data[1:lContent+1], eh.Content) + + nextExtensionHeaderType = eh.Type + } + + if g.ExtensionHeaderFlag || g.SequenceNumberFlag || g.NPDUFlag { + data, err := b.PrependBytes(4) + if err != nil { + return err + } + + binary.BigEndian.PutUint16(data[:2], g.SequenceNumber) + data[2] = g.NPDU + data[3] = nextExtensionHeaderType + } + + if opts.FixLengths { + g.MessageLength = uint16(len(b.Bytes())) + } + data, err := b.PrependBytes(gtpMinimumSizeInBytes) if err != nil { return err } data[0] |= (g.Version << 5) data[0] |= (1 << 4) - if len(g.GTPExtensionHeaders) > 0 { + if g.ExtensionHeaderFlag { data[0] |= 0x04 - g.ExtensionHeaderFlag = true } if g.SequenceNumberFlag { data[0] |= 0x02 @@ -128,29 +163,7 @@ func (g *GTPv1U) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.Serialize data[1] = g.MessageType binary.BigEndian.PutUint16(data[2:4], g.MessageLength) binary.BigEndian.PutUint32(data[4:8], g.TEID) - if g.ExtensionHeaderFlag || g.SequenceNumberFlag || g.NPDUFlag { - data, err := b.AppendBytes(4) - if err != nil { - return err - } - binary.BigEndian.PutUint16(data[:2], g.SequenceNumber) - data[2] = g.NPDU - for _, eh := range g.GTPExtensionHeaders { - data[len(data)-1] = eh.Type - lContent := len(eh.Content) - // extensionLength is in 4-octet units - extensionLength := (lContent + 2) / 4 - // Get two extra byte for the next extension header type and length - data, err = b.AppendBytes(lContent + 2) - if err != nil { - return err - } - data[0] = byte(extensionLength) - copy(data[1:lContent+1], eh.Content) - } - } return nil - } // CanDecode returns a set of layers that GTP objects can decode. diff --git a/vendor/github.com/gopacket/gopacket/layers/ip6.go b/vendor/github.com/gopacket/gopacket/layers/ip6.go index 1fbd085ae..77937da46 100644 --- a/vendor/github.com/gopacket/gopacket/layers/ip6.go +++ b/vendor/github.com/gopacket/gopacket/layers/ip6.go @@ -603,6 +603,23 @@ type IPv6Fragment struct { Identification uint32 } +func (i *IPv6Fragment) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + data, err := b.PrependBytes(8) + if err != nil { + return err + } + + data[0] = uint8(i.NextHeader) + data[1] = i.Reserved1 + binary.BigEndian.PutUint16(data[2:4], i.FragmentOffset<<3) + data[3] = data[3] | ((i.Reserved2 << 1) & 0x6) + if i.MoreFragments { + data[3] = data[3] | 0x1 + } + binary.BigEndian.PutUint32(data[4:8], i.Identification) + return nil +} + // LayerType returns LayerTypeIPv6Fragment. func (i *IPv6Fragment) LayerType() gopacket.LayerType { return LayerTypeIPv6Fragment } diff --git a/vendor/github.com/gopacket/gopacket/layers/layertypes.go b/vendor/github.com/gopacket/gopacket/layers/layertypes.go index 1f5cfc65b..a973b877d 100644 --- a/vendor/github.com/gopacket/gopacket/layers/layertypes.go +++ b/vendor/github.com/gopacket/gopacket/layers/layertypes.go @@ -149,6 +149,7 @@ var ( LayerTypeERSPANII = gopacket.RegisterLayerType(145, gopacket.LayerTypeMetadata{Name: "ERSPAN Type II", Decoder: gopacket.DecodeFunc(decodeERSPANII)}) LayerTypeRADIUS = gopacket.RegisterLayerType(146, gopacket.LayerTypeMetadata{Name: "RADIUS", Decoder: gopacket.DecodeFunc(decodeRADIUS)}) LayerTypeLinuxSLL2 = gopacket.RegisterLayerType(276, gopacket.LayerTypeMetadata{Name: "Linux SLL2", Decoder: gopacket.DecodeFunc(decodeLinuxSLL2)}) + LayerTypeMDP = gopacket.RegisterLayerType(147, gopacket.LayerTypeMetadata{Name: "MDP", Decoder: gopacket.DecodeFunc(decodeMDP)}) ) var ( diff --git a/vendor/github.com/gopacket/gopacket/layers/mdp.go b/vendor/github.com/gopacket/gopacket/layers/mdp.go new file mode 100644 index 000000000..a3e3bd5da --- /dev/null +++ b/vendor/github.com/gopacket/gopacket/layers/mdp.go @@ -0,0 +1,162 @@ +// Copyright 2024 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "fmt" + "net" + "strconv" + + "github.com/gopacket/gopacket" +) + +const ( + MdpTlvType uint8 = iota + MdpTlvLength + MdpTlvDeviceInfo + MdpTlvNetworkInfo + MdpTlvLongitude + MdpTlvLatitude + MdpTlvType6 + MdpTlvType7 + MdpTlvIP = 11 + MdpTlvUnknownBool = 13 + MdpTlvEnd = 255 +) + +// MDP defines a MDP over LLC layer. +type MDP struct { + BaseLayer + PreambleData []byte + DeviceInfo string + NetworkInfo string + Longitude float64 + Latitude float64 + Type6UUID string + Type7UUID string + IPAddress net.IP + Type13Bool bool + + Type EthernetType + Length int +} + +// LayerType returns LayerTypeMDP. +func (m *MDP) LayerType() gopacket.LayerType { return LayerTypeMDP } + +// DecodeFromBytes decodes the given bytes into this layer. +func (m *MDP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + var length int + if len(data) < 28 { + df.SetTruncated() + return fmt.Errorf("MDP length %d too short", len(data)) + } + m.Type = EthernetTypeMerakiDiscoveryProtocol + m.Length = len(data) + offset := 28 + m.PreambleData = data[:offset] + + for { + if offset >= m.Length { + break + } + t := data[offset] + switch t { + case MdpTlvDeviceInfo: + offset += 2 + length = int(data[offset-1]) + m.Contents = append(m.Contents, data[offset-2:offset+length]...) + m.DeviceInfo = string(data[offset : offset+length]) + offset += length + break + case MdpTlvNetworkInfo: + offset += 2 + length = int(data[offset-1]) + m.NetworkInfo = string(data[offset : offset+length]) + offset += length + break + case MdpTlvLongitude: + offset += 2 + length = int(data[offset-1]) + m.Longitude, _ = strconv.ParseFloat(string(data[offset:offset+length]), 64) + offset += length + break + case MdpTlvLatitude: + offset += 2 + length = int(data[offset-1]) + m.Latitude, _ = strconv.ParseFloat(string(data[offset:offset+length]), 64) + offset += length + break + case MdpTlvType6: + offset += 2 + length = int(data[offset-1]) + m.Type6UUID = string(data[offset : offset+length]) + offset += length + break + case MdpTlvType7: + offset += 2 + length = int(data[offset-1]) + m.Type7UUID = string(data[offset : offset+length]) + offset += length + break + case MdpTlvIP: + offset += 2 + length = int(data[offset-1]) + m.IPAddress = net.ParseIP(string(data[offset : offset+length])) + offset += length + break + case MdpTlvUnknownBool: + offset += 2 + length = int(data[offset-1]) + m.Type13Bool, _ = strconv.ParseBool(string(data[offset : offset+length])) + offset += length + break + case MdpTlvEnd: + offset = m.Length + break + default: + // Skip over unknown junk + offset += 2 + length = int(data[offset-1]) + offset += length + break + + } + } + m.BaseLayer = BaseLayer{Contents: data, Payload: nil} + return nil +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer +func (m *MDP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + // bytes, _ := b.PrependBytes(4) + // bytes[0] = m.Version + // bytes[1] = byte(m.Type) + // binary.BigEndian.PutUint16(bytes[2:], m.Length) + return nil +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (m *MDP) CanDecode() gopacket.LayerClass { + return LayerTypeMDP +} + +// NextLayerType returns the layer type contained by this DecodingLayer. +func (m *MDP) NextLayerType() gopacket.LayerType { + return m.Type.LayerType() +} + +func decodeMDP(data []byte, p gopacket.PacketBuilder) error { + m := &MDP{} + err := m.DecodeFromBytes(data, p) + if err != nil { + return err + } + p.AddLayer(m) + return p.NextDecoder(m.NextLayerType()) +} diff --git a/vendor/github.com/gopacket/gopacket/layers/multipathtcp.go b/vendor/github.com/gopacket/gopacket/layers/multipathtcp.go new file mode 100644 index 000000000..313cb86c9 --- /dev/null +++ b/vendor/github.com/gopacket/gopacket/layers/multipathtcp.go @@ -0,0 +1,161 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "fmt" + "net" +) + +// MPTCPSubtype represents an MPTCP subtype code. +type MPTCPSubtype uint8 + +// MPTCP Subtypes constonts from https://www.iana.org/assignments/tcp-parameters/tcp-parameters.xml#mptcp-option-subtypes +const ( + MPTCPSubtypeMPCAPABLE = 0x0 + MPTCPSubtypeMPJOIN = 0x1 + MPTCPSubtypeDSS = 0x2 + MPTCPSubtypeADDADDR = 0x3 + MPTCPSubtypeREMOVEADDR = 0x4 + MPTCPSubtypeMPPRIO = 0x5 + MPTCPSubtypeMPFAIL = 0x6 + MPTCPSubtypeMPFASTCLOSE = 0x7 + MPTCPSubtypeMPTCPRST = 0x8 +) + +func (k MPTCPSubtype) String() string { + switch k { + case MPTCPSubtypeMPCAPABLE: + return "MP_CAPABLE" + case MPTCPSubtypeMPJOIN: + return "MP_JOIN" + case MPTCPSubtypeDSS: + return "DSS" + case MPTCPSubtypeADDADDR: + return "ADD_ADDR" + case MPTCPSubtypeREMOVEADDR: + return "REMOVE_ADDR" + case MPTCPSubtypeMPPRIO: + return "MP_PRIO" + case MPTCPSubtypeMPFAIL: + return "MP_FAIL" + case MPTCPSubtypeMPFASTCLOSE: + return "MP_FASTCLOSE" + case MPTCPSubtypeMPTCPRST: + return "MP_TCPRST" + default: + return fmt.Sprintf("Unknown(%d)", k) + } +} + +const ( + MptcpVersion0 = 0 + MptcpVersion1 = 1 +) + +const ( + OptionLenMpCapableSyn = 4 + OptionLenMpCapableSynAck = 12 + OptionLenMpCapableAck = 20 + OptionLenMpCapableAckData = 22 + OptionLenMpCapableAckDataCSum = 24 + OptionLenMpJoinSyn = 12 + OptionLenMpJoinSynAck = 16 + OptionLenMpJoinAck = 24 + OptionLenDssAck = 4 + OptionLenDssAck64 = 8 + OptionLenDssDSN = 4 + OptionLenDssDSN64 = 8 + OptionLenDssSSN = 4 + OptionLenDssDataLen = 2 + OptionLenDssCSum = 2 + OptionLenAddAddrv4 = 8 + OptionLenAddAddrv6 = 20 + OptionLenAddAddrPort = 2 + OptionLenAddAddrHmac = 8 + OptionLenRemAddr = 4 + OptionLenMpPrio = 3 + OptionLenMpPrioAddr = 4 + OptionLenMpFail = 12 + OptionLenMpFClose = 12 + OptionLenMpTcpRst = 4 +) + +// MPCapable contains the fields from the MP_CAPABLE MPTCP Option +type MPCapable struct { + BaseLayer + Version uint8 + A, B, C, D, E, F, G, H bool + SendKey []byte + ReceivKey []byte + DataLength uint16 + Checksum uint16 +} + +// MPJoin contains the fields from the MP_JOIN MPTCP Option +type MPJoin struct { + BaseLayer + Backup bool + AddrID uint8 + ReceivToken uint32 + SendRandNum uint32 + SendHMAC []byte +} + +// Dss contains the fields from the DSS MPTCP Option +type Dss struct { + BaseLayer + F, m, M, a, A bool + DataAck []byte + DSN []byte + SSN uint32 + DataLength uint16 + Checksum uint16 +} + +// AddAddr contains the fields from the ADD_ADDR MPTCP Option +type AddAddr struct { + BaseLayer + IPVer uint8 + E bool + AddrID uint8 + Address net.IP + Port uint16 + SendHMAC []byte +} + +// RemAddr contains the fields from the REMOVE_ADDR MPTCP Option +type RemAddr struct { + BaseLayer + AddrIDs []uint8 +} + +// MPPrio contains the fields from the MP_PRIO MPTCP Option +type MPPrio struct { + BaseLayer + Backup bool + AddrID uint8 +} + +// MPFail contains the fields from the MP_FAIL MPTCP Option +type MPFail struct { + BaseLayer + DSN uint64 +} + +// MPFClose contains the fields from the MP_FASTCLOSE MPTCP Option +type MPFClose struct { + BaseLayer + ReceivKey []byte +} + +// MPTcpRst contains the fields from the MP_TCPRST MPTCP Option +type MPTcpRst struct { + BaseLayer + U, V, W, T bool + Reason uint8 +} diff --git a/vendor/github.com/gopacket/gopacket/layers/ospf.go b/vendor/github.com/gopacket/gopacket/layers/ospf.go index 371b9292b..ca2ac6e65 100644 --- a/vendor/github.com/gopacket/gopacket/layers/ospf.go +++ b/vendor/github.com/gopacket/gopacket/layers/ospf.go @@ -518,7 +518,8 @@ func (ospf *OSPFv2) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) err for i := 32; uint16(i+20) <= ospf.PacketLength; i += 20 { lsa := LSAheader{ LSAge: binary.BigEndian.Uint16(data[i : i+2]), - LSType: binary.BigEndian.Uint16(data[i+2 : i+4]), + LSOptions: data[i+2], + LSType: uint16(data[i+3]), LinkStateID: binary.BigEndian.Uint32(data[i+4 : i+8]), AdvRouter: binary.BigEndian.Uint32(data[i+8 : i+12]), LSSeqNumber: binary.BigEndian.Uint32(data[i+12 : i+16]), diff --git a/vendor/github.com/gopacket/gopacket/layers/radiotap.go b/vendor/github.com/gopacket/gopacket/layers/radiotap.go index 89641e4a1..f63b0f493 100644 --- a/vendor/github.com/gopacket/gopacket/layers/radiotap.go +++ b/vendor/github.com/gopacket/gopacket/layers/radiotap.go @@ -49,6 +49,10 @@ const ( RadioTapPresentMCS RadioTapPresentAMPDUStatus RadioTapPresentVHT + RadiotapPresentTimestamp + RadiotapPresentHE + RadioTapPresentHEMU + RadioTapPresentHEUOtherUser RadioTapPresentEXT RadioTapPresent = 1 << 31 ) @@ -115,6 +119,18 @@ func (r RadioTapPresent) AMPDUStatus() bool { func (r RadioTapPresent) VHT() bool { return r&RadioTapPresentVHT != 0 } +func (r RadioTapPresent) Timestamp() bool { + return r&RadiotapPresentTimestamp != 0 +} +func (r RadioTapPresent) HE() bool { + return r&RadiotapPresentHE != 0 +} +func (r RadioTapPresent) HEMU() bool { + return r&RadioTapPresentHEMU != 0 +} +func (r RadioTapPresent) HEUOtherUser() bool { + return r&RadioTapPresentHEUOtherUser != 0 +} func (r RadioTapPresent) EXT() bool { return r&RadioTapPresentEXT != 0 } @@ -674,6 +690,569 @@ func (self RadioTapVHTMCSNSS) String() string { return fmt.Sprintf("NSS#%dMCS#%d", uint32(self&0xf), uint32(self>>4)) } +type RadiotapHE struct { + Data1 RadiotapHEData1 + Data2 RadiotapHEData2 + Data3 RadiotapHEData3 + Data4 RadiotapHEData4 + Data5 RadiotapHEData5 + Data6 RadiotapHEData6 +} + +func (self RadiotapHE) String() string { + var tokens []string + tokens = append(tokens, fmt.Sprintf("HE PPDU Format: %v", self.Data1.HE_PPDUFormat())) + if self.Data1.BSSColorKnown() { + tokens = append(tokens, fmt.Sprintf("BSS Color: %d", self.Data3.BSSColor())) + } + if self.Data1.BeamChangeKnown() { + if self.Data3.BeamChange() { + tokens = append(tokens, "Beam Change") + } else { + tokens = append(tokens, "No Beam Change") + } + } + if self.Data1.ULDLKnown() { + if self.Data3.ULDL() { + tokens = append(tokens, "UL") + } else { + tokens = append(tokens, "DL") + } + } + if self.Data1.DataMCSKnown() { + tokens = append(tokens, fmt.Sprintf("Data MCS: %d", self.Data3.DataMCS())) + } + if self.Data1.DataDCMKnown() { + if self.Data3.DataDCM() { + tokens = append(tokens, "Data DCM applied") + } else { + tokens = append(tokens, "Data DCM not applied") + } + } + if self.Data1.CodingKnown() { + tokens = append(tokens, fmt.Sprintf("Coding: %v", self.Data3.Coding())) + } + if self.Data1.LDPCExtraSymbolSegmentKnown() { + if self.Data3.LDPCExtraSymbolSegment() { + tokens = append(tokens, "LDPC Extra Symbol Segment") + } else { + tokens = append(tokens, "No LDPC Extra Symbol Segment") + } + } + if self.Data1.STBCKnown() { + if self.Data3.STBC() { + tokens = append(tokens, "STBC") + } else { + tokens = append(tokens, "No STBC") + } + } + switch self.Data1.HE_PPDUFormat() { + case RadiotapHePpduFormatHE_SU: + case RadiotapHePpduFormatHE_EXT_SU: + if self.Data1.SpatialReuseKnown() { + tokens = append(tokens, fmt.Sprintf("Spatial Reuse: %d", self.Data4&0x000f)) + } + case RadiotapHePpduFormatHE_TRIG: + if self.Data1.SpatialReuse1Known() { + tokens = append(tokens, fmt.Sprintf("Spatial Reuse 1: %d", self.Data4&0x000f)) + } + if self.Data1.SpatialReuse2Known() { + tokens = append(tokens, fmt.Sprintf("Spatial Reuse 2: %d", self.Data4&0x00f0>>4)) + } + if self.Data1.SpatialReuse3Known() { + tokens = append(tokens, fmt.Sprintf("Spatial Reuse 3: %d", self.Data4&0x0f00>>8)) + } + if self.Data1.SpatialReuse4Known() { + tokens = append(tokens, fmt.Sprintf("Spatial Reuse 4: %d", self.Data4&0xf000>>12)) + } + case RadiotapHePpduFormatHE_MU: + if self.Data1.SpatialReuseKnown() { + tokens = append(tokens, fmt.Sprintf("Spatial Reuse: %d", self.Data4&0x000f)) + } + if self.Data1.StaIDKnown() { + tokens = append(tokens, fmt.Sprintf("STA ID: %d", self.Data4&0x7ff0>>4)) + } + } + if self.Data1.DataBWRUAllocationKnown() { + tokens = append(tokens, fmt.Sprintf("Data BW/RU Allocation: %s", self.Data5.DataBandwidth())) + } + if self.Data2.GIKnown() { + tokens = append(tokens, fmt.Sprintf("GI: %v", self.Data5.Gi())) + } + if self.Data2.NumLTFKnown() { + tokens = append(tokens, fmt.Sprintf("LTF Symbol size: %s", self.Data5.LTFSize())) + tokens = append(tokens, fmt.Sprintf("Number of LTF symbols: %s", self.Data5.NumLTFSymbols())) + } + if self.Data2.PreFECPaddingFactorKnown() { + tokens = append(tokens, fmt.Sprintf("Pre-FEC Padding Factor: %d", self.Data5.PreFECPaddingFactor())) + } + if self.Data2.TxBFKnown() { + if self.Data5.TxBF() { + tokens = append(tokens, "TxBF") + } else { + tokens = append(tokens, "No TxBF") + } + } + if self.Data2.PEDisambiguityKnown() { + if self.Data5.PEDisambiguity() { + tokens = append(tokens, "PE Disambiguity") + } else { + tokens = append(tokens, "No PE Disambiguity") + } + } + nSts := self.Data6.NSTS() + if nSts > 0 { + tokens = append(tokens, fmt.Sprintf("NSTS: %d", self.Data6.NSTS())) + } else { + tokens = append(tokens, "NSTS: unknown") + } + if self.Data1.DopplerKnown() { + if self.Data6.Doppler() { + tokens = append(tokens, "Doppler") + } else { + tokens = append(tokens, "No Doppler") + } + } + if self.Data2.TXOPKnown() { + tokens = append(tokens, fmt.Sprintf("TXOP: %d", self.Data6.TXOP())) + } + if self.Data2.MidamblePeriodicityKnown() { + tokens = append(tokens, fmt.Sprintf("Midamble Periodicity: %v", self.Data6.MidamblePeriodicity())) + } + return strings.Join(tokens, ",") +} + +type RadiotapHEData1 uint16 + +const ( + RadiotapHEData1_HE_PPDUFormatMask RadiotapHEData1 = 0x0003 + RadiotapHEData1BSSColorKnown RadiotapHEData1 = 0x0004 + RadiotapHEData1BeamChangeKnown RadiotapHEData1 = 0x0008 + RadiotapHEData1ULDLKnown RadiotapHEData1 = 0x0010 + RadiotapHEData1DataMCSKnown RadiotapHEData1 = 0x0020 + RadiotapHEData1DataDCMKnown RadiotapHEData1 = 0x0040 + RadiotapHEData1CodingKnown RadiotapHEData1 = 0x0080 + RadiotapHEData1LDPCExtraSymbolSegmentKnown RadiotapHEData1 = 0x0100 + RadiotapHEData1STBCKnown RadiotapHEData1 = 0x0200 + RadiotapHEData1SpatialReuseKnown RadiotapHEData1 = 0x0400 + RadiotapHEData1SpatialReuse1Known RadiotapHEData1 = 0x0400 + RadiotapHEData1SpatialReuse2Known RadiotapHEData1 = 0x0800 + RadiotapHEData1StaIDKnown RadiotapHEData1 = 0x8000 + RadiotapHEData1SpatialReuse3Known RadiotapHEData1 = 0x1000 + RadiotapHEData1SpatialReuse4Known RadiotapHEData1 = 0x2000 + RadiotapHEData1DataBWRUAllocationKnown RadiotapHEData1 = 0x4000 + RadiotapHEData1DopplerKnown RadiotapHEData1 = 0x8000 +) + +func (self RadiotapHEData1) HE_PPDUFormat() RadiotapHePpduFormat { + return RadiotapHePpduFormat(self & 0x0003) +} + +func (self RadiotapHEData1) BSSColorKnown() bool { + return self&RadiotapHEData1BSSColorKnown != 0 +} + +func (self RadiotapHEData1) BeamChangeKnown() bool { + return self&RadiotapHEData1BeamChangeKnown != 0 +} + +func (self RadiotapHEData1) ULDLKnown() bool { + return self&RadiotapHEData1ULDLKnown != 0 +} + +func (self RadiotapHEData1) DataMCSKnown() bool { + return self&RadiotapHEData1DataMCSKnown != 0 +} + +func (self RadiotapHEData1) DataDCMKnown() bool { + return self&RadiotapHEData1DataDCMKnown != 0 +} + +func (self RadiotapHEData1) CodingKnown() bool { + return self&RadiotapHEData1CodingKnown != 0 +} + +func (self RadiotapHEData1) LDPCExtraSymbolSegmentKnown() bool { + return self&RadiotapHEData1LDPCExtraSymbolSegmentKnown != 0 +} + +func (self RadiotapHEData1) STBCKnown() bool { + return self&RadiotapHEData1STBCKnown != 0 +} + +func (self RadiotapHEData1) SpatialReuseKnown() bool { + return self&RadiotapHEData1SpatialReuseKnown != 0 +} + +func (self RadiotapHEData1) SpatialReuse1Known() bool { + return self&RadiotapHEData1SpatialReuse1Known != 0 +} + +func (self RadiotapHEData1) SpatialReuse2Known() bool { + return self&RadiotapHEData1SpatialReuse2Known != 0 +} + +func (self RadiotapHEData1) StaIDKnown() bool { + return self&RadiotapHEData1StaIDKnown != 0 +} + +func (self RadiotapHEData1) SpatialReuse3Known() bool { + return self&RadiotapHEData1SpatialReuse3Known != 0 +} + +func (self RadiotapHEData1) SpatialReuse4Known() bool { + return self&RadiotapHEData1SpatialReuse4Known != 0 +} + +func (self RadiotapHEData1) DataBWRUAllocationKnown() bool { + return self&RadiotapHEData1DataBWRUAllocationKnown != 0 +} + +func (self RadiotapHEData1) DopplerKnown() bool { + return self&RadiotapHEData1DopplerKnown != 0 +} + +type RadiotapHePpduFormat uint8 + +const ( + RadiotapHePpduFormatHE_SU RadiotapHePpduFormat = iota + RadiotapHePpduFormatHE_EXT_SU + RadiotapHePpduFormatHE_MU + RadiotapHePpduFormatHE_TRIG +) + +func (self RadiotapHePpduFormat) String() string { + switch self { + case RadiotapHePpduFormatHE_SU: + return "HE SU" + case RadiotapHePpduFormatHE_EXT_SU: + return "HE EXT SU" + case RadiotapHePpduFormatHE_MU: + return "HE MU" + case RadiotapHePpduFormatHE_TRIG: + return "HE TRIG" + } + return fmt.Sprintf("HE Unknown(%d)", self) +} + +type RadiotapHEData2 uint16 + +const ( + RadiotapHEData2PriSec80MHzKnown RadiotapHEData2 = 0x0001 + RadiotapHEData2GIKnown RadiotapHEData2 = 0x0002 + RadiotapHEData2NumLTFKnown RadiotapHEData2 = 0x0004 + RadiotapHEData2PreFECPaddingFactorKnown RadiotapHEData2 = 0x0008 + RadiotapHEData2TxBFKnown RadiotapHEData2 = 0x0010 + RadiotapHEData2PEDisambiguityKnown RadiotapHEData2 = 0x0020 + RadiotapHEData2TXOPKnown RadiotapHEData2 = 0x0040 + RadiotapHEData2MidamblePeriodicityKnown RadiotapHEData2 = 0x0080 + RadiotapHEData2RUAllocationOffset RadiotapHEData2 = 0x3f00 + RadiotapHEData2RUAllocationOffsetKnown RadiotapHEData2 = 0x4000 + RadiotapHEData2PriSec80MHz RadiotapHEData2 = 0x8000 +) + +func (self RadiotapHEData2) PriSec80MHzKnown() bool { + return self&RadiotapHEData2PriSec80MHzKnown != 0 +} + +func (self RadiotapHEData2) GIKnown() bool { + return self&RadiotapHEData2GIKnown != 0 +} + +func (self RadiotapHEData2) NumLTFKnown() bool { + return self&RadiotapHEData2NumLTFKnown != 0 +} + +func (self RadiotapHEData2) PreFECPaddingFactorKnown() bool { + return self&RadiotapHEData2PreFECPaddingFactorKnown != 0 +} + +func (self RadiotapHEData2) TxBFKnown() bool { + return self&RadiotapHEData2TxBFKnown != 0 +} + +func (self RadiotapHEData2) PEDisambiguityKnown() bool { + return self&RadiotapHEData2PEDisambiguityKnown != 0 +} + +func (self RadiotapHEData2) TXOPKnown() bool { + return self&RadiotapHEData2TXOPKnown != 0 +} + +func (self RadiotapHEData2) MidamblePeriodicityKnown() bool { + return self&RadiotapHEData2MidamblePeriodicityKnown != 0 +} + +func (self RadiotapHEData2) RUAllocationOffset() int { + return int(self&RadiotapHEData2RUAllocationOffset) >> 8 +} + +func (self RadiotapHEData2) RUAllocationOffsetKnown() bool { + return self&RadiotapHEData2RUAllocationOffsetKnown != 0 +} + +func (self RadiotapHEData2) PriSec80MHz() bool { + return self&RadiotapHEData2PriSec80MHz != 0 +} + +type RadiotapHEPriSec80MHz bool + +type RadiotapHEData3 uint16 + +const ( + RadiotapHEData3BSSColorMask RadiotapHEData3 = 0x003F + RadiotapHEData3BeamChange RadiotapHEData3 = 0x0040 + RadiotapHEData3ULDL RadiotapHEData3 = 0x0080 + RadiotapHEData3DataMCSMask RadiotapHEData3 = 0x0F00 + RadiotapHEData3DataDCM RadiotapHEData3 = 0x1000 + RadiotapHEData3Coding RadiotapHEData3 = 0x2000 + RadiotapHEData3LDPCEXtraSymbolSegment RadiotapHEData3 = 0x4000 + RadiotapHEData3STBC RadiotapHEData3 = 0x8000 +) + +func (self RadiotapHEData3) BSSColor() int { + return int(self & RadiotapHEData3BSSColorMask) +} + +func (self RadiotapHEData3) BeamChange() bool { + return self&RadiotapHEData3BeamChange != 0 +} + +func (self RadiotapHEData3) ULDL() bool { + return self&RadiotapHEData3ULDL != 0 +} + +func (self RadiotapHEData3) DataMCS() uint8 { + return uint8((self & RadiotapHEData3DataMCSMask) >> 8) +} + +func (self RadiotapHEData3) DataDCM() bool { + return self&RadiotapHEData3DataDCM != 0 +} + +func (self RadiotapHEData3) Coding() RadiotapHECoding { + return self&RadiotapHEData3Coding != 0 +} + +func (self RadiotapHEData3) LDPCExtraSymbolSegment() bool { + return self&RadiotapHEData3LDPCEXtraSymbolSegment != 0 +} + +func (self RadiotapHEData3) STBC() bool { + return self&RadiotapHEData3STBC != 0 +} + +type RadiotapHECoding bool + +const ( + RadiotapHECodingBCC RadiotapHECoding = false + RadiotapHECodingLDPC RadiotapHECoding = true +) + +type RadiotapHEData4 uint16 + +type RadiotapHEData5 uint16 + +const ( + RadiotapHEData5DataBandwidthMask RadiotapHEData5 = 0x000F + RadiotapHEData5GI RadiotapHEData5 = 0x0030 + RadiotapHEData5LTFSize RadiotapHEData5 = 0x00C0 + RadiotapHEData5NumLTFSymbols RadiotapHEData5 = 0x0700 + RadiotapHEData5PreFECPaddingFactor RadiotapHEData5 = 0x3000 + RadiotapHEData5TxBF RadiotapHEData5 = 0x4000 + RadiotapHEData5PEDisambiguity RadiotapHEData5 = 0x8000 +) + +type DataBandwidth uint8 + +const ( + DataBandwidth20 DataBandwidth = iota + DataBandwidth40 + DataBandwidth80 + DataBandwidth160 + DataBandwidth26ToneRU + DataBandwidth52ToneRU + DataBandwidth106ToneRU + DataBandwidth242ToneRU + DataBandwidth484ToneRU + DataBandwidth996ToneRU + DataBandwidth2x996ToneRU +) + +func (db DataBandwidth) String() string { + switch db { + case DataBandwidth20: + return "20" + case DataBandwidth40: + return "40" + case DataBandwidth80: + return "80" + case DataBandwidth160: + return "160/80+80" + case DataBandwidth26ToneRU: + return "26-tone RU" + case DataBandwidth52ToneRU: + return "52-tone RU" + case DataBandwidth106ToneRU: + return "106-tone RU" + case DataBandwidth242ToneRU: + return "242-tone RU" + case DataBandwidth484ToneRU: + return "484-tone RU" + case DataBandwidth996ToneRU: + return "996-tone RU" + case DataBandwidth2x996ToneRU: + return "2x996-tone RU" + default: + return "Unknown" + } +} + +func (self RadiotapHEData5) DataBandwidth() DataBandwidth { + return DataBandwidth(self & RadiotapHEData5DataBandwidthMask) +} + +func (self RadiotapHEData5) Gi() Gi { + return Gi((self & RadiotapHEData5GI) >> 4) +} + +func (self RadiotapHEData5) LTFSize() LTF { + return LTF((self & RadiotapHEData5LTFSize) >> 6) +} + +func (self RadiotapHEData5) NumLTFSymbols() NLTF { + return NLTF((self & RadiotapHEData5NumLTFSymbols) >> 8) +} + +func (self RadiotapHEData5) PreFECPaddingFactor() uint8 { + return uint8((self & RadiotapHEData5PreFECPaddingFactor) >> 12) +} + +func (self RadiotapHEData5) TxBF() bool { + return self&RadiotapHEData5TxBF != 0 +} + +func (self RadiotapHEData5) PEDisambiguity() bool { + return self&RadiotapHEData5PEDisambiguity != 0 +} + +type Gi uint8 + +const ( + Gi_0_8us Gi = iota + Gi_1_6us + Gi_3_2us + Gi_reserved +) + +func (gi Gi) String() string { + switch gi { + case Gi_0_8us: + return "0.8us" + case Gi_1_6us: + return "1.6us" + case Gi_3_2us: + return "3.2us" + default: + return "Reserved" + } +} + +type LTF uint8 + +const ( + LTF_unknown LTF = iota + LTF_1x + LTF_2x + LTF_4x +) + +func (ltf LTF) String() string { + switch ltf { + case LTF_unknown: + return "Unknown" + case LTF_1x: + return "1x" + case LTF_2x: + return "2x" + case LTF_4x: + return "4x" + default: + return "Unknown" + } +} + +type NLTF uint8 + +const ( + NLTF_1x NLTF = iota + NLTF_2x + NLTF_4x + NLTF_6x + NLTF_8x + NLTF_reserved +) + +func (nltf NLTF) String() string { + switch nltf { + case NLTF_1x: + return "1x" + case NLTF_2x: + return "2x" + case NLTF_4x: + return "4x" + case NLTF_6x: + return "6x" + case NLTF_8x: + return "8x" + default: + return "Reserved" + } +} + +type MidamblePeriodicity uint8 + +const ( + MidamblePeriodicity_10 MidamblePeriodicity = iota + MidamblePeriodicity_20 +) + +func (mp MidamblePeriodicity) String() string { + switch mp { + case MidamblePeriodicity_10: + return "10" + case MidamblePeriodicity_20: + return "20" + default: + return "Unknown" + } +} + +type RadiotapHEData6 uint16 + +const ( + RadiotapHEData6NSTS RadiotapHEData6 = 0x000F + RadiotapHEData6Doppler RadiotapHEData6 = 0x0010 + RadiotapHEData6TXOP RadiotapHEData6 = 0x7F00 + RadiotapHEData6MidamblePeriodic RadiotapHEData6 = 0x8000 +) + +func (self RadiotapHEData6) NSTS() int { + return int(self & RadiotapHEData6NSTS) +} + +func (self RadiotapHEData6) Doppler() bool { + return self&RadiotapHEData6Doppler != 0 +} + +func (self RadiotapHEData6) TXOP() int { + return int((self & RadiotapHEData6TXOP) >> 8) +} + +func (self RadiotapHEData6) MidamblePeriodicity() MidamblePeriodicity { + return MidamblePeriodicity((self & RadiotapHEData6MidamblePeriodic) >> 15) +} + func decodeRadioTap(data []byte, p gopacket.PacketBuilder) error { d := &RadioTap{} // TODO: Should we set LinkLayer here? And implement LinkFlow @@ -725,12 +1304,14 @@ type RadioTap struct { MCS RadioTapMCS AMPDUStatus RadioTapAMPDUStatus VHT RadioTapVHT + HE RadiotapHE } func (m *RadioTap) LayerType() gopacket.LayerType { return LayerTypeRadioTap } func (m *RadioTap) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { - if len(data) < 8 { + dataLen := uint16(len(data)) + if dataLen < 8 { df.SetTruncated() return errors.New("RadioTap too small") } @@ -738,6 +1319,11 @@ func (m *RadioTap) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) erro m.Length = binary.LittleEndian.Uint16(data[2:4]) m.Present = RadioTapPresent(binary.LittleEndian.Uint32(data[4:8])) + // Truncate the length to avoid panics, might be smaller due to corruption or loss + if m.Length > dataLen { + m.Length = dataLen + } + offset := uint16(4) for (binary.LittleEndian.Uint32(data[offset:offset+4]) & 0x80000000) != 0 { @@ -864,6 +1450,22 @@ func (m *RadioTap) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) erro } offset += 12 } + if m.Present.Timestamp() { + offset += align(offset, 8) + offset += 12 + } + if m.Present.HE() { + offset += align(offset, 2) + m.HE = RadiotapHE{ + Data1: RadiotapHEData1(binary.LittleEndian.Uint16(data[offset:])), + Data2: RadiotapHEData2(binary.LittleEndian.Uint16(data[offset+2:])), + Data3: RadiotapHEData3(binary.LittleEndian.Uint16(data[offset+4:])), + Data4: RadiotapHEData4(binary.LittleEndian.Uint16(data[offset+6:])), + Data5: RadiotapHEData5(binary.LittleEndian.Uint16(data[offset+8:])), + Data6: RadiotapHEData6(binary.LittleEndian.Uint16(data[offset+10:])), + } + offset += 12 + } payload := data[m.Length:] diff --git a/vendor/github.com/gopacket/gopacket/layers/sctp.go b/vendor/github.com/gopacket/gopacket/layers/sctp.go index d9df040e9..368497bc5 100644 --- a/vendor/github.com/gopacket/gopacket/layers/sctp.go +++ b/vendor/github.com/gopacket/gopacket/layers/sctp.go @@ -136,6 +136,23 @@ func decodeSCTPChunk(data []byte) (SCTPChunk, error) { }, nil } +func decodeSCTPDataChunk(data []byte) (SCTPChunk, error) { + length := binary.BigEndian.Uint16(data[2:4]) + if length < 4 { + return SCTPChunk{}, errors.New("invalid SCTP chunk length") + } + actual := roundUpToNearest4(int(length)) + ct := SCTPChunkType(data[0]) + + return SCTPChunk{ + Type: ct, + Flags: data[1], + Length: length, + ActualLength: actual, + BaseLayer: BaseLayer{data[:actual], data[actual:]}, + }, nil +} + // SCTPParameter is a TLV parameter inside a SCTPChunk. type SCTPParameter struct { Type uint16 @@ -214,6 +231,7 @@ type SCTPData struct { StreamId uint16 StreamSequence uint16 PayloadProtocol SCTPPayloadProtocol + Payload []byte } // LayerType returns gopacket.LayerTypeSCTPData. @@ -290,10 +308,11 @@ func (p SCTPPayloadProtocol) String() string { } func decodeSCTPData(data []byte, p gopacket.PacketBuilder) error { - chunk, err := decodeSCTPChunk(data) + chunk, err := decodeSCTPDataChunk(data) if err != nil { return err } + l := chunk.ActualLength sc := &SCTPData{ SCTPChunk: chunk, Unordered: data[1]&0x4 != 0, @@ -303,20 +322,24 @@ func decodeSCTPData(data []byte, p gopacket.PacketBuilder) error { StreamId: binary.BigEndian.Uint16(data[8:10]), StreamSequence: binary.BigEndian.Uint16(data[10:12]), PayloadProtocol: SCTPPayloadProtocol(binary.BigEndian.Uint32(data[12:16])), + Payload: []byte{}, + } + if l >= 16 { + sc.Payload = data[16:l] } // Length is the length in bytes of the data, INCLUDING the 16-byte header. p.AddLayer(sc) - return p.NextDecoder(gopacket.LayerTypePayload) + return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix)) } // SerializeTo is for gopacket.SerializableLayer. func (sc SCTPData) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { - payload := b.Bytes() - // Pad the payload to a 32 bit boundary - if rem := len(payload) % 4; rem != 0 { - b.AppendBytes(4 - rem) + payload := sc.Payload + length := len(payload) + 16 + + if rem := length % 4; rem != 0 { + length += 4 - rem } - length := 16 bytes, err := b.PrependBytes(length) if err != nil { return err @@ -333,11 +356,12 @@ func (sc SCTPData) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.Seriali flags |= 0x1 } bytes[1] = flags - binary.BigEndian.PutUint16(bytes[2:4], uint16(length+len(payload))) + binary.BigEndian.PutUint16(bytes[2:4], sc.Length) binary.BigEndian.PutUint32(bytes[4:8], sc.TSN) binary.BigEndian.PutUint16(bytes[8:10], sc.StreamId) binary.BigEndian.PutUint16(bytes[10:12], sc.StreamSequence) binary.BigEndian.PutUint32(bytes[12:16], uint32(sc.PayloadProtocol)) + copy(bytes[16:], payload) return nil } diff --git a/vendor/github.com/gopacket/gopacket/layers/sip.go b/vendor/github.com/gopacket/gopacket/layers/sip.go index c45fffb95..2e8834ffb 100644 --- a/vendor/github.com/gopacket/gopacket/layers/sip.go +++ b/vendor/github.com/gopacket/gopacket/layers/sip.go @@ -197,8 +197,8 @@ type SIP struct { ResponseStatus string // Private fields - cseq int64 - contentLength int64 + cseq uint32 + contentLength int lastHeaderParsed string } @@ -219,6 +219,7 @@ func decodeSIP(data []byte, p gopacket.PacketBuilder) error { func NewSIP() *SIP { s := new(SIP) s.Headers = make(map[string][]string) + s.contentLength = -1 return s } @@ -296,11 +297,41 @@ func (s *SIP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { countLines++ } - s.BaseLayer = BaseLayer{Contents: data[:offset], Payload: data[offset:]} + s.setBaseLayer(data, offset, df) return nil } +// setBaseLayer is used to set the base layer of the SIP packet. +// +// According to "RFC3261 - 20.14 - Content-Length" the Content-Length header is mandatory +// for SIP packages transported over TCP. When transporting over UDP, the message +// body length CAN be determined by the length of the UDP datagram. +// +// So by using the Content-Length header, if present we can mark the packet as truncated if we do not +// have enough data. We are also able to limit the payload to the number bytes actually specified. +// If the header is not present, we can assume that the data was transported over UDP we can then +// use the length of the data as payload length. +func (s *SIP) setBaseLayer(data []byte, offset int, df gopacket.DecodeFeedback) { + // The content-length header was not present in the packet, we use the rest of the packet as payload + if s.contentLength == -1 { + s.BaseLayer = BaseLayer{Contents: data[:offset], Payload: data[offset:]} + } else if s.contentLength == 0 { + // We have a zero Content-Length, no payload + s.BaseLayer = BaseLayer{Contents: data[:offset], Payload: []byte{}} // no payload + } else if len(data) < offset+s.contentLength { + // Not enough data to fulfill the Content-Length. We set the packet as truncated + // and return what we have. The receiver of the packet will be able to determine this + // by comparing the SIP.ContentLength with the length of the SIP.Payload. + df.SetTruncated() + s.BaseLayer = BaseLayer{Contents: data[:offset], Payload: data[offset:]} + } else { + // we have at least enough data, to fulfill the Content-Length. But we only add the number + // of bytes specified in the Content-Length header to the payload. + s.BaseLayer = BaseLayer{Contents: data[:offset], Payload: data[offset : offset+s.contentLength]} + } +} + // ParseFirstLine will compute the first line of a SIP packet. // The first line will tell us if it's a request or a response. // @@ -420,19 +451,16 @@ func (s *SIP) ParseSpecificHeaders(headerName string, headerValue string) (err e switch headerName { case "cseq": - // CSeq header value is formatted like that : // CSeq: 123 INVITE // We split the value to parse Cseq integer value, and method splits := strings.Split(headerValue, " ") if len(splits) > 1 { - - // Parse Cseq - s.cseq, err = strconv.ParseInt(splits[0], 10, 64) + // parse CSEQ + s.cseq, err = parseUint32(splits[0]) if err != nil { - return err + return fmt.Errorf("invalid CSEQ value: %w", err) } - // Validate method if s.IsResponse { s.Method, err = GetSIPMethod(splits[1]) @@ -443,17 +471,38 @@ func (s *SIP) ParseSpecificHeaders(headerName string, headerValue string) (err e } case "content-length": - // Parse Content-Length - s.contentLength, err = strconv.ParseInt(headerValue, 10, 64) + s.contentLength, err = parsePositiveInt32(headerValue) if err != nil { - return err + return fmt.Errorf("invalid Content-Length: %w", err) } } return nil } +// parsePositiveInt32 will parse the string as an int, but will return error if +// value is < 0 or above the max positive value of an int32 +func parsePositiveInt32(s string) (int, error) { + i, err := strconv.ParseInt(s, 10, 32) + if err != nil { + return 0, err + } + if i < 0 { + return 0, fmt.Errorf("%d out of range", i) + } + return int(i), nil +} + +// parseUint32 parse string value to uint32, return error if not successful +func parseUint32(s string) (uint32, error) { + i, err := strconv.ParseUint(s, 10, 32) + if err != nil { + return 0, err + } + return uint32(i), nil +} + // GetAllHeaders will return the full headers of the // current SIP packets in a map[string][]string func (s *SIP) GetAllHeaders() map[string][]string { @@ -529,11 +578,15 @@ func (s *SIP) GetUserAgent() string { // GetContentLength will return the parsed integer // Content-Length header of the current SIP packet func (s *SIP) GetContentLength() int64 { - return s.contentLength + // to keep compatibility with previous versions, we return 0 if contentLength is not set by header + if s.contentLength == -1 { + return 0 + } + return int64(s.contentLength) } // GetCSeq will return the parsed integer CSeq header // header of the current SIP packet func (s *SIP) GetCSeq() int64 { - return s.cseq + return int64(s.cseq) } diff --git a/vendor/github.com/gopacket/gopacket/layers/tcp.go b/vendor/github.com/gopacket/gopacket/layers/tcp.go index b38858950..782c0005f 100644 --- a/vendor/github.com/gopacket/gopacket/layers/tcp.go +++ b/vendor/github.com/gopacket/gopacket/layers/tcp.go @@ -31,12 +31,14 @@ type TCP struct { Options []TCPOption Padding []byte opts [4]TCPOption + Multipath bool tcpipchecksum } // TCPOptionKind represents a TCP option code. type TCPOptionKind uint8 +// TCP Option Kind constonts from https://www.iana.org/assignments/tcp-parameters/tcp-parameters.xml#tcp-parameters-1 const ( TCPOptionKindEndList = 0 TCPOptionKindNop = 1 @@ -54,6 +56,7 @@ const ( TCPOptionKindCCEcho = 13 // obsolete TCPOptionKindAltChecksum = 14 // len = 3, obsolete TCPOptionKindAltChecksumData = 15 // len = n, obsolete + TCPOptionKindMultipathTCP = 30 ) func (k TCPOptionKind) String() string { @@ -90,15 +93,28 @@ func (k TCPOptionKind) String() string { return "AltChecksum" case TCPOptionKindAltChecksumData: return "AltChecksumData" + case TCPOptionKindMultipathTCP: + return "MultipathTCP" default: return fmt.Sprintf("Unknown(%d)", k) } } +// TCPOption are the possible TCP and MPTCP Options type TCPOption struct { - OptionType TCPOptionKind - OptionLength uint8 - OptionData []byte + OptionType TCPOptionKind + OptionLength uint8 + OptionData []byte + OptionMultipath MPTCPSubtype + OptionMPTCPMpCapable *MPCapable + OptionMPTCPDss *Dss + OptionMPTCPMpJoin *MPJoin + OptionMPTCPMpPrio *MPPrio + OptionMPTCPAddAddr *AddAddr + OptionMTCPRemAddr *RemAddr + OptionMTCPMPFastClose *MPFClose + OptionMPTCPMPTcpRst *MPTcpRst + OptionMTCPMPFail *MPFail } func (t TCPOption) String() string { @@ -123,6 +139,48 @@ func (t TCPOption) String() string { binary.BigEndian.Uint32(t.OptionData[4:8]), hd) } + + case TCPOptionKindMultipathTCP: + switch t.OptionMultipath { + case MPTCPSubtypeMPCAPABLE: + return fmt.Sprintf("MPTCPOption(%s Version %v)", + t.OptionMultipath, + t.OptionMPTCPMpCapable.Version) + case MPTCPSubtypeMPJOIN: + return fmt.Sprintf("MPTCPOption(%s Backup %v;Address ID %v)", + t.OptionMultipath, + t.OptionMPTCPMpJoin.Backup, + t.OptionMPTCPMpJoin.AddrID) + case MPTCPSubtypeDSS: + return fmt.Sprintf("MPTCPOption(%s)", + t.OptionMultipath) + case MPTCPSubtypeMPPRIO: + return fmt.Sprintf("MPTCPOption(%s Backup %v;Address ID %v)", + t.OptionMultipath, + t.OptionMPTCPMpPrio.Backup, + t.OptionMPTCPMpPrio.AddrID) + case MPTCPSubtypeADDADDR: + return fmt.Sprintf("MPTCPOption(%s Address ID %v;Address %v;Port %v)", + t.OptionMultipath, + t.OptionMPTCPAddAddr.AddrID, + t.OptionMPTCPAddAddr.Address, + t.OptionMPTCPAddAddr.Port) + case MPTCPSubtypeREMOVEADDR: + return fmt.Sprintf("MPTCPOption(%s Address ID %v)", + t.OptionMultipath, + t.OptionMTCPRemAddr.AddrIDs) + case MPTCPSubtypeMPFASTCLOSE: + return fmt.Sprintf("MPTCPOption(%s)", + t.OptionMultipath) + case MPTCPSubtypeMPTCPRST: + return fmt.Sprintf("MPTCPOption(%s Transient %v; Reason %v)", + t.OptionMultipath, + t.OptionMPTCPMPTcpRst.T, + t.OptionMPTCPMPTcpRst.Reason) + case MPTCPSubtypeMPFAIL: + return fmt.Sprintf("MPTCPOption(%s)", + t.OptionMultipath) + } } return fmt.Sprintf("TCPOption(%s:%s)", t.OptionType, hd) } @@ -286,6 +344,190 @@ OPTIONS: break OPTIONS case TCPOptionKindNop: // 1 byte padding opt.OptionLength = 1 + case TCPOptionKindMultipathTCP: + tcp.Multipath = true + opt.OptionLength = data[1] + opt.OptionMultipath = MPTCPSubtype(data[2] >> 4) + switch opt.OptionMultipath { + case MPTCPSubtypeMPCAPABLE: + if opt.OptionLength != OptionLenMpCapableSyn && opt.OptionLength != OptionLenMpCapableSynAck && opt.OptionLength != OptionLenMpCapableAck && opt.OptionLength != OptionLenMpCapableAckData && opt.OptionLength != OptionLenMpCapableAckDataCSum { + return fmt.Errorf("MP_CAPABLE bad option length %d", opt.OptionLength) + } + opt.OptionMPTCPMpCapable = &MPCapable{ + Version: data[2] & 0x0F, + A: data[3]&0x80 != 0, + B: data[3]&0x40 != 0, + C: data[3]&0x20 != 0, + D: data[3]&0x10 != 0, + E: data[3]&0x08 != 0, + F: data[3]&0x04 != 0, + G: data[3]&0x02 != 0, + H: data[3]&0x01 != 0, + } + if opt.OptionLength >= OptionLenMpCapableSynAck { + opt.OptionMPTCPMpCapable.SendKey = data[4:12] + } + if opt.OptionLength >= OptionLenMpCapableAck { + opt.OptionMPTCPMpCapable.ReceivKey = data[12:20] + } + if opt.OptionLength >= OptionLenMpCapableAckData { + opt.OptionMPTCPMpCapable.DataLength = binary.BigEndian.Uint16(data[20:22]) + } + if opt.OptionLength == OptionLenMpCapableAckDataCSum { + opt.OptionMPTCPMpCapable.Checksum = binary.BigEndian.Uint16(data[22:24]) + } + case MPTCPSubtypeMPJOIN: + if opt.OptionLength != OptionLenMpJoinSyn && opt.OptionLength != OptionLenMpJoinSynAck && opt.OptionLength != OptionLenMpJoinAck { + return fmt.Errorf("MP_JOIN bad option length %d", opt.OptionLength) + } + switch opt.OptionLength { + case OptionLenMpJoinSyn: + opt.OptionMPTCPMpJoin = &MPJoin{ + Backup: data[2]&0x01 != 0, + AddrID: data[3], + ReceivToken: binary.BigEndian.Uint32(data[4:8]), + SendRandNum: binary.BigEndian.Uint32(data[8:12]), + } + case OptionLenMpJoinSynAck: + opt.OptionMPTCPMpJoin = &MPJoin{ + Backup: data[2]&0x01 != 0, + AddrID: data[3], + SendHMAC: data[4:12], + SendRandNum: binary.BigEndian.Uint32(data[12:16]), + } + case OptionLenMpJoinAck: + opt.OptionMPTCPMpJoin = &MPJoin{ + SendHMAC: data[4:24], + } + } + case MPTCPSubtypeDSS: + opt.OptionMPTCPDss = &Dss{ + F: data[3]&0x10 != 0, + m: data[3]&0x08 != 0, + M: data[3]&0x04 != 0, + a: data[3]&0x02 != 0, + A: data[3]&0x01 != 0, + } + if opt.OptionLength != optionMptcpDsslen(opt.OptionMPTCPDss, false) && opt.OptionLength != optionMptcpDsslen(opt.OptionMPTCPDss, true) { + return fmt.Errorf("DSS bad option length %d", opt.OptionLength) + } + var lenOpt uint8 = 4 + if opt.OptionMPTCPDss.A { // Data ACK present + if opt.OptionMPTCPDss.a { // Data ACK is 8 octets + opt.OptionMPTCPDss.DataAck = data[lenOpt : lenOpt+OptionLenDssAck64] + lenOpt += OptionLenDssAck64 + } else { + opt.OptionMPTCPDss.DataAck = data[lenOpt : lenOpt+OptionLenDssAck] + lenOpt += OptionLenDssAck + } + } + if opt.OptionMPTCPDss.M { // Data Sequence Number (DSN), Subflow Sequence Number (SSN), Data-Level Length, and Checksum (if negotiated) present + if opt.OptionMPTCPDss.m { // Data Sequence Number is 8 octets + opt.OptionMPTCPDss.DSN = data[lenOpt : lenOpt+OptionLenDssDSN64] + lenOpt += OptionLenDssDSN64 + } else { + opt.OptionMPTCPDss.DSN = data[lenOpt : lenOpt+OptionLenDssDSN] + lenOpt += OptionLenDssDSN + } + opt.OptionMPTCPDss.SSN = binary.BigEndian.Uint32(data[lenOpt : lenOpt+OptionLenDssSSN]) + lenOpt += OptionLenDssSSN + opt.OptionMPTCPDss.DataLength = binary.BigEndian.Uint16(data[lenOpt : lenOpt+OptionLenDssDataLen]) + lenOpt += OptionLenDssDataLen + if opt.OptionLength-lenOpt == 2 { // Checksum present + opt.OptionMPTCPDss.Checksum = binary.BigEndian.Uint16(data[lenOpt : lenOpt+OptionLenDssCSum]) + } + } + case MPTCPSubtypeADDADDR: + var mptcpVer uint8 + var bitE bool + lenOpt := opt.OptionLength + + if data[2]&0x0F > 1 { + mptcpVer = MptcpVersion0 + } else { + mptcpVer = MptcpVersion1 + bitE = data[2]&0x01 != 0 + } + if !isValidOptionMptcpAddAddrlen(opt.OptionLength, mptcpVer, bitE) { + return fmt.Errorf("ADD_ADDR bad option length %d", opt.OptionLength) + } + switch mptcpVer { + case MptcpVersion0: + opt.OptionMPTCPAddAddr = &AddAddr{ + IPVer: data[2] & 0x0F, + AddrID: data[3], + } + case MptcpVersion1: + opt.OptionMPTCPAddAddr = &AddAddr{ + E: data[2]&0x01 != 0, + AddrID: data[3], + } + if !opt.OptionMPTCPAddAddr.E { + opt.OptionMPTCPAddAddr.SendHMAC = data[opt.OptionLength-8:] + lenOpt -= OptionLenAddAddrHmac + } + } + switch lenOpt { + case OptionLenAddAddrv4: + opt.OptionMPTCPAddAddr.Address = data[4:8] + case OptionLenAddAddrv4 + OptionLenAddAddrPort: + opt.OptionMPTCPAddAddr.Address = data[4:8] + opt.OptionMPTCPAddAddr.Port = binary.BigEndian.Uint16(data[8:10]) + case OptionLenAddAddrv6: + opt.OptionMPTCPAddAddr.Address = data[4:20] + case OptionLenAddAddrv6 + OptionLenAddAddrPort: + opt.OptionMPTCPAddAddr.Address = data[4:20] + opt.OptionMPTCPAddAddr.Port = binary.BigEndian.Uint16(data[20:22]) + } + case MPTCPSubtypeREMOVEADDR: + if opt.OptionLength < OptionLenRemAddr { + return fmt.Errorf("Rem_ADDR bad option length %d", opt.OptionLength) + } + var addrIds []uint8 + var n uint8 + for n = 0; n < opt.OptionLength-3; n++ { + addrIds = append(addrIds, data[3+n]) + } + opt.OptionMTCPRemAddr = &RemAddr{ + AddrIDs: addrIds, + } + case MPTCPSubtypeMPPRIO: + if opt.OptionLength != OptionLenMpPrio && opt.OptionLength != OptionLenMpPrioAddr { + return fmt.Errorf("MP_PRIO bad option length %d", opt.OptionLength) + } + opt.OptionMPTCPMpPrio = &MPPrio{ + Backup: data[2]&0x01 != 0, + } + if opt.OptionLength == OptionLenMpPrioAddr { + opt.OptionMPTCPMpPrio.AddrID = data[3] + } + case MPTCPSubtypeMPFAIL: + if opt.OptionLength != OptionLenMpFail { + return fmt.Errorf("MP_FAIL bad option length %d", opt.OptionLength) + } + opt.OptionMTCPMPFail = &MPFail{ + DSN: binary.BigEndian.Uint64(data[4:OptionLenMpFail]), + } + + case MPTCPSubtypeMPFASTCLOSE: + if opt.OptionLength != OptionLenMpFClose { + return fmt.Errorf("MP_FASTCLOSE bad option length %d", opt.OptionLength) + } + opt.OptionMTCPMPFastClose = &MPFClose{ + ReceivKey: data[4:OptionLenMpFClose], + } + case MPTCPSubtypeMPTCPRST: + if opt.OptionLength != OptionLenMpTcpRst { + return fmt.Errorf("MP_TCPRST bad option length %d", opt.OptionLength) + } + opt.OptionMPTCPMPTcpRst = &MPTcpRst{ + U: data[2]&0x08 != 0, + V: data[2]&0x04 != 0, + W: data[2]&0x02 != 0, + T: data[2]&0x01 != 0, + Reason: data[3], + } + } default: if len(data) < 2 { df.SetTruncated() @@ -305,6 +547,40 @@ OPTIONS: return nil } +func optionMptcpDsslen(OptionMPTCPDss *Dss, csum bool) uint8 { + var len uint8 = 4 + if OptionMPTCPDss.A { // Data ACK + len += 4 + if OptionMPTCPDss.a { + len += 4 + } // Data ACK 8 octets + } + if OptionMPTCPDss.M { // DSN (4)+ SSN (4) + Data-Level Length (2) = 10 + len += 10 + if OptionMPTCPDss.m { + len += 4 + } // DSN 8 octets + if csum { + len += 2 + } + } + return len +} + +func isValidOptionMptcpAddAddrlen(length uint8, mptcpVer uint8, hmac bool) bool { + var ret bool + switch mptcpVer { + case MptcpVersion0: + ret = length == OptionLenAddAddrv4 || length == OptionLenAddAddrv4+OptionLenAddAddrPort || length == OptionLenAddAddrv6 || length == OptionLenAddAddrv6+OptionLenAddAddrPort + case MptcpVersion1: + if !hmac { + length -= OptionLenAddAddrHmac + } + ret = length == OptionLenAddAddrv4 || length == OptionLenAddAddrv4+OptionLenAddAddrPort || length == OptionLenAddAddrv6 || length == OptionLenAddAddrv6+OptionLenAddAddrPort + } + return ret +} + func (t *TCP) CanDecode() gopacket.LayerClass { return LayerTypeTCP } diff --git a/vendor/github.com/gopacket/gopacket/layers/test_creator.py b/vendor/github.com/gopacket/gopacket/layers/test_creator.py index c92d2765a..92cba4d4c 100644 --- a/vendor/github.com/gopacket/gopacket/layers/test_creator.py +++ b/vendor/github.com/gopacket/gopacket/layers/test_creator.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # Copyright 2012 Google, Inc. All rights reserved. """TestCreator creates test templates from pcap files.""" @@ -9,7 +9,6 @@ import re import string import subprocess -import sys class Packet(object): @@ -30,7 +29,7 @@ def _DecodeText(cls, packet_lines): if m is None: continue for hexpart in m.group(1).split(): packet_bytes.append(base64.b16decode(hexpart.upper())) - return ''.join(packet_bytes) + return b''.join(packet_bytes) def Test(self, name, link_type): """Yields a test using this packet, as a set of lines.""" @@ -41,7 +40,8 @@ def Test(self, name, link_type): data = list(self.data) while data: linebytes, data = data[:16], data[16:] - yield ''.join(['\t'] + ['0x%02x, ' % ord(c) for c in linebytes]) + b = ''.join(["0x{:02x}, ".format(c) for c in linebytes]) + yield f'\t{b}' yield '}' yield 'func TestPacket%s(t *testing.T) {' % name yield '\tp := gopacket.NewPacket(testPacket%s, LinkType%s, gopacket.Default)' % (name, link_type) @@ -61,14 +61,14 @@ def Test(self, name, link_type): def GetTcpdumpOutput(filename): """Runs tcpdump on the given file, returning output as string.""" return subprocess.check_output( - ['tcpdump', '-XX', '-s', '0', '-n', '-r', filename]) + ['tcpdump', '-XX', '-s', '0', '-n', '-r', filename]) def TcpdumpOutputToPackets(output): """Reads a pcap file with TCPDump, yielding Packet objects.""" pdata = [] - for line in output.splitlines(): - if line[0] not in string.whitespace and pdata: + for line in output.decode('utf-8').split('\n'): + if line and line[0] not in string.whitespace and pdata: yield Packet(pdata) pdata = [] pdata.append(line) @@ -96,8 +96,9 @@ def _format_usage(self, usage, actions, groups, prefix=None): for arg in args.files: for path in glob.glob(arg): for i, packet in enumerate(TcpdumpOutputToPackets(GetTcpdumpOutput(path))): - print '\n'.join(packet.Test( - args.name % i, args.link_type)) + print('\n'.join(packet.Test( + f'{args.name}{i}', args.link_type)) + ) if __name__ == '__main__': - main() + main() diff --git a/vendor/github.com/gopacket/gopacket/layers/tls_handshake.go b/vendor/github.com/gopacket/gopacket/layers/tls_handshake.go index dba0c4c75..7c3a68b0e 100644 --- a/vendor/github.com/gopacket/gopacket/layers/tls_handshake.go +++ b/vendor/github.com/gopacket/gopacket/layers/tls_handshake.go @@ -9,11 +9,43 @@ package layers import ( "encoding/binary" "errors" - "fmt" "github.com/gopacket/gopacket" ) +// TLS Extensions http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml +type TLSExtension uint16 + +const ( + TLSExtServerName TLSExtension = 0 + TLSExtMaxFragLen TLSExtension = 1 + TLSExtClientCertURL TLSExtension = 2 + TLSExtTrustedCAKeys TLSExtension = 3 + TLSExtTruncatedHMAC TLSExtension = 4 + TLSExtStatusRequest TLSExtension = 5 + TLSExtUserMapping TLSExtension = 6 + TLSExtClientAuthz TLSExtension = 7 + TLSExtServerAuthz TLSExtension = 8 + TLSExtCertType TLSExtension = 9 + TLSExtSupportedGroups TLSExtension = 10 + TLSExtECPointFormats TLSExtension = 11 + TLSExtSRP TLSExtension = 12 + TLSExtSignatureAlgs TLSExtension = 13 + TLSxtUseSRTP TLSExtension = 14 + TLSExtHeartbeat TLSExtension = 15 + TLSExtALPN TLSExtension = 16 + TLSExtStatusRequestV2 TLSExtension = 17 + TLSExtSignedCertTS TLSExtension = 18 + TLSExtClientCertType TLSExtension = 19 + TLSExtServerCertType TLSExtension = 20 + TLSExtPadding TLSExtension = 21 + TLSExtEncryptThenMAC TLSExtension = 22 + TLSExtExtendedMasterSecret TLSExtension = 23 + TLSExtSessionTicket TLSExtension = 35 + TLSExtNPN TLSExtension = 13172 + TLSExtRenegotiationInfo TLSExtension = 65281 +) + /*refer to https://datatracker.ietf.org/doc/html/rfc5246#appendix-A.4*/ const ( TLSHandshakeHelloRequest = 0 @@ -56,6 +88,7 @@ type TLSHandshakeRecordClientHello struct { CompressionMethods []uint8 ExtensionsLength uint16 Extensions []uint8 + SNI []uint8 } type TLSHandshakeRecordClientKeyChange struct { @@ -84,7 +117,35 @@ func (t *TLSHandshakeRecordClientHello) decodeFromBytes(data []byte, df gopacket t.CompressionMethodsLength = data[(39 + uint16(t.SessionIDLength) + 2 + t.CipherSuitsLength)] t.CompressionMethods = data[(39+uint16(t.SessionIDLength)+2+t.CipherSuitsLength)+1 : (39+uint16(t.SessionIDLength)+2+t.CipherSuitsLength)+1+uint16(t.CompressionMethodsLength)] t.ExtensionsLength = binary.BigEndian.Uint16(data[(39+uint16(t.SessionIDLength)+2+t.CipherSuitsLength)+1+uint16(t.CompressionMethodsLength) : (39+uint16(t.SessionIDLength)+2+t.CipherSuitsLength)+1+uint16(t.CompressionMethodsLength)+2]) - t.Extensions = data[((39 + uint16(t.SessionIDLength) + 2 + t.CipherSuitsLength) + 1 + uint16(t.CompressionMethodsLength) + 2) : ((39+uint16(t.SessionIDLength)+2+t.CipherSuitsLength)+1+uint16(t.CompressionMethodsLength)+2)+t.ExtensionsLength] + + // extract extension data + data = data[((39 + uint16(t.SessionIDLength) + 2 + t.CipherSuitsLength) + 1 + uint16(t.CompressionMethodsLength) + 2) : ((39+uint16(t.SessionIDLength)+2+t.CipherSuitsLength)+1+uint16(t.CompressionMethodsLength)+2)+t.ExtensionsLength] + t.Extensions = data + for len(data) > 0 { + if len(data) < 4 { + break + } + extensionType := binary.BigEndian.Uint16(data[:2]) + length := binary.BigEndian.Uint16(data[2:4]) + if len(data) < 4+int(length) { + break + } + switch TLSExtension(extensionType) { + case TLSExtServerName: + if len(data) > 6 { + serverNameExtensionLength := binary.BigEndian.Uint16(data[4:6]) + entryType := data[6] + if serverNameExtensionLength > 0 && entryType == 0 && len(data) > 8 { // 0 = DNS hostname + hostnameLength := binary.BigEndian.Uint16(data[7:9]) + if len(data) > int(8+hostnameLength) { + t.SNI = data[9 : 9+hostnameLength] + } + } + } + } + data = data[4+length:] + } + return nil } func (t *TLSHandshakeRecordClientKeyChange) decodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { @@ -130,7 +191,6 @@ func (t *TLSHandshakeRecord) decodeFromBytes(h TLSRecordHeader, data []byte, df t.Length = h.Length if t.isEncryptedHandshakeMessage(h, data) { - fmt.Printf("encrypted message\n") return nil } handshakeType := data[0] diff --git a/vendor/github.com/gopacket/gopacket/runtests.sh b/vendor/github.com/gopacket/gopacket/runtests.sh new file mode 100644 index 000000000..61e95a4de --- /dev/null +++ b/vendor/github.com/gopacket/gopacket/runtests.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +DIRS="afpacket layers pcap pcapgo tcpassembly tcpassembly/tcpreader reassembly routing ip4defrag bytediff macs routing defrag/lcmdefrag" +set -e +export CGO_ENABLED=1 +for subdir in $DIRS; do + pushd $subdir + sudo -E go test -v -count=1 . + popd +done diff --git a/vendor/modules.txt b/vendor/modules.txt index 11583cc9e..5b2a830d0 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -172,8 +172,8 @@ github.com/google/gofuzz/bytesource # github.com/google/uuid v1.6.0 ## explicit github.com/google/uuid -# github.com/gopacket/gopacket v1.2.0 -## explicit; go 1.20 +# github.com/gopacket/gopacket v1.3.1 +## explicit; go 1.22.0 github.com/gopacket/gopacket github.com/gopacket/gopacket/layers # github.com/gorilla/websocket v1.5.0