Example #1
0
// 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
}
Example #2
0
// 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
}