123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- package gopacket
- import (
- "bytes"
- "fmt"
- "strconv"
- )
- const MaxEndpointSize = 16
- type Endpoint struct {
- typ EndpointType
- len int
- raw [MaxEndpointSize]byte
- }
- func (a Endpoint) EndpointType() EndpointType { return a.typ }
- func (a Endpoint) Raw() []byte { return a.raw[:a.len] }
- func (a Endpoint) LessThan(b Endpoint) bool {
- return a.typ < b.typ || (a.typ == b.typ && bytes.Compare(a.raw[:a.len], b.raw[:b.len]) < 0)
- }
- func fnvHash(s []byte) (h uint64) {
- h = fnvBasis
- for i := 0; i < len(s); i++ {
- h ^= uint64(s[i])
- h *= fnvPrime
- }
- return
- }
- const fnvBasis = 14695981039346656037
- const fnvPrime = 1099511628211
- func (a Endpoint) FastHash() (h uint64) {
- h = fnvHash(a.raw[:a.len])
- h ^= uint64(a.typ)
- h *= fnvPrime
- return
- }
- func NewEndpoint(typ EndpointType, raw []byte) (e Endpoint) {
- e.len = len(raw)
- if e.len > MaxEndpointSize {
- panic("raw byte length greater than MaxEndpointSize")
- }
- e.typ = typ
- copy(e.raw[:], raw)
- return
- }
- type EndpointTypeMetadata struct {
-
- Name string
-
-
- Formatter func([]byte) string
- }
- type EndpointType int64
- var endpointTypes = map[EndpointType]EndpointTypeMetadata{}
- func RegisterEndpointType(num int, meta EndpointTypeMetadata) EndpointType {
- t := EndpointType(num)
- if _, ok := endpointTypes[t]; ok {
- panic("Endpoint type number already in use")
- }
- endpointTypes[t] = meta
- return t
- }
- func (e EndpointType) String() string {
- if t, ok := endpointTypes[e]; ok {
- return t.Name
- }
- return strconv.Itoa(int(e))
- }
- func (a Endpoint) String() string {
- if t, ok := endpointTypes[a.typ]; ok && t.Formatter != nil {
- return t.Formatter(a.raw[:a.len])
- }
- return fmt.Sprintf("%v:%v", a.typ, a.raw)
- }
- type Flow struct {
- typ EndpointType
- slen, dlen int
- src, dst [MaxEndpointSize]byte
- }
- func FlowFromEndpoints(src, dst Endpoint) (_ Flow, err error) {
- if src.typ != dst.typ {
- err = fmt.Errorf("Mismatched endpoint types: %v->%v", src.typ, dst.typ)
- return
- }
- return Flow{src.typ, src.len, dst.len, src.raw, dst.raw}, nil
- }
- func (f Flow) FastHash() (h uint64) {
-
-
- h = fnvHash(f.src[:f.slen]) + fnvHash(f.dst[:f.dlen])
- h ^= uint64(f.typ)
- h *= fnvPrime
- return
- }
- func (f Flow) String() string {
- s, d := f.Endpoints()
- return fmt.Sprintf("%v->%v", s, d)
- }
- func (f Flow) EndpointType() EndpointType {
- return f.typ
- }
- func (f Flow) Endpoints() (src, dst Endpoint) {
- return Endpoint{f.typ, f.slen, f.src}, Endpoint{f.typ, f.dlen, f.dst}
- }
- func (f Flow) Src() (src Endpoint) {
- src, _ = f.Endpoints()
- return
- }
- func (f Flow) Dst() (dst Endpoint) {
- _, dst = f.Endpoints()
- return
- }
- func (f Flow) Reverse() Flow {
- return Flow{f.typ, f.dlen, f.slen, f.dst, f.src}
- }
- func NewFlow(t EndpointType, src, dst []byte) (f Flow) {
- f.slen = len(src)
- f.dlen = len(dst)
- if f.slen > MaxEndpointSize || f.dlen > MaxEndpointSize {
- panic("flow raw byte length greater than MaxEndpointSize")
- }
- f.typ = t
- copy(f.src[:], src)
- copy(f.dst[:], dst)
- return
- }
- var EndpointInvalid = RegisterEndpointType(0, EndpointTypeMetadata{Name: "invalid", Formatter: func(b []byte) string {
- return fmt.Sprintf("%v", b)
- }})
- var InvalidEndpoint = NewEndpoint(EndpointInvalid, nil)
- var InvalidFlow = NewFlow(EndpointInvalid, nil, nil)
|