drop files unrelated to osmo-bsc

These either remain from openbsc.git or slipped in while applying recent
patches from openbsc.git and do not belong in osmo-bsc.

Empty out contrib: remove things that are either obviously unrelated to
osmo-bsc, or seem old and/or esoteric.

osmoappdesc.py: drop nitb_e1_configs (and some ws)

Change-Id: Ib20064f35e623d99c7d59496a3156e84b8a0d07a
changes/95/3795/3
Neels Hofmeyr 2017-09-04 03:27:02 +02:00
parent 630df7d608
commit 5282a81323
56 changed files with 0 additions and 3037 deletions

View File

@ -1 +0,0 @@
Some crazy scripts call testing... and MSC link failure simulation

View File

@ -1,8 +0,0 @@
ABORT BUSY
ABORT 'NO CARRIER'
ABORT 'OK'
'' AT
SAY "Dialing a number\n"
'OK' ATD05660066;

View File

@ -1,11 +0,0 @@
#!/bin/sh
# Evil dial script..
while true;
do
chat -v -f all_dial < /dev/ttyACM0 > /dev/ttyACM0
sleep 5s
chat -v -f hangup < /dev/ttyACM0 > /dev/ttyACM0
sleep 2s
done

View File

@ -1,6 +0,0 @@
#!/bin/sh
sleep 3
echo "enable"
sleep 1
echo "drop bts connection 0 oml"
sleep 1

View File

@ -1,8 +0,0 @@
#!/bin/sh
while true;
do
echo "Going to drop the OML connection"
./drop-oml.sh | telnet 127.0.0.1 4242
sleep 58m
done

View File

@ -1,4 +0,0 @@
TIMEOUT 10
'' ^Z
SAY "Waiting for hangup confirm\n"
'' ATH;

View File

@ -1,8 +0,0 @@
#!/bin/sh
while true;
do
echo "Kill the osmo-bsc"
/usr/bin/kill -s SIGUSR2 `pidof osmo-bsc`
sleep 58s
done

View File

@ -1,33 +0,0 @@
#!/usr/bin/env python
import os
f = open("unbalanced")
lines = []
for line in f:
lines.append(line)
filenames = {}
output = []
for line in lines:
if "[0x" in line:
start = line.find("[")
end = line.find("]")
addr = line[start+1:end]
try:
file = filenames[addr]
except KeyError:
r = os.popen("addr2line -fs -e ./bsc_hack %s" % addr)
all = r.read().replace("\n", ",")
file = all
filenames[addr] = file
line = line.replace(addr, file)
output.append(line)
g = open("unbalanced.2", "w")
g.write("".join(output))

View File

@ -1,37 +0,0 @@
#!/usr/bin/env python
#
# Convert ETSI documents to an enum
#
import re, sys
def convert(string):
string = string.strip().replace(" ", "").rjust(8, "0")
var = 0
offset = 7
for char in string:
assert offset >= 0
var = var | (int(char) << offset)
offset = offset - 1
return var
def string(name):
name = name.replace(" ", "_")
name = name.replace('"', "")
name = name.replace('/', '_')
name = name.replace('(', '_')
name = name.replace(')', '_')
return "%s_%s" % (sys.argv[2], name.upper())
file = open(sys.argv[1])
for line in file:
m = re.match(r"[ \t]*(?P<value>[01 ]+)[ ]+(?P<name>[a-zA-Z /0-9()]+)", line[:-1])
if m:
print "\t%s\t\t= %d," % (string(m.groupdict()["name"]), convert(m.groupdict()["value"]))
else:
print line[:-1]

View File

@ -1,147 +0,0 @@
#!/usr/bin/python2
mod_license = '''
/*
* Copyright (C) 2016 sysmocom s.f.m.c. GmbH
*
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
'''
import sys, argparse, random, logging, tornado.ioloop, tornado.web, tornado.tcpclient, tornado.httpclient, eventsource, bsc_control
from eventsource import listener, request
'''
N. B: this is not an example of building proper REST API or building secure web application.
It's only purpose is to illustrate conversion of Osmocom's Control Interface to web-friendly API.
Exposing this to Internet while connected to production network might lead to all sorts of mischief and mayhem
from NSA' TAO breaking into your network to zombie apocalypse. Do NOT do that.
'''
token = None
stream = None
url = None
'''
Returns json according to following schema - see http://json-schema.org/documentation.html for details:
{
"title": "Ctrl Schema",
"type": "object",
"properties": {
"variable": {
"type": "string"
},
"varlue": {
"type": "string"
}
},
"required": ["interface", "variable", "value"]
}
Example validation from command-line:
json validate --schema-file=schema.json --document-file=data.json
The interface is represented as string because it might look different for IPv4 vs v6.
'''
def read_header(data):
t_length = bsc_control.ipa_ctrl_header(data)
if (t_length):
stream.read_bytes(t_length - 1, callback = read_trap)
else:
print >> sys.stderr, "protocol error: length missing in %s!" % data
@tornado.gen.coroutine
def read_trap(data):
(t, z, v, p) = data.split()
if (t != 'TRAP' or int(z) != 0):
print >> sys.stderr, "protocol error: TRAP != %s or 0! = %d" % (t, int(z))
else:
yield tornado.httpclient.AsyncHTTPClient().fetch(tornado.httpclient.HTTPRequest(url = "%s/%s/%s" % (url, "ping", token),
method = 'POST',
headers = {'Content-Type': 'application/json'},
body = tornado.escape.json_encode({ 'variable' : v, 'value' : p })))
stream.read_bytes(4, callback = read_header)
@tornado.gen.coroutine
def trap_setup(host, port, target_host, target_port, tk):
global stream
global url
global token
token = tk
url = "http://%s:%s/sse" % (host, port)
stream = yield tornado.tcpclient.TCPClient().connect(target_host, target_port)
stream.read_bytes(4, callback = read_header)
def get_v(s, v):
return { 'variable' : v, 'value' : bsc_control.get_var(s, tornado.escape.native_str(v)) }
class CtrlHandler(tornado.web.RequestHandler):
def initialize(self):
self.skt = bsc_control.connect(self.settings['ctrl_host'], self.settings['ctrl_port'])
def get(self, v):
self.write(get_v(self.skt, v))
def post(self):
self.write(get_v(self.skt, self.get_argument("variable")))
class SetCtrl(CtrlHandler):
def get(self, var, val):
bsc_control.set_var(self.skt, tornado.escape.native_str(var), tornado.escape.native_str(val))
super(SetCtrl, self).get(tornado.escape.native_str(var))
def post(self):
bsc_control.set_var(self.skt, tornado.escape.native_str(self.get_argument("variable")), tornado.escape.native_str(self.get_argument("value")))
super(SetCtrl, self).post()
class Slash(tornado.web.RequestHandler):
def get(self):
self.write('<html><head><title>%s</title></head><body>Using Tornado framework v%s'
'<form action="/get" method="POST">'
'<input type="text" name="variable">'
'<input type="submit" value="GET">'
'</form>'
'<form action="/set" method="POST">'
'<input type="text" name="variable">'
'<input type="text" name="value">'
'<input type="submit" value="SET">'
'</form>'
'</body></html>' % ("Osmocom Control Interface Proxy", tornado.version))
if __name__ == '__main__':
p = argparse.ArgumentParser(description='Osmocom Control Interface proxy.')
p.add_argument('-c', '--control-port', type = int, default = 4252, help = "Target Control Interface port")
p.add_argument('-a', '--control-host', default = 'localhost', help = "Target Control Interface adress")
p.add_argument('-b', '--host', default = 'localhost', help = "Adress to bind proxy's web interface")
p.add_argument('-p', '--port', type = int, default = 6969, help = "Port to bind proxy's web interface")
p.add_argument('-d', '--debug', action='store_true', help = "Activate debugging (default off)")
p.add_argument('-t', '--token', default = 'osmocom', help = "Token to be used by SSE client in URL e. g. http://127.0.0.1:8888/poll/osmocom where 'osmocom' is default token value")
p.add_argument('-k', '--keepalive', type = int, default = 5000, help = "Timeout betwwen keepalive messages, in milliseconds, defaults to 5000")
args = p.parse_args()
random.seed()
tornado.netutil.Resolver.configure('tornado.netutil.ThreadedResolver') # Use non-blocking resolver
logging.basicConfig()
application = tornado.web.Application([
(r"/", Slash),
(r"/get", CtrlHandler),
(r"/get/(.*)", CtrlHandler),
(r"/set", SetCtrl),
(r"/set/(.*)/(.*)", SetCtrl),
(r"/sse/(.*)/(.*)", listener.EventSourceHandler, dict(event_class = listener.JSONIdEvent, keepalive = args.keepalive)),
], debug = args.debug, ctrl_host = args.control_host, ctrl_port = args.control_port)
application.listen(address = args.host, port = args.port)
trap_setup(args.host, args.port, application.settings['ctrl_host'], application.settings['ctrl_port'], args.token)
tornado.ioloop.IOLoop.instance().start()

View File

@ -1,58 +0,0 @@
#!/usr/bin/env python
"""
demonstrate a unblock bug on the GB Proxy..
"""
bts_ns_reset = "\x02\x00\x81\x01\x01\x82\x1f\xe7\x04\x82\x1f\xe7"
ns_reset_ack = "\x03\x01\x82\x1f\xe7\x04\x82\x1f\xe7"
bts_ns_unblock = "\x06"
ns_unblock_ack = "\x07"
bts_bvc_reset_0 = "\x00\x00\x00\x00\x22\x04\x82\x00\x00\x07\x81\x03\x3b\x81\x02"
ns_bvc_reset_0_ack = "\x00\x00\x00\x00\x23\x04\x82\x00\x00"
bts_bvc_reset_8167 = "\x00\x00\x00\x00\x22\x04\x82\x1f\xe7\x07\x81\x08\x08\x88\x72\xf4\x80\x10\x1c\x00\x9c\x40"
import socket
socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
socket.bind(("0.0.0.0", 0))
socket.setblocking(1)
import sys
port = int(sys.argv[1])
print "Sending data to port: %d" % port
def send_and_receive(packet):
socket.sendto(packet, ("127.0.0.1", port))
try:
data, addr = socket.recvfrom(4096)
except socket.error, e:
print "ERROR", e
import sys
sys.exit(0)
return data
#send stuff once
to_send = [
(bts_ns_reset, ns_reset_ack, "reset ack"),
(bts_ns_unblock, ns_unblock_ack, "unblock ack"),
(bts_bvc_reset_0, ns_bvc_reset_0_ack, "BVCI=0 reset ack"),
]
for (out, inp, type) in to_send:
res = send_and_receive(out)
if res != inp:
print "Failed to get the %s" % type
sys.exit(-1)
import time
time.sleep(3)
res = send_and_receive(bts_bvc_reset_8167)
print "Sent all messages... check wireshark for the last response"

View File

@ -1,78 +0,0 @@
-- Simple LUA script to print the size of BSSGP messages over their type...
do
local ip_bucket = {}
local pdu_types = {}
pdu_types[ 6] = "PAGING"
pdu_types[11] = "SUSPEND"
pdu_types[12] = "SUSPEND-ACK"
pdu_types[32] = "BVC-BLOCK"
pdu_types[33] = "BVC-BLOCK-ACK"
pdu_types[34] = "BVC-RESET"
pdu_types[35] = "BVC-RESET-ACK"
pdu_types[36] = "UNBLOCK"
pdu_types[37] = "UNBLOCK-ACK"
pdu_types[38] = "FLOW-CONTROL-BVC"
pdu_types[39] = "FLOW-CONTROL-BVC-ACK"
pdu_types[40] = "FLOW-CONTROL-MS"
pdu_types[41] = "FLOW-CONTROL-MS-ACK"
pdu_types[44] = "LLC-DISCARDED"
local function init_listener()
-- handle the port as NS over IP
local udp_port_table = DissectorTable.get("udp.port")
local gprs_ns_dis = Dissector.get("gprs_ns")
udp_port_table:add(23000,gprs_ns_dis)
-- bssgp filters
local bssgp_pdu_get = Field.new("bssgp.pdu_type")
local udp_length_get = Field.new("udp.length")
local tap = Listener.new("ip", "udp.port == 23000")
function tap.packet(pinfo,tvb,ip)
local pdu = bssgp_pdu_get()
local len = udp_length_get()
-- only handle bssgp, but we also want the IP frame
if not pdu then
return
end
pdu = tostring(pdu)
if tonumber(pdu) == 0 or tonumber(pdu) == 1 then
return
end
local ip_src = tostring(ip.ip_src)
local bssgp_histo = ip_bucket[ip_src]
if not bssgp_histo then
bssgp_histo = {}
ip_bucket[ip_src] = bssgp_histo
end
local key = pdu
local bucket = bssgp_histo[key]
if not bucket then
bucket = {}
bssgp_histo[key] = bucket
end
table.insert(bucket, tostring(len))
print("IP: " .. ip_src .. " PDU: " .. pdu_types[tonumber(pdu)] .. " Length: " .. tostring(len))
end
function tap.draw()
-- well... this will not be called...
-- for ip,bssgp_histo in pairs(dumpers) do
-- print("IP " .. ip)
-- end
end
function tap.reset()
-- well... this will not be called...
end
end
init_listener()
end

View File

@ -1,80 +0,0 @@
-- I count the buffer space needed for LLC PDUs in the worse case and print it
do
local function init_listener()
-- handle the port as NS over IP
local udp_port_table = DissectorTable.get("udp.port")
local gprs_ns_dis = Dissector.get("gprs_ns")
udp_port_table:add(23000,gprs_ns_dis)
-- bssgp filters
local bssgp_pdu_get = Field.new("bssgp.pdu_type")
local bssgp_delay_get = Field.new("bssgp.delay_val")
local llcgprs_get = Field.new("llcgprs")
local pdus = nil
print("START...")
local tap = Listener.new("ip", "udp.port == 23000 && bssgp.pdu_type == 0")
function tap.packet(pinfo,tvb,ip)
local pdu = bssgp_pdu_get()
local len = llcgprs_get().len
local delay = bssgp_delay_get()
-- only handle bssgp, but we also want the IP frame
if not pdu then
return
end
if tonumber(tostring(delay)) == 65535 then
pdus = { next = pdus,
len = len,
expires = -1 }
else
local off = tonumber(tostring(delay)) / 100.0
pdus = { next = pdus,
len = len,
expires = pinfo.rel_ts + off }
end
local now_time = tonumber(tostring(pinfo.rel_ts))
local now_size = 0
local l = pdus
local prev = nil
local count = 0
while l do
if now_time < l.expires or l.expires == -1 then
now_size = now_size + l.len
prev = l
l = l.next
count = count + 1
else
-- delete things
if prev == nil then
pdus = nil
l = nil
else
prev.next = l.next
l = l.next
end
end
end
-- print("TOTAL: " .. now_time .. " PDU_SIZE: " .. now_size)
print(now_time .. " " .. now_size / 1024.0 .. " " .. count)
-- print("NOW: " .. tostring(pinfo.rel_ts) .. " Delay: " .. tostring(delay) .. " Length: " .. tostring(len))
end
function tap.draw()
-- well... this will not be called...
-- for ip,bssgp_histo in pairs(dumpers) do
-- print("IP " .. ip)
-- end
print("END")
end
function tap.reset()
-- well... this will not be called...
end
end
init_listener()
end

View File

@ -1,46 +0,0 @@
-- Create a file named by_ip/''ip_addess''.cap with all ip traffic of each ip host. (works for tshark only)
-- Dump files are created for both source and destination hosts
do
local dir = "by_tlli"
local dumpers = {}
local function init_listener()
local udp_port_table = DissectorTable.get("udp.port")
local gprs_ns_dis = Dissector.get("gprs_ns")
udp_port_table:add(23000,gprs_ns_dis)
local field_tlli = Field.new("bssgp.tlli")
local tap = Listener.new("ip", "udp.port == 23000")
-- we will be called once for every IP Header.
-- If there's more than one IP header in a given packet we'll dump the packet once per every header
function tap.packet(pinfo,tvb,ip)
local tlli = field_tlli()
if not tlli then
return
end
local tlli_str = tostring(tlli)
tlli_dmp = dumpers[tlli_str]
if not tlli_dmp then
local tlli_hex = string.format("0x%x", tonumber(tlli_str))
print("Creating dump for TLLI " .. tlli_hex)
tlli_dmp = Dumper.new_for_current(dir .. "/" .. tlli_hex .. ".pcap")
dumpers[tlli_str] = tlli_dmp
end
tlli_dmp:dump_current()
tlli_dmp:flush()
end
function tap.draw()
for tlli,dumper in pairs(dumpers) do
dumper:flush()
end
end
function tap.reset()
for tlli,dumper in pairs(dumpers) do
dumper:close()
end
dumpers = {}
end
end
init_listener()
end

View File

@ -1,59 +0,0 @@
-- This script verifies that the N(U) is increasing...
--
do
local nu_state_src = {}
local function init_listener()
-- handle the port as NS over IP
local udp_port_table = DissectorTable.get("udp.port")
local gprs_ns_dis = Dissector.get("gprs_ns")
udp_port_table:add(23000,gprs_ns_dis)
-- we want to look here...
local llc_sapi_get = Field.new("llcgprs.sapib")
local llc_nu_get = Field.new("llcgprs.nu")
local bssgp_tlli_get = Field.new("bssgp.tlli")
local tap = Listener.new("ip", "udp.port == 23000")
function tap.packet(pinfo,tvb,ip)
local llc_sapi = llc_sapi_get()
local llc_nu = llc_nu_get()
local bssgp_tlli = bssgp_tlli_get()
if not llc_sapi or not llc_nu or not bssgp_tlli then
return
end
local ip_src = tostring(ip.ip_src)
local bssgp_tlli = tostring(bssgp_tlli)
local llc_nu = tostring(llc_nu)
local llc_sapi = tostring(llc_sapi)
local src_key = ip_src .. "-" .. bssgp_tlli .. "-" .. llc_sapi
local last_nu = nu_state_src[src_key]
if not last_nu then
-- print("Establishing mapping for " .. src_key)
nu_state_src[src_key] = llc_nu
return
end
local function tohex(number)
return string.format("0x%x", tonumber(number))
end
nu_state_src[src_key] = llc_nu
if tonumber(last_nu) + 1 ~= tonumber(llc_nu) then
print("JUMP in N(U) on TLLI " .. tohex(bssgp_tlli) .. " and SAPI: " .. llc_sapi .. " src: " .. ip_src)
print("\t last: " .. last_nu .. " now: " .. llc_nu)
end
end
function tap.draw()
end
function tap.reset()
end
end
init_listener()
end

View File

@ -1,18 +0,0 @@
-- Remove old data from the database
DELETE FROM Subscriber
WHERE id != 1 AND datetime('now', '-10 days') > updated AND authorized != 1;
DELETE FROM Equipment
WHERE datetime('now', '-10 days') > updated;
DELETE FROM EquipmentWatch
WHERE datetime('now', '-10 days') > updated;
DELETE FROM SMS
WHERE datetime('now', '-10 days') > created;
DELETE FROM VLR
WHERE datetime('now', '-10 days') > updated;
DELETE FROM ApduBlobs
WHERE datetime('now', '-10 days') > created;
DELETE FROM Counters
WHERE datetime('now', '-10 days') > timestamp;
DELETE FROM RateCounters
WHERE datetime('now', '-10 days') > timestamp;
VACUUM;

View File

@ -1,125 +0,0 @@
#!/usr/bin/python2.5
from __future__ import with_statement
from pysqlite2 import dbapi2 as sqlite3
import sys
hlr = sqlite3.connect(sys.argv[1])
web = sqlite3.connect(sys.argv[2])
# switch to autocommit
hlr.isolation_level = None
web.isolation_level = None
hlr.row_factory = sqlite3.Row
web.row_factory = sqlite3.Row
with hlr:
hlr_subscrs = hlr.execute("""
SELECT * FROM Subscriber
""").fetchall()
hlr_tokens = hlr.execute("""
SELECT * FROM AuthToken
""").fetchall()
with web:
web_tokens = web.execute("""
SELECT * FROM reg_tokens
""").fetchall()
web_sms = web.execute("""
SELECT * FROM sms_queue
""").fetchall()
# index by subscr id
hlr_subscrs_by_id = {}
hlr_subscrs_by_ext = {}
hlr_tokens_by_subscr_id = {}
for x in hlr_subscrs:
hlr_subscrs_by_id[x['id']] = x
hlr_subscrs_by_ext[x['extension']] = x
del hlr_subscrs
for x in hlr_tokens:
hlr_tokens_by_subscr_id[x['subscriber_id']] = x
del hlr_tokens
web_tokens_by_subscr_id = {}
for x in web_tokens:
web_tokens_by_subscr_id[x['subscriber_id']] = x
del web_tokens
# remove leftover web_tokens and correct inconsistent fields
with web:
for x in web_tokens_by_subscr_id.values():
subscr = hlr_subscrs_by_id.get(x['subscriber_id'], None)
if subscr is None:
web.execute("""
DELETE FROM reg_tokens WHERE subscriber_id = ?
""", (x['subscriber_id'],))
del web_tokens_by_subscr_id[x['subscriber_id']]
continue
if str(x['imsi']) != str(subscr['imsi']) or \
x['extension'] != subscr['extension'] or \
x['tmsi'] != subscr['tmsi'] or \
x['lac'] != subscr['lac']:
web.execute("""
UPDATE reg_tokens
SET imsi = ?, extension = ?, tmsi = ?, lac = ?
WHERE subscriber_id = ?
""", (str(subscr['imsi']), subscr['extension'],
subscr['tmsi'], subscr['lac'], x['subscriber_id']))
# add missing web_tokens
with web:
for x in hlr_tokens_by_subscr_id.values():
subscr = hlr_subscrs_by_id.get(x['subscriber_id'], None)
if subscr is None:
hlr.execute("""
DELETE FROM AuthToken WHERE subscriber_id = ?
""", (x['subscriber_id'],))
del hlr_tokens_by_subscr_id[x['subscriber_id']]
continue
webtoken = web_tokens_by_subscr_id.get(x['subscriber_id'], None)
if webtoken is None:
web.execute("""
INSERT INTO reg_tokens
(subscriber_id, extension, reg_completed, name, email, lac, imsi, token, tmsi)
VALUES
(?, ?, 0, ?, '', ?, ?, ?, ?)
""", (x['subscriber_id'], subscr['extension'], subscr['name'],
subscr['lac'], str(subscr['imsi']), x['token'], subscr['tmsi']))
# authorize subscribers
with hlr:
for x in web_tokens_by_subscr_id.values():
subscr = hlr_subscrs_by_id.get(x['subscriber_id'], None)
if x['reg_completed'] and not subscr['authorized']:
hlr.execute("""
UPDATE Subscriber
SET authorized = 1
WHERE id = ?
""", (x['subscriber_id'],))
# Sync SMS from web to hlr
with hlr:
for sms in web_sms:
subscr = hlr_subscrs_by_ext.get(sms['receiver_ext'])
if subscr is None:
print '%s not found' % sms['receiver_ext']
continue
hlr.execute("""
INSERT INTO SMS
(created, sender_id, receiver_id, reply_path_req, status_rep_req, protocol_id, data_coding_scheme, ud_hdr_ind, text)
VALUES
(?, 1, ?, 0, 0, 0, 0, 0, ?)
""", (sms['created'], subscr['id'], sms['text']))
with web:
for sms in web_sms:
web.execute("""
DELETE FROM sms_queue WHERE id = ?
""", (sms['id'],))
hlr.close()
web.close()

View File

@ -1,60 +0,0 @@
#!/usr/bin/env python
# Simple server for mgcp... send audit, receive response..
import socket, time
MGCP_GATEWAY_PORT = 2427
MGCP_CALLAGENT_PORT = 2727
rsip_resp = """200 321321332\r\n"""
audit_packet = """AUEP %d 13@mgw MGCP 1.0\r\n"""
crcx_packet = """CRCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nL: p:20, a:GSM-EFR, nt:IN\r\nM: recvonly\r\n"""
dlcx_packet = """DLCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nI: %d\r\n"""
mdcx_packet = """MDCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nI: %d\r\nL: p:20, a:GSM-EFR, nt:IN\r\nM: recvonly\r\n\r\nv=0\r\no=- 258696477 0 IN IP4 172.16.1.107\r\ns=-\r\nc=IN IP4 172.16.1.107\r\nt=0 0\r\nm=audio 6666 RTP/AVP 127\r\na=rtpmap:127 GSM-EFR/8000/1\r\na=ptime:20\r\na=recvonly\r\nm=image 4402 udptl t38\r\na=T38FaxVersion:0\r\na=T38MaxBitRate:14400\r\n"""
def hexdump(src, length=8):
"""Recipe is from http://code.activestate.com/recipes/142812/"""
result = []
digits = 4 if isinstance(src, unicode) else 2
for i in xrange(0, len(src), length):
s = src[i:i+length]
hexa = b' '.join(["%0*X" % (digits, ord(x)) for x in s])
text = b''.join([x if 0x20 <= ord(x) < 0x7F else b'.' for x in s])
result.append( b"%04X %-*s %s" % (i, length*(digits + 1), hexa, text) )
return b'\n'.join(result)
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind(("127.0.0.1", MGCP_CALLAGENT_PORT))
server_socket.setblocking(1)
last_ci = 1
def send_and_receive(packet):
global last_ci
server_socket.sendto(packet, ("127.0.0.1", MGCP_GATEWAY_PORT))
try:
data, addr = server_socket.recvfrom(4096)
# attempt to store the CI of the response
list = data.split("\n")
for item in list:
if item.startswith("I: "):
last_ci = int(item[3:])
print hexdump(data), addr
except socket.error, e:
print e
pass
def generate_tid():
import random
return random.randint(0, 65123)
while True:
send_and_receive(audit_packet % generate_tid())
send_and_receive(crcx_packet % generate_tid() )
send_and_receive(mdcx_packet % (generate_tid(), last_ci))
send_and_receive(dlcx_packet % (generate_tid(), last_ci))
time.sleep(3)

View File

@ -1,30 +0,0 @@
/* make test_regexp */
#include <sys/types.h>
#include <regex.h>
#include <stdio.h>
int main(int argc, char **argv)
{
regex_t reg;
regmatch_t matches[2];
if (argc != 4) {
printf("Invoke with: test_regexp REGEXP REPLACE NR\n");
return -1;
}
if (regcomp(&reg, argv[1], REG_EXTENDED) != 0) {
fprintf(stderr, "Regexp '%s' is not valid.\n", argv[1]);
return -1;
}
if (regexec(&reg, argv[3], 2, matches, 0) == 0 && matches[1].rm_eo != -1)
printf("New Number: %s%s\n", argv[2], &argv[3][matches[1].rm_so]);
else
printf("No match.\n");
regfree(&reg);
return 0;
}

View File

@ -1,65 +0,0 @@
#!/usr/bin/env python2.7
"""
AGPLv3+ 2016 Copyright Holger Hans Peter Freyther
Example of how to connect to the USSD side-channel and how to respond
with a fixed message.
"""
import socket
import struct
ussdSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ussdSocket.connect(('127.0.0.1', 5001))
def send_dt1(dstref, data):
dlen = struct.pack('B', len(data)).encode('hex')
hex = '06' + dstref.encode('hex') + '00' + '01' + dlen + data.encode('hex')
pdata = hex.decode('hex')
out = struct.pack('>HB', len(pdata), 0xfd) + pdata
ussdSocket.send(out)
def send_rel(srcref, dstref):
hex = '04' + dstref.encode('hex') + srcref.encode('hex') + '000100'
pdata = hex.decode('hex')
out = struct.pack('>HB', len(pdata), 0xfd) + pdata
ussdSocket.send(out)
def recv_one():
plen = ussdSocket.recv(3)
(plen,ptype) = struct.unpack(">HB", plen)
data = ussdSocket.recv(plen)
return ptype, data
# Assume this is the ID request
data = ussdSocket.recv(4)
ussdSocket.send("\x00\x08\xfe\x05\x00" + "\x05\x01" + "ussd")
# ^len ^len of tag ... and ignore
# Expect a fake message. see struct ipac_msgt_sccp_state
ptype, data = recv_one()
print("%d %s" % (ptype, data.encode('hex')))
(srcref, dstref, transid, invokeid) = struct.unpack("<3s3sBB", data[1:9])
print("New transID %d invoke %d" % (transid, invokeid))
# Expect a the invocation.. todo.. extract invoke id
ptype, data = recv_one()
print("%d %s" % (ptype, data.encode('hex')))
# Reply with BSSAP + GSM 04.08 + MAP portion
# 00 == invoke id 0f == DCS
res = "01002a9b2a0802e1901c22a220020100301b02013b301604010f041155e7d2f9bc3a41412894991c06a9c9a713"
send_dt1(dstref, res.decode('hex'))
clear = "000420040109"
send_dt1(dstref, clear.decode('hex'))
# should be the clear complete
send_rel(srcref, dstref)
# Give it some time to handle connection shutdown properly
print("Gracefully sleeping")
import time
time.sleep(3)

View File

@ -1,420 +0,0 @@
#!/usr/bin/env escript
%% -*- erlang -*-
%%! -smp disable
-module(gen_rtp_header).
% -mode(compile).
-define(VERSION, "0.1").
-export([main/1]).
-record(rtp_packet,
{
version = 2,
padding = 0,
marker = 0,
payload_type = 0,
seqno = 0,
timestamp = 0,
ssrc = 0,
csrcs = [],
extension = <<>>,
payload = <<>>,
realtime
}).
main(Args) ->
DefaultOpts = [{format, state},
{ssrc, 16#11223344},
{rate, 8000},
{pt, 98}],
{PosArgs, Opts} = getopts_checked(Args, DefaultOpts),
log(debug, fun (Dev) ->
io:format(Dev, "Initial options:~n", []),
dump_opts(Dev, Opts),
io:format(Dev, "~s: ~p~n", ["Args", PosArgs])
end, [], Opts),
main(PosArgs, Opts).
main([First | RemArgs], Opts) ->
try
F = list_to_integer(First),
Format = proplists:get_value(format, Opts, state),
PayloadData = proplists:get_value(payload, Opts, undef),
InFile = proplists:get_value(file, Opts, undef),
Payload = case {PayloadData, InFile} of
{undef, undef} ->
% use default value
#rtp_packet{}#rtp_packet.payload;
{P, undef} -> P;
{_, File} ->
log(info, "Loading file '~s'~n", [File], Opts),
{ok, InDev} = file:open(File, [read]),
DS = [ Pl#rtp_packet.payload || {_T, Pl} <- read_packets(InDev, Opts)],
file:close(InDev),
log(debug, "File '~s' closed, ~w packets read.~n", [File, length(DS)], Opts),
DS
end,
Dev = standard_io,
write_packet_pre(Dev, Format),
do_groups(Dev, Payload, F, RemArgs, Opts),
write_packet_post(Dev, Format),
0
catch
_:_ ->
log(debug, "~p~n", [hd(erlang:get_stacktrace())], Opts),
usage(),
halt(1)
end
;
main(_, _Opts) ->
usage(),
halt(1).
%%% group (count + offset) handling %%%
do_groups(_Dev, _Pl, _F, [], _Opts) ->
ok;
do_groups(Dev, Pl, F, [L], Opts) ->
do_groups(Dev, Pl, F, [L, 0], Opts);
do_groups(Dev, Pl, First, [L, O | Args], Opts) ->
Ssrc = proplists:get_value(ssrc, Opts, #rtp_packet.ssrc),
PT = proplists:get_value(pt, Opts, #rtp_packet.payload_type),
Len = list_to_num(L),
Offs = list_to_num(O),
log(info, "Starting group: Ssrc=~.16B, PT=~B, First=~B, Len=~B, Offs=~B~n",
[Ssrc, PT, First, Len, Offs], Opts),
Pkg = #rtp_packet{ssrc = Ssrc, payload_type = PT},
Pl2 = write_packets(Dev, Pl, Pkg, First, Len, Offs, Opts),
{Args2, Opts2} = getopts_checked(Args, Opts),
log(debug, fun (Io) ->
io:format(Io, "Changed options:~n", []),
dump_opts(Io, Opts2 -- Opts)
end, [], Opts),
do_groups(Dev, Pl2, First+Len, Args2, Opts2).
%%% error handling helpers %%%
getopts_checked(Args, Opts) ->
try
getopts(Args, Opts)
catch
C:R ->
log(error, "~s~n",
[explain_error(C, R, erlang:get_stacktrace(), Opts)], Opts),
usage(),
halt(1)
end.
explain_error(error, badarg, [{erlang,list_to_integer,[S,B]} | _ ], _Opts) ->
io_lib:format("Invalid number '~s' (base ~B)", [S, B]);
explain_error(error, badarg, [{erlang,list_to_integer,[S]} | _ ], _Opts) ->
io_lib:format("Invalid decimal number '~s'", [S]);
explain_error(C, R, [Hd | _ ], _Opts) ->
io_lib:format("~p, ~p:~p", [Hd, C, R]);
explain_error(_, _, [], _Opts) ->
"".
%%% usage and options %%%
myname() ->
filename:basename(escript:script_name()).
usage(Text) ->
io:format(standard_error, "~s: ~s~n", [myname(), Text]),
usage().
usage() ->
io:format(standard_error,
"Usage: ~s [Options] Start Count1 Offs1 [[Options] Count2 Offs2 ...]~n",
[myname()]).
show_version() ->
io:format(standard_io,
"~s ~s~n", [myname(), ?VERSION]).
show_help() ->
io:format(standard_io,
"Usage: ~s [Options] Start Count1 Offs1 [[Options] Count2 Offs2 ...]~n~n" ++
"Options:~n" ++
" -h, --help this text~n" ++
" --version show version info~n" ++
" -i, --file=FILE reads payload from file (state format by default)~n" ++
" -f, --frame-size=N read payload as binary frames of size N instead~n" ++
" -p, --payload=HEX set constant payload~n" ++
" --verbose=N set verbosity~n" ++
" -v increase verbosity~n" ++
" --format=state use state format for output (default)~n" ++
" -C, --format=c use simple C lines for output~n" ++
" --format=carray use a C array for output~n" ++
" -s, --ssrc=SSRC set the SSRC~n" ++
" -t, --type=N set the payload type~n" ++
" -r, --rate=N set the RTP rate [8000]~n" ++
" -D, --duration=N set the packet duration in RTP time units [160]~n" ++
" -d, --delay=FLOAT add offset to playout timestamp~n" ++
"~n" ++
"Arguments:~n" ++
" Start initial packet (sequence) number~n" ++
" Count number of packets~n" ++
" Offs timestamp offset (in RTP units)~n" ++
"", [myname()]).
getopts([ "--file=" ++ File | R], Opts) ->
getopts(R, [{file, File} | Opts]);
getopts([ "-i" ++ T | R], Opts) ->
getopts_alias_arg("--file", T, R, Opts);
getopts([ "--frame-size=" ++ N | R], Opts) ->
Size = list_to_integer(N),
getopts(R, [{frame_size, Size}, {in_format, bin} | Opts]);
getopts([ "-f" ++ T | R], Opts) ->
getopts_alias_arg("--frame-size", T, R, Opts);
getopts([ "--duration=" ++ N | R], Opts) ->
Duration = list_to_integer(N),
getopts(R, [{duration, Duration} | Opts]);
getopts([ "-D" ++ T | R], Opts) ->
getopts_alias_arg("--duration", T, R, Opts);
getopts([ "--rate=" ++ N | R], Opts) ->
Rate = list_to_integer(N),
getopts(R, [{rate, Rate} | Opts]);
getopts([ "-r" ++ T | R], Opts) ->
getopts_alias_arg("--rate", T, R, Opts);
getopts([ "--version" | _], _Opts) ->
show_version(),
halt(0);
getopts([ "--help" | _], _Opts) ->
show_help(),
halt(0);
getopts([ "-h" ++ T | R], Opts) ->
getopts_alias_no_arg("--help", T, R, Opts);
getopts([ "--verbose=" ++ V | R], Opts) ->
Verbose = list_to_integer(V),
getopts(R, [{verbose, Verbose} | Opts]);
getopts([ "-v" ++ T | R], Opts) ->
Verbose = proplists:get_value(verbose, Opts, 0),
getopts_short_no_arg(T, R, [ {verbose, Verbose+1} | Opts]);
getopts([ "--format=state" | R], Opts) ->
getopts(R, [{format, state} | Opts]);
getopts([ "--format=c" | R], Opts) ->
getopts(R, [{format, c} | Opts]);
getopts([ "-C" ++ T | R], Opts) ->
getopts_alias_no_arg("--format=c", T, R, Opts);
getopts([ "--format=carray" | R], Opts) ->
getopts(R, [{format, carray} | Opts]);
getopts([ "--payload=" ++ Hex | R], Opts) ->
getopts(R, [{payload, hex_to_bin(Hex)} | Opts]);
getopts([ "--ssrc=" ++ Num | R], Opts) ->
getopts(R, [{ssrc, list_to_num(Num)} | Opts]);
getopts([ "-s" ++ T | R], Opts) ->
getopts_alias_arg("--ssrc", T, R, Opts);
getopts([ "--type=" ++ Num | R], Opts) ->
getopts(R, [{pt, list_to_num(Num)} | Opts]);
getopts([ "-t" ++ T | R], Opts) ->
getopts_alias_arg("--type", T, R, Opts);
getopts([ "--delay=" ++ Num | R], Opts) ->
getopts(R, [{delay, list_to_float(Num)} | Opts]);
getopts([ "-d" ++ T | R], Opts) ->
getopts_alias_arg("--delay", T, R, Opts);
% parsing helpers
getopts([ "--" | R], Opts) ->
{R, normalize_opts(Opts)};
getopts([ O = "--" ++ _ | _], _Opts) ->
usage("Invalid option: " ++ O),
halt(1);
getopts([ [ $-, C | _] | _], _Opts) when C < $0; C > $9 ->
usage("Invalid option: -" ++ [C]),
halt(1);
getopts(R, Opts) ->
{R, normalize_opts(Opts)}.
getopts_short_no_arg([], R, Opts) -> getopts(R, Opts);
getopts_short_no_arg(T, R, Opts) -> getopts([ "-" ++ T | R], Opts).
getopts_alias_no_arg(A, [], R, Opts) -> getopts([A | R], Opts);
getopts_alias_no_arg(A, T, R, Opts) -> getopts([A, "-" ++ T | R], Opts).
getopts_alias_arg(A, [], [T | R], Opts) -> getopts([A ++ "=" ++ T | R], Opts);
getopts_alias_arg(A, T, R, Opts) -> getopts([A ++ "=" ++ T | R], Opts).
normalize_opts(Opts) ->
[ proplists:lookup(E, Opts) || E <- proplists:get_keys(Opts) ].
%%% conversions %%%
bin_to_hex(Bin) -> [hd(integer_to_list(N,16)) || <<N:4>> <= Bin].
hex_to_bin(Hex) -> << <<(list_to_integer([Nib],16)):4>> || Nib <- Hex>>.
list_to_num("-" ++ Str) -> -list_to_num(Str);
list_to_num("0x" ++ Str) -> list_to_integer(Str, 16);
list_to_num("0b" ++ Str) -> list_to_integer(Str, 2);
list_to_num(Str = [ $0 | _ ]) -> list_to_integer(Str, 8);
list_to_num(Str) -> list_to_integer(Str, 10).
%%% dumping data %%%
dump_opts(Dev, Opts) ->
dump_opts2(Dev, Opts, proplists:get_keys(Opts)).
dump_opts2(Dev, Opts, [OptName | R]) ->
io:format(Dev, " ~-10s: ~p~n",
[OptName, proplists:get_value(OptName, Opts)]),
dump_opts2(Dev, Opts, R);
dump_opts2(_Dev, _Opts, []) -> ok.
%%% logging %%%
log(L, Fmt, Args, Opts) when is_list(Opts) ->
log(L, Fmt, Args, proplists:get_value(verbose, Opts, 0), Opts).
log(debug, Fmt, Args, V, Opts) when V > 2 -> log2("DEBUG", Fmt, Args, Opts);
log(info, Fmt, Args, V, Opts) when V > 1 -> log2("INFO", Fmt, Args, Opts);
log(notice, Fmt, Args, V, Opts) when V > 0 -> log2("NOTICE", Fmt, Args, Opts);
log(warn, Fmt, Args, _V, Opts) -> log2("WARNING", Fmt, Args, Opts);
log(error, Fmt, Args, _V, Opts) -> log2("ERROR", Fmt, Args, Opts);
log(Lvl, Fmt, Args, V, Opts) when V >= Lvl -> log2("", Fmt, Args, Opts);
log(_, _, _, _i, _) -> ok.
log2(Type, Fmt, Args, _Opts) when is_list(Fmt) ->
io:format(standard_error, "~s: " ++ Fmt, [Type | Args]);
log2("", Fmt, Args, _Opts) when is_list(Fmt) ->
io:format(standard_error, Fmt, Args);
log2(_Type, Fun, _Args, _Opts) when is_function(Fun, 1) ->
Fun(standard_error).
%%% RTP packets %%%
make_rtp_packet(P = #rtp_packet{version = 2}) ->
<< (P#rtp_packet.version):2,
0:1, % P
0:1, % X
0:4, % CC
(P#rtp_packet.marker):1,
(P#rtp_packet.payload_type):7,
(P#rtp_packet.seqno):16,
(P#rtp_packet.timestamp):32,
(P#rtp_packet.ssrc):32,
(P#rtp_packet.payload)/bytes
>>.
parse_rtp_packet(
<< 2:2, % Version 2
0:1, % P (not supported yet)
0:1, % X (not supported yet)
0:4, % CC (not supported yet)
M:1,
PT:7,
SeqNo: 16,
TS:32,
Ssrc:32,
Payload/bytes >>) ->
#rtp_packet{
version = 0,
marker = M,
payload_type = PT,
seqno = SeqNo,
timestamp = TS,
ssrc = Ssrc,
payload = Payload}.
%%% payload generation %%%
next_payload(F) when is_function(F) ->
{F(), F};
next_payload({F, D}) when is_function(F) ->
{P, D2} = F(D),
{P, {F, D2}};
next_payload([P | R]) ->
{P, R};
next_payload([]) ->
undef;
next_payload(Bin = <<_/bytes>>) ->
{Bin, Bin}.
%%% real writing work %%%
write_packets(_Dev, DS, _P, _F, 0, _O, _Opts) ->
DS;
write_packets(Dev, DataSource, P = #rtp_packet{}, F, L, O, Opts) ->
Format = proplists:get_value(format, Opts, state),
Ptime = proplists:get_value(duration, Opts, 160),
Delay = proplists:get_value(delay, Opts, 0),
Rate = proplists:get_value(rate, Opts, 8000),
case next_payload(DataSource) of
{Payload, DataSource2} ->
write_packet(Dev, Ptime * F / Rate + Delay,
P#rtp_packet{seqno = F, timestamp = F*Ptime+O,
payload = Payload},
Format),
write_packets(Dev, DataSource2, P, F+1, L-1, O, Opts);
Other -> Other
end.
write_packet(Dev, Time, P = #rtp_packet{}, Format) ->
Bin = make_rtp_packet(P),
write_packet_line(Dev, Time, P, Bin, Format).
write_packet_pre(Dev, carray) ->
io:format(Dev,
"struct {float t; int len; char *data;} packets[] = {~n", []);
write_packet_pre(_Dev, _) -> ok.
write_packet_post(Dev, carray) ->
io:format(Dev, "};~n", []);
write_packet_post(_Dev, _) -> ok.
write_packet_line(Dev, Time, _P, Bin, state) ->
io:format(Dev, "~f ~s~n", [Time, bin_to_hex(Bin)]);
write_packet_line(Dev, Time, #rtp_packet{seqno = N, timestamp = TS}, Bin, c) ->
ByteList = [ [ $0, $x | integer_to_list(Byte, 16) ] || <<Byte:8>> <= Bin ],
ByteStr = string:join(ByteList, ", "),
io:format(Dev, "/* time=~f, SeqNo=~B, TS=~B */ {~s}~n", [Time, N, TS, ByteStr]);
write_packet_line(Dev, Time, #rtp_packet{seqno = N, timestamp = TS}, Bin, carray) ->
io:format(Dev, " /* RTP: SeqNo=~B, TS=~B */~n", [N, TS]),
io:format(Dev, " {~f, ~B, \"", [Time, size(Bin)]),
[ io:format(Dev, "\\x~2.16.0B", [Byte]) || <<Byte:8>> <= Bin ],
io:format(Dev, "\"},~n", []).
%%% real reading work %%%
read_packets(Dev, Opts) ->
Format = proplists:get_value(in_format, Opts, state),
read_packets(Dev, Opts, Format).
read_packets(Dev, Opts, Format) ->
case read_packet(Dev, Opts, Format) of
eof -> [];
Tuple -> [Tuple | read_packets(Dev, Opts, Format)]
end.
read_packet(Dev, Opts, bin) ->
Size = proplists:get_value(frame_size, Opts),
case file:read(Dev, Size) of
{ok, Data} -> {0, #rtp_packet{payload = iolist_to_binary(Data)}};
eof -> eof
end;
read_packet(Dev, _Opts, Format) ->
case read_packet_line(Dev, Format) of
{Time, Bin} -> {Time, parse_rtp_packet(Bin)};
eof -> eof
end.
read_packet_line(Dev, state) ->
case io:fread(Dev, "", "~f ~s") of
{ok, [Time, Hex]} -> {Time, hex_to_bin(Hex)};
eof -> eof
end.

View File

@ -1,21 +0,0 @@
"
Simple UDP replay from the state files
"