#  All attribute lengths are implicit, and are calculated automatically
#
#  Input is of the form:
#
#	WORD ...
#
#  The WORD is a keyword which indicates the format of the following text.
#  WORD is one of:
#
#	raw - read the grammar defined below, and encode an attribute.
#	      The grammar supports a trivial way of describing RADIUS
#	      attributes, without reference to dictionaries or fancy
#	      parsers
#
#	encode - reads "Attribute-Name = value", encodes it, and prints
#	         the result as text.
#		use "-" to encode the output of the last command
#
#	decode - reads hex, and decodes it "Attribute-Name = value"
#		use "-" to decode the output of the last command
#
#	data - the expected output of the previous command, in ASCII form.
#	       if the actual command output is different, an error message
#	       is produced, and the program terminates.
#
#
#  The "raw" input satisfies the following grammar:
#
#	Identifier = 1*DIGIT *( "." 1*DIGIT )
#
#	HEXCHAR = HEXDIG HEXDIG 
#
#	STRING = DQUOTE *CHAR DQUOTE
#
#	TLV = "{" 1*DIGIT DATA "}"
#
#	DATA = 1*HEXCHAR / 1*TLV / STRING
#
#	LINE = Identifier DATA
#
#  The "Identifier" is a RADIUS attribute identifier, as given in the draft.
#
#	e.g.	1		for User-Name
#		26.9.1		Vendor-Specific, Cisco, Cisco-AVPAir
#		241.1		Extended Attribute, number 1
#		241.2.3		Extended Attribute 2, data type TLV, TLV type 3
#		etc.
#
#  The "DATA" portion is the contents of the RADIUS Attribute.
#
#		123456789abcdef hex string
#		12 34 56 ab	with spaces for clarity
#		"hello"	 	Text string
#		{ 1 abcdef }	TLV, TLV-Type 1, data "abcdef"
#
#  TLVs can be nested:
#
#	{ tlv-type { tlv-type data } }		{ 3 { 4 01020304 } }
#
#  TLVs can be concatencated
#
#	{tlv-type data } { tlv-type data}	{ 3 040506 } { 8 aabbcc }
#
#  The "raw" data is encoded without reference to dictionaries.  Any
#  valid string is parsed to a RADIUS attribute.  The resulting RADIUS
#  attribute *may not* be correctly formatted to the relevant RADIUS
#  specifications.  i.e. you can use this tool to create attribute 1
#  (User-Name), which is encoded as a series of TLVs.  That's up to you.
#
#  The purpose of the "raw" command is to have a simple way of encoding
#  attributes which is independent of any dictionaries or packet processing
#  routines.
#
#  The output data is the hex version of the encoded attribute.
#

encode User-Name = "bob"
data 01 05 62 6f 62

decode -
data User-Name = "bob"

decode 01 05 62 6f 62
data User-Name = "bob"

#
#  The Type/Length is OK, but the attribute data is of the wrong size.
#
decode 04 04 ab cd
data Attr-4 = 0xabcd

#  Zero-length attributes
decode 01 02
data 

# don't encode zero-length attributes
encode User-Name = ""
data 

# except for CUI.  Thank you, WiMAX!
decode 59 02
data Chargeable-User-Identity = 0x

# Hah! Thought you had it figured out, didn't you?
encode -
data 59 02

attribute Framed-IP-Address = 127.0.0.1/32
data Framed-IP-Address = 127.0.0.1

attribute Framed-IP-Address = 127.0.0.1/323
data Invalid IPv4 mask length "/323".  Should be between 0-32

attribute Framed-IP-Address = 127.0.0.1/30
data Invalid IPv4 mask length "/30".  Only "/32" permitted for non-prefix types

attribute Framed-IP-Address = *
data Framed-IP-Address = 0.0.0.0

attribute Framed-IP-Address = 127
data Framed-IP-Address = 0.0.0.127

attribute Framed-IP-Address = 127.0
data Framed-IP-Address = 127.0.0.0

attribute Framed-IPv6-Prefix = ::1
data Framed-IPv6-Prefix = ::1/128

attribute Framed-IPv6-Prefix = ::1/200
data Invalid IPv6 mask length "/200".  Should be between 0-128

attribute Framed-IPv6-Prefix = ::1/200
data Invalid IPv6 mask length "/200".  Should be between 0-128

attribute Framed-IPv6-Prefix = 11:22:33:44:55:66:77:88/128
data Framed-IPv6-Prefix = 11:22:33:44:55:66:77:88/128

attribute Framed-IPv6-Prefix = *
data Framed-IPv6-Prefix = ::/128

attribute PMIP6-Home-IPv4-HoA = 127/8
data PMIP6-Home-IPv4-HoA = 127.0.0.0/8

attribute PMIP6-Home-IPv4-HoA = 127/8
data PMIP6-Home-IPv4-HoA = 127.0.0.0/8

#
#  Octets outside of the mask are OK, but
#  are mashed to zero.
#
attribute PMIP6-Home-IPv4-HoA = 127.63/8
data PMIP6-Home-IPv4-HoA = 127.0.0.0/8

#
#  Unless you give a good mask.
#
attribute PMIP6-Home-IPv4-HoA = 127.63/16
data PMIP6-Home-IPv4-HoA = 127.63.0.0/16

attribute PMIP6-Home-IPv4-HoA = 127.999/16
data Failed to parse IPv4 address string "127.999/16"

attribute PMIP6-Home-IPv4-HoA = 127.bob/16
data Failed to parse IPv4 address string "127.bob/16"

attribute PMIP6-Home-IPv4-HoA = 127.63/15
data PMIP6-Home-IPv4-HoA = 127.62.0.0/15

attribute PMIP6-Home-IPv4-HoA = 127.63.1/24
data PMIP6-Home-IPv4-HoA = 127.63.1.0/24

attribute PMIP6-Home-IPv4-HoA = 127.63.1.6
data PMIP6-Home-IPv4-HoA = 127.63.1.6/32

attribute PMIP6-Home-IPv4-HoA = 256/8
data Failed to parse IPv4 address string "256/8"

attribute PMIP6-Home-IPv4-HoA = bob/8
data Failed to parse IPv4 address string "bob/8"

#
#  A "concat" attribute, with no data
#
decode 89 02
data PKM-SS-Cert = 0x

#
#  The configuration can use the old names, but they
#  get automatically converted to the new names.
#
attribute User-Service-Type = 1
data Service-Type = Login-User

#
#  Or with weirdly formatted data
#
decode 89 03 ff 89 02 89 03 fe
data PKM-SS-Cert = 0xfffe

$INCLUDE tunnel.txt
$INCLUDE errors.txt
$INCLUDE extended.txt
$INCLUDE lucent.txt
$INCLUDE wimax.txt
