package common import ( "encoding/binary" "fmt" "net" "reflect" "strings" ) const ( FORMAT_TYPE_UNKNOWN = iota FORMAT_TYPE_STRING_FUNC FORMAT_TYPE_STRING FORMAT_TYPE_INTEGER FORMAT_TYPE_IP FORMAT_TYPE_MAC FORMAT_TYPE_BYTES ) var ( EtypeName = map[uint32]string{ 0x806: "ARP", 0x800: "IPv4", 0x86dd: "IPv6", } ProtoName = map[uint32]string{ 1: "ICMP", 6: "TCP", 17: "UDP", 58: "ICMPv6", 132: "SCTP", } IcmpTypeName = map[uint32]string{ 0: "EchoReply", 3: "DestinationUnreachable", 8: "Echo", 9: "RouterAdvertisement", 10: "RouterSolicitation", 11: "TimeExceeded", } Icmp6TypeName = map[uint32]string{ 1: "DestinationUnreachable", 2: "PacketTooBig", 3: "TimeExceeded", 128: "EchoRequest", 129: "EchoReply", 133: "RouterSolicitation", 134: "RouterAdvertisement", } TextFields = map[string]int{ "Type": FORMAT_TYPE_STRING_FUNC, "SamplerAddress": FORMAT_TYPE_IP, "SrcAddr": FORMAT_TYPE_IP, "DstAddr": FORMAT_TYPE_IP, "SrcMac": FORMAT_TYPE_MAC, "DstMac": FORMAT_TYPE_MAC, "NextHop": FORMAT_TYPE_IP, "MPLSLabelIP": FORMAT_TYPE_IP, } RenderExtras = map[string]RenderExtraFunction{ "EtypeName": RenderExtraFunctionEtypeName, "ProtoName": RenderExtraFunctionProtoName, "IcmpName": RenderExtraFunctionIcmpName, } ) /* func AddTextField(name string, jtype int) { TextFields = append(TextFields, name) TextFieldsTypes = append(TextFieldsTypes, jtype) }*/ type RenderExtraFunction func(interface{}) string func RenderExtraFetchNumbers(msg interface{}, fields []string) []uint64 { vfm := reflect.ValueOf(msg) vfm = reflect.Indirect(vfm) values := make([]uint64, len(fields)) for i, kf := range fields { fieldValue := vfm.FieldByName(kf) if fieldValue.IsValid() { values[i] = fieldValue.Uint() } } return values } func RenderExtraFunctionEtypeName(msg interface{}) string { num := RenderExtraFetchNumbers(msg, []string{"Etype"}) return EtypeName[uint32(num[0])] } func RenderExtraFunctionProtoName(msg interface{}) string { num := RenderExtraFetchNumbers(msg, []string{"Proto"}) return ProtoName[uint32(num[0])] } func RenderExtraFunctionIcmpName(msg interface{}) string { num := RenderExtraFetchNumbers(msg, []string{"Proto", "IcmpCode", "IcmpType"}) return IcmpCodeType(uint32(num[0]), uint32(num[1]), uint32(num[2])) } func IcmpCodeType(proto, icmpCode, icmpType uint32) string { if proto == 1 { return IcmpTypeName[icmpType] } else if proto == 58 { return Icmp6TypeName[icmpType] } return "" } func RenderIP(addr []byte) string { if addr == nil || (len(addr) != 4 && len(addr) != 16) { return "" } return net.IP(addr).String() } func FormatMessageReflectText(msg interface{}, ext string) string { return FormatMessageReflectCustom(msg, ext, "", " ", "=", false) } func FormatMessageReflectJSON(msg interface{}, ext string) string { return fmt.Sprintf("{%s}", FormatMessageReflectCustom(msg, ext, "\"", ",", ":", true)) } func ExtractTag(name, original string, tag reflect.StructTag) string { lookup, ok := tag.Lookup(name) if !ok { return original } before, _, _ := strings.Cut(lookup, ",") return before } func FormatMessageReflectCustom(msg interface{}, ext, quotes, sep, sign string, null bool) string { customSelector := selector reMap := make(map[string]string) vfm := reflect.ValueOf(msg) vfm = reflect.Indirect(vfm) vft := vfm.Type() if len(customSelector) == 0 || selectorTag != "" { /* // we would need proto v2 msgR := msg.ProtoReflect() customSelector = make([]string, msgR.Fields().Len()) for i := 0; i