miconda / sipexer

Modern and flexible SIP/VoIP cli tool
GNU General Public License v3.0
293 stars 37 forks source link
go golang sip telephony voip webrtc websocket

sipexer

Modern and flexible SIP (RFC3261) command line tool.

Project URL:

Table Of Content

Overview

sipexer is a cli tool that facilitates sending SIP requests to servers. It uses a flexible template system to allow defining many parts of the SIP request via command line parameters. It has support for UDP, TCP, TLS and WebSocket transport protocols, being suitable to test modern WebRTC SIP servers.

sipexer is not a SIP cli softphone, but a tool for crafting SIP requests mainly for the purpose of testing SIP signaling routing or monitoring servers.

It is written in Go, aiming to be usable from Linux, MacOS or Windows.

The meaning of the name sipexer: randomly selected to be easy to write and pronounce, quickly after thought of it as the shortening of SIP EXEcutoR.

sipexer in action sending a SIP OPTIONS request:

SIP OPTIONS Request

Features

Among features:

Installation

Compile From Sources

First install Go. Once the Go environment is configured, clone sipexer git repository:

git clone https://github.com/miconda/sipexer

Download dependencies and build:

cd sipexer
go get ./...
go build .

The binary sipexer should be generated in the current directory.

Note: On some OS distributions, it may be required to run the go build command with CGO_ENABLED=0, like:

CGO_ENABLED=0 go build .

Download Binary Release

Binary releases for Linux, MacOS and Windows are available at:

Usage

Prototype:

sipexer [options] [target]

See sipexer -h for the command line options and arguments.

Defaults:

Examples

Send an OPTIONS request over UDP to 127.0.0.1 and port 5060 - couple of variants:

sipexer
sipexer 127.0.0.1
sipexer 127.0.0.1 5060
sipexer udp 127.0.0.1 5060
sipexer udp:127.0.0.1:5060
sipexer sip:127.0.0.1:5060
sipexer "sip:127.0.0.1:5060;transport=udp"

Specify a different R-URI:

sipexer -ruri sip:alice@server.com udp:127.0.0.1:5060

Send from UDP local port 55060:

sipexer -laddr 127.0.0.1:55060 udp:127.0.0.1:5060

Send REGISTER request with generated contact, expires as well as user and password authentication:

sipexer -register -cb -ex 600 -au alice -ap test123 udp:127.0.0.1:5060

Send REGISTER request with expires 60s, wait 20000ms (20s) and then unregister:

sipexer -register -vl 3 -co -com -ex 60 -fuser alice -cb -ap "abab..." -ha1 -sd -sw 20000 udp:127.0.0.1:5060

Set fuser field to carol:

sipexer -sd -fu "carol" udp:127.0.0.1:5060
# or 
sipexer -sd -fv "fuser:carol" udp:127.0.0.1:5060

Set fuser field to carol and tuser field to david, with R-URI user same as To-user when providing proxy address destination:

sipexer -sd -fu "carol"  -tu "david" -su udp:127.0.0.1:5060
# or
sipexer -sd -fv "fuser:carol"  -fv "tuser:david" -su udp:127.0.0.1:5060

Add extra headers:

sipexer -sd -xh "X-My-Key:abcdefgh" -xh "P-Info:xyzw" udp:127.0.0.1:5060

Send MESSAGE request with body:

sipexer -message -mb 'Hello!' -sd -su udp:127.0.0.1:5060

Send MESSAGE request with body over tcp:

sipexer -message -mb 'Hello!' -sd -su tcp:127.0.0.1:5060

Send MESSAGE request with body over tls:

sipexer -message -mb 'Hello!' -sd -su tls:127.0.0.1:5061

Send MESSAGE request with body over wss (WebSocket Secure):

sipexer -message -mb 'Hello!' -sd -su wss://server.com:8443/sip

Send INVITE request with default From user alice and To user bob:

sipexer -invite -vl 3 -co -com -sd -su udp:server.com:5060

Initiate a call from alice to bob, with user authentication providing the password in HA1 format, waiting 10000 milliseconds before sending the BYE, with higher verbosity level (3) and color printing:

sipexer -invite -vl 3 -co -com -fuser alice -tuser bob -cb -ap "4a4a4a4a4a..." -ha1 -sw 10000 -sd -su udp:server.com:5060

Target Address

The target address can be provided as last arguments to the sipexer command. It is optional, if not provided, then the SIP message is sent over UDP to 127.0.0.1 port 5060.

The format can be:

Message Template

Template Data

The message to be sent via the SIP connection is built from a template file and a fields file.

The template file can contain any any of the directives supported by Go package text/template - for more see:

Example:

{{.method}} {{.ruri}} SIP/2.0
Via: SIP/2.0/{{.viaproto}} {{.viaaddr}}{{.rport}};branch=z9hG4bKSG.{{.viabranch}}
From: {{if .fname}}"{{.fname}}" {{end}}<sip:{{if .fuser}}{{.fuser}}@{{end}}{{.fdomain}}>;tag={{.fromtag}}
To: {{if .tname}}"{{.tname}}" {{end}}<sip:{{if .tuser}}{{.tuser}}@{{end}}{{.tdomain}}>
Call-ID: {{.callid}}
CSeq: {{.cseqnum}} {{.method}}
{{if .subject}}Subject: {{.subject}}{{else}}$rmeol{{end}}
{{if .date}}Date: {{.date}}{{else}}$rmeol{{end}}
{{if .contacturi}}Contact: {{.contacturi}}{{if .contactparams}};{{.contactparams}}{{end}}{{else}}$rmeol{{end}}
{{if .expires}}Expires: {{.expires}}{{else}}$rmeol{{end}}
{{if .useragent}}User-Agent: {{.useragent}}{{else}}$rmeol{{end}}
Content-Length: 0

Example SDP body template:

v=0{{.cr}}
o={{.sdpuser}} {{.sdpsessid}} {{.sdpsessversion}} IN {{.sdpaf}} {{.localip}}{{.cr}}
s=call{{.cr}}
c=IN {{.sdpaf}} {{.localip}}{{.cr}}
t=0 0{{.cr}}
m=audio {{.sdprtpport}} RTP 0 8 101{{.cr}}
a=rtpmap:0 pcmu/8000{{.cr}}
a=rtpmap:8 pcma/8000{{.cr}}
a=rtpmap:101 telephone-event/8000{{.cr}}
a=sendrecv{{.cr}}

The internal templates can be found at the top of sipexer.go file:

Template Fields

The fields file has to contain a JSON document with the fields to be replaced in the template file. The path to the JSON file is provided via -ff or --fields-file parameters.

When the --fields-eval of -fe cli option is provided, sipexer evaluates the values of the fields in the root structure of the JSON document. That means special tokens (expressions) are replaced if the value of the field is a string matching one of the next:

When internal template is used, --fields-eval is turned on.

Example fields file:

{
    "method": "OPTIONS",
    "fuser": "alice",
    "fdomain": "localhost",
    "tuser": "bob",
    "tdomain": "localhost",
    "viabranch": "$uuid",
    "rport": ";rport",
    "fromtag": "$uuid",
    "totag": "",
    "callid": "$uuid",
    "cseqnum": "$randseq",
    "date": "$daterfc1123",
    "sdpuser": "sipexer",
    "sdpsessid": "$timestamp",
    "sdpsessversion": "$timestamp",
    "sdpaf": "IP4",
    "sdprtpport": "$rand(20000,40000)"
}

The internal fields data can be found at the top of sipexer.go file.

The values for fields can be also provided using --field-val or -fv cli parameter, in format name:value, for example:

sipexer --field-val="domain:openrcs.com" ...

The value provided via --field-val overwrites the value provided in the JSON fields file.

When sending out, before the template is evaluated, the following fields are also added internally and will replace the corresponding {{.name}} (e.g., {{.proto}}) in the template:

Alternatives

There are several alternatives that might be useful to consider:

License

GPLv3

Copyright: Daniel-Constantin Mierla (Asipto)

Contributions

Contributions are welcome!

Fork and do pull requests: