vowifi-sms
October 11, 2025 · View on GitHub
Minimal VoWiFi/IMS client for receiving SMS over Wi-Fi using a physical USIM (PC/SC).
This client performs SIP registration to an IMS network with AKA (AKAv1-MD5) authentication via a physical USIM.
Typical use case: establish IMS access over ePDG (SWu, IPsec) and run this client inside the corresponding network namespace or interface to receive SMS without a phone.
Reference guide for ePDG tunnel setup (strongSwan / SWu, IMS / VoWiFi): “VoWiFi with Asterisk” by Osmocom — osmocom.org/projects/foss-ims-client/wiki/VoWiFi_with_Asterisk
Requirements
- Linux with XFRM support (
iproute2) and IPv6 - Go 1.21+ (recommended)
- PC/SC stack:
pcscd,libpcsclite/libpcsclite-dev, USB reader, and USIM tcpdump(optional, required only when using-d)
Example for Debian/Ubuntu:
sudo apt update
sudo apt install -y golang iproute2 pcscd libpcsclite-dev pcsc-tools tcpdump
sudo systemctl enable --now pcscd
Build or run
To build:
go build -o sip-client .
To run directly:
sudo ip netns exec ims go run . -p <PCSCF_IPV6>
How it works (short)
- Read IMSI and MNC length from the USIM via PC/SC.
- Send initial
REGISTER(TCP/5060 to P-CSCF) with an emptyAuthorizationheader and proposed local SPI/ports inSecurity-Client. - Receive
401 UnauthorizedwithWWW-Authenticate(RAND/AUTN) andSecurity-Server. - Perform AKA authentication (AKAv1-MD5).
- Configure XFRM policies for the negotiated client/server ports and SPI.
- Re-
REGISTERover secured TCP (s-port, IPsec-protected) withSecurity-Verify→ receive200 OK. - Wait for incoming SIP
MESSAGEpackets containing SMS payloads.
Connecting to ePDG (strongSwan / SWu)
This client requires an active SWu tunnel to the ePDG and a local IPv6 address on the interface tun23 (preferably inside the ims namespace).
The ePDG FQDN is derived from MCC/MNC as:
epdg.epc.mncYYY.mccXXX.pub.3gppnetwork.org
(MNC and MCC are three-digit, zero-padded.)
Example:
dig epdg.epc.mnc001.mcc262.pub.3gppnetwork.org
You can read the IMSI using pySim or pcsc-tools.
See the Osmocom guide: VoWiFi with Asterisk.
Option A (recommended): strongSwan
Stable and scalable. Note: official strongSwan packages do not include native USIM/PCSC authentication — use the fork/branch referenced in the Osmocom guide.
Steps:
- Install or build strongSwan with USIM (PCSC) support — see “Option 2 → Install strongSwan” in the Osmocom guide.
- Configure an SWu/IKEv2 profile for
epdg.epc.mncYYY.mccXXX.pub.3gppnetwork.orgusing EAP-AKA (IMSI). - Use an up/down script to operate within a namespace and bind a virtual interface named
tun23insideims(the guide provides an example). - Start the connection and verify that
tun23has an IPv6 address insideims.
Important: strongSwan does not create network namespaces automatically — use an up/down script for that.
Either name the interface tun23 or modify the interface name in the code before building.
Option B (simpler but less reliable; not compatible with all operators): SWu-IKEv2 (Python)
This method is easier to set up, but the tunnel may drop when idle and supports only one connection per IP address.
Steps:
- Clone SWu-IKEv2, create a virtual environment, and install dependencies.
- In
swu_emulator.py, change the TUN name totun23:
(replace any existing reference toself.tunnel = self.open_tun(23)open_tun(1)). - Run with correct MCC/MNC values (3 digits, MNC left, MCC right in the FQDN), always inside a namespace.
Example:
python3 swu_emulator.py -m0 -a ims -I 310240xxxxxxxxx -M 310 -N 240 -n i1 -d epdg.epc.mnc240.mcc310.pub.3gppnetwork.org
Running the client
- Ensure
tun23has an IPv6 address inside theimsnamespace:
sudo ip netns exec ims ip -6 addr show dev tun23
-
Find the P-CSCF IPv6 address — usually discovered via SRV/NAPTR for
ims.mncYYY.mccXXX.3gppnetwork.org, or extracted from registration traces (Pathheader in the401response). -
Start the client (inside the same namespace):
sudo ip netns exec ims ./sip-client -p <PCSCF_IPV6>
Where -p is the P-CSCF IPv6 address (no brackets, no port).
The -d flag enables verbose logging and ESP packet capture.
When an SMS arrives, the client will:
- Send
200 OKin response to the incoming SIPMESSAGE. - Decode the sender number and message text and print them to stdout.
Debugging
- Use
-dfor verbose logs and automatic ESP packet capture (ipsec_<ports>_<timestamp>.pcap). - Verify that
pcscdis running and the reader is visible usingpcsc_scan. - Check
ip -6 xfrm stateandip -6 xfrm policyfor the expected SPI and port pairs after step 5.