1# UTscapy syntax is explained here: http://www.secdev.org/projects/UTscapy/
2
3# original author: patrick battistello
4
5% Validation of Diameter layer
6
7
8#######################################################################
9+ Different ways of building basic AVPs
10#######################################################################
11
12= AVP identified by full name
13a1 = AVP ('High-User-Priority', val=15)
14a1.show()
15raw(a1) == b'\x00\x00\x02/@\x00\x00\x0c\x00\x00\x00\x0f'
16
17= Same AVP identified by the beggining of the name
18a1b = AVP ('High-U', val=15)
19a1b.show()
20raw(a1b) == raw(a1)
21
22= Same AVP identified by its code
23a1c = AVP (559, val=15)
24a1c.show()
25raw(a1c) == raw(a1)
26
27= The Session-Id AVP (with some padding added)
28a2 = AVP ('Session-Id', val='aaa.test.orange.fr;1428128;644587')
29a2.show()
30raw(a2) == b'\x00\x00\x01\x07@\x00\x00)aaa.test.orange.fr;1428128;644587\x00\x00\x00'
31
32= An enumerated AVP
33a3 = AVP ('Auth-Session-State', val='NO_STATE_MAINTAINED')
34a3.show()
35raw(a3) == b'\x00\x00\x01\x15@\x00\x00\x0c\x00\x00\x00\x01'
36
37= An address AVP
38a4v4 = AVP("CG-Address", val='192.168.0.1')
39a4v4.show()
40raw(a4v4) == b'\x00\x00\x03N\xc0\x00\x00\x12\x00\x00(\xaf\x00\x01\xc0\xa8\x00\x01\x00\x00'
41
42a4v6 = AVP("CG-Address", val='::1')
43a4v6.show()
44raw(a4v6) == b'\x00\x00\x03N\xc0\x00\x00\x1e\x00\x00(\xaf\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00'
45
46a4error = AVP("CG-Address", val="unknown")
47a4error.show()
48assert raw(a4error) == raw(AVP("CG-Address"))
49
50= A time AVP
51a5 = AVP("Expiry-Time")
52a5.show()
53assert not a5.val
54
55= An empty Auth App ID AVP
56a6 = AVP("Auth-Application-Id")
57a6.show()
58raw(a6) == b'\x00\x00\x01\x02@\x00\x00\x0c\x00\x00\x00\x00'
59
60= An ISDN AVP
61a7 = AVP("MSISDN", val="101")
62a7.show()
63raw(a7) == b'\x00\x00\x02\xbd\xc0\x00\x00\x0e\x00\x00(\xaf\x01\xf1\x00\x00'
64
65= Some OctetString AVPs
66a8 = AVP("Authorization-Token", val="test")
67a8.show()
68assert raw(a8) == b'\x00\x00\x01\xfa\xc0\x00\x00\x10\x00\x00(\xaftest'
69
70a8 = AVP("Authorization-Token", val=b"test\xc3\xa9")
71a8.show()
72assert a8.val == b"test\xc3\xa9"
73assert raw(a8) == b'\x00\x00\x01\xfa\xc0\x00\x00\x12\x00\x00(\xaftest\xc3\xa9\x00\x00'
74
75= Unknown AVP identifier
76
77a9 = AVP("wrong")
78assert not a9
79
80
81#######################################################################
82+ AVPs with vendor field
83#######################################################################
84
85= Vendor AVP identified by full name
86a4 = AVP ('Feature-List-ID', val=1)
87a4.show()
88raw(a4) == b'\x00\x00\x02u\x80\x00\x00\x10\x00\x00(\xaf\x00\x00\x00\x01'
89
90= Same AVP identified by its code and vendor ID
91* This time a list is required as first argument 
92a4c = AVP ( [629, 10415], val=1)
93raw(a4c) == raw(a4)
94
95
96#######################################################################
97+ Altering the AVPs default provided values
98#######################################################################
99
100= Altering the flags of the Origin-Host AVP
101a5 = AVP ('Origin-Host', avpFlags=187, val='aaa.test.orange.fr')
102a5.show()
103raw(a5) == b'\x00\x00\x01\x08\xbb\x00\x00\x1aaaa.test.orange.fr\x00\x00'
104
105= Altering the length of the Destination-Realm AVP
106a6 = AVP (283, avpLen=33, val='foreign.realm1.fr')
107a6.show()
108raw(a6) == b'\x00\x00\x01\x1b@\x00\x00!foreign.realm1.fr\x00\x00\x00'
109
110= Altering the vendor of the Public-Identity AVP, and hence the flags ...
111a7 = AVP ( [601, 98765432], val = 'sip:+0123456789@aaa.test.orange.fr')
112a7.show()
113raw(a7) == b'\x00\x00\x02Y\x80\x00\x00.\x05\xe3\nxsip:+0123456789@aaa.test.orange.fr\x00\x00'
114
115
116#######################################################################
117+ Grouped AVPs
118#######################################################################
119
120= The Supported-Features AVP (with vendor)
121a8 = AVP ('Supported-Features')
122a8.val.append(a1)
123a8.val.append(a5)
124a8.show()
125raw(a8) == b'\x00\x00\x02t\x80\x00\x004\x00\x00(\xaf\x00\x00\x02/@\x00\x00\x0c\x00\x00\x00\x0f\x00\x00\x01\x08\xbb\x00\x00\x1aaaa.test.orange.fr\x00\x00'
126
127= The same AVP created more simply
128a8b = AVP ('Supported-Features', val = [a1, a5])
129raw(a8b) == raw(a8)
130
131= (re)Building the previous AVP from scratch
132a8c = AVP ('Supported-Features', val = [
133            AVP ('High-User-Priority', val=15),
134            AVP ('Origin-Host', avpFlags=187, val='aaa.test.orange.fr') ])
135raw(a8c) == raw(a8)
136
137= Another (dummy) grouped AVP
138a9 = AVP (297, val = [a2, a4, a6])
139a9.show()
140raw(a9) == b'\x00\x00\x01)@\x00\x00`\x00\x00\x01\x07@\x00\x00)aaa.test.orange.fr;1428128;644587\x00\x00\x00\x00\x00\x02u\x80\x00\x00\x10\x00\x00(\xaf\x00\x00\x00\x01\x00\x00\x01\x1b@\x00\x00!foreign.realm1.fr\x00\x00\x00'
141
142= A grouped AVP inside another grouped AVP
143a10 = AVP ('Server-Cap', val = [a1, a9])
144a10.show()
145raw(a10) == b'\x00\x00\x02[\xc0\x00\x00x\x00\x00(\xaf\x00\x00\x02/@\x00\x00\x0c\x00\x00\x00\x0f\x00\x00\x01)@\x00\x00`\x00\x00\x01\x07@\x00\x00)aaa.test.orange.fr;1428128;644587\x00\x00\x00\x00\x00\x02u\x80\x00\x00\x10\x00\x00(\xaf\x00\x00\x00\x01\x00\x00\x01\x1b@\x00\x00!foreign.realm1.fr\x00\x00\x00'
146
147= A big grouped AVP
148a11 = AVP ('SIP-Auth', val = [a2, a4, a8, a10])
149a11.show()
150raw(a11) == b'\x00\x00\x01x@\x00\x00\xf0\x00\x00\x01\x07@\x00\x00)aaa.test.orange.fr;1428128;644587\x00\x00\x00\x00\x00\x02u\x80\x00\x00\x10\x00\x00(\xaf\x00\x00\x00\x01\x00\x00\x02t\x80\x00\x004\x00\x00(\xaf\x00\x00\x02/@\x00\x00\x0c\x00\x00\x00\x0f\x00\x00\x01\x08\xbb\x00\x00\x1aaaa.test.orange.fr\x00\x00\x00\x00\x02[\xc0\x00\x00x\x00\x00(\xaf\x00\x00\x02/@\x00\x00\x0c\x00\x00\x00\x0f\x00\x00\x01)@\x00\x00`\x00\x00\x01\x07@\x00\x00)aaa.test.orange.fr;1428128;644587\x00\x00\x00\x00\x00\x02u\x80\x00\x00\x10\x00\x00(\xaf\x00\x00\x00\x01\x00\x00\x01\x1b@\x00\x00!foreign.realm1.fr\x00\x00\x00'
151
152= Dissect grouped AVP
153
154a12 = DiamG(b'\x01\x00\x00!\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xbd\xc0\x00\x00\r\x00\x00(\xaf\x01')
155assert isinstance(a12.avpList[0], AVP_10415_701)
156assert "MSISDN" in a12.avpList[0].name
157
158#######################################################################
159+ Diameter Requests (without AVPs)
160#######################################################################
161
162= A simple request identified by its name
163r1 = DiamReq ('Capabilities-Exchange', drHbHId=1234, drEtEId=5678)
164r1.show()
165raw(r1) == b'\x01\x00\x00\x14\x80\x00\x01\x01\x00\x00\x00\x00\x00\x00\x04\xd2\x00\x00\x16.'
166
167= Unknown request by its name
168ur = DiamReq ('Unknown')
169raw(ur) == b'\x01\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
170
171= The same one identified by its code
172r1b = DiamReq (257, drHbHId=1234, drEtEId=5678)
173raw(r1b) == raw(r1)
174
175= Unknown request by its code
176ur = DiamReq (0)
177raw(ur) == b'\x01\x00\x00\x14\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
178
179= The same one identified by its abbreviation
180* Only the first 2 abbreviation letters are significant (although 3 are provided in this example)
181r1c = DiamReq ('CER', drHbHId=1234, drEtEId=5678)
182raw(r1c) == raw(r1)
183
184= Altering the request default fields
185r2 =  DiamReq ('CER', drHbHId=1234, drEtEId=5678, drFlags=179, drAppId=978, drLen=12)
186r2.show()
187raw(r2) == b'\x01\x00\x00\x0c\xb3\x00\x01\x01\x00\x00\x03\xd2\x00\x00\x04\xd2\x00\x00\x16.'
188
189= Altering the default request fields with string
190r2b =  DiamReq ('CER', drAppId="1")
191r2b.show()
192raw(r2b) == b'\x01\x00\x00\x14\x00\x00\x01\x01\x01\x00\x00$\x00\x00\x00\x00\x00\x00\x00\x00'
193
194= Altering the default request fields with invalid string
195r2be =  DiamReq ('CER', drAppId="-1")
196r2be.show()
197raw(r2be) == b'\x01\x00\x00\x14\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
198
199
200#######################################################################
201+ Diameter Answers (without AVPs)
202#######################################################################
203
204= A simple answer identified by its name
205ans1 = DiamAns ('Capabilities-Exchange', drHbHId=1234, drEtEId=5678)
206ans1.show()
207raw(ans1) == b'\x01\x00\x00\x14\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x04\xd2\x00\x00\x16.'
208
209= Same answer identified by its code or abbreviation
210ans1b = DiamAns (257, drHbHId=1234, drEtEId=5678)
211ans1c = DiamAns ('CEA', drHbHId=1234, drEtEId=5678)
212raw(ans1b) == raw(ans1), raw(ans1c) == raw(ans1)
213_ == (True, True)
214
215= Altering the answer default fields
216ans2 =  DiamAns ('CEA', drHbHId=1234, drEtEId=5678, drFlags=115, drAppId=1154, drLen=18)
217ans2.show()
218raw(ans2) == b'\x01\x00\x00\x12s\x00\x01\x01\x00\x00\x04\x82\x00\x00\x04\xd2\x00\x00\x16.'
219
220
221#######################################################################
222+ Full Diameter messages
223#######################################################################
224
225= A dummy Multimedia-Auth request (identified by only a portion of its name)
226r3 = DiamReq ('Multimedia-Auth', drHbHId=0x5478, drEtEId=0x1234, avpList = [a11])
227r3.show()
228raw(r3) == b'\x01\x00\x01\x04\xc0\x00\x01\x1e\x00\x00\x00\x06\x00\x00Tx\x00\x00\x124\x00\x00\x01x@\x00\x00\xf0\x00\x00\x01\x07@\x00\x00)aaa.test.orange.fr;1428128;644587\x00\x00\x00\x00\x00\x02u\x80\x00\x00\x10\x00\x00(\xaf\x00\x00\x00\x01\x00\x00\x02t\x80\x00\x004\x00\x00(\xaf\x00\x00\x02/@\x00\x00\x0c\x00\x00\x00\x0f\x00\x00\x01\x08\xbb\x00\x00\x1aaaa.test.orange.fr\x00\x00\x00\x00\x02[\xc0\x00\x00x\x00\x00(\xaf\x00\x00\x02/@\x00\x00\x0c\x00\x00\x00\x0f\x00\x00\x01)@\x00\x00`\x00\x00\x01\x07@\x00\x00)aaa.test.orange.fr;1428128;644587\x00\x00\x00\x00\x00\x02u\x80\x00\x00\x10\x00\x00(\xaf\x00\x00\x00\x01\x00\x00\x01\x1b@\x00\x00!foreign.realm1.fr\x00\x00\x00'
229
230
231= The same request built from scratch
232r3b = DiamReq ('Multimedia-Auth', drHbHId=0x5478, drEtEId=0x1234,
233                avpList = [
234                  AVP ('SIP-Auth', val = [
235                        AVP ('Session-Id', val='aaa.test.orange.fr;1428128;644587'),
236                        AVP ('Feature-List-ID', val=1),
237                        AVP ('Supported-Features', val = [
238                              AVP ('High-User-Priority', val=15),
239                              AVP ('Origin-Host', avpFlags=187, val='aaa.test.orange.fr')
240                              ]),
241                        AVP ('Server-Cap', val = [
242                              AVP ('High-User-Priority', val=15),
243                              AVP (297, val = [
244                                  AVP ('Session-Id', val='aaa.test.orange.fr;1428128;644587'),
245                                  AVP ('Feature-List-ID', val=1),
246                                  AVP (283, avpLen=33, val='foreign.realm1.fr')
247                                  ])
248                              ])
249                       ])
250                ])
251
252raw(r3b) == raw(r3)
253
254