Tsharkd
Материал из b4wiki
Содержание |
Создаем свой сетевой анализатор по типу tshark'а
"tshark" - это сетевой анализатор с текстовым интерфейсом, входящий в пакет известного анализатора "wireshark". Мы назвали наш проект tsharkd.
Недостатки tshark'а:
- буферизация при декодировании пакетов получаемых со стандартного входа
- медленная загрузка
Отличия tsharkd:
- + нет буферизации
- + сетевой демон
- - упрощенные настройки
Термины
- EPAN - Ethereal Packet ANalyzer
- dissector - результат разбора/анализа, а также декодер для конкретного протокола
Для начала разработки нам необходим:
- glib-2.0 [libs, headers]
- библиотеки libwireshark, libwiretap, libwsutil (поставляются вместе с бинарным пакетом wireshark)
- исходники wireshark[1]
Описание общего процесса функционирования
Основные стадии
- Инициализация
- В цикле: прием и декодирование пакетов
- Деинициализация
Описание стадий
- Инициализация
- задаем тип timestamp
timestamp_set_type( type_of_ts );
timestamp_set_precision( TS_PREC_AUTO_USEC ); - инициализируем EPAN
epan_init( register_all_protocols, register_all_protocol_handoffs, NULL, NULL, failure_message, open_failure_message, read_failure_message, write_failure_message ); - регистрируем не-dissect модули
prefs_register_modules( ); - сбрасываем настройки
setlocale( LC_ALL, "" ); - Инициализируем глобальные настройки
prefs = read_prefs( &gpf_open_errno, &gpf_read_errno, &gpf_path, &pf_open_errno, &pf_read_errno, &pf_path ); - (при необходимости) заполняем шаблон колонок
- инициализируем декодеры
init_dissection( );
- задаем тип timestamp
- Деинициализация
- деинициализируем декодеры
cleanup_dissection( ); - деинициализируем EPAN
epan_cleanup( );
- деинициализируем декодеры
- Декодирование пакета
- заполняем дополнительную информацию о пакете (структура frame_data)
- создаем стуктуру для разбора пакета
edt = epan_dissect_new( verbose, verbose ); - декодируем пакет
epan_dissect_run( edt, &psh, pkt, &fdata, ( verbose ) ? NULL : cinfo ); - освобождаем структуру с разобранным пакетом
epan_dissect_free( edt );
- Краткое отображение пакета
- получаем информацию о колонках
column_info *cinfo = ( edt->pi ).cinfo; - выводим необходимые колонки
for( i = 0; i < cinfo->num_cols; i++ ) {
switch ( cinfo->col_fmt[i] ) {
... cinfo->col_data[i] ...
- получаем информацию о колонках
- Подробное отображение пакета
- заполнение колонок
epan_dissect_fill_in_columns( edt ); - декодируем вниз по стеку протоколов (вызывает отображение
информации пакета для текущего уровня)
proto_tree_children_foreach( edt->tree, proto_tree_print_node, &pd );
- заполнение колонок
- Отображение информации пакета для текущего уровня
- получаем текущее информационное поле в виде строки
if ( fi->rep ) {
label_ptr = fi->rep->representation;
} else {
label_ptr = label_str; proto_item_fill_label( fi, label_str );
} - если есть более низкие уровни (node->first_child != NULL), декодируем вниз по стеку
протоколов
proto_tree_children_foreach( node, proto_tree_print_node, pd );
- получаем текущее информационное поле в виде строки
Упоминаемые переменные
| Имя переменной |
Тип переменной |
Комментарий |
| edt | epan_dissect_t * | Декодированный пакет |
| fdata | frame_data | Дополнительная информация о пакете |
| prefs | e_prefs * | Указатель на глобальные настройки |
| node | proto_node * | Указатель на текущий узел |
| fi | field_info * | Информация о поле декодированного пакета. |
Что из wireshark'а использовалось
Использованные заголовочные файлы wireshark'а
- epan/column.h
Используется для совместимости - epan/column_info.h
Здесь объявлена структура column_info - epan/column-utils.h
Функции для инициализации и прочей работы со структурой column_info - epan/epan.h
Общие функции для работы с EPAN [epan_init, epan_cleanup] - epan/epan_dissect.h
Здесь объявлена структура epan_dissect_t - epan/filesystem.h
Вспомогательные функции - epan/frame_data.h
Здесь объявлена структура frame_data - epan/packet.h
Функции для работы с диссекторами [init_dissection, cleanup_dissection] - epan/packet_info.h
Здесь объявлена структура packet_info - epan/prefs.h
Здесь объявлена структура e_prefs - epan/proto.h
Функции для работы с подробно декодированным пакетом - epan/timestamp.h
Перечисления для типа/точности временной отметки. Функции для задания/получения типа/точности отметки.
Использованные структуры wireshark'а
- column_info [epan/column_info.h]
Шаблон/информация о колонке.
Некоторые полезные поля:- num_cols - количество колонок
- col_fmt[i] - формат i-ой колонки
- col_data[i] - информация об i-ой колонке в виде строки
- e_prefs [epan/prefs.h]
Общие настройки.
Некоторые полезные поля:- num_cols - количество колонок по умолчанию
- epan_dissect_t [epan/epan_dissect.h]
Информация о результате декодирования.
Некоторые полезные поля:- pi - информация о декодированном пакете в структуре packet_info
- field_info [epan/proto.h]
Информация о конкретном поле декодированного пакет. - frame_data [epan/frame_data.h]
Дополнительная информация о пакете.
Некоторые полезные поля:- num - номер пакета
- pkt_len - длина пакета
- cap_len - длина реально захваченных данных
- abs_ts, rel_ts - различные временные метки
- packet_info [epan/packet_info.h]
Информация о декодированном макете.
Некоторые полезные поля:- cinfo - информация о декодированном пакете в виде структуры column_info
- proto_node [epan/proto.h]
Узел дерева для хранения подробной информации о декодированном пакете.
Некоторые полезные поля:- first_child - указатель на первое декодированное поле для нижележащего протокола
Использованные функции wireshark'а
- cleanup_dissection [epan/packet.h]
Освободить структуры выделенные для разбора
Сигнатура
void cleanup_dissection(void) - epan_cleanup [epan/epan.h]
Очистить весь модуль epan, в программе вызывается один раз
Сигнатура
void epan_cleanup(void) - epan_dissect_fill_in_columns [epan/epan.h]
Перенести результаты разбора в колонки пакета
Параметр edt - структура, заполненная разобранным пакетом
Сигнатура
void epan_dissect_fill_in_columns(epan_dissect_t *edt) - epan_dissect_free [epan/epan.h]
Освобить результат разбора для одного пакета
Параметр edt - структура для хранения разобранного пакета
Сигнатура
void epan_dissect_free(epan_dissect_t* edt) - epan_dissect_new [epan/epan.h]
Выделить память для разбора одного пакета, д.б. освобождена посредством epan_dissect_free() после выполнения разбора пакета
Параметр create_proto_tree - создавать дерево (необходимо при детальном разборе)
Параметр proto_tree_visible - отображать дерево (необходимо при детальном разборе)
Результат - структура для хранения разобранного пакета
Сигнатура
epan_dissect_t* epan_dissect_new(gboolean create_proto_tree, gboolean proto_tree_visible); - epan_dissect_run [epan/epan.h]
Выполнить разбор для одного пакета
Параметр edt - структура для хранения разобранного пакета
Параметр pseudo_header - указатель на wtap_pseudo_header
Параметр data - указатель на данные пакета
Параметр fd - дополнительные данные пакета
Параметр cinfo - если не NULL, то на выходе информация о колонках (использается при кратком разборе)
Сигнатура
void epan_dissect_run(epan_dissect_t edt, void pseudo_header, const guint8* data, frame_data *fd, column_info *cinfo); - epan_init [epan/epan.h]
Инициализация всего модуля epan, в программе вызывается один раз
Параметр register_all_protocols_func - указатель на функцию register_all_protocols
Параметр register_all_handoffs_func - указатель на функцию register_all_protocol_handoffs
Параметр cb - NULL
Параметр client_data - NULL
Параметр report_failure, report_read_failure, report_write_failure - указатели на функции оповещения об ошибках
Сигнатура
void epan_init(void (*register_all_protocols_func)(register_cb cb, gpointer client_data), void (*register_all_handoffs_func)(register_cb cb, gpointer client_data), register_cb cb, void *client_data, void (*report_failure)(const char *, va_list), void (*report_open_failure)(const char *, int, gboolean), void (*report_read_failure)(const char *, int), void (*report_write_failure)(const char *, int)); - init_dissection [epan/packet.h]
Инициализация структур используемых для разбора
Сигнатура
void init_dissection(void) - prefs_register_modules [epan/prefs.h]
Зарегистрировать модули
Сигнатура
void prefs_register_modules(void) - proto_item_fill_label [epan/proto.h]
Заполнить переденную label_str строковым пердставлением поля
Параметр fi - струтура, описывающая поле
Параметр label_str - строка для заполнения
Сигнатура
void proto_item_fill_label(field_info *fi, gchar *label_str) - proto_tree_children_foreach [epan/proto.h]
Пройтись по всем полям текущего протокола
Параметр tree - дерево
Параметр func - callback, вызываемый для каждого поля для текущего протокола
Параметр data - данные для callback
Сигнатура
void proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func, gpointer data) - read_prefs [epan/prefs.h]
Проинициализировать глобальные настройки
Параметры gpf_open_errno, gpf_read_errno, pf_open_errno, pf_read_errno - указатели на какие-то коды ошибок
Параметры gpf_path, pf_path - указатели на какие-то пути
Сигнатура
e_prefs *read_prefs(int *gpf_open_errno, int- gpf_read_errno, char **gpf_path, int *pf_open_errno, int
- pf_read_errno, char **pf_path);
- timestamp_set_type [epan/timestamp.h]
Установить тип временной отметки
Параметр tst - тип отметки
Сигнатура
void timestamp_set_type(ts_type tst) - timestamp_set_precision [epan/timestamp.h]
Установить точность временной отметки
Параметр tsp - точность отметки
Сигнатура
void timestamp_set_precision(int tsp);
