-module(save_to_pcap). %% %% Start up MTP-2 monitoring on the given E1 interface/timeslot and %% save the signal units to a file in libpcap format. %% %% PCAP file format: http://wiki.wireshark.org/Development/LibpcapFileFormat %% %% Typical use: %% save_to_pcap:go("172.16.2.7", "2B", 16, "/tmp/isup.pcap"). %% %% Program loops forever, you need to kill it to end it. %% %% $Id: save_to_pcap.erl,v 1.2 2009-09-26 15:34:34 matthias Exp $ %% -export([go/4, from_file/2]). go(GTH_IP, Span, Timeslot, Filename) -> {ok, A} = gth:start_link(GTH_IP), {ok, Out} = file:open(Filename, [raw, write]), ok = file:write(Out, pcap_file_header()), ok = gth:set(A, "pcm" ++ Span, [{"mode", "E1"}, {"framing", "doubleframe"}, {"tx_enabled", "false"}, {"monitoring", "true"}, {"status", "enabled"}]), {ok, _ID, D} = gth:new_mtp2_monitor(A, Span, Timeslot), dump_packets(D, Out), ok = file:close(Out). dump_packets(D, Out) -> {ok, <<_Tag:16, _Flags:16, Timestamp:48, SU/binary>>} = gen_tcp:recv(D, 0), ok = file:write(Out, [pcap_packet_header(Timestamp, size(SU)), SU]), dump_packets(D, Out). pcap_file_header() -> Magic = 16#a1b2c3d4, Major = 2, Minor = 4, GMT_to_localtime = 0, Sigfigs = 0, Snaplen = 65535, %% the maximum allowed Network = 140, %% 140 means MTP-2 <>. pcap_packet_header(Timestamp_ms, Payload_len) -> Timestamp_us = (Timestamp_ms rem 1000) * 1000, Timestamp_s = Timestamp_ms div 1000, <>. %% This function takes a saved stream from a GTH and converts it into %% PCAP format. %% %% One way to generate such a saved stream is to save GTH output with %% netcat, e.g. netcat -l -p 1234 > /tmp/captured.raw %% %% Another way is to sniff the ethernet with tcpdump or wireshark and %% then reconstruct the TCP stream with either tcpflow or with the 'follow tcp' %% tool in wireshark. Example: %% %% tcpdump -w /tmp/captured_ethernet.pcap -s 0 port 1234 %% tcpflow -r /tmp/captured_ethernet.pcap %% from_file(In_filename, Out_filename) -> {ok, In} = file:open(In_filename, [read, binary]), {ok, Out} = file:open(Out_filename, [write]), ok = file:write(Out, pcap_file_header()), file_to_file(In, Out), ok = file:close(In), ok = file:close(Out). file_to_file(In, Out) -> case file:read(In, 2) of {ok, <>} -> {ok, <<_Tag:16, Proto:3, _Flags:13, Time:48, SU/binary>>} = file:read(In, Size), MSU_size = size(SU) - 2, <> = SU, Expected_crc = crc:crc16(MSU), io:fwrite("SU length=~p CRC=~p expected CRC=~p\n", [size(SU), CRC, Expected_crc]), CRC = Expected_crc, Proto = 0, %% 0 == MTP-2 ok = file:write(Out, [pcap_packet_header(Time, size(SU)), SU]), file_to_file(In, Out); eof -> done end.