Copyright©
1999 Henrik Isaksson Последняя модернизация 24
октября 1999
Содержание
Об
этом документе
Пакеты
Клиент - Сервер
- Пакеты
Сервер - Клиент
- SRV_ACK (10)
- SRV_GO_AWAY (40)
- SRV_NEW_UIN (70)
- SRV_LOGIN_REPLY (90)
- SRV_BAD_PASS (100)
- SRV_USER_ONLINE (110)
- SRV_USER_OFFLINE
(120)
- SRV_QUERY (130)
- SRV_USER_FOUND (140)
- SRV_END_OF_SEARCH
(160)
- SRV_NEW_USER (180)
- SRV_UPDATE_EXT (200)
- SRV_RECV_MESSAGE
(220)
- SRV_X2 (230)
- SRV_NOT_CONNECTED
(240)
- SRV_TRY_AGAIN (250)
- SRV_SYS_DELIVERED_MESS
(260)
- SRV_INFO_REPLY (280)
- SRV_EXT_INFO_REPLY
(290)
- SRV_STATUS_UPDATE
(420)
- SRV_SYSTEM_MESSAGE
(450)
- SRV_UPDATE_SUCCESS
(480)
- SRV_UPDATE_FAIL (490)
- SRV_AUTH_UPDATE (500)
- SRV_MULTI_PACKET
(530)
- SRV_X1 (540)
- SRV_RAND_USER (590)
- SRV_META_USER (990)
- Расчет
контрольной суммы
- Шифрование
1. Об этом
документе
Это -
неофициальная спецификация,
основанная на спецификации Magnus
Ihses для версии 2
протокола ICQ, Mattew
Smith's MICQ, описанием
шифрования,сделанном Sebastien
Dault, и на
дискуссии по icq-devel в списке
рассылки.
Если Вы хотите
прочесть документ по второй версии
протокола ICQ или подписаться на
рассылку, то воспользуйтесь
следующим линком: http://www.student.nada.kth.se/~d95-mih/icq/
Все трэйдмарки,
упомянутые в этом тексте,
принадлежат его владельцу
Номер соглашения
0x12345678 |
Число,
записанное в
десятично-шестнадцатеричной
форме |
78 56 34 12 |
Шестнадцатиричное
значение |
(1234) |
Десятеричное
значение |
2. Пакеты Клиент -
Сервер
Пакеты Клиент -
Сервер посылаются с использованием
протокола
UDP ICQ
серверу.Каждый UDP-пакет начинается
со следующего заголовка:
Заголовок
ICQ-пакета (со стороны Клиента)
Длина
|
Содержание (если
установлено)
|
Сигнатура
|
Описание
|
2 байта
|
05 00
|
VERSION
|
Версия протокола
|
4
байта
|
00
00 00 00
|
ZERO
|
просто
устанавливается в ноль, цель
непонятна
|
4
байта
|
xx
xx xx xx
|
UIN
|
Ваш
(клиентский) номер ICQ
|
4
байта
|
xx
xx xx xx
|
SESSION_ID
|
Используется,
чтобы предотвратить spoofing - см.
ниже
|
2
байта
|
xx
xx
|
COMMAND
|
|
2
байта
|
xx
xx
|
SEQ_NUM1
|
Стартовать
со случайного числа
|
2
байта
|
xx
xx
|
SEQ_NUM2
|
Стартовать
с 1
|
4
байта
|
xx
xx xx xx
|
|
|
переменная
|
xx
...
|
PARAMETERS
|
Параметры
посылаемой команды
|
Пакеты,
посылаемые от клиента к серверу,
зашифрованы до их посылки, в
отличие от пакетов, посылаемых от
сервера клиенту, которые не
шифруются. Для более подробной
информации относительно
шифровки/расшифровывания смотрите Sebastien Dault's document.
Session_ID - случайное
число, выбранное, когда послан
login-пакет, оно сохраняется до log out.
Этот номер должен быть одним и тем
же для каждого посланного вами
пакета, иначе сервер проигнорирует
их. Session_id (идентификатор сеанса)
также будет послан вам назад
сервером с каждым полученным вами
пакетом - таким способом вы сможете
определить, исходит ли пакет из
сервера или же это "spoofed" пачка
(сравнив идентификаторы
полученного и посланного пакетов).
Порядковые номера
(sequence numbers) используются, чтобы
удостовериться в том, что пакеты
действительно достигают
получателя, и приходят один раз.
Когда вы посылаете пакет серверу,
вы должны получить квитанцию (SRV_ACK)
с сервера, если вы ее не получили,
необходимо отправить пакет еще раз
(метод квитирования). Если вы
получаете два или более пакетов с
тем же самым порядковым номером,
вам следует проигнорировать все
пакеты, кроме первого. Аналогично,
сервер ожидает, что вы пошлете
квитанцию после каждого
полученного вами пакета с сервера,
кроме SRV_ACK. См. SRV_ACK и CMD_ACK.
SEQ_NUM1 устанавливает
случайное число в login-пакете, и
затем проставляет это число, каждый
раз увеличенное на 1, в каждом
последующем пакете (например если
login-пакет имеет SEQ_NUM1=123, то следующий
отосланный вами пакет имеет
SEQ_NUM1=124).
SEQ_NUM2 устанавливает в
login-пакете число 1, и затем
проставляет это число, каждый раз
увеличенное на 1, в каждом
последующем посылаемом вами пакете
- но не для всех пакетов -
например CMD_KEEP_ALIVE всегда должен
содержать SEQ_NUM2=0
CMD_ACK
0A 00 (10)
Эта команда
посылается, чтобы подтвердить
получение пакета, посланного вам с
сервера.
Длина
|
Содержание
|
Сигнатура
|
Описание
|
4
байта
|
xx
xx xx xx
|
RANDOM
|
Случайное
число
|
Примечание! Порядковый
номер в заголовке пакета
содержит порядковый номер
полученного с сервера пакета
(квитанции) |
CMD_SEND_MESSAGE
0E 01 (270)
Эта команда
используется, чтоб послать
сообщение пользователям,
находящимся в off-line или в режиме
Invisible.
Параметры
Длина
|
Содержание
|
Сигнатура
|
Описание
|
4
байта
|
xx
xx xx xx
|
RECIEVER_UIN
|
номер
аси пользователя, которому
отсылается сообщение
|
2
байта
|
см.
ниже
|
MESSAGE_TYPE
|
тип
сообщения
|
2
байта
|
xx
xx
|
MESSAGE_LENGTH
|
длина
сообщения, включающего
заключительный NULL-байт
|
переменная
|
xx...00
|
MESSAGE_TEXT
|
текст
сообщения, заканчивающийся NULL
|
MESSAGE_TYPE может
быть одним из следующих:
Сигнатура |
Значение |
Описание |
MSG_TXT |
01 00 |
Обычное текстовое
сообщение |
MSG_URL |
04 00 |
URL-сообщение, состоит
из 2-х частей, разделенных 0xFE.
Первая - описание URL |
MSG_AUTH_REQ |
06 00 |
Запрос на добавление
пользователя в контакт лист.
Состоит из 5 частей,
разделенных 0xFE - ник, имя,
фамилия, эл.адрес, причина |
MSG_AUTH |
08 00 |
Разрешение добавить
пользователя в контакт лист |
MSG_USER_ADDED |
0C 00 |
Сообщение о том, что
пользователь был добавлен в
контакт лист. Состоит из 4
частей, разделенных 0xFE - ник,
имя, фамилия, эл.адрес |
MSG_CONTACTS |
13 00 |
Послан Contact. Это
сообщение состоит из
нескольких ников и номеров ICQ,
разделенных 0xFE. Первая часть
сообщения - число контактов
(пары nickname/UIN) в сообщении,
записанное в ASCII-коде,
завершается 0xFE |
CMD_LOGIN
E8 03 (1000)
Этот пакет
используется для подключения (log) к
серверу, которое должно быть
выполнено до исполнения всех
остальных команд, кроме тех,
которые используются для
регистрации нового пользователя.
Параметры
Длина
|
Содержание
|
Сигнатура
|
Описание
|
4
байта
|
xx
xx xx xx
|
TIME
|
время
(NULL), число секунд, начиная с
1января 1979 г.
|
4
байта
|
xx
xx xx xx
|
PORT
|
порт
для TCP-соединения
|
2
байта
|
xx
xx
|
PASS_LENGTH
|
длина
пароля, включающая NULL
|
переменная
|
xx...00
|
PASSWORD
|
строка,
содержащая пароль и
заканчивающаяся NULL
|
4 байта
|
xx
xx xx xx
|
X1
|
неизвестно,
обычно d5 00 00 00
|
4 байта
|
xx
xx xx xx
|
IP
|
IP
|
1 байта
|
xx
|
X2
|
Обычно
0x04, 0x06 значит, что вы не вводите
TCP-соединения
|
4 байта
|
xx
xx xx xx
|
STATUS
|
Статус,
см. CMD_CHANGE_STATUS для описания
|
4 байта
|
xx
xx xx xx
|
X3
|
неизвестно,
обычно 06 00 00 00
|
4 байта
|
xx
xx xx xx
|
X4
|
неизвестно,
обычно 00 00 00 00
|
4 байта
|
xx
xx xx xx
|
X5
|
неизвестно,
обычно 08 00 00 00
|
4 байта
|
xx
xx xx xx
|
X6
|
неизвестно,
обычно 50 00 00 00
|
4 байта
|
xx
xx xx xx
|
X7
|
неизвестно,
обычно 03 00 00 00
|
4 байта
|
xx
xx xx xx
|
X8
|
неизвестно,
случайное ?
|
Когда login-пакет
приходит на сервер, предполагаем,
что он корректен, вам будет
отправлена квитанция-уведомление о
получении (SRV_ACK) и login (SRV_LOGIN_REPLY).
CMD_REG_NEW_USER
FC 03 (1020)
Эта команда
посылается на сервер без
предварительного log в него. UIN-поле
заголовка пакета содержит NULL
Сервер подтвердит этот пакет и
ответит пакетом SRV_NEW_USER,
который содежит ваш новый UIN, с
которым вы должны немедленно
залогиниться (послать CMD_LOGIN с вашим
новым UIN и паролем). Когда вы успешно
залогинитесь (SRV_LOGIN_REPLY), вы должны
использовать команду CMD_NEW_USER_INFO для
установки основной информации,
такой как ваш ник например.
Параметры
Длина
|
Содержание
|
Сигнатура
|
Описание
|
2
байта
|
xx
xx
|
PASS_LENGTH
|
длина пароля
(максимум 9 символов)
|
переменная
|
xx...00
|
PASS
|
пароль для вашего
нового аккаунта
|
4
байта
|
A0
00 00 00
|
UNKNOWN1
|
неизвестно |
4
байта
|
61
24 00 00
|
UNKNOWN2
|
неизвестно
|
4 байта
|
00
00 A0 00
|
UNKNOWN3
|
неизвестно
|
4 байта
|
00
00 00 00
|
UNKNOWN4
|
неизвестно
|
CMD_CONTACT_LIST
06 04 (1030)
Эта команда
используется для информирования
сервера о пользователях, от которых
вы хотите получить online/offline событие
Параметры
Длина
|
Содержание
|
Сигнатура
|
Описание
|
1
байт
|
xx
|
NUM_CONTACTS
|
количество
UIN в этом пакете
|
4
байта
|
xx
xx xx xx
|
UIN_1
|
1-й
UIN в вашем контакт листе
|
...
|
...
|
...
|
...
|
4
байта
|
xx
xx xx xx
|
UIN_n
|
последний
UIN в вашем контакт листе
|
Примечание! Максимальное
число пользователей - 120 из-за длины
ICQ - пакета в 450 байт, если ваш
контакт лист содержит большее
число пользователей, вам следует
отправить этот пакет несколько раз.
CMD_SEARCH_UIN
1A 04 (1050)
Параметры
Длина
|
Содержание
|
Сигнатура
|
Описание
|
2
байта
|
xx
xx
|
SEARCH_SEQ
|
см.
инже
|
4
байта
|
xx
xx xx xx
|
SEARCH_UIN
|
искомый
UIN
|
CMD_SEARCH_USER
24 04 (1060)
Поиск
пользователя. Сервер отвечает
SRV_USER_FOUND для каждого найденного
пользователя и SRV_END_OF_SEARCH.
Параметры
Длина
|
Содержание
|
Сигнатура
|
Описание
|
2 байта
|
xx
xx
|
NICK_LENGTH
|
длина ника (включая
NULL)
|
переменная
|
xx...00
|
NICK
|
Ник, заканчивающийся
NULL
|
2 байта
|
xx
xx
|
FIRST_LENGTH
|
длина
имени (включая NULL) |
переменная
|
xx...00
|
FIRST
|
Имя, заканчивающееся
NULL
|
2 байта
|
xx
xx
|
LAST_LENGTH
|
длина фамилии
(включая NULL)
|
переменная
|
xx...00
|
LAST
|
Фамилия,
заканчивающаяся NULL
|
2
байта |
xx
xx
|
EMAIL_LENGTH |
длина
эл.адреса (включая NULL)
|
переменная
|
xx...00
|
EMAIL |
Эл.
адрес, заканчивающийся NULL
|
CMD_KEEP_ALIVE
2E 04 (1070)
Эта команда
должна посылаться серверу каждые 2
минуты. Если она не будет послана.
то сервер примет, что вы находитесь
off-line.
Длина
|
Содержание
|
Сигнатура
|
Описание
|
4
байта
|
xx
xx xx xx
|
RANDOM
|
Случайное
число
|
CMD_SEND_TEXT_CODE
38 04 (1080)
Этот пакет
используется для отправки серверу
специальных команд как текста.
Параметры
Длина
|
Содержание
|
Сигнатура
|
Описание
|
2
байта
|
xx
xx
|
LENGTH
|
длина
текстовой команды, включая
NULL-байт
|
переменная
|
xx..
|
TEXT_CODE
|
текст
кода, заканчивающаяся NULL
|
2
байта |
05 00 |
X1 |
неизвестно,
обычно 05 00 |
Возможные значения
TEXT_CODE:
TEXT_CODE |
Описание |
B_USER_DISCONNECTED |
Отсоединиться от
сервера |
B_MESSAGE_ACK |
Сказать
серверу ответить немедленно,
используется, если у вас
проблемы с подключением
|
B_KEEPALIVE_ACK |
Неизвестно,
возможно сходно с B_MESSAGE_ACK
|
Примечание!
При посылке этой команды поле SEQ_NUM2
заголовка пакета должно содержать
ноль.
CMD_ACK_MESSAGES
42 04 (1090)
Удаляет с
сервера старые сообщения. Обычно
используется, когда получено SRV_X2
Длина
|
Содержание
|
Сигнатура
|
Описание
|
4
байта
|
xx
xx xx xx
|
RANDOM
|
Случайное
число
|
CMD_LOGIN_1
4C 04 (1100)
Во время логина
посылается неизвестный пакет. Не
появляется при использовании ICQ99.
Длина
|
Содержание
|
Сигнатура
|
Описание
|
4
байта
|
xx
xx xx xx
|
RANDOM
|
Случайное
число
|
CMD_MSG_TO_NEW_USER
56 04 (1110)
CMD_INFO_REQ
60 04 (1120)
Запрашивает
основную информацию о
пользователе.
Длина
|
Содержание
|
Сигнатура
|
Описание
|
4
байта
|
xx
xx xx xx
|
UIN
|
UIN
пользователя, чье инфо вы
запрашиваете
|
Сервер ответит
SRV_INFO_REPLY
CMD_EXT_INFO_REQ
6A 04 (1130)
Запрашивает
расширенную информацию о
пользователе.
Длина
|
Содержание
|
Сигнатура
|
Описание
|
4
байта
|
xx
xx xx xx
|
UIN
|
UIN
пользователя, чье инфо вы
запрашиваете
|
Сервер ответит
SRV_EXT_INFO_REPLY
CMD_CHANGE_PW
9C 04 (1180)
Сменить пароль
входа. Эта команда устаревает.
Используйте вместо нее CMD_META_USER
CMD_NEW_USER_INFO
A6 04 (1190)
Отсылает
основную информацию о новом
зарегистрированном пользователе.
Эта команда отсылается, когда вы
залогинились в первый раз под своим
новым UIN. Смотри CMD_REG_NEW_USER.
Параметры
Длина
|
Содержание
|
Сигнатура
|
Описание
|
2 байта
|
xx
xx
|
NICK_LENGTH
|
длина ника (включая
NULL)
|
переменная
|
xx...00
|
NICK
|
Ник, заканчивающийся
NULL
|
2 байта
|
xx
xx
|
FIRST_LENGTH
|
длина
имени (включая NULL) |
переменная
|
xx...00
|
FIRST
|
Имя, заканчивающееся
NULL
|
2 байта
|
xx
xx
|
LAST_LENGTH
|
длина фамилии
(включая NULL)
|
переменная
|
xx...00
|
LAST
|
Фамилия,
заканчивающаяся NULL
|
2
байта |
xx
xx
|
EMAIL_LENGTH |
длина
эл.адреса (включая NULL)
|
переменная
|
xx...00
|
EMAIL |
Эл.
адрес, заканчивающийся NULL
|
1
байт |
01 |
UNKNOWN1 |
Неизвестно |
1
байт |
01 |
UNKNOWN2 |
Неизвестно |
1
байт |
01 |
UNKNOWN3 |
Неизвестно |
CMD_UPDATE_EXT_INFO
B0 04 (1200)
CMD_QUERY_SERVERS
BA 04 (1210)
Запрашивает
сервер об адресах других серверов
CMD_QUERY_ADDONS
С4 04 (1220)
Запрашивает
сервер об глобально-определенных
компонентах
CMD_STATUS_CHANGE
D8 04 (1240)
Изменяет online
статус пользователя (Away, Invisible и др.)
Параметры
Длина
|
Содержание
|
Сигнатура
|
Описание
|
4
байта
|
xx
xx xx xx
|
STATUS
|
Новый
статус - см.ниже
|
Статусы
Сигнатура |
Значение |
Описание |
STATUS_ONLINE |
00 00 00 00 |
User is online |
STATUS_AWAY |
01 00 00 00 |
User is away |
STATUS_DND |
13 00 00 00 |
Do Not Disturb |
STATUS_INVISIBLE |
00 01 00 00 |
User is invisible |
STATUS_OCCUPIED |
10 00 00 00 |
Occupied |
STATUS_NA |
04 00 00 00 |
Not Available |
STATUS_CHAT
|
20
00 00 00
|
Free
for chat
|
STATUS_DND и STATUS_NA могут
быть объединены со STATUS_AWAY в
зависимости от того, какую версию ICQ
вы используете.
CMD_NEW_USER_1
EC 04 (1260)
Запрашивает
разрешение на добавление нового
пользователя.
CMD_UPDATE_INFO
02 05 (1290)
Обновляет ваше
Info на серверах базы данных
пользователей ICQ
Параметры
Длина
|
Содержание
|
Сигнатура
|
Описание
|
2 байта
|
xx
xx
|
NICK_LENGTH
|
длина ника (включая
NULL)
|
переменная
|
xx...00
|
NICK
|
Ник, заканчивающийся
NULL
|
2 байта
|
xx
xx
|
FIRST_LENGTH
|
длина
имени (включая NULL) |
переменная
|
xx...00
|
FIRST
|
Имя, заканчивающееся
NULL
|
2 байта
|
xx
xx
|
LAST_LENGTH
|
длина фамилии
(включая NULL)
|
переменная
|
xx...00
|
LAST
|
Фамилия,
заканчивающаяся NULL
|
2
байта |
xx
xx
|
EMAIL_LENGTH |
длина
эл.адреса (включая NULL)
|
переменная
|
xx...00
|
EMAIL |
Эл.
адрес, заканчивающийся NULL
|
CMD_AUTH_UPDATE
14 05 (1300)
Обновляет ваш
статус авторизации (т.е. позволяете
ли вы пользователям добавить вас в
их контакт лист?)
Параметры
Длина
|
Содержание
|
Сигнатура
|
Описание
|
4
байта
|
xx
xx xx xx
|
AUTHORIZE
|
TRUE
- авторизация не запрашивается,
FALSE - запрашивается
|
CMD_KEEP_ALIVE2
1E 05 (1310)
В ранних версиях
эта команда посылалась серверу
наряду с командой CMD_KEEP_ALIVE. В ICQ99b уже
не используется.
Длина
|
Содержание
|
Сигнатура
|
Описание
|
4
байта
|
xx
xx xx xx
|
RANDOM
|
Случайное
число
|
CMD_LOGIN_2
28 05 (1320)
В ранних версиях
эта команда использовалась во
время логина.
CMD_ADD_TO_LIST
3C 05 (1340)
Добавить
пользователя в контакт лист. После
использования этой команды вы
получите данные о статусе
пользователя в дополнение к тем,
что уже находятся в вашем контакт
листе.
Длина
|
Содержание
|
Сигнатура
|
Описание
|
4
байта
|
xx
xx xx xx
|
UIN
|
UIN
пользователя, которого вы
хотите добавить в свой контакт
лист
|
CMD_RAND_SET
64 05 (1380)
Определяет, в
какой группе вы хотите быть
объявленным для Random Chat
Длина
|
Содержание
|
Сигнатура
|
Описание
|
4
байта
|
xx
xx xx xx
|
RAND_GROUP
|
См.
CMD_RAND_SEARCH
|
CMD_RAND_SEARCH
6E 05 (1390)
Поиск
случайного пользователя
Длина
|
Содержание
|
Сигнатура
|
Описание
|
4
байта
|
xx
xx xx xx
|
RAND_GROUP
|
См.
ниже
|
RAND_GROUP должно иметь
одно из следующих значений:
Name |
Value |
General |
1 |
Romance |
2 |
Games |
3 |
Students |
4 |
20 something |
6 |
30 something |
7 |
40 something |
8 |
50+ |
9 |
Man chat requesting women |
10 |
Woman chat requesting men |
11 |
CMD_META_USER
4A 06 (1610)
CMD_INVIS_LIST
A4 06 (1700)
Эта команда
информирует сервер о тех
пользователях, которых вы занесли в
Invisible список, даже если вы не
находитесь в статусе Invisible
Параметры
Длина
|
Содержание
|
Сигнатура
|
Описание
|
1
байт
|
xx
|
NUM_USERS
|
количество
UIN в этом пакете
|
4
байта
|
xx
xx xx xx
|
UIN_1
|
1-й
UIN в вашем контакт листе
|
...
|
...
|
...
|
...
|
4
байта
|
xx
xx xx xx
|
UIN_n
|
последний
UIN в вашем контакт листе
|
Примечание! Максимальное
число пользователей - 120 из-за длины
ICQ - пакета в 450 байт, если ваш
контакт лист содержит большее
число пользователей, вам следует
отправить этот пакет несколько раз.
CMD_VIS_LIST
AE 06 (1710)
Эта команда
информирует сервер о тех
пользователях, которых вы занесли в
Visible список, находясь в режиме Invisible
Параметры
Длина
|
Содержание
|
Сигнатура
|
Описание
|
1
байт
|
xx
|
NUM_USERS
|
количество
UIN в этом пакете
|
4
байта
|
xx
xx xx xx
|
UIN_1
|
1-й
UIN в вашем контакт листе
|
...
|
...
|
...
|
...
|
4
байта
|
xx
xx xx xx
|
UIN_n
|
последний
UIN в вашем контакт листе
|
Примечание! Максимальное
число пользователей - 120 из-за длины
ICQ - пакета в 450 байт, если ваш
контакт лист содержит большее
число пользователей, вам следует
отправить этот пакет несколько раз.
CMD_UPDATE_LIST
B8 06 (1720)
Эта команда
информирует сервер об изменениях в
ваших Invisible/Visible списках
Параметры
Длина
|
Содержание
|
Сигнатура
|
Описание
|
4
байта
|
xx
xx xx xx
|
UIN
|
UIN
добавленного или удаленного из
списка пользователя
|
1
байт
|
xx
|
LIST
|
Список
до изменения, 01-Invisible, 02-Visible
|
1
байт |
xx |
REMADD |
00 -
пользователь удален, 01-
пользователь добавлен в список |
3. Пакеты Сервер -
Клиент
Каждый
сервер-клиентский UDP-пакет имеет
следующий заголовок:
Заголовок
ICQ-пакета (со стороны Сервера)
Длина
|
Содержание (если
установлено)
|
Сигнатура
|
Описание
|
2 байта
|
05 00
|
VERSION
|
Версия протокола
|
1
байт
|
00
|
ZERO
|
неизвестно
|
4
байта
|
xx
xx xx xx
|
SESSION_ID
|
Такое
же как в вашем login-пакете
|
2
байта
|
xx
xx
|
COMMAND
|
|
2
байта
|
xx
xx
|
SEQ_NUM1
|
Последовательность
1
|
2
байта
|
xx
xx
|
SEQ_NUM2
|
Последовательность
2
|
4
байта
|
xx
xx xx xx
|
UIN
|
Ваш
(клиентский) номер ICQ
|
4
байта
|
xx
xx xx xx
|
|
|
переменная
|
xx
...
|
PARAMETERS
|
Параметры
посылаемой команды
|
Эти пакеты всегда не
шифрованы. Для подробного описания
полей см. раздел Клиент-сервер
SRV_ACK
0A 00 (10)
Квитанция на
команду, посланную серверу. Пока
эта квитанция не получена, вы
должна продолжать посылать на
сервер свою команду, с приемлемой
задержкой. Клиент Mirabilis посылает
команду 6 раз с задержкой в 10 секунд.
Затем посылается CMD_SEND_TEXT_CODE
с B_MESSAGE_ACK.
Параметров нет.
Порядковые номера в
заголовке содержат порядковые
номера клиентский подтвержденных
пакетов.
SRV_GO_AWAY
28 00 (40)
Сообщение от сервера
об ошибке. Вам следует
дисконнектиться и повторить
попытку подключения к серверу.
Параметров нет.
SRV_NEW_UIN
46 00 (70)
Новый UIN, запрошенный
CMD_REG_NEW_USER, был сохранен для вас. UIN -
это поле UIN в заголовке. После
получения вы должны законнектиться
к серверу, используя новый UIN для
завершения регистрации (нормальная
процедура входа).
Параметров нет.
SRV_LOGIN_REPLY
5A 00 (90)
Этот пакет
отсылается сервером в случае, если
он корректно получил команду CMD_LOGIN.
Параметры
Длина
|
Содержание
|
Сигнатура
|
Описание
|
4 байта
|
8C
00 00 00
|
X1
|
неизвестно (dec:
140)
|
2 байта
|
F0
00
|
X2
|
неизвестно (dec: 240)
|
2 байта
|
0A
00
|
X3
|
неизвестно
(dec: 10) |
2 байта
|
0A
00
|
X4
|
неизвестно (dec: 10)
|
2 байта
|
05
00
|
X5
|
неизвестно (dec:
5, версия?)
|
4 байта
|
xx
xx xx xx
|
IP
|
Ваш IP
|
4 байта
|
xx
xx xx xx
|
X6
|
неизвестно
|
SRV_BAD_PASS
64 00 (100)
Пароль в login-пакете
был неверный. Если вы уверены в его
правильности, проверьте длину
пароля и удостоверьтесь, что он
заканчивается NULL.
Параметров нет.
SRV_USER_ONLINE
6E 00 (110)
Пользователь из
вашего контакт листа сменил свой
статус так, что теперь вы можете его
видеть (т.е. он сменил свой статус
Invisible или offline на любой другой)
Параметры
Длина
|
Содержание
|
Сигнатура
|
Описание
|
4
байта
|
xx
xx xx xx
|
UIN
|
UIN
пользователя, сменившего
статус
|
4
байта
|
xx
xx xx xx
|
IP
|
IP-адрес
пользователя
|
4
байта
|
xx
xx xx xx
|
PORT
|
порт,
используемый пользователем
для соединения
|
4
байта
|
xx
xx xx xx
|
REAL_IP
|
реальный
IP-адрес пользователя
|
1 байт
|
xx
|
X1
|
неизвестно,
обычно 04
|
4 байта
|
xx
xx xx xx
|
STATUS
|
Новый
статус пользователя, см.
CMD_STATUS_CHANGE
|
4 байта
|
xx
xx xx xx
|
X2
|
неизвестно
|
4 байта
|
xx
xx xx xx
|
X3
|
неизвестно
|
4 байта
|
xx
xx xx xx
|
X4
|
неизвестно
|
4 байта
|
xx
xx xx xx
|
X5
|
неизвестно
|
4 байта
|
xx
xx xx xx
|
X6
|
неизвестно
|
4 байта
|
xx
xx xx xx
|
X7
|
неизвестно
|
SRV_USER_OFFLINE
78 00 (120)
Пользователь из
вашего контакт листа ушел в
офф-лайн
Длина
|
Содержание
|
Сигнатура
|
Описание
|
4
байта
|
xx
xx xx xx
|
UIN
|
UIN
пользователя, ушедшего в
офф-лайн
|
SRV_QUERY
82 00 (130)
Ответ на CMD_QUERY_SERVES и
CMD_QUERY_ADDONS.
SRV_USER_FOUND
8C 00 (140)
Пользователь,
соответствующий критериям выбора в
ранее посланной команде CMD_SEARCH_USER
или CMD_SEARCH_UIN, найден. Если было
найдено несколько пользователей,
вы получите пакет для каждого из
них.
Параметры
Длина
|
Содержание
|
Сигнатура
|
Описание
|
4
байта |
xx xx
xx xx |
UIN |
UIN
найденного пользователя |
2 байта
|
xx
xx
|
NICK_LENGTH
|
длина ника (включая
NULL)
|
переменная
|
xx...00
|
NICK
|
Ник, заканчивающийся
NULL
|
2 байта
|
xx
xx
|
FIRST_LENGTH
|
длина
имени (включая NULL) |
переменная
|
xx...00
|
FIRST
|
Имя, заканчивающееся
NULL
|
2 байта
|
xx
xx
|
LAST_LENGTH
|
длина фамилии
(включая NULL)
|
переменная
|
xx...00
|
LAST
|
Фамилия,
заканчивающаяся NULL
|
2
байта |
xx
xx
|
EMAIL_LENGTH |
длина
эл.адреса (включая NULL)
|
переменная
|
xx...00
|
EMAIL |
Эл.
адрес, заканчивающийся NULL
|
1
байт |
xx |
AUTHORIZE |
Статус
автороизации пользователя, см.
ниже |
AUTHORIZE может содержать
только 00 или 01. 00 значит, что клиенту
нужно послать запрос об
авторизации, перед тем, как
добавить пользователя в контакт
лист, 01 - посылать запрос не надо.
SRV_END_OF_SEARCH
A0 00 (160)
Пользователь не
найден или найдено слишком много
пользователей.
Длина
|
Содержание
|
Сигнатура
|
Описание
|
1
байт
|
xx
|
TOO_MANY
|
Было
найдено слишком много
пользователей
|
Если TOO_MANY равно 00, то
вы получите всех подходящих
пользователей из базы данных. Если
01, то в базе данных очень много
пользователей, удовлетворяющих
критериям поиска, но они вам
посланы не будут. Предел - 40
пользователей.
SRV_RECV_MESSAGE
DC 00 (220)
Этот пакет
шлется вам во время вашего логина
на сервер, если на сервере есть для
вас какие-либо пакеты (так
называемые
"оффлайн-сообщения")
Длина
|
Содержание
|
Сигнатура
|
Описание
|
4
байта
|
xx
xx xx xx
|
UIN
|
UIN отправителя
|
2
байта
|
xx
xx
|
YEAR
|
год, когда было
послано сообщение
|
1
байт
|
xx
|
MONTH
|
месяц,
когда было послано сообщение |
1
байт
|
xx
|
DAY
|
день месяца
|
1 байт
|
xx
|
HOUR
|
час, когда было
послано сообщение
|
1 байт
|
xx
|
MINUTE
|
минута
|
2
байта |
xx xx |
MESSAGE_TYPE |
тип
сообщения, см. ниже |
2
байта |
xx xx |
MESSAGE_LENGTH |
длина
сообщения (включая NULL) |
переменная |
xx...00 |
MESSAGE_TEXT |
текст
сообщения |
MESSAGE_TYPE может
иметь одно из следующих значений:
Сигнатура |
Значение |
Описание |
MSG_TXT |
01 00 |
Обычное текстовое
сообщение |
MSG_URL |
04 00 |
URL-сообщение, состоит
из 2-х частей, разделенных 0xFE.
Первая - описание URL |
MSG_AUTH_REQ |
06 00 |
Запрос на добавление
пользователя в контакт лист.
Состоит из 5 частей,
разделенных 0xFE - ник, имя,
фамилия, эл.адрес, причина |
MSG_AUTH |
08 00 |
Разрешение добавить
пользователя в контакт лист |
MSG_USER_ADDED |
0C 00 |
Сообщение о том, что
пользователь был добавлен в
контакт лист. Состоит из 4
частей, разделенных 0xFE - ник,
имя, фамилия, эл.адрес |
MSG_CONTACTS |
13 00 |
Послан Contact. Это
сообщение состоит из
нескольких ников и номеров ICQ,
разделенных 0xFE. Первая часть
сообщения - число контактов
(пары nickname/UIN) в сообщении,
записанное в ASCII-коде,
завершается 0xFE |
Образец URL-сообщения:
0000: 78 56 34 12 CF 07 04 0E 0D 07 04 00 16 00 4D 69 xV4...........Mi
0010: 72 61 62 69 6C 69 73
FE 77
77 77 2E 69 63 71 2E rabilis.www.icq.com
0020: 63 6F 6D 00
Цветной текст - это
MESSAGE_TEXT. Зеленые номера показывают
описание URL ('Mirabilis'). Синие
номера показывают непосредственно
сам URL. Красный байт разделяет эти две
строки, и заключительный желтый
байт (00) - NULL - окончание
Часть сообщения,
написанная черным цветом, содержит
следующие сведения:
UIN: 0x12345678
Date: 1999-04-14
Time: 13:07
Type: MSG_URL
Length: 22 bytes
SRV_UPDATE_SUCCESS
E0 01 (480)
Команда CMD_UPDATE_INFO по изменению
вашего info была успешно выполнена
SRV_UPDATE_FAIL
E0 01 (480)
Команда CMD_UPDATE_INFO по изменению
вашего info не была выполнена
SRV_MULTI_PACKET
12 02 (530)
Одновременно
послано несколько пакетов. Сервер
использует этот пакет всегда, когда
послан более, чем один пакет.
Параметры
Длина
|
Содержание
|
Сигнатура
|
Описание
|
1
байт |
xx |
NUM_PACKETS |
кол-во
пакетов |
2 байта
|
xx
xx
|
SIZE_1
|
размер первого пакета
|
переменная
|
05...00...
|
PKT_1
|
1-й пакет
|
2 байта
|
xx
xx
|
SIZE_2
|
размер
второго пакета |
переменная
|
05...00...
|
PKT_2
|
2-й пакет
|
...
|
...
|
...
|
...
|
2
байта |
xx
xx
|
SIZE_n |
размер
n-го пакета
|
переменная
|
05...00...
|
PKT_n |
n-й
пакет
|
Поля CHECK всех
входящих пакетов все установлены в
NULL. Квитирование должно быть
выполнено только к SRV_MULTI, а не ко
всем инкапсулированным пакетам.
SRV_META_USER
DE 03 (990)
Ответ на CMD_META_USER.
Параметры
Длина
|
Содержание
|
Сигнатура
|
Описание
|
2
байта
|
xx
xx
|
SUBCMD
|
Подкоманда,
см. ниже
|
1
байт
|
xx
|
RESULT
|
Результат
выполнения функции - удачное
или неудачное завершение, см.
ниже
|
переменная |
xx... |
DATA |
Запрашиваемые
вами данные, см. ниже |
RESULT
: 0x0A - удачное завершение, 0x32 -
неудачное
SUBCMD
и DATA
META_USER_FOUND - 9A 01
(xx)
DATA
для подкоманды META_USER_FOUND
Длина
|
Содержание
|
Сигнатура
|
Описание
|
4
байта |
xx xx
xx xx |
UIN |
UIN
найденного пользователя |
2 байта
|
xx
xx
|
NICK_LENGTH
|
длина ника (включая
NULL)
|
переменная
|
xx...00
|
NICK
|
Ник, заканчивающийся
NULL
|
2 байта
|
xx
xx
|
FIRST_LENGTH
|
длина
имени (включая NULL) |
переменная
|
xx...00
|
FIRST
|
Имя, заканчивающееся
NULL
|
2 байта
|
xx
xx
|
LAST_LENGTH
|
длина фамилии
(включая NULL)
|
переменная
|
xx...00
|
LAST
|
Фамилия,
заканчивающаяся NULL
|
2
байта |
xx
xx
|
EMAIL_LENGTH |
длина
эл.адреса (включая NULL)
|
переменная
|
xx...00
|
EMAIL |
Эл.
адрес, заканчивающийся NULL
|
1
байт |
xx |
AUTHORIZE |
Статус
автороизации пользователя, см.
ниже |
2
байта |
xx xx |
X2 |
неизвестно |
4
байта |
xx xx
xx xx |
X3 |
неизвестно |
AUTHORIZE может содержать
только 0x00 или 0x01. 0x00 значит, что
клиенту нужно послать запрос об
авторизации, перед тем, как
добавить пользователя в контакт
лист, 0x01 - посылать запрос не надо.
META_ABOUT - E6 00 (xx)
DATA
для подкоманды META_ABOUT
Длина
|
Содержание
|
Сигнатура
|
Описание
|
2
байта
|
xx
xx
|
ABOUT_LENGTH
|
длина
строки
|
переменная
|
xx
...00
|
ABOUT
|
строка
|
META_USER_INFO - C8 00 (xx)
DATA
для подкоманды META_USER_INFO
Длина
|
Содержание
|
Сигнатура
|
Описание
|
4
байта |
xx xx
xx xx |
UIN |
UIN
пользователя |
2 байта
|
xx
xx
|
NICK_LENGTH
|
длина ника
|
переменная
|
xx...00
|
NICK
|
Ник
|
2 байта
|
xx
xx
|
FIRST_LENGTH
|
длина
имени |
переменная
|
xx...00
|
FIRST
|
Имя
|
2 байта
|
xx
xx
|
LAST_LENGTH
|
длина фамилии
|
переменная
|
xx...00
|
LAST
|
Фамилия
|
2
байта |
xx
xx
|
PRIMARY_LENGTH |
длина
эл.адреса
|
переменная
|
xx...00
|
PRIMARY_EMAIL |
Эл.
адрес
|
2
байта |
xx xx |
SECONDARY_LENGTH |
длина
второго эл.адреса |
переменная |
xx...00 |
SECONDARY_EMAIL |
Второй
эл.адрес |
2
байта |
xx xx |
OLD_LENGTH |
длина
старого эл.адреса |
переменная |
xx...00 |
OLD_EMAIL |
старый
эл.адрес |
2
байта |
xx xx |
CITY_LENGTH |
длина
названия города |
переменная |
xx...00 |
CITY |
город |
2
байта |
xx xx |
STATE_LENGTH |
длина
названия штата |
переменная |
xx...00 |
STATE |
штат |
2
байта |
xx xx |
PHONE_LENGTH |
длина
номера телефона |
переменная |
xx...00 |
PHONE |
номер
телефона |
2
байта |
xx xx |
FAX_LENGTH |
длина
номера факса |
переменная |
xx...00 |
FAX |
номер
факса |
2
байта |
xx xx |
STREET_LENGTH |
длина
названия улицы |
переменная |
xx...00 |
STREET |
название
улицы |
2
байта |
xx xx |
CELL_LENGTH |
длина
номера сотового телефона |
переменная |
xx...00 |
CELLULAR |
номер
сотового телефона |
4
байта |
xx xx
xx xx |
ZIPCODE |
Zip
код |
2
байта |
xx xx |
COUNTRY |
Страна |
1
байт |
xx |
TIMEZONE |
Часовой
пояс |
1
байт |
xx |
AUTHORIZE |
Нужен
ли запрос на авторизацию (0x00 -
нужен, 0x01 - нет) |
1
байт |
xx |
WEBAWARE |
Статус
пользователя в Web |
1
байт |
xx |
HIDEIP |
Не
показывать IP пользователя |
4. Расчет
контрольной суммы
Контрольная
сумма вычисляется до шифрования
пакета.
- Вычисление
NUMBER1
- B8 = байт в
позиции 8 пакета. (начиная с
позиции 0)
- B4 = байт в
позиции 4 пакета.
- B2 = байт в
позиции 2 пакета.
- B6 = байт в
позиции 6 пакета
Соединяем эти
части вместе и получаем NUMBER1:
NUMBER1 = 0x B8 B4 B2 B6 (B8 = MSB,
B6 = LSB)
Вот фрагмент кода
на С:
unsigned long number1;
number1 = packet[8];
number1 <<= 8;
number1 |= packet[4];
number1 <<= 8;
number1 |= packet[2];
number1 <<= 8;
number1 |= packet[6];
- Следующее
вычисление
- PL - длина пакета
- R1 - случайное
число между 0x18 и PL
- R2 - другое
случайное число между 0 и 0xFF
C-код:
int r1, r2;
r1 = 0x18 + rand() % (PL - 0x18);
r2 = rand() % 0xFF;
- Вычисление
NUMBER2
- X4=R1
- X3=NOT(байт в
позиции X4 в пакете)
- X2=R2
- X1=NOT(байт в
позиции X2 в ТАБЛИЦЕ) (см.
секцию ТАБЛИЦЫ)
- NUMBER2 = 0x X4 X3 X2 X1 (X4 =
MSB, X1 = LSB)
Пример C-кода:
unsigned long number2;
number2 = r1;
number2 <<= 8;
number2 |= packet[r1];
number2 <<= 8;
number2 |= r2;
number2 <<= 8;
number2 |= table[r2];
number2 ^= 0xff00ff;
Сейчас вы можете подсчитать контрольную сумму:
CHECKCODE = NUMBER1 XOR NUMBER2
C-код:
unsigned long cc = number1 ^ number2
ТАБЛИЦА
Алгоритм
использует данную таблицу
констант. TABLE[x] означает число в
позиции X таблицы (начиная с позиции
0)
POS DATA ASCII
--- ----------------------------------------------- ----------------
00 - 59 60 37 6B 65 62 46 48 53 61 4C 59 60 57 5B 3D Y`7kebFHSaLY`W[=
10 - 5E 34 6D 36 50 3F 6F 67 53 61 4C 59 40 47 63 39 ^4m6P?ogSaLY@Gc9
20 - 50 5F 5F 3F 6F 47 43 69 48 33 31 64 35 5A 4A 42 P__?oGCiH31d5ZJB
30 - 56 40 67 53 41 07 6C 49 58 3B 4D 46 68 43 69 48 V@gSA.lIX;MFhCiH
40 - 33 31 44 65 62 46 48 53 41 07 6C 69 48 33 51 54 31DebFHSA.liH3QT
50 - 5D 4E 6C 49 38 4B 55 4A 62 46 48 33 51 34 6D 36 ]NlI8KUJbFH3Q4m6
60 - 50 5F 5F 5F 3F 6F 47 63 59 40 67 33 31 64 35 5A P___?oGcY@g31d5Z
70 - 6A 52 6E 3C 51 34 6D 36 50 5F 5F 3F 4F 37 4B 35 jRn.Q4m6P__?O7K5
80 - 5A 4A 62 66 58 3B 4D 66 58 5B 5D 4E 6C 49 58 3B ZJbfX;MfX[]NlIX;
90 - 4D 66 58 3B 4D 46 48 53 61 4C 59 40 67 33 31 64 MfX;MFHSaLY@g31d
A0 - 55 6A 32 3E 44 45 52 6E 3C 31 64 55 6A 52 4E 6C Uj2.DERn.1dUjRNl
B0 - 69 48 53 61 4C 39 30 6F 47 63 59 60 57 5B 3D 3E iHSaL90oGcY`W[=.
C0 - 64 35 3A 3A 5A 6A 52 4E 6C 69 48 53 61 6C 49 58 d5::ZjRNliHSalIX
D0 - 3B 4D 46 68 63 39 50 5F 5F 3F 6F 67 53 41 25 41 ;MFhc9P__?ogSA%A
E0 - 3C 51 54 3D 5E 54 5D 4E 4C 39 50 5F 5F 5F 3F 6F .QT=^T]NL9P___?o
F0 - 47 43 69 48 33 51 54 5D 6E 3C 31 64 35 5A 00 00 GCiH3QT]n.1d5Z..
--- ----------------------------------------------- ----------------
The Table in C
static const BYTE table[] = {
0x59, 0x60, 0x37, 0x6B, 0x65, 0x62, 0x46, 0x48,
0x53, 0x61, 0x4C, 0x59, 0x60, 0x57, 0x5B, 0x3D,
0x5E, 0x34, 0x6D, 0x36, 0x50, 0x3F, 0x6F, 0x67,
0x53, 0x61, 0x4C, 0x59, 0x40, 0x47, 0x63, 0x39,
0x50, 0x5F, 0x5F, 0x3F, 0x6F, 0x47, 0x43, 0x69,
0x48, 0x33, 0x31, 0x64, 0x35, 0x5A, 0x4A, 0x42,
0x56, 0x40, 0x67, 0x53, 0x41, 0x07, 0x6C, 0x49,
0x58, 0x3B, 0x4D, 0x46, 0x68, 0x43, 0x69, 0x48,
0x33, 0x31, 0x44, 0x65, 0x62, 0x46, 0x48, 0x53,
0x41, 0x07, 0x6C, 0x69, 0x48, 0x33, 0x51, 0x54,
0x5D, 0x4E, 0x6C, 0x49, 0x38, 0x4B, 0x55, 0x4A,
0x62, 0x46, 0x48, 0x33, 0x51, 0x34, 0x6D, 0x36,
0x50, 0x5F, 0x5F, 0x5F, 0x3F, 0x6F, 0x47, 0x63,
0x59, 0x40, 0x67, 0x33, 0x31, 0x64, 0x35, 0x5A,
0x6A, 0x52, 0x6E, 0x3C, 0x51, 0x34, 0x6D, 0x36,
0x50, 0x5F, 0x5F, 0x3F, 0x4F, 0x37, 0x4B, 0x35,
0x5A, 0x4A, 0x62, 0x66, 0x58, 0x3B, 0x4D, 0x66,
0x58, 0x5B, 0x5D, 0x4E, 0x6C, 0x49, 0x58, 0x3B,
0x4D, 0x66, 0x58, 0x3B, 0x4D, 0x46, 0x48, 0x53,
0x61, 0x4C, 0x59, 0x40, 0x67, 0x33, 0x31, 0x64,
0x55, 0x6A, 0x32, 0x3E, 0x44, 0x45, 0x52, 0x6E,
0x3C, 0x31, 0x64, 0x55, 0x6A, 0x52, 0x4E, 0x6C,
0x69, 0x48, 0x53, 0x61, 0x4C, 0x39, 0x30, 0x6F,
0x47, 0x63, 0x59, 0x60, 0x57, 0x5B, 0x3D, 0x3E,
0x64, 0x35, 0x3A, 0x3A, 0x5A, 0x6A, 0x52, 0x4E,
0x6C, 0x69, 0x48, 0x53, 0x61, 0x6C, 0x49, 0x58,
0x3B, 0x4D, 0x46, 0x68, 0x63, 0x39, 0x50, 0x5F,
0x5F, 0x3F, 0x6F, 0x67, 0x53, 0x41, 0x25, 0x41,
0x3C, 0x51, 0x54, 0x3D, 0x5E, 0x54, 0x5D, 0x4E,
0x4C, 0x39, 0x50, 0x5F, 0x5F, 0x5F, 0x3F, 0x6F,
0x47, 0x43, 0x69, 0x48, 0x33, 0x51, 0x54, 0x5D,
0x6E, 0x3C, 0x31, 0x64, 0x35, 0x5A, 0x00, 0x00,
};
5. Шифрование
Выполните
следующие действия:
- Подсчитайте
контрольную сумму (см. главу 4)
- Установите
PL=длина пакета
- Вычислите код
шифрования:
CODE = (LONG) (PL * 0x68656C6C) +
CHECKCODE (округлите)
- Для каждой
записи типа longword (32 бита) в
структуре, начинающейся с
адреса 0x0A, выполняется
операция XOR для значения
предварительно вычисленной
суммы CODE и байта в
соответствующей позиции
таблицы. (Например для записи
(longword) по адресу 0x0A должно быть
вычислено значение операции
исключающего ИЛИ с значением
по адресу 0x0A в таблице
сложенным с CODE.)
Итак, пакет
зашифрован. Теперь надо поместить
контрольную сумму в пакет, так
чтобы сервер смог расшифровать его.
/*
Encrypting the packet.
Assuming that checkcode has been calculated as previously
described, and that pl = packet length.
The packet to encrypt is pointed to by pkpptr.
*/
code = pl * 0x68656c6c + checkcode;
for(pos=0xa;pos < (pl + 3);pos+=4)
{
pktptr[pos]^ = code + table[pos & 0xFF];
}
/*
Scrambling the checkcode.
Assuming that cc holds the checkcode.
*/
ULONG a[6];
a[1] = cc & 0x0000001F;
a[2] = cc & 0x03E003E0;
a[3] = cc & 0xF8000400;
a[4] = cc & 0x0000F800;
a[5] = cc & 0x041F0000;
a[1] <<= 0x0C;
a[2] <<= 0x01;
a[3] >>= 0x0A;
a[4] <<= 0x10;
a[5] >>= 0x0F;
checkcodetoinsert = a[1] + a[2] + a[3] + a[4] + a[5];
Литература по ICQ протоколу
|