diff --git a/src/log.txt b/src/log.txt new file mode 100644 index 0000000..72ae2be --- /dev/null +++ b/src/log.txt @@ -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}}}]}}} diff --git a/src/tcap_udp_server.erl b/src/tcap_udp_server.erl new file mode 100644 index 0000000..d9470a3 --- /dev/null +++ b/src/tcap_udp_server.erl @@ -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. +