Skip to content

Instantly share code, notes, and snippets.

@giavac
giavac / create_turn_credentials.py
Created January 16, 2026 15:11
python script to generate ephemeral TURN credentials from a shared secret, with TTL
#!/usr/bin/env python3
"""
Generate ephemeral TURN credentials using a shared secret.
TURN servers can use time-limited credentials where:
- Username: <expiry_timestamp>:<username>
- Password: Base64(HMAC-SHA1(shared_secret, username))
The expiry timestamp is a Unix timestamp indicating when the credentials expire.
"""
@giavac
giavac / stream_server.py
Created December 5, 2025 17:48
WebSocket stream echo server with some test APIs
import asyncio
import json
import ssl
import websockets
from websockets.server import WebSocketServerProtocol
from aiohttp import web
# Track per-connection state: streamSid + media counter
client_state = {} # websocket -> {"streamSid": str | None, "media_count": int}
@giavac
giavac / custom_encap.lua
Last active November 16, 2025 18:47
Lua plugin for Wireshark. It interprets encapsulated IP frames inside UDP payload. Copy inside the "Wireshark custom plugin" folder and restart Wireshark.
-- Minimal Custom UDP Encapsulation Dissector
-- Ignore the first 42 Bytes and treat the UDP payload as an IP frame
-- This will show the content of encapsulated traffic
local OUTER_UDP_PORT = 1024 -- default port. You can use "Decode as..." and choose UDP-ENCAP-IP
local p_skip = Proto("udp_encap_ip", "UDP Encapsulated IP (skip 42 bytes)")
local HEADER_SIZE = 42
local ip_dissector = Dissector.get("ip")
<?xml version="1.0" encoding="iso-8859-2" ?>
<!DOCTYPE scenario SYSTEM "sipp.dtd">
<scenario name="UAC INVITE + call">
<send retrans="500">
<![CDATA[
INVITE sip:[field3]@[field4]:5061;transport=tls SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
@giavac
giavac / unescape_jsonify_cstring.py
Created July 12, 2023 15:37
Convert a multiline string into a CString usable with C code
#!/usr/local/bin/python3
import json
import argparse
def rewrite_as_c_string(json_str):
data = json.loads(json_str)
formatted_json = json.dumps(data, indent=4)
c_string = '"' + formatted_json.replace('"', '\\"').replace('\n', '\\n"\n"') + '"'
return c_string
@giavac
giavac / extract_opus_and_decode.py
Created July 5, 2023 14:58
Extracts the RTP payload and decodes it into a wav file
import pyshark
import opuslib
import wave
import argparse
FRAME_SIZE = 960
SAMPLE_RATE = 48000
CHANNEL_COUNT = 1
SAMPLE_WIDTH = 2
@giavac
giavac / parse_raw_opus.py
Created July 5, 2023 09:32
Get a raw opus file in, decode it into a wav file
#!/usr/bin/python3
import binascii
import opuslib
import wave
total_len = 0
def process_audio_data(audio_data, wav_file):
# print(binascii.hexlify(audio_data))
@giavac
giavac / decrypt_script.sh
Created July 4, 2023 15:42
Bash script to launch a decrypt program
#!/bin/bash
gcc decrypt.c -o decrypt -lssl -lz -lcrypto
encrypted="..."
tag="..."
iv="..."
key="..."
./decrypt "${encrypted}" "${tag}" "${iv}" "${key}"
@giavac
giavac / decrypt.c
Last active July 4, 2023 16:26
Decodes from base64, decrypts with key, tag and iv, then decompresses
#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>
#include <zlib.h>
static char *base64_decode(const char *input, int length, int *output_length) {
BIO *bio, *b64;
@giavac
giavac / ACK_RFC3665
Created July 6, 2018 12:00
ACK as in RFC-3665
F15 ACK Alice -> Proxy 1
ACK sip:bob@client.biloxi.example.com SIP/2.0
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74b76
Max-Forwards: 70
Route: <sip:ss1.atlanta.example.com;lr>,
<sip:ss2.biloxi.example.com;lr>
From: Alice <sip:alice@atlanta.example.com>;tag=9fxced76sl
To: Bob <sip:bob@biloxi.example.com>;tag=314159
Call-ID: 3848276298220188511@atlanta.example.com