Académique Documents
Professionnel Documents
Culture Documents
A quick guide
1.
1.1
Let's start with copying existing diameter packets. Ladies and gentlemans start
your Wiresharks and open your snoops.
Open the diameter message you want to copy/emulate, and do the right-click on
Diameter message, and Copy the Bytes as Hex-Stream.
Note that I just copy-pasted the value from wireshark, put them under quotes and
gave them appropriate name.
Here is simplified and minimalistic example. See example files for more info. Greyed
is the python script.
#!/usr/bin/env python
from diamClient import *
if __name__ == '__main__':
HOST='server'
PORT=3868
Please modify HOST and PORT to proper values (you'll definitely want to change
HOST to your server hostname/IP). Dictionary is not used in this example.
Conn=Connect(HOST,PORT)
# Let's build CER
Please insert newly created CER variable after this. Note that python uses
indentation, so please do it right. Examples in this document are NOT aligned
properly. Please see examples directory or read some python manual. This variable
should be in single line
CER='0100008c8000010100000000000000010860000100000108400000167374
612e737072696e742e636f6d00000000012840000012737072696e742e636f6d0
000000001014000000e00010a1e60c800000000010a4000000c000028af000001
0d000000154c616e64736c69646548534757000000000001024000000c0100002
2000001164000000c4f32a086'
# send data
Conn.send(CER.decode('hex'))
# Receive response
received = Conn.recv(1024)
You now can add in exactly the same way any diameter message. When done,
please close connection.
Conn.close()
And we are done. This is NOT the full message flow, but it showed you how to
quickly build the diameter messages using diamClient and existing snoop from
Wireshark.
1.2
This is rather simple manually add all AVPs to message. Just be sure that ALL
AVPs are in dictionary. Commands and Vendors are defined in dictionary, so make
sure that you DID load the diameter dictionary with command
LoadDictionary("dictDiameter.xml")
Let's build CER (Note: Use your values for ORIGIN_HOST and ORIGIN_REALM):
# Let's build CER
CER_avps=[ ]
CER_avps.append(encodeAVP('Origin-Host', ORIGIN_HOST))
CER_avps.append(encodeAVP('Origin-Realm', ORIGIN_REALM))
CER_avps.append(encodeAVP('Vendor-Id', 11))
CER_avps.append(encodeAVP('Origin-State-Id', 1094807040))
CER_avps.append(encodeAVP('Supported-Vendor-Id', 11))
CER_avps.append(encodeAVP('Acct-Application-Id', 16777265))
# 3GPP SWx=16777265
# Create message header (empty)
CER=HDRItem()
# Set command code
CER.cmd=dictCOMMANDname2code('Capabilities-Exchange')
# Set Hop-by-Hop and End-to-End
initializeHops(CER)
# Add AVPs to header and calculate remaining fields
msg=createReq(CER,CER_avps)
# msg now contains CER Request as hex string
And to send it, we will use exactly the same code as before
# send data
Conn.send(msg.decode('hex'))
# Receive response
received = Conn.recv(1024)
So just replace single line we copied in previous example with these lines, and... you
are done! That way you can quickly start, and replace copied message with one you
can change/adapt.
1.3
Sometimes you'll need something in between. E.g I want to change one AVP, but
do not want to touch others in copied message.
Let's show how it can be done using message containing AVP we DO NOT WANT
TO CHANGE, and User-Name WE DO WANT TO CHANGE.
Note: You can copy the RAW values directly from wireshark snoop. Open AVP you
want to copy, right-click on it, and Copy Bytes as Hex-Stream. Remember always
click on TOPMOST level of AVP you want to copy, not on expanded ones.
Once we can see values in wireshark we want to copy/change, we can make any mix
we want to. Capital letter variables are for clarity. Replace them with expected values
# Let's build DER
DER_avps=[]
DER_avps.append(encodeAVP("Origin-Host", ORIGIN_HOST))
DER_avps.append(encodeAVP("Origin-Realm", ORIGIN_REALM))
DER_avps.append(encodeAVP("Session-Id", SESSION_ID))
DER_avps.append(encodeAVP("Destination-Host", DEST_HOST))
DER_avps.append(encodeAVP("Destination-Realm", DEST_REALM))
DER_avps.append(encodeAVP("Origin-State-Id", 1329853127))
DER_avps.append(encodeAVP("User-Name",
"0121112222000623@wlan.mnc023.mcc262.3gppnetwork.org"))
# And now some values I do NOT want to change or understand
DER_avps.append("000001ce40000040020000380130313231313132323232
30303036323340776c616e2e6d6e633032332e6d63633236322e336770706e6
574776f726b2e6f7267")
DER_avps.append("00000408c0000010000028af00000000")
# Just to ilustrate that you can mix it any way you want
DER_avps.append("000005e0c0000010000028af48525044")
DER_avps.append(encodeAVP("Auth-Session-State", 0))
DER_avps.append(encodeAVP("Origin-State-Id", 1321976431))
DER_avps.append(encodeAVP("Calling-Station-Id",
'310006232157383')
DER_avps.append(encodeAVP("Vendor-Id", 10415)
And now proceed with adding header fields and making it the proper Diameter
message
# Create empty message header
DER_H=HDRItem()
# Set command code
DER_H.cmd=getCommandCode('Diameter-EAP')
# Set Hop-by-Hop and End-to-End
initializeHops(DER_H)
# Add AVPs to header and calculate remaining fields
msg=createReq(DER_H,DER_avps)
# msg now contains Diameter-EAP-Request as hex string
Note:
If you have to send Enumerated AVP, use numeric value, not enumerated
string
If you have to send Grouped AVP, see example
# Example for ENUMERATED AVP
# 0-WLAN 1-UTRAN 2-GERAN 2001-HRPD 2003-EHRPD ...
DER_avps.append(encodeAVP("RAT-Type", 0))
2.1
Let's start with copying existing radius packets. Ladies and gentlemans start your
Wiresharks and open your snoops.
Open the radius message you want to copy/emulate, and do the right-click on Radius
message, and Copy the Bytes as Hex-Stream.
Here is simplified and minimalistic example. See example files for more info. Greyed
is the python script.
#!/usr/bin/env python
from radClient import *
if __name__ == '__main__':
HOST='server'
PORT=3868
Please modify HOST and PORT to proper values (you'll definitely want to change
HOST to your server hostname/IP). Dictionary is not used in this example.
Conn=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Let's build message
Please insert newly created variable after this. Note that python uses indentation, so
please do it right. Examples in this document are NOT aligned properly. Please see
examples directory or read some python manual. This variable should be in single
line
msg="0b03005616af199ad8906acbc1ab69c2eff86a4c4f0e0102000c17050000
0d0100005012989f092fca647c2b5973ed1bfc3a180d1822d51ee1f848bcc9a44
973282f625303e4e9023a9562b8ff9c02f6ddc28d5e00eb"
# send data
Conn.sendto(msg.decode("hex"),(HOST,PORT))
# Receive response
received = Conn.recv(1024)
You now can add in exactly the same way any radius message. When done, please
close connection.
Conn.close()
And we are done. This is NOT the full message flow, but it showed you how to
quickly build the radius messages using radClient and existing snoop from
Wireshark.
2.2
This is rather simple manually add all AVPs to message. Just be sure that ALL
AVPs are in dictionary. Commands and Vendors are defined in dictionary, so make
sure that you DID load the radius dictionary with command
LoadDictionary("dictRadius.xml")
Let's build radius message (Note: Use your values for ORIGIN_HOST and
ORIGIN_REALM):
# Let's build message
RES_avps=[]
RES_avps.append(encodeAVP("State", STATE))
RES_avps.append(encodeAVP("Calling-Station-Id",
CALLING_ID))
RES_avps.append(encodeAVP("Called-Station-Id", CALLED_ID))
RES_avps.append(encodeAVP("NAS-Identifier", "default"))
RES_avps.append(encodeAVP("User-Name", "testuser"))
RES_avps.append(encodeAVP("Acct-Session-Id", "a1"))
RES_avps.append(encodeAVP("NAS-IP-Address", NAS_IP))
RES_avps.append(encodeAVP("NAS-Port-Id", NAS_PORT))
# Create message header (empty)
RES=HDRItem()
# Set command code
RES.Code=dictCOMMANDname2code("Access-Request")
RES.Identifier=RID
# Add AVPs to header and calculate remaining fields
msg=createReq(RES,RES_avps)
# msg now contains Response as hex string
And to send it, we will use exactly the same code as before
# send data
Conn. sendto(msg.decode("hex"),(HOST,PORT))
# Receive response
received = Conn.recv(1024)
So just replace single line we copied in previous example with these lines, and... you
are done! That way you can quickly start, and replace copied message with one you
can change/adapt.
2.3
Sometimes you'll need something in between. E.g I want to change one AVP, but
do not want to touch others in copied message.
Let's show how it can be done using message containing AVP we DO NOT WANT
TO CHANGE, and User-Name WE DO WANT TO CHANGE.
Note: You can copy the RAW values directly from wireshark snoop. Open AVP you
want to copy, right-click on it, and Copy Bytes as Hex-Stream. Remember always
click on TOPMOST level of AVP you want to copy, not on expanded ones.
Once we can see values in wireshark we want to copy/change, we can make any mix
we want to.
# Let's build RAD
RAD_avps=[]
RAD_avps.append(encodeAVP("User-Name",
"0121112222000623@wlan.mnc023.mcc262.3gppnetwork.org"))
# And now some values I do NOT want to change or understand
RAD_avps.append("000001ce40000040020000380130313231313132323232
30303036323340776c616e2e6d6e633032332e6d63633236322e336770706e6
574776f726b2e6f7267")
RAD_avps.append("00000408c0000010000028af00000000")
# Just to ilustrate that you can mix it any way you want
RAD_avps.append("000005e0c0000010000028af48525044")
RAD_avps.append(encodeAVP("Auth-Session-State", 0))
RAD_avps.append(encodeAVP("Calling-Station-Id",
'310006232157383')
And now proceed with adding header fields and making it the proper Radius
message
# Create message header (empty)
RES=HDRItem()
# Set command code
RES.Code=dictCOMMANDname2code("Access-Request")
RES.Identifier=RID
# Add AVPs to header and calculate remaining fields
msg=createReq(RES,RES_avps)
# msg now contains Response as hex string
Note:
If you have to send Enumerated AVP, use numeric value, not enumerated
string
# Example for ENUMERATED AVP
# 1-Login 2-Framed 17-Authorize only...
DER_avps.append(encodeAVP("Service-Type", 1))
That is it. Happy coding.
3. EAP-Payload/EAP-Message
To be able to create/modify/decode EAP message, import EAP module.
#!/usr/bin/env python
from ???Client import *
import eap
if __name__ == '__main__':
HOST='server'
PORT=3868
LoadDictionary("dict????.xml")
eap.LoadEAPDictionary("dictEAP.xml")
And from now on you can access EAP messages in similar manner.
See included examples for more details.
3.1
3.2
3.3
4. Bug reports
Please send any changes, enhancements, fixes, bug reports and successful
examples to my email. If you like this tool, a small donation might encourage me to
extend it a bit further.