Madeya gotarê ji min hatiye girtin .

Bikaranîna TShark ji bo analîzkirina pakêtên RTP

Di ya paşîn de Me ji jeneratorek tone û detektorek tone çerxek kontrolê ji dûr ve berhev kir, ragihandina di navbera wan de bi karanîna tîrêjek RTP pêk hat.
Di vê gotarê de, em xwendina veguheztina sînyala dengî bi karanîna protokola RTP berdewam dikin. Pêşîn, bila em serîlêdana xweya ceribandinê li veguhezkerek û wergirek dabeş bikin û fêr bibin ka meriv çawa bi karanîna analîzkerek seyrûsefera torê vekolîna RTP-ê çawa lêkolîn dike.
Ji ber vê yekê, ji bo ku em zelaltir bibînin ka kîjan hêmanên bernameyê ji veguheztina RTP-ê berpirsiyar in û kîjan ji wergirtinê berpirsiyar in, em pelê mstest6.c ji bo veguhezkar û wergir di nav du bernameyên serbixwe de dabeş dikin; di pelê sêyemîn de, ku em ê jê re dibêjin mstest_common.c, ew ê ji hêla veguhezker û wergirê ve bi karanîna rêwerziya tevlêbûnê ve were girêdan:
/* Файл mstest_common.c Общие функции для передатчика и приемника. */
#include <mediastreamer2/msfilter.h>
#include <mediastreamer2/msticker.h>
#include <mediastreamer2/msrtp.h>
#include <ortp/rtpsession.h>
#include <ortp/payloadtype.h>
define PCMU 0
/*---------------------------------------------------------*/
/* Функция регистрации типов полезных нагрузок. */
void register_payloads(void)
{
/* Регистрируем типы нагрузок в таблице профилей. Позднее, по индексу взятому
из заголовка RTP-пакета из этой таблицы будут извлекаться параметры
нагрузки, необходимые для декодирования данных пакета. */
rtp_profile_set_payload (&av_profile, PCMU, &payload_type_pcm8000);
}
/*---------------------------------------------------------*/
/* Эта функция создана из функции create_duplex_rtpsession() в audiostream.c медиастримера2. */
static RtpSession *create_rtpsession (int loc_rtp_port, int loc_rtcp_port, bool_t ipv6, RtpSessionMode mode)
{
RtpSession *rtpr; rtpr = rtp_session_new ((int) mode);
rtp_session_set_scheduling_mode (rtpr, 0);
rtp_session_set_blocking_mode (rtpr, 0);
rtp_session_enable_adaptive_jitter_compensation (rtpr, TRUE);
rtp_session_set_symmetric_rtp (rtpr, TRUE);
rtp_session_set_local_addr (rtpr, ipv6 ? "::" : "0.0.0.0", loc_rtp_port, loc_rtcp_port);
rtp_session_signal_connect (rtpr, "timestamp_jump", (RtpCallback) rtp_session_resync, 0);
rtp_session_signal_connect (rtpr, "ssrc_changed", (RtpCallback) rtp_session_resync, 0);
rtp_session_set_ssrc_changed_threshold (rtpr, 0);
rtp_session_set_send_payload_type(rtpr, PCMU);
/* По умолчанию выключаем RTCP-сессию, так как наш пульт не будет использовать
её. */
rtp_session_enable_rtcp (rtpr, FALSE);
return rtpr;
}
Naha pelê veguhezkarê veqetandî:
/* Файл mstest6.c Имитатор пульта управления (передатчика). */
#include <mediastreamer2/dtmfgen.h>
#include <mediastreamer2/msrtp.h>
#include "mstest_common.c"
/*----------------------------------------------------------*/
int main()
{
ms_init();
/* Создаем экземпляры фильтров. */
MSFilter *voidsource = ms_filter_new(MS_VOID_SOURCE_ID);
MSFilter *dtmfgen = ms_filter_new(MS_DTMF_GEN_ID);
/* Создаем фильтр кодера. */
MSFilter *encoder = ms_filter_create_encoder("PCMU");
/* Регистрируем типы нагрузки. */
register_payloads();
/* Создаем RTP-сессию передатчика. */
RtpSession *tx_rtp_session = create_rtpsession (8010, 8011, FALSE, RTP_SESSION_SENDONLY);
rtp_session_set_remote_addr_and_port(tx_rtp_session,"127.0.0.1", 7010, 7011);
rtp_session_set_send_payload_type(tx_rtp_session, PCMU);
MSFilter *rtpsend = ms_filter_new(MS_RTP_SEND_ID);
ms_filter_call_method(rtpsend, MS_RTP_SEND_SET_SESSION, tx_rtp_session);
/* Создаем источник тактов - тикер. */
MSTicker *ticker_tx = ms_ticker_new();
/* Соединяем фильтры передатчика. */
ms_filter_link(voidsource, 0, dtmfgen, 0);
ms_filter_link(dtmfgen, 0, encoder, 0);
ms_filter_link(encoder, 0, rtpsend, 0);
/* Подключаем источник тактов. */
ms_ticker_attach(ticker_tx, voidsource);
/* Настраиваем структуру, управляющую выходным сигналом генератора. */
MSDtmfGenCustomTone dtmf_cfg;
dtmf_cfg.tone_name[0] = 0;
dtmf_cfg.duration = 1000;
dtmf_cfg.frequencies[0] = 440;
/* Будем генерировать один тон, частоту второго тона установим в 0. */
dtmf_cfg.frequencies[1] = 0;
dtmf_cfg.amplitude = 1.0;
dtmf_cfg.interval = 0.;
dtmf_cfg.repeat_count = 0.;
/* Организуем цикл сканирования нажатых клавиш. Ввод нуля завершает
* цикл и работу программы. */
char key='9';
printf("Нажмите клавишу команды, затем ввод.n"
"Для завершения программы введите 0.n");
while(key != '0')
{
key = getchar();
if ((key >= 49) && (key <= 54))
{
printf("Отправлена команда: %cn", key);
/* Устанавливаем частоту генератора в соответствии с
* кодом нажатой клавиши. */
dtmf_cfg.frequencies[0] = 440 + 100*(key-49);
/* Включаем звуковой генератор c обновленной частотой. */
ms_filter_call_method(dtmfgen, MS_DTMF_GEN_PLAY_CUSTOM, (void*)&dtmf_cfg);
}
/* Укладываем тред в спячку на 20мс, чтобы другие треды
* приложения получили время на работу. */
ms_usleep(20000);
}
}Û di dawiyê de, pelê wergirê:
/* Файл mstest7.c Имитатор приемника. */
include <mediastreamer2/mssndcard.h>
include <mediastreamer2/mstonedetector.h>
include <mediastreamer2/msrtp.h>
/* Подключаем заголовочный файл с функциями управления событиями медиастримера.*/
include <mediastreamer2/mseventqueue.h>
/* Подключаем файл общих функций. */
include "mstest_common.c"
/* Функция обратного вызова, она будет вызвана фильтром, как только он обнаружит совпадение характеристик входного сигнала с заданными. */
static void tone_detected_cb(void *data, MSFilter *f, unsigned int event_id,MSToneDetectorEvent *ev)
{
printf("Принята команда: %sn", ev->tone_name);
}
/*----------------------------------------------------------*/
int main()
{
ms_init();
/* Создаем экземпляры фильтров. */
MSSndCard *card_playback = ms_snd_card_manager_get_default_card(ms_snd_card_manager_get());
MSFilter *snd_card_write = ms_snd_card_create_writer(card_playback);
MSFilter *detector = ms_filter_new(MS_TONE_DETECTOR_ID);
/* Очищаем массив находящийся внутри детектора тонов, он описывает
* особые приметы разыскиваемых сигналов.*/
ms_filter_call_method(detector, MS_TONE_DETECTOR_CLEAR_SCANS, 0);
/* Подключаем к фильтру функцию обратного вызова. */
ms_filter_set_notify_callback(detector, (MSFilterNotifyFunc)tone_detected_cb, NULL);
/* Создаем массив, каждый элемент которого описывает характеристику
* одного из тонов, который требуется обнаруживать:
Текстовое имя
* данного элемента, частота в герцах, длительность в миллисекундах,
* минимальный уровень относительно 0,775В. */
MSToneDetectorDef scan[6]=
{
{"V+",440, 100, 0.1}, /* Команда "Увеличить громкость". */
{"V-",540, 100, 0.1}, /* Команда "Уменьшить громкость". */
{"C+",640, 100, 0.1}, /* Команда "Увеличить номер канала". */
{"C-",740, 100, 0.1}, /* Команда "Уменьшить номер канала". */
{"ON",840, 100, 0.1}, /* Команда "Включить телевизор". */
{"OFF", 940, 100, 0.1}/* Команда "Выключить телевизор". */
};
/* Передаем "приметы" сигналов детектор тонов. */
int i;
for (i = 0; i < 6; i++)
{
ms_filter_call_method(detector, MS_TONE_DETECTOR_ADD_SCAN, &scan[i]);
}
/* Создаем фильтр декодера */
MSFilter *decoder=ms_filter_create_decoder("PCMU");
/* Регистрируем типы нагрузки. */
register_payloads();
/* Создаем RTP-сессию приемника. */
MSFilter *rtprecv = ms_filter_new(MS_RTP_RECV_ID);
RtpSession *rx_rtp_session = create_rtpsession (7010, 7011, FALSE, RTP_SESSION_RECVONLY);
ms_filter_call_method(rtprecv, MS_RTP_RECV_SET_SESSION, rx_rtp_session);
/* Создаем источник тактов - тикер. */
MSTicker *ticker_rx = ms_ticker_new();
/* Соединяем фильтры приёмника. */
ms_filter_link(rtprecv, 0, decoder, 0);
ms_filter_link(decoder, 0, detector, 0);
ms_filter_link(detector, 0, snd_card_write, 0);
/* Подключаем источник тактов. */
ms_ticker_attach(ticker_rx, rtprecv);
char key='9';
printf( "Для завершения программы введите 0.n");
while(key != '0')
{
key = getchar();
/* Укладываем тред в спячку на 20мс, чтобы другие треды * приложения получили время на работу. */
ms_usleep(20000);
}
}
Em veguhezker û wergir berhev dikin, dûv re her yekê di konsolê xwe de dest pê dikin. Dûv re divê ew wekî berê bixebite - tenê divê em ji 1-ê heya 6-an jimareyên di konsolê veguhêz de binivîsin, û bersiva wan divê di konsolê wergir de xuya bibe. Divê deng di dengbêjê de bêne bihîstin. Ger her tişt wusa be, wê hingê me têkiliyek di navbera wergir û veguhezker de saz kiriye - veguheztinek domdar a pakêtên RTP ji veguhezderê heya wergir heye.
Naha dema sazkirina analîzkerek trafîkê ye ji bo vê yekê em ê guhertoya konsolê ya bernameya hêja ya Wireshark saz bikin - jê re TSark tê gotin. Min TSark ji bo nîqaşek din hilbijart da ku ravekirina rêveberiya bernameyê hêsantir bikim. Bi Wireshark re, ez ê hewceyê deryayek dîmenan bikim, ku gava ku guhertoyek nû ya Wireshark were berdan zû zû kevnar bibe.
Heke hûn dizanin ka meriv çawa Wireshark bikar tîne, hûn dikarin wê bikar bînin ku mînakên me bixwînin. Lê tewra di vê rewşê de, ez pêşniyar dikim ku hûn TSark master bikin, ji ber ku ew ê ji we re bibe alîkar ku hûn ceribandina serîlêdanên VoIP-ya xwe otomatîk bikin, û hem jî girtina ji dûr ve bikin.
TSark bi fermanê saz bikin:
$ sudo apt-get install tsharkBi kevneşopî, em encama sazkirinê bi pirskirina guhertoya bernameyê kontrol dikin:
$ tshark --versionGer bersivek têr were girtin, em hêj berdewam dikin.
Ji ber ku pakêtên me niha tenê di hundurê komputerê de diçin, em dikarin ji tshark re bibêjin ku tenê pakêtên weha nîşan bide. Ji bo vê yekê, hûn hewce ne ku hûn girtina pakêtê ji navrûyê hilbijêrin loopback (loopback) bi derbaskirina vebijarka TShark -ilo:
$ sudo tshark -i loMesajên li ser pakêtên ku ji hêla veguhezvanê me ve têne şandin dê tavilê dest bi rijandina konsolê bikin (berdewam, bêyî ku me bişkoka li ser kontrolê ji dûr ve bikişîne an na). Dibe ku li ser komputera we bername hebin ku di heman demê de pakêtan bi riya lûpek herêmî jî dişînin, di vê rewşê de em ê pakêtek ji pakêtên xwe û yên kesên din bistînin. Ji bo ku em pê bawer bin ku di navnîşê de em tenê pakêtên ku ji hêla kontrola xweya dûr ve têne şandin dibînin, em ê li gorî jimareya portê parzûnek zêde bikin. Bi tikandina Ctrl-C em analîzkerê radiwestînin û parzûnek ji bo hejmara portê ya ku kontrola ji dûr ve wekî porta mebestê ji bo veguheztina xwe bikar tîne têkevin (8010): -f "udp port 8010". Naha rêzika fermana me dê wiha xuya bike:
$ sudo tshark -i lo -f "udp port 8010"Hilbera jêrîn dê di konsolê de xuya bibe (10 rêzên pêşîn):
1 0.000000000 127.0.0.1 → 127.0.0.1 UDP 214 8010 → 7010 Len=172
2 0.020059705 127.0.0.1 → 127.0.0.1 UDP 214 8010 → 7010 Len=172
3 0.040044409 127.0.0.1 → 127.0.0.1 UDP 214 8010 → 7010 Len=172
4 0.060057104 127.0.0.1 → 127.0.0.1 UDP 214 8010 → 7010 Len=172
5 0.080082311 127.0.0.1 → 127.0.0.1 UDP 214 8010 → 7010 Len=172
6 0.100597153 127.0.0.1 → 127.0.0.1 UDP 214 8010 → 7010 Len=172
7 0.120122668 127.0.0.1 → 127.0.0.1 UDP 214 8010 → 7010 Len=172
8 0.140204789 127.0.0.1 → 127.0.0.1 UDP 214 8010 → 7010 Len=172
9 0.160719008 127.0.0.1 → 127.0.0.1 UDP 214 8010 → 7010 Len=172
10 0.180673685 127.0.0.1 → 127.0.0.1 UDP 214 8010 → 7010 Len=172Heya nuha, ev ne pakêt in, lê navnîşek jimarekirî ya bûyeran in, ku her rêzek peyamek li ser pakêta din a ku li ser navberê hate dîtin e. Ji ber ku me berê xwe daye parzûnkirina pakêtê, em di navnîşê de tenê peyamên li ser pakêtên ji veguhezvanê xwe dibînin. Piştre, em vê tabloyê bi hejmarên stûnê deşîfre bikin:
Hejmara bûyerê.
Dema çêbûna wê.
Navnîşana IP-ya çavkaniyê ya pakêtê û navnîşana IP-ya armancê ya pakêtê.
Protokola pakêtê wekî UDP tê nîşandan ji ber ku pakêtên RTP di hundurê pakêtên UDP de wekî bargiran têne şandin.
Mezinahiya pakêtê bi byte.
Hejmara porta çavkaniyê ya pakêtê û jimara porta mebesta pakêtê.
Mezinahiya bargiraniya pakêtê, ji vir em dikarin encam bidin ku veguhezkarê me pakêtên RTP yên bi mezinahiya 172 byte diafirîne, ku, mîna ordekek di sîngê de, di hundurê pakêtek UDP ya bi mezinahiya 214 byte de ye.
Naha ew dem e ku meriv li hundurê pakêtên UDP binêre, ji bo vê yekê em ê TSark bi komek bişkokên berfireh bidin destpêkirin:
sudo tshark -i lo -f "udp port 8010" -P -V -O rtp -o rtp.heuristic_rtp:TRUE -xWekî encamek, derketina bernameyê dê dewlemend bibe - deşîfrekirina naveroka hundurê pakêtê ya ku bûye sedema wê dê li her bûyerê were zêdekirin. Ji bo ku hûn çêtir li derketinê mêze bikin, hûn dikarin TSark bi tikandina Ctrl-C rawestînin, an jî derana wê li pelek dûpat bikin û bi lêzêdekirina boriyek li bernameya tee li fermana xebitandinê, navê pelê diyar bikin, tee <navê pelê>:
$ sudo tshark -i lo -f "udp port 8010" -P -V -O rtp -o rtp.heuristic_rtp:TRUE -x | tee log.txtNaha em binihêrin ka me di pelê de çi girt, li vir pakêta yekem ji wê ye:
1 0.000000000 127.0.0.1 → 127.0.0.1 RTP 214 PT=ITU-T G.711 PCMU, SSRC=0x6B8B4567, Seq=58366, Time=355368720
Frame 1: 214 bytes on wire (1712 bits), 214 bytes captured (1712 bits) on interface 0
Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00 (00:00:00:00:00:00)
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1User Datagram Protocol, Src Port: 8010, Dst Port: 7010
Real-Time Transport Protocol [Stream setup by HEUR RT (frame 1)]
[Setup frame: 1]
[Setup Method: HEUR RT]
10.. .... = Version: RFC 1889 Version (2)
..0. .... = Padding: False
...0 .... = Extension: False
.... 0000 = Contributing source identifiers count: 0
0... .... = Marker: False
Payload type: ITU-T G.711 PCMU (0)
Sequence number: 58366 [Extended sequence number: 58366]
Timestamp: 355368720
Synchronization Source identifier: 0x6b8b4567 (1804289383)
Payload: ffffffffffffffffffffffffffffffffffffffffffffffff...
0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 ..............E.
0010 00 c8 3c 69 40 00 40 11 ff b9 7f 00 00 01 7f 00 ..<i@.@.........
0020 00 01 1f 4a 1b 62 00 b4 fe c7 80 00 e3 fe 15 2e ...J.b..........
0030 7f 10 6b 8b 45 67 ff ff ff ff ff ff ff ff ff ff ..k.Eg..........
0040 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
0050 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
0060 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
0070 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
0080 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
0090 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
00a0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
00b0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
00c0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
00d0 ff ff ff ff ff ff ......Em ê gotara din veqetînin analîzkirina agahdariya ku di vê navnîşê de heye û bê guman dê li ser avahiya hundurê pakêta RTP-ê biaxivin.
Source: www.habr.com
