// validate ensures the given acct or auth application ID exists in // the given dictionary. func (app *Application) validate(d *dict.Parser, appType uint32, appAVP *diam.AVP) (failedAVP *diam.AVP, err error) { if appAVP == nil { return nil, nil } var typ string switch appType { case avp.AcctApplicationID: typ = "acct" case avp.AuthApplicationID: typ = "auth" } if appAVP.Code != appType { return appAVP, &ErrUnexpectedAVP{appAVP} } appID, ok := appAVP.Data.(datatype.Unsigned32) if !ok { return appAVP, &ErrUnexpectedAVP{appAVP} } id := uint32(appID) avp, err := d.App(id) if err != nil { return appAVP, &ErrNoCommonApplication{id, typ} } if len(avp.Type) > 0 && avp.Type != typ { return appAVP, &ErrNoCommonApplication{id, typ} } app.id = append(app.id, id) return nil, nil }
// DecodeFromBytes decodes the bytes of a Diameter AVP. // It uses the given application id and dictionary for decoding the bytes. func (a *AVP) DecodeFromBytes(data []byte, application uint32, dictionary *dict.Parser) error { dl := len(data) if dl < 8 { return fmt.Errorf("Not enough data to decode AVP header: %d bytes", dl) } a.Code = binary.BigEndian.Uint32(data[0:4]) a.Flags = data[4] a.Length = int(uint24to32(data[5:8])) if dl < int(a.Length) { return fmt.Errorf("Not enough data to decode AVP: %d != %d", dl, a.Length) } data = data[:a.Length] // this cuts padded bytes off var hdrLength int var payload []byte // Read VendorId when required. if a.Flags&avp.Vbit == avp.Vbit { a.VendorID = binary.BigEndian.Uint32(data[8:12]) payload = data[12:] hdrLength = 12 } else { payload = data[8:] hdrLength = 8 } // Find this code in the dictionary. dictAVP, err := dictionary.FindAVPWithVendor(application, a.Code, a.VendorID) if err != nil { return err } bodyLen := a.Length - hdrLength if n := len(payload); n < bodyLen { return fmt.Errorf( "Not enough data to decode AVP: %d != %d", hdrLength, n, ) } a.Data, err = datatype.Decode(dictAVP.Data.Type, payload) if err != nil { return err } // Handle grouped AVPs. if a.Data.Type() == datatype.GroupedType { a.Data, err = DecodeGrouped( a.Data.(datatype.Grouped), application, dictionary, ) if err != nil { return err } } return nil }