add initial early Erlang/ASN.1 MAP patching code (unfinished)
This commit is contained in:
parent
36874b38fb
commit
e0c7236c69
|
@ -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}}}]}}}
|
|
@ -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.
|
||||
|
Reference in New Issue