erlang
/
osmo-map-masq
Archived
4
0
Fork 0

add initial early Erlang/ASN.1 MAP patching code (unfinished)

This commit is contained in:
Harald Welte 2010-08-01 14:04:41 +02:00
parent 36874b38fb
commit e0c7236c69
2 changed files with 208 additions and 0 deletions

88
src/log.txt Normal file
View File

@ -0,0 +1,88 @@
1> {ok, IoDev} = file:open("/tmp/bin", read).
{ok,<0.33.0>}
2> {ok, Data} = file:read(IoDev, 255).
{ok,[98,129,129,72,4,104,34,66,102,107,26,40,24,6,7,0,17,
134,5,1,1,1,160,13,96,11,161|...]}
3> asn1rt:decode('MAP','MapSpecificPDUs', Data).
{ok,{'begin',
{'MapSpecificPDUs_begin',"h\"Bf",
{'EXTERNAL',
{syntax,{0,0,17,773,1,1,1}},
asn1_NOVALUE,
<<96,11,161,9,6,7,4,0,0,1,0,3,3>>},
[{basicROS,
{invoke,
{'MapSpecificPDUs_begin_components_SEQOF_basicROS_invoke',
{present,27},
asn1_NOVALUE,
{local,4},
{'ProvideRoamingNumberArg',
[21,16,96,51,153,89,73,249],
[145,38,24,1,5,113],
[145,38,24,99,147,136,57|...],
[0,3,67,198],
{'ExternalSignalInfo','gsm-0408',[4,1|...],asn1_NOVALUE},
asn1_NOVALUE,asn1_NOVALUE,
[145,38|...],
[245|...],
asn1_NOVALUE,...}}}}]}}}
4> gen_udp:open([4243], [binary, inet]).
** exception error: no function clause matching inet_udp:getserv([4243])
in function gen_udp:open/2
5> gen_udp:open(4243, [binary, inet]).
{ok,#Port<0.692>}
6> receive.
* 1: syntax error before: '.'
6> receive
6> receive .
* 2: syntax error before: '.'
6> receive {udp, Sock, ClientIP, ClientPort, Packet}.
* 1: syntax error before: '.'
6> receive {udp, Sock, ClientIP, ClientPort, Packet} end.
* 1: syntax error before: 'end'
6> receive {udp, Sock, ClientIP, ClientPort, Packet} io:format("foo~n").
* 1: syntax error before: io
6> receive {udp, Sock, ClientIP, ClientPort, Packet} -> io:format("foo~n").
* 1: syntax error before: '.'
6> receive {udp, Sock, ClientIP, ClientPort, Packet} -> io:format("foo~n") end.
foo
ok
7> receive {udp, Sock, ClientIP, ClientPort, Packet} -> io:format("foo~n") end.
foo
ok
8> receive {udp, Sock, ClientIP, ClientPort, Packet} -> asn1rt:decode('MAP', 'MapSpecificPDUs', Packet) end.
{ok,{'begin',
{'MapSpecificPDUs_begin',
[0,0,128,0],
{'EXTERNAL',
{syntax,{0,4,0,0,1,0,1,3}},
asn1_NOVALUE,
<<128,17,96,15,128,2,7,128,161,9,6,7,4,0,0,1,0,32,...>>},
[{basicROS,
{invoke,
{'MapSpecificPDUs_begin_components_SEQOF_basicROS_invoke',
{present,0},
asn1_NOVALUE,
{local,23},
{'UpdateGprsLocationArg',
[21,16,96,36,6,0,133,248],
[145,38,24,1,33,7,241],
[4,221,132,193,53],
asn1_NOVALUE,
{'SGSN-Capability',asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,
'NULL',...},
asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE}}}},
{basicROS,
{invoke,
{'MapSpecificPDUs_begin_components_SEQOF_basicROS_invoke',
{present,1},
asn1_NOVALUE,
{local,23},
asn1_NOVALUE}}},
{basicROS,
{invoke,
{'MapSpecificPDUs_begin_components_SEQOF_basicROS_invoke',
{present,-1},
asn1_NOVALUE,
{local,23},
asn1_NOVALUE}}}]}}}

120
src/tcap_udp_server.erl Normal file
View File

@ -0,0 +1,120 @@
-module(tcap_udp_server).
-compile(export_all).
-define(PATCH_HLR_NUMBER, [1]).
-define(PATCH_SGSN_NUMBER, [2]).
-define(PATCH_SGSN_ADDRESS, [3]).
-define(PATCH_VMSC_ADDRESS, [4]).
-include("MAP.hrl").
init(ServerPort) ->
{ok, Sock} = gen_udp:open(ServerPort, [binary, inet]),
loop().
% patch a UpdateGprsLocationArg and replace SGSN number and SGSN address
% !!! TESTING ONLY !!!
patch_UpdateGprsLocationArg(Arg) ->
Arg1 = Arg#'UpdateGprsLocationArg'{'sgsn-Number' = ?PATCH_SGSN_NUMBER},
Arg1#'UpdateGprsLocationArg'{'sgsn-Address' = ?PATCH_SGSN_ADDRESS}.
% Some other SGSN is sendingu us a GPRS location update. In the response,
% we indicate teh HLR number, which we need to masquerade
patch_UpdateGprsLocationRes(Arg) ->
Arg#'UpdateGprsLocationRes'{'hlr-Number' = ?PATCH_HLR_NUMBER}.
% Some other MSC/VLR is sendingu us a GSM location update. In the response,
% we indicate teh HLR number, which we need to masquerade
patch_UpdateLocationRes(Arg) ->
Arg#'UpdateLocationRes'{'hlr-Number' = ?PATCH_HLR_NUMBER}.
% HLR responds to VLR's MAP_RESTORE_REQ (i.e. it has lost information)
patch_RestoreDataRes(Arg) ->
Arg#'RestoreDataRes'{'hlr-Number' = ?PATCH_HLR_NUMBER}.
% HLR sends subscriber data to VLR/SGSN, including CAMEL info
patch_InsertSubscriberDataArg(Arg) ->
VlrCamel = Arg#'InsertSubscriberDataArg'.'vlrCamelSubscriptionInfo',
%Arg1 = Arg#'InsertSubscriberDataArg'{'vlrCamelSubscriptionInfo' = patch_vlrCamelSubscrInfo(VlrCamel)},
SgsnCamel = Arg#'InsertSubscriberDataArg'.'sgsn-CAMEL-SubscriptionInfo',
%Arg#'InsertSubscriberDataArg'{'sgsn-CAMEL-SubscriptionInfo' = patch_sgsnCamelSubscrInfo(SgsnCamel)},
Arg.
%patch_vlrCamelSubscrInfo(VlrCamel) ->
% case VlrCamel of
% asn1_NOVALUE ->
% VlrCamel;
% {'CAMEL-SubscriptionInfo', {Sinfo}} ->
% Sinfo#
%patch_sgsnCamelSubscrInfo(SgsnCamel) ->
% case SgsnCamel of
% asn1_NOVALUE ->
% SgsnCamel;
% {'SGSN-CAMEL-SubscriptionInfo', {Sinfo}} ->
% Gcsi = Sinfo#'SGSN-CAMEL-SubscriptionInfo'.'gprs=CSI',
% case Gcsi of
% asn1_NOVALUE ->
% SgsnCamel;
% {'GPRS-CSI', {Gcsi}} ->
% TdpList =
% process the Argument of a particular MAP invocation
process_component_arg(OpCode, Arg) ->
case Arg of
asn1_NOVALUE -> Arg;
_ -> patch_UpdateGprsLocationArg(Arg)
end.
% recurse over all components
handle_tcap_components([]) -> 0;
handle_tcap_components([Component|Tail]) ->
case Component of
{basicROS, {Primitive, Body}} ->
io:format("handle component ~p primitive ~n", [Component]),
case Body of
{'MapSpecificPDUs_begin_components_SEQOF_basicROS_invoke', _, _, {local, OpCode}, Arg} ->
NewArg = process_component_arg(OpCode, Arg),
end,
NewBody = setelement(5, Body, NewArg)
end,
NewComponent = {basicROS, {Primitive, NewBody}},
io:format("=> modified component ~p~n", [NewComponent]),
handle_tcap_components(Tail).
handle_tcap_msg_dec(TcapMsgDec) ->
case TcapMsgDec of
{'unidirectional', {'MapSpecificPDUs_unidirectional', Dialg, Components}} ->
NewComponents = handle_tcap_components(Components);
{'begin', {'MapSpecificPDUs_begin', Otid, Dialg, Components}} ->
NewComponents = handle_tcap_components(Components);
{'continue', {'MapSpecificPDUs_continue', Otid, Dtid, Dialg, Components}} ->
NewComponents = handle_tcap_components(Components);
{'end', {'MapSpecificPDUs_end', Dtid, Dialg, Components}} ->
NewComponents = handle_tcap_components(Components)
end.
handle_tcap_msg(PayloadL) ->
io:format("aboout to tcap_msg_dec..."),
case asn1rt:decode('MAP', 'MapSpecificPDUs', PayloadL) of
{ok, TcapMsgDec} ->
io:format("success!~n"),
handle_tcap_msg_dec(TcapMsgDec);
Error -> Error
end.
loop() ->
io:format("udp_server_loop~n"),
receive {udp, Sock, ClientIP, ClientPort, Packet} ->
io:format("UDP received from ~p:~p ==> ~p~n", [ClientIP, ClientPort, Packet]),
handle_tcap_msg(binary_to_list(Packet))%,
%loop()
end.