= The ATTRIBUTE keyword

.Syntax
----
ATTRIBUTE <name> <number> <type> [<flags>]
----

.Description
The `ATTRIBUTE` keyword defines a name, number, and data type mapping.

<name>:: The name of the attribute.  The name can contain alphanumeric
characters, `-`, and `_`.  The name should be short and descriptive.
+
As the names are hierarchical, the name is scoped to its parent.  So
the name `Counter` can mean different things, depending on its
context.

<number>:: The number of the attribute.  Numbers can be specified as
decimal (`19`), or as hex (`0xffee`).
+
Numbers can also be specified as object identifiers (OIDs), `26.1.9`,
or as partial OIDs (`.14`).
+
There are a number of complex rules and interpretations of OID values
which are difficult to clearly document using simple examples.  This
complex behavior is only needed for rare situations.  In short, if you
are creating complex protocol dictionaries, you need to understand
those protocols before creating the dictionaries.  On the other hand,
if you are creating simple protocol dictionaries, there is no need to
understand any complex rules around the use of OIDs.

<type>:: A xref:type/index.adoc[data type]
+
A few data types can be marked up as being fixed size, by adding an
"array-style" suffix, such as with `octets[3]`.  See below for details.

<flags>:: The flag field is optional, and is usually protocol-specific.  See
the xref:dictionary/flags.adoc[FLAGS] page for definitions of common
flags.
+
Please see the protocol dictionaries for examples of these flags.
Only the flags which are used in a protocol dictionary are valid,
and those flags are only valid for that protocol dictionary.
+
The old-style RADIUS syntax of specifying a vendor name in the `flags`
field is not supported.

Common flags and meanings
[options="header"]
[cols="30%,70%"]
|=====
| Name           | Description
| `array`        | For fixed-size types, declare that the contents of the packet can have an array of this value.
| `clone=<ref>`  | For `tlv` or 'struct' types, clone (or copy) child definitions from another attribute of the same type
| `concat`       | For `octet` data types, the server will automatically split/merge values into attributes.
| `counter`      | For numeric data types, treat the values as SNMP-style counters, which can be automatically added.
| `enum=<ref>`   | For "leaf" types, copy xref:dictionary/value.adoc[VALUE]s from an xref:dictionary/enum.adoc[ENUM] or other attribute.
| `internal`     | This attribute is internal to the server, and will never be sent "on the wire"
| `ref=<ref>`    | For `group` types, the referenced attributes will be allowed in the group
| `secret`       | The server will not print `secret` values in debug mode, and in many other situations.
|=====

The `<ref>` field in the examples above is an attribute references such as `Foo`, or `Foo.Bar`, or `@dhcpv4.foo.bar`.  All `<ref>` fields use the same syntax.

If the ref begins with `@` the ref will be treated as a "foreign" reference to another protocol.  The first component will be used as the protocol name e.g. `ref=@RADIUS`.

If the ref begins with `.` the ref will be treated as relative to the current attribute, else resolution will begin from the root of the current dictionary.

Multiple consecutive `.` can be used to traverse up the attribute hierarchy from the current attribute.

.Examples
----
ATTRIBUTE Foo 1 string[3]
ATTRIBUTE Bar 2 octets
ATTRIBUTE baz 3 ipv4addr
----


== Enum

In some cases, attributes need to reuse the same set of `VALUE` statements.
The `enum=...` flag allows an attribute to copy enumerated vl

The `enum` flag can only be used for "leaf" data types.  i.e. ones
which can contain a `VALUE`.

.Enum Examples
----
ATTRIBUTE Foo 1 integer
VALUE Zero Foo 0

ATTRIBUTE Bar 2 integer enum=Foo
----

The result of the above dictionary is that the `Bar` attribute also has `VALUE` defined, with name `Zero`.

== Clone

In some cases, structured attributes have different parents, but
identical children. The `clone=...` flag allows an attribute to copy
or "clone" the children of another attribute.

The `clone` flag can only be used for data types `tlv` and `struct`.

.Clone Examples
----
ATTRIBUTE Foo 1 tlv
ATTRIBUTE Bar 1.1 ipaddr
ATTRIBUTE Baz 2 tlv clone=Foo
----

The result of the above dictionary is that the `Baz` attribute also has child attribute, of name `Bar`.

== Ref

In some cases, attributes can "group" other attributes without adding
a new hierarchy.  The `ref=...` flag allows a grouped attribute to
reference another attribute.  The grouped attribute can then contain
the referenced attributes, as if those other attributes were members
of the group.

If `ref` is not given for an attribute of type `group` then the
reference is assumed to be to the "root" of the current protocol
dictionary.

The `ref` flag can only be used for the data type `group`.  The referenced attribute must be of data type `group` or `tlv`.
613 816 8331
== Fixed Size Data types

The following data types can be marked up as having fixed size, by
using an array suffix, e.g. `octets[14]`.

Fixed Size types and meanings
[options="header"]
[cols="30%,70%"]
|=====
| Type         | Description
| `octets[n]`  | Declare that this attribute uses `n` bytes of `octets` data
| `string[n]`  | Declare that this attribute uses `n` bytes of `string` data
| `struct[n]`  | Declare that this structure uses `n` bytes for itself, including all child xref:dictionary/member.adoc[MEMBER]s
|=====


// Copyright (C) 2023 Network RADIUS SAS.  Licenced under CC-by-NC 4.0.
// This documentation was developed by Network RADIUS SAS.
