From c14292dc508fddb334c30307bae46943ced78092 Mon Sep 17 00:00:00 2001 From: ionutboangiu Date: Thu, 19 Feb 2026 20:11:43 +0200 Subject: [PATCH] radius: support reading vendor-specific attributes handles paths with 2 elements the same way radAppendAttributes does e.g. *req.Microsoft.MS-CHAP2-Response Ref: #4962 --- agents/librad.go | 12 +++++++++--- agents/librad_test.go | 15 ++++++++++++++- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/agents/librad.go b/agents/librad.go index 78caf44e8..fc82829ca 100644 --- a/agents/librad.go +++ b/agents/librad.go @@ -72,7 +72,7 @@ func (pk *radiusDP) String() string { // FieldAsInterface is part of utils.DataProvider interface func (pk *radiusDP) FieldAsInterface(fldPath []string) (data any, err error) { - if len(fldPath) != 1 { + if len(fldPath) == 0 || len(fldPath) > 2 { return nil, utils.ErrNotFound } if data, err = pk.cache.FieldAsInterface(fldPath); err != nil { @@ -83,8 +83,14 @@ func (pk *radiusDP) FieldAsInterface(fldPath []string) (data any, err error) { } else { return // data found in cache } - if len(pk.req.AttributesWithName(fldPath[0], "")) != 0 { - data = pk.req.AttributesWithName(fldPath[0], "")[0].GetStringValue() + var attrName, vendorName string + if len(fldPath) == 2 { + vendorName, attrName = fldPath[0], fldPath[1] + } else { + attrName = fldPath[0] + } + if avps := pk.req.AttributesWithName(attrName, vendorName); len(avps) != 0 { + data = avps[0].GetStringValue() } pk.cache.Set(fldPath, data) return diff --git a/agents/librad_test.go b/agents/librad_test.go index a97d4f9fd..a36b747cc 100644 --- a/agents/librad_test.go +++ b/agents/librad_test.go @@ -166,9 +166,22 @@ func TestLibradRadiusDPString(t *testing.T) { } } +func TestRadiusDPFieldAsInterfaceVSA(t *testing.T) { + pkt := radigo.NewPacket(radigo.AccountingRequest, 1, dictRad, coder, "CGRateS.org") + if err := pkt.AddAVPWithName("Cisco-NAS-Port", "CGR1", "Cisco"); err != nil { + t.Fatal(err) + } + dp := newRADataProvider(pkt) + if data, err := dp.FieldAsInterface([]string{"Cisco", "Cisco-NAS-Port"}); err != nil { + t.Error(err) + } else if data != "CGR1" { + t.Errorf("Expected CGR1, got: %v", data) + } +} + func TestLibradFieldAsInterfaceWithInvalidPathLength(t *testing.T) { pk := &radiusDP{} - fldPath := []string{"attribute1", "attribute2"} + fldPath := []string{"vendor", "attribute", "extra"} data, err := pk.FieldAsInterface(fldPath) if err != utils.ErrNotFound { t.Errorf("Expected ErrNotFound error, got: %v", err)