#!/usr/bin/env python3
"""
Educational SIP Decoder for SIPp Training
-----------------------------------------
This script teaches:
1. How SIP messages are structured
2. How to decode SIP headers and body
3. How SIPp scenarios map to real SIP packets
"""
import re
def parse_sip_message(raw):
"""
Parse a raw SIP message into:
- Request/Status line
- Headers (dict)
- Body
"""
lines = raw.split("\n")
start_line = lines[0].strip()
headers = {}
body = ""
in_body = False
for line in lines[1:]:
line = line.rstrip("\r")
if line == "":
in_body = True
continue
if not in_body:
# Header line: Key: Value
if ":" in line:
key, value = line.split(":", 1)
headers[key.strip()] = value.strip()
else:
body += line + "\n"
return start_line, headers, body.strip()
def decode_sip(raw):
start_line, headers, body = parse_sip_message(raw)
print("=== SIP MESSAGE DECODE ===")
print(f"Start Line: {start_line}")
print("\n--- Headers ---")
for k, v in headers.items():
print(f"{k}: {v}")
print("\n--- Body ---")
print(body if body else "(no body)")
# Educational extras
if "Via" in headers:
print("\nVia branch:", re.findall(r"branch=([^;]+)", headers["Via"]))
if "Call-ID" in headers:
print("Call-ID:", headers["Call-ID"])
if "CSeq" in headers:
method = headers["CSeq"].split()[1]
print("CSeq Method:", method)
if __name__ == "__main__":
# Example SIPp REGISTER message
raw_msg = """REGISTER sip:server.com SIP/2.0
Via: SIP/2.0/UDP 10.0.0.1:5060;branch=z9hG4bK12345
Max-Forwards: 70
To: <sip:alice@server.com>
From: <sip:alice@server.com>;tag=abcd
Call-ID: 123456@10.0.0.1
CSeq: 1 REGISTER
Contact: <sip:alice@10.0.0.1>
Content-Length: 0
"""
decode_sip(raw_msg)
sipp -sn uac -trace_msg -trace_err server_ip
messages.log
with open("messages.log") as f:
for msg in f.read().split("------------------------------------------------------------------------"):
decode_sip(msg)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Digest Auth Simulator</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 40px;
background: #f5f5f5;
}
.container {
background: white;
padding: 25px;
border-radius: 10px;
width: 600px;
margin: auto;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
input, select {
width: 100%;
padding: 8px;
margin: 6px 0 15px 0;
}
pre {
background: #eee;
padding: 10px;
border-radius: 5px;
}
button {
padding: 10px 20px;
background: #0078ff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
button:hover {
background: #005fcc;
}
</style>
</head>
<body>
<div class="container">
<h2>Digest Authentication Calculator</h2>
<label>Username</label>
<input id="username" value="alice">
<label>Password</label>
<input id="password" value="secret">
<label>Realm</label>
<input id="realm" value="server.com">
<label>Method</label>
<input id="method" value="REGISTER">
<label>URI</label>
<input id="uri" value="sip:server.com">
<label>Nonce</label>
<input id="nonce" value="abcdef123456">
<label>Nonce Count (nc)</label>
<input id="nc" value="00000001">
<label>Client Nonce (cnonce)</label>
<input id="cnonce" value="xyz987">
<label>QOP</label>
<select id="qop">
<option value="auth">auth</option>
<option value="auth-int">auth-int</option>
</select>
<button onclick="calculate()">Compute Digest</button>
<h3>Results</h3>
<pre id="output"></pre>
</div>
<script>
// Simple MD5 implementation (RFC 1321)
function md5(str) {
return CryptoJS.MD5(str).toString();
}
function calculate() {
let username = document.getElementById("username").value;
let password = document.getElementById("password").value;
let realm = document.getElementById("realm").value;
let method = document.getElementById("method").value;
let uri = document.getElementById("uri").value;
let nonce = document.getElementById("nonce").value;
let nc = document.getElementById("nc").value;
let cnonce = document.getElementById("cnonce").value;
let qop = document.getElementById("qop").value;
let HA1 = md5(`${username}:${realm}:${password}`);
let HA2 = md5(`${method}:${uri}`);
let response = md5(`${HA1}:${nonce}:${nc}:${cnonce}:${qop}:${HA2}`);
document.getElementById("output").innerText =
`HA1 = MD5(${username}:${realm}:${password})
→ ${HA1}
HA2 = MD5(${method}:${uri})
→ ${HA2}
Response = MD5(${HA1}:${nonce}:${nc}:${cnonce}:${qop}:${HA2})
→ ${response}`;
}
</script>
<!-- CryptoJS MD5 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
</body>
</html>
















































