Інструкція до специфікації SMPP

Різні сервіси, що використовують SMS повідомлення або SMS авторизацію, з кожним днем набирають популярність, т. к. це дійсно дуже зручно з точки зору користувача і досить безпечно з точки зору розробників. Більшість компаній, що надають сервіс SMS розсилок, пропонують свої API для реалізації процесу відправлення (як правило на основі HTTP), але у всіх є стандартний варіант підключення — протокол SMPP. Мій досвід роботи з користувачами SMPP протоколу показує, що вони відчуваю досить багато складностей. Причиною цього (на мою думку) є бездумне використання готових бібліотек і в результаті повне нерозуміння що відбувається «під капотом».

У цій статті я опишу один з найбільш частих питань від клієнтів — «Як прочитати текст вхідного повідомлення? Я знайшов on-line декодер, але він показує абракадабру». Справа в тому, що у деяких сервісів є не тільки можливість відправки повідомлень, але і отримання на них відповідей. Однак алгоритм, описаний мною, застосовний до будь-якої дії в SMPP протоколі, оскільки по суті є інструкцією до специфікації протоколу.

Розбір вхідного повідомлення без використання будь-якого SMPP

Нам потрібні:

  • SMPP Protocol Specification v3.4
  • Wireshark
  • Блокнот
  • Браузер

Я не буду описувати процес отримання самого cap файлу дампа) SMPP обміну, т. к. вже є багато статей на цю тему (наприклад, ).

Загальний порядок обміну пакетами в SMPP виглядає наступним чином:



Як видно в разі вхідного повідомлення нас цікавить пакет deliver_sm. Визначення типу пакета відбувається по полю command_id, яке в разі deliver_sm має значення 0x00000005 (пункт 5.1.2.1 в специфікації).

У підсумку фільтр wireshark виглядає так:


smpp.command_id == 0x00000005


Після того як знайшли пакет з фільтру копіюємо його вміст в HEX форматі:



Підсумковий рядок, яку належить розшифрувати:


00000048000000050000000000000003000101636F6F6E6F6C616E642E727500010137393132333435363738390000000000000000
0800000424000c043f044004380432043504424


Пункт, що описує формат пакета deliver_sm, специфікації, має номер 4.6.1 «DELIVER_SM» Syntax. У цьому пункті є таблиця, у якій розписується кожне поле пакету:



Приступимо до розбору пакета
Перше поле пакету — command_length має розмір 4 октету (стовпець size octets) і тип Integer. Це означає, що від початку нашої HEX рядка необхідно відрахувати 4 х 2 = 8 символів.

Чому множимо на 2?Ми скопіювали рядок у шістнадцятковому форматі який кодує один октет (байт) двома символами.

00 00 00 48 000000050000000000000003000101636F6F6...


(HEX) 00000048 -> (DEC) 72 октету або 144 символу — довжина всього SMPP пакета.

Наступне поле command_id — аналогічно 4 октету та Integer.

00000048 00 00 00 05 0000000000000003000101636F6F6...


Перетворимо в читабельний вигляд: 00000005 = deliver_sm



Поля command_status та sequence_number так само маю по 4 октету. Де подивитися їх значення, я припускаю Ви вже здогадуєтеся.

0000004800000005 00 00 00 00 00 00 00 03 000101636F6F6...


Поле service_type може містити максимум 6 октетів і має тип C-Octet String. У пункті 3.1 SMPP PDU — Type Definitions сказано:

C-Octet String A series of ASCII characters terminated with the NULL character
Іншими словами, це послідовність ASCII символів з нульовим октетом як символ закінчення поля. Тобто це поле може містити максимум 6 символів, але може бути і менше — кінець даного поля позначається HEX 00. У цьому конкретному прикладі ми відразу бачимо 00 — полі не містить жодного значення.

00000048000000050000000000000003 00 0101636F6F6...


Якщо б цей стовпець був заповнений, то розшифрувати його можна за таблицею ASCII символів.

Пропустимо наступні 2 поля source_addr_ton та source_addr_npi, т. к. як їх розшифрувати вже ясно і розберемо ще одне поле з типом C-Octet String — source_addr.

Source_addr може містити максимум 21 октет, але в даному випадку воно складається з 13 октетів включаючи нульовий октет який означає закінчення поля:

63 6F 6F 6E 6F 6C 61 6E 64 2E 72 75 00

В пошуковику робимо запит «ascii table» і починаємо розшифровувати:



63 = c
6F = o
6F = o
6E = n
6F = o
6C = l
61 = a
6E = n
64 = d

І так далі до символів 00.

Інші поля я теж пропускаю — їх багато і їх визначення ні чим не відрізняється від описаного вище. Перейдемо до поля data_coding, без значення даного поля ми не зможемо прочитати текст повідомлення.

Я розділив всі поля HEX рядку прикладу, а поле data_coding виділив жирним і ось що вийшло:
00000047;00000005;00000000;00000003;00;01;01;373932393937333630333000;01;01;373932333235303039353900;00;00;00;00;00;00;00;
08;00;00;0424;000c;043f04400438043204350442

Пункт 5.2.19 специфікації вказує що використовується кодування UCS2 (ISO/IEC-10646). (HEX) 08 -> (BIN) 00001000 -> UCS2 (ISO/IEC-10646):



Шукаємо таблицю символів за запитом: «ucs2 code chart»

043f04400438043204350442

Вибираємо перші 2 октету тексту «043f» і шукаємо їх на сторінці



Продовжуємо виділяти по 2 октету і шукати:
[р] 0440 CYRILLIC SMALL LETTER ER
[і] 0438 CYRILLIC SMALL LETTER I
[в] 0432 CYRILLIC SMALL LETTER VE
[е] 0435 CYRILLIC SMALL LETTER IE
[т] 0442 CYRILLIC SMALL LETTER TE

На цьому розбір пакету закінчено. Сподіваюся що опис вийшло ясна і достатньо повна. В цілому якщо у Вас вийшло усвідомити як прочитати повідомлення, відправити його не складе ніякої праці. Зміниться кілька полів.

Читайте специфікації — там майже все вже написано.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.